1 /***************************************************************************
2 * Copyright 2004 Lubos Lunak <l.lunak@kde.org> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License (version 2) as *
6 * published by the Free Software Foundation. (The original KSplash/ML *
7 * codebase (upto version 0.95.3) is BSD-licensed.) *
9 ***************************************************************************/
11 #include <config-workspace.h>
14 #include <X11/Xutil.h>
15 #include <config-X11.h>
17 extern "C" { // for older XFree86 versions
18 #include <X11/extensions/Xinerama.h>
25 # ifdef HAVE_SYS_TIME_H
26 # include <sys/time.h>
33 int main( int argc
, char* argv
[])
37 bool print_pid
= false;
42 if( strcmp( argv
[ i
], "--test" ) == 0 )
44 if( strcmp( argv
[ i
], "--pid" ) == 0 )
46 if( strcmp( argv
[ i
], "SimpleSmall" ) == 0 )
58 printf( "%d\n", pid
);
62 close( 0 ); // close stdin,stdout,stderr, otherwise startkde will block
65 Display
* dpy
= XOpenDisplay( NULL
);
72 // Xinerama code from Qt
73 XineramaScreenInfo
*xinerama_screeninfo
= 0;
75 bool use_xinerama
= XineramaQueryExtension( dpy
, &unused
, &unused
)
76 && XineramaIsActive( dpy
);
80 xinerama_screeninfo
= XineramaQueryScreens( dpy
, &screenCount
);
81 sx
= xinerama_screeninfo
[ 0 ].x_org
;
82 sy
= xinerama_screeninfo
[ 0 ].y_org
;
83 sw
= xinerama_screeninfo
[ 0 ].width
;
84 sh
= xinerama_screeninfo
[ 0 ].height
;
86 { // create windows covering other xinerama screens
87 wins_count
= screenCount
;
88 wins
= new Window
[ wins_count
];
89 for( int i
= 1; // not 0
93 XSetWindowAttributes attrs
;
94 attrs
.override_redirect
= True
;
95 attrs
.background_pixel
= BlackPixel( dpy
, 0 ); // background
96 wins
[ i
] = XCreateWindow( dpy
, DefaultRootWindow( dpy
),
97 xinerama_screeninfo
[ i
].x_org
, xinerama_screeninfo
[ i
].y_org
,
98 xinerama_screeninfo
[ i
].width
, xinerama_screeninfo
[ i
].height
,
99 0, CopyFromParent
, CopyFromParent
, CopyFromParent
,
100 CWOverrideRedirect
| CWBackPixel
, &attrs
);
108 sw
= WidthOfScreen( ScreenOfDisplay( dpy
, DefaultScreen( dpy
)));
109 sh
= HeightOfScreen( ScreenOfDisplay( dpy
, DefaultScreen( dpy
)));
111 XSetWindowAttributes attrs
;
112 attrs
.override_redirect
= True
;
113 const int states
= 6;
115 const int segment
= sw
/ 2 / states
;
116 const int pw
= segment
* states
+ 2 * frame
; // size of progressbar
117 const int ph
= sh
/ 20 + frame
;
118 const int px
= small
? 0 : sx
+ ( sw
- pw
) / 2; // position in the pixmap
119 const int py
= small
? 0 : sy
+ ( sh
- ph
) / 2;
120 const int x
= small
? sx
+ ( sw
- pw
) / 2 : sx
; // position of the window
121 const int y
= small
? sy
+ ( sh
- ph
) / 2 : sy
;
122 const int w
= small
? pw
: sw
;
123 const int h
= small
? ph
: sh
;
126 wins
= new Window
[ 1 ];
129 Window win
= XCreateWindow( dpy
, DefaultRootWindow( dpy
), x
, y
, w
, h
,
130 0, CopyFromParent
, CopyFromParent
, CopyFromParent
, CWOverrideRedirect
, &attrs
);
132 Pixmap pix
= XCreatePixmap( dpy
, DefaultRootWindow( dpy
), w
, h
, DefaultDepth( dpy
, 0 ));
134 values
.foreground
= BlackPixel( dpy
, 0 ); // background
135 GC gc
= XCreateGC( dpy
, pix
, GCForeground
, &values
);
136 XFillRectangle( dpy
, pix
, gc
, 0, 0, w
, h
);
137 values
.foreground
= WhitePixel( dpy
, 0 ); // outline
138 XChangeGC( dpy
, gc
, GCForeground
, &values
);
139 XFillRectangle( dpy
, pix
, gc
, px
, py
, pw
, ph
);
140 values
.foreground
= BlackPixel( dpy
, 0 ); // progressbar
141 XChangeGC( dpy
, gc
, GCForeground
, &values
);
142 XSetWindowBackgroundPixmap( dpy
, win
, pix
);
143 XSelectInput( dpy
, DefaultRootWindow( dpy
), SubstructureNotifyMask
);
148 XSelectInput( dpy
, wins
[ i
], ButtonPressMask
);
149 XClassHint class_hint
;
150 class_hint
.res_name
= const_cast< char* >( "ksplashsimple" );
151 class_hint
.res_class
= const_cast< char* >( "ksplashsimple" );
152 XSetWMProperties( dpy
, wins
[ i
], NULL
, NULL
, NULL
, NULL
, NULL
, NULL
, &class_hint
);
153 XMapWindow( dpy
, wins
[ i
] );
156 int state
= 1; // cannot check dcop connection - make this state initial
157 const int delay
= 200; // ms
158 time_t final_time
= time( NULL
) + 300;
159 time_t test_time
= time( NULL
) + 1;
160 Atom kde_splash_progress
= XInternAtom( dpy
, "_KDE_SPLASH_PROGRESS", False
);
163 while( XPending( dpy
))
166 XNextEvent( dpy
, &ev
);
167 if( ev
.type
== ButtonPress
&& ev
.xbutton
.button
== Button1
)
169 final_time
= time( NULL
);
172 if( ev
.type
== ConfigureNotify
&& ev
.xconfigure
.event
== DefaultRootWindow( dpy
))
174 XRaiseWindow( dpy
, wins
[ 0 ] );
176 XRestackWindows( dpy
, wins
, wins_count
);
178 if( ev
.type
== ClientMessage
&& ev
.xclient
.window
== DefaultRootWindow( dpy
)
179 && ev
.xclient
.message_type
== kde_splash_progress
)
181 // these are also in ksplashx and in krunner
182 const char* s
= ev
.xclient
.data
.b
;
184 fprintf( stderr
,"MESSAGE: %s\n", s
);
186 if( strcmp( s
, "initial" ) == 0 && state
< 0 )
187 state
= 0; // not actually used
188 else if( strcmp( s
, "kded" ) == 0 && state
< 1 )
190 else if( strcmp( s
, "confupdate" ) == 0 && state
< 2 )
192 else if( strcmp( s
, "kcminit" ) == 0 && state
< 3 )
194 else if( strcmp( s
, "ksmserver" ) == 0 && state
< 4 )
196 else if( strcmp( s
, "wm" ) == 0 && state
< 5 )
198 else if( strcmp( s
, "desktop" ) == 0 && state
< 6 )
200 // This last one isn't used, make splash go away as soon as desktop is ready.
201 // else if( strcmp( s, "ready" ) == 0 && state < 7 )
205 if( test
&& time( NULL
) >= test_time
)
208 test_time
= time( NULL
) + 1;
212 while( pos
< state
&& pos
< states
)
215 fprintf( stderr
, "POS: %d\n", pos
);
217 XFillRectangle( dpy
, pix
, gc
, px
+ frame
+ pos
* segment
, py
+ frame
, segment
, ph
- 2 * frame
);
218 XSetWindowBackgroundPixmap( dpy
, win
, pix
);
219 XClearWindow( dpy
, win
);
224 fprintf( stderr
, "CLOSING DOWN\n" );
226 final_time
= time( NULL
) + 2;
232 FD_SET( XConnectionNumber( dpy
), &set
);
235 tv
.tv_usec
= delay
* 1000;
236 select( XConnectionNumber( dpy
) + 1, &set
, NULL
, NULL
, &tv
);
237 if( time( NULL
) >= final_time
)
240 fprintf( stderr
, "EXITING\n" );
245 XFreePixmap( dpy
, pix
);
249 XDestroyWindow( dpy
, wins
[ i
] );
252 XCloseDisplay( dpy
);