00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <tdeconfig.h>
00013
00014 #include "main.h"
00015
00016 #include <tdelocale.h>
00017 #include <tdeglobal.h>
00018 #include <kdebug.h>
00019 #include <stdlib.h>
00020 #include <tdecmdlineargs.h>
00021 #include <tdeaboutdata.h>
00022 #include <dcopclient.h>
00023 #include <dcopref.h>
00024 #include <unistd.h>
00025 #include <signal.h>
00026 #include <fcntl.h>
00027
00028 #include "atoms.h"
00029 #include "options.h"
00030 #include "sm.h"
00031
00032 #define INT8 _X11INT8
00033 #define INT32 _X11INT32
00034 #include <X11/Xproto.h>
00035 #undef INT8
00036 #undef INT32
00037
00038 namespace KWinInternal
00039 {
00040
00041 Options* options;
00042
00043 Atoms* atoms;
00044
00045 int screen_number = -1;
00046 bool disable_twin_composition_manager = false;
00047
00048 static bool initting = FALSE;
00049
00050 static
00051 int x11ErrorHandler(Display *d, XErrorEvent *e)
00052 {
00053 char msg[80], req[80], number[80];
00054 bool ignore_badwindow = TRUE;
00055
00056 if (initting &&
00057 (
00058 e->request_code == X_ChangeWindowAttributes
00059 || e->request_code == X_GrabKey
00060 )
00061 && (e->error_code == BadAccess))
00062 {
00063 fputs(i18n("[twin] it looks like there's already a window manager running. twin not started.\n").local8Bit(), stderr);
00064 exit(1);
00065 }
00066
00067 if (ignore_badwindow && (e->error_code == BadWindow || e->error_code == BadColor))
00068 return 0;
00069
00070 XGetErrorText(d, e->error_code, msg, sizeof(msg));
00071 sprintf(number, "%d", e->request_code);
00072 XGetErrorDatabaseText(d, "XRequest", number, "<unknown>", req, sizeof(req));
00073
00074 fprintf(stderr, "[twin] %s(0x%lx): %s\n", req, e->resourceid, msg);
00075
00076 if (initting)
00077 {
00078 fputs(i18n("[twin] failure during initialization; aborting").local8Bit(), stderr);
00079 exit(1);
00080 }
00081 return 0;
00082 }
00083
00084 Application::Application( )
00085 : TDEApplication( ), owner( screen_number )
00086 {
00087 #ifdef USE_QT4
00088
00089 setQuitOnLastWindowClosed(false);
00090 #endif // USE_QT4
00091 TDECmdLineArgs* args = TDECmdLineArgs::parsedArgs();
00092 if (!config()->isImmutable() && args->isSet("lock"))
00093 {
00094 config()->setReadOnly(true);
00095 config()->reparseConfiguration();
00096 }
00097
00098 if (screen_number == -1) {
00099 screen_number = DefaultScreen(tqt_xdisplay());
00100 }
00101
00102 if (args->isSet( "disablecompositionmanager" )) {
00103 disable_twin_composition_manager = true;
00104 }
00105
00106 if( !owner.claim( args->isSet( "replace" ), true ))
00107 {
00108 Display* dpy = tqt_xdisplay();
00109 Window w;
00110 Atom a;
00111 static char net_wm_sm[] = "WM_Sxx";
00112
00113 snprintf (net_wm_sm, sizeof (net_wm_sm), "WM_S%d", screen_number);
00114 a = XInternAtom (dpy, net_wm_sm, False);
00115
00116 w = XGetSelectionOwner (dpy, a);
00117
00118 if (w != None)
00119 {
00120 Atom actual;
00121 int format;
00122 unsigned long n, left;
00123 unsigned char *data;
00124 Atom twinRunningAtom = XInternAtom (dpy, "_KDE_WM_IS_KWIN", True);
00125
00126 int result = XGetWindowProperty (dpy, w, twinRunningAtom, 0L, 1L, False,
00127 XA_ATOM, &actual, &format,
00128 &n, &left, &data);
00129
00130 if (result == Success && data != None && format == 32 )
00131 {
00132 Atom a;
00133 a = *(long*)data;
00134 XFree ( (void *) data);
00135 if( !owner.claim( true, true ))
00136 {
00137 fputs(i18n("[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
00138 ::exit(1);
00139 }
00140 }
00141 else
00142 {
00143 fputs(i18n("[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
00144 ::exit(1);
00145 }
00146 }
00147 else
00148 {
00149 fputs(i18n("[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
00150 ::exit(1);
00151 }
00152 }
00153 connect( &owner, TQT_SIGNAL( lostOwnership()), TQT_SLOT( lostSelection()));
00154
00155
00156 config()->reparseConfiguration();
00157
00158 initting = TRUE;
00159
00160
00161 XSetErrorHandler( x11ErrorHandler );
00162
00163
00164 XSelectInput(tqt_xdisplay(), tqt_xrootwin(), SubstructureRedirectMask );
00165 syncX();
00166
00167 options = new Options;
00168 atoms = new Atoms;
00169
00170
00171 Atom kde_wm_system_modal_notification;
00172 kde_wm_system_modal_notification = XInternAtom(tqt_xdisplay(), "_KDE_WM_IS_KWIN", False);
00173 XChangeProperty(tqt_xdisplay(), owner.ownerWindow(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
00174
00175
00176 (void) new Workspace( isSessionRestored() );
00177
00178 syncX();
00179
00180 DCOPRef ref( "kded", "kded" );
00181 ref.send( "unloadModule", TQCString( "kdetrayproxy" ));
00182
00183 initting = FALSE;
00184
00185 dcopClient()->send( "ksplash", "", "upAndRunning(TQString)", TQString("wm started"));
00186 XEvent e;
00187 e.xclient.type = ClientMessage;
00188 e.xclient.message_type = XInternAtom( tqt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
00189 e.xclient.display = tqt_xdisplay();
00190 e.xclient.window = tqt_xrootwin();
00191 e.xclient.format = 8;
00192 strcpy( e.xclient.data.b, "wm started" );
00193 XSendEvent( tqt_xdisplay(), tqt_xrootwin(), False, SubstructureNotifyMask, &e );
00194 }
00195
00196 Application::~Application()
00197 {
00198 delete Workspace::self();
00199 if( owner.ownerWindow() != None )
00200 {
00201 XSetInputFocus( tqt_xdisplay(), PointerRoot, RevertToPointerRoot, GET_QT_X_TIME() );
00202 DCOPRef ref( "kded", "kded" );
00203 if( !ref.send( "loadModule", TQCString( "kdetrayproxy" )))
00204 kdWarning( 176 ) << "Loading of kdetrayproxy failed." << endl;
00205 }
00206 delete options;
00207 }
00208
00209 void Application::lostSelection()
00210 {
00211 delete Workspace::self();
00212
00213 XSelectInput(tqt_xdisplay(), tqt_xrootwin(), PropertyChangeMask );
00214 DCOPRef ref( "kded", "kded" );
00215 if( !ref.send( "loadModule", TQCString( "kdetrayproxy" )))
00216 kdWarning( 176 ) << "Loading of kdetrayproxy failed." << endl;
00217 quit();
00218 }
00219
00220 bool Application::x11EventFilter( XEvent *e )
00221 {
00222 if ( Workspace::self()->workspaceEvent( e ) )
00223 return TRUE;
00224 return TDEApplication::x11EventFilter( e );
00225 }
00226
00227 static void sighandler(int)
00228 {
00229 TQApplication::exit();
00230 }
00231
00232
00233 }
00234
00235 static const char version[] = "3.0";
00236 static const char description[] = I18N_NOOP( "TDE window manager" );
00237
00238 static TDECmdLineOptions args[] =
00239 {
00240 { "lock", I18N_NOOP("Disable configuration options"), 0 },
00241 { "replace", I18N_NOOP("Replace already-running ICCCM2.0-compliant window manager"), 0 },
00242 { "disablecompositionmanager", I18N_NOOP("Do not start composition manager"), 0 },
00243 TDECmdLineLastOption
00244 };
00245
00246 extern "C"
00247 KDE_EXPORT int kdemain( int argc, char * argv[] )
00248 {
00249 bool restored = false;
00250 for (int arg = 1; arg < argc; arg++)
00251 {
00252 if (! qstrcmp(argv[arg], "-session"))
00253 {
00254 restored = true;
00255 break;
00256 }
00257 }
00258
00259 if (! restored)
00260 {
00261
00262
00263
00264 TQCString multiHead = getenv("TDE_MULTIHEAD");
00265 if (multiHead.lower() == "true")
00266 {
00267
00268 Display* dpy = XOpenDisplay( NULL );
00269 if ( !dpy )
00270 {
00271 fprintf(stderr, "%s: FATAL ERROR while trying to open display %s\n",
00272 argv[0], XDisplayName(NULL ) );
00273 exit (1);
00274 }
00275
00276 int number_of_screens = ScreenCount( dpy );
00277 KWinInternal::screen_number = DefaultScreen( dpy );
00278 int pos;
00279 TQCString display_name = XDisplayString( dpy );
00280 XCloseDisplay( dpy );
00281 dpy = 0;
00282
00283 if ((pos = display_name.findRev('.')) != -1 )
00284 display_name.remove(pos,10);
00285
00286 TQCString envir;
00287 if (number_of_screens != 1)
00288 {
00289 for (int i = 0; i < number_of_screens; i++ )
00290 {
00291
00292
00293 if ( i != KWinInternal::screen_number && fork() == 0 )
00294 {
00295 KWinInternal::screen_number = i;
00296
00297
00298 break;
00299 }
00300 }
00301
00302
00303 envir.sprintf("DISPLAY=%s.%d", display_name.data(), KWinInternal::screen_number);
00304
00305 if (putenv( strdup(envir.data())) )
00306 {
00307 fprintf(stderr,
00308 "[twin] %s: WARNING: unable to set DISPLAY environment variable\n",
00309 argv[0]);
00310 perror("[twin] putenv()");
00311 }
00312 }
00313 }
00314 }
00315
00316 TDEGlobal::locale()->setMainCatalogue("twin");
00317
00318 TDEAboutData aboutData( "twin", I18N_NOOP("TWin"),
00319 version, description, TDEAboutData::License_GPL,
00320 I18N_NOOP("(c) 1999-2005, The KDE Developers"));
00321 aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
00322 aboutData.addAuthor("Cristian Tibirna",0, "tibirna@kde.org");
00323 aboutData.addAuthor("Daniel M. Duley",0, "mosfet@kde.org");
00324 aboutData.addAuthor("Luboš Luňák", I18N_NOOP( "Maintainer" ), "l.lunak@kde.org");
00325
00326 TDECmdLineArgs::init(argc, argv, &aboutData);
00327 TDECmdLineArgs::addCmdLineOptions( args );
00328
00329 if (signal(SIGTERM, KWinInternal::sighandler) == SIG_IGN)
00330 signal(SIGTERM, SIG_IGN);
00331 if (signal(SIGINT, KWinInternal::sighandler) == SIG_IGN)
00332 signal(SIGINT, SIG_IGN);
00333 if (signal(SIGHUP, KWinInternal::sighandler) == SIG_IGN)
00334 signal(SIGHUP, SIG_IGN);
00335
00336 TDEApplication::disableAutoDcopRegistration();
00337 KWinInternal::Application a;
00338 KWinInternal::SessionManaged weAreIndeed;
00339 KWinInternal::SessionSaveDoneHelper helper;
00340
00341 fcntl(ConnectionNumber(tqt_xdisplay()), F_SETFD, 1);
00342
00343 TQCString appname;
00344 if (KWinInternal::screen_number == 0)
00345 appname = "twin";
00346 else
00347 appname.sprintf("twin-screen-%d", KWinInternal::screen_number);
00348
00349 DCOPClient* client = a.dcopClient();
00350 client->registerAs( appname.data(), false);
00351 client->setDefaultObject( "KWinInterface" );
00352
00353 return a.exec();
00354 }
00355
00356 #include "main.moc"