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