12 #include <tdeconfig.h>
16 #include <tdelocale.h>
17 #include <tdeglobal.h>
20 #include <tdecmdlineargs.h>
21 #include <tdeaboutdata.h>
22 #include <dcopclient.h>
33 #define INT32 _X11INT32
34 #include <X11/Xproto.h>
38 namespace KWinInternal
45 int screen_number = -1;
46 bool disable_twin_composition_manager =
false;
48 static bool initting = FALSE;
51 int x11ErrorHandler(Display *d, XErrorEvent *e)
53 char msg[80], req[80], number[80];
54 bool ignore_badwindow = TRUE;
58 e->request_code == X_ChangeWindowAttributes
59 || e->request_code == X_GrabKey
61 && (e->error_code == BadAccess))
63 fputs(i18n(
"[twin] it looks like there's already a window manager running. twin not started.\n").local8Bit(), stderr);
67 if (ignore_badwindow && (e->error_code == BadWindow || e->error_code == BadColor))
70 XGetErrorText(d, e->error_code, msg,
sizeof(msg));
71 sprintf(number,
"%d", e->request_code);
72 XGetErrorDatabaseText(d,
"XRequest", number,
"<unknown>", req,
sizeof(req));
74 fprintf(stderr,
"[twin] %s(0x%lx): %s\n", req, e->resourceid, msg);
78 fputs(i18n(
"[twin] failure during initialization; aborting").local8Bit(), stderr);
84 Application::Application( )
85 : TDEApplication( ), owner( screen_number )
87 TDECmdLineArgs* args = TDECmdLineArgs::parsedArgs();
88 if (!config()->isImmutable() && args->isSet(
"lock"))
90 config()->setReadOnly(
true);
91 config()->reparseConfiguration();
94 if (screen_number == -1) {
95 screen_number = DefaultScreen(tqt_xdisplay());
98 if (args->isSet(
"disablecompositionmanager" )) {
99 disable_twin_composition_manager =
true;
102 if( !owner.claim( args->isSet(
"replace" ),
true ))
104 Display* dpy = tqt_xdisplay();
107 static char net_wm_sm[] =
"WM_Sxx";
109 snprintf (net_wm_sm,
sizeof (net_wm_sm),
"WM_S%d", screen_number);
110 a = XInternAtom (dpy, net_wm_sm, False);
112 w = XGetSelectionOwner (dpy, a);
118 unsigned long n, left;
120 Atom twinRunningAtom = XInternAtom (dpy,
"_KDE_WM_IS_KWIN", True);
122 int result = XGetWindowProperty (dpy, w, twinRunningAtom, 0L, 1L, False,
123 XA_ATOM, &actual, &format,
126 if (result == Success && data != None && format == 32 )
130 XFree ( (
void *) data);
131 if( !owner.claim(
true,
true ))
133 fputs(i18n(
"[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
139 fputs(i18n(
"[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
145 fputs(i18n(
"[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
149 connect( &owner, TQ_SIGNAL( lostOwnership()), TQ_SLOT( lostSelection()));
152 config()->reparseConfiguration();
157 XSetErrorHandler( x11ErrorHandler );
160 XSelectInput(tqt_xdisplay(), tqt_xrootwin(), SubstructureRedirectMask );
163 options =
new Options;
167 Atom kde_wm_system_modal_notification;
168 kde_wm_system_modal_notification = XInternAtom(tqt_xdisplay(),
"_KDE_WM_IS_KWIN", False);
169 XChangeProperty(tqt_xdisplay(), owner.ownerWindow(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (
unsigned char *)
"TRUE", 1L);
172 (void)
new Workspace( isSessionRestored() );
176 DCOPRef ref(
"kded",
"kded" );
177 ref.send(
"unloadModule", TQCString(
"kdetrayproxy" ));
181 dcopClient()->send(
"ksplash",
"",
"upAndRunning(TQString)", TQString(
"wm started"));
183 e.xclient.type = ClientMessage;
184 e.xclient.message_type = XInternAtom( tqt_xdisplay(),
"_KDE_SPLASH_PROGRESS", False );
185 e.xclient.display = tqt_xdisplay();
186 e.xclient.window = tqt_xrootwin();
187 e.xclient.format = 8;
188 strcpy( e.xclient.data.b,
"wm started" );
189 XSendEvent( tqt_xdisplay(), tqt_xrootwin(), False, SubstructureNotifyMask, &e );
192 Application::~Application()
194 delete Workspace::self();
195 if( owner.ownerWindow() != None )
197 XSetInputFocus( tqt_xdisplay(), PointerRoot, RevertToPointerRoot, get_tqt_x_time() );
198 DCOPRef ref(
"kded",
"kded" );
199 if( !ref.send(
"loadModule", TQCString(
"kdetrayproxy" )))
200 kdWarning( 176 ) <<
"Loading of kdetrayproxy failed." << endl;
205 void Application::lostSelection()
207 delete Workspace::self();
209 XSelectInput(tqt_xdisplay(), tqt_xrootwin(), PropertyChangeMask );
210 DCOPRef ref(
"kded",
"kded" );
211 if( !ref.send(
"loadModule", TQCString(
"kdetrayproxy" )))
212 kdWarning( 176 ) <<
"Loading of kdetrayproxy failed." << endl;
216 bool Application::x11EventFilter( XEvent *e )
218 if ( Workspace::self()->workspaceEvent( e ) )
220 return TDEApplication::x11EventFilter( e );
223 static void sighandler(
int)
225 TQApplication::exit();
231 static const char version[] =
"3.0";
232 static const char description[] = I18N_NOOP(
"TDE window manager" );
234 static TDECmdLineOptions args[] =
236 {
"lock", I18N_NOOP(
"Disable configuration options"), 0 },
237 {
"replace", I18N_NOOP(
"Replace already-running ICCCM2.0-compliant window manager"), 0 },
238 {
"disablecompositionmanager", I18N_NOOP(
"Do not start composition manager"), 0 },
243 TDE_EXPORT
int kdemain(
int argc,
char * argv[] )
245 bool restored =
false;
246 for (
int arg = 1; arg < argc; arg++)
248 if (! qstrcmp(argv[arg],
"-session"))
260 TQCString multiHead = getenv(
"TDE_MULTIHEAD");
261 if (multiHead.lower() ==
"true")
264 Display* dpy = XOpenDisplay( NULL );
267 fprintf(stderr,
"%s: FATAL ERROR while trying to open display %s\n",
268 argv[0], XDisplayName(NULL ) );
272 int number_of_screens = ScreenCount( dpy );
273 KWinInternal::screen_number = DefaultScreen( dpy );
275 TQCString display_name = XDisplayString( dpy );
276 XCloseDisplay( dpy );
279 if ((pos = display_name.findRev(
'.')) != -1 )
280 display_name.remove(pos,10);
283 if (number_of_screens != 1)
285 for (
int i = 0; i < number_of_screens; i++ )
289 if ( i != KWinInternal::screen_number && fork() == 0 )
291 KWinInternal::screen_number = i;
299 envir.sprintf(
"DISPLAY=%s.%d", display_name.data(), KWinInternal::screen_number);
301 if (putenv( strdup(envir.data())) )
304 "[twin] %s: WARNING: unable to set DISPLAY environment variable\n",
306 perror(
"[twin] putenv()");
312 TDEGlobal::locale()->setMainCatalogue(
"twin");
314 TDEAboutData aboutData(
"twin", I18N_NOOP(
"TWin"),
315 version, description, TDEAboutData::License_GPL,
316 I18N_NOOP(
"(c) 1999-2005, The KDE Developers"));
317 aboutData.addAuthor(
"Matthias Ettrich",0,
"ettrich@kde.org");
318 aboutData.addAuthor(
"Cristian Tibirna",0,
"tibirna@kde.org");
319 aboutData.addAuthor(
"Daniel M. Duley",0,
"mosfet@kde.org");
320 aboutData.addAuthor(
"Luboš Luňák", I18N_NOOP(
"Maintainer" ),
"l.lunak@kde.org");
322 TDECmdLineArgs::init(argc, argv, &aboutData);
323 TDECmdLineArgs::addCmdLineOptions( args );
325 if (signal(SIGTERM, KWinInternal::sighandler) == SIG_IGN)
326 signal(SIGTERM, SIG_IGN);
327 if (signal(SIGINT, KWinInternal::sighandler) == SIG_IGN)
328 signal(SIGINT, SIG_IGN);
329 if (signal(SIGHUP, KWinInternal::sighandler) == SIG_IGN)
330 signal(SIGHUP, SIG_IGN);
332 TDEApplication::disableAutoDcopRegistration();
333 KWinInternal::Application a;
334 KWinInternal::SessionManaged weAreIndeed;
335 KWinInternal::SessionSaveDoneHelper helper;
337 fcntl(ConnectionNumber(tqt_xdisplay()), F_SETFD, 1);
340 if (KWinInternal::screen_number == 0)
343 appname.sprintf(
"twin-screen-%d", KWinInternal::screen_number);
345 TDEGlobal::locale()->insertCatalogue(
"twin_lib");
347 DCOPClient* client = a.dcopClient();
348 client->registerAs( appname.data(),
false);
349 client->setDefaultObject(
"KWinInterface" );