00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <kconfig.h>
00014
00015 #include "main.h"
00016
00017 #include <klocale.h>
00018 #include <kglobal.h>
00019 #include <kdebug.h>
00020 #include <stdlib.h>
00021 #include <kcmdlineargs.h>
00022 #include <kaboutdata.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 extern Time qt_x_time;
00040
00041 namespace KWinInternal
00042 {
00043
00044 Options* options;
00045
00046 Atoms* atoms;
00047
00048 int screen_number = -1;
00049
00050 static bool initting = FALSE;
00051
00052 static
00053 int x11ErrorHandler(Display *d, XErrorEvent *e)
00054 {
00055 char msg[80], req[80], number[80];
00056 bool ignore_badwindow = TRUE;
00057
00058 if (initting &&
00059 (
00060 e->request_code == X_ChangeWindowAttributes
00061 || e->request_code == X_GrabKey
00062 )
00063 && (e->error_code == BadAccess))
00064 {
00065 fputs(i18n("kwin: it looks like there's already a window manager running. kwin not started.\n").local8Bit(), stderr);
00066 exit(1);
00067 }
00068
00069 if (ignore_badwindow && (e->error_code == BadWindow || e->error_code == BadColor))
00070 return 0;
00071
00072 XGetErrorText(d, e->error_code, msg, sizeof(msg));
00073 sprintf(number, "%d", e->request_code);
00074 XGetErrorDatabaseText(d, "XRequest", number, "<unknown>", req, sizeof(req));
00075
00076 fprintf(stderr, "kwin: %s(0x%lx): %s\n", req, e->resourceid, msg);
00077
00078 if (initting)
00079 {
00080 fputs(i18n("kwin: failure during initialization; aborting").local8Bit(), stderr);
00081 exit(1);
00082 }
00083 return 0;
00084 }
00085
00086 Application::Application( )
00087 : KApplication( ), owner( screen_number )
00088 {
00089 KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
00090 if (!config()->isImmutable() && args->isSet("lock"))
00091 {
00092 config()->setReadOnly(true);
00093 config()->reparseConfiguration();
00094 }
00095
00096 if (screen_number == -1)
00097 screen_number = DefaultScreen(qt_xdisplay());
00098
00099 if( !owner.claim( args->isSet( "replace" ), true ))
00100 {
00101 fputs(i18n("kwin: unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
00102 ::exit(1);
00103 }
00104 connect( &owner, SIGNAL( lostOwnership()), SLOT( lostSelection()));
00105
00106
00107 config()->reparseConfiguration();
00108
00109 initting = TRUE;
00110
00111
00112 XSetErrorHandler( x11ErrorHandler );
00113
00114
00115 XSelectInput(qt_xdisplay(), qt_xrootwin(), SubstructureRedirectMask );
00116 syncX();
00117
00118 options = new Options;
00119 atoms = new Atoms;
00120
00121
00122 (void) new Workspace( isSessionRestored() );
00123
00124 syncX();
00125
00126 DCOPRef ref( "kded", "kded" );
00127 ref.send( "unloadModule", QCString( "kdetrayproxy" ));
00128
00129 initting = FALSE;
00130
00131 dcopClient()->send( "ksplash", "", "upAndRunning(QString)", QString("wm started"));
00132 XEvent e;
00133 e.xclient.type = ClientMessage;
00134 e.xclient.message_type = XInternAtom( qt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
00135 e.xclient.display = qt_xdisplay();
00136 e.xclient.window = qt_xrootwin();
00137 e.xclient.format = 8;
00138 strcpy( e.xclient.data.b, "wm started" );
00139 XSendEvent( qt_xdisplay(), qt_xrootwin(), False, SubstructureNotifyMask, &e );
00140 }
00141
00142 Application::~Application()
00143 {
00144 delete Workspace::self();
00145 if( owner.ownerWindow() != None )
00146 {
00147 XSetInputFocus( qt_xdisplay(), PointerRoot, RevertToPointerRoot, qt_x_time );
00148 DCOPRef ref( "kded", "kded" );
00149 if( !ref.send( "loadModule", QCString( "kdetrayproxy" )))
00150 kdWarning( 176 ) << "Loading of kdetrayproxy failed." << endl;
00151 }
00152 delete options;
00153 }
00154
00155 void Application::lostSelection()
00156 {
00157 delete Workspace::self();
00158
00159 XSelectInput(qt_xdisplay(), qt_xrootwin(), PropertyChangeMask );
00160 DCOPRef ref( "kded", "kded" );
00161 if( !ref.send( "loadModule", QCString( "kdetrayproxy" )))
00162 kdWarning( 176 ) << "Loading of kdetrayproxy failed." << endl;
00163 quit();
00164 }
00165
00166 bool Application::x11EventFilter( XEvent *e )
00167 {
00168 if ( Workspace::self()->workspaceEvent( e ) )
00169 return TRUE;
00170 return KApplication::x11EventFilter( e );
00171 }
00172
00173 static void sighandler(int)
00174 {
00175 QApplication::exit();
00176 }
00177
00178
00179 }
00180
00181 static const char version[] = "3.0";
00182 static const char description[] = I18N_NOOP( "KDE window manager" );
00183
00184 static KCmdLineOptions args[] =
00185 {
00186 { "lock", I18N_NOOP("Disable configuration options"), 0 },
00187 { "replace", I18N_NOOP("Replace already-running ICCCM2.0-compliant window manager"), 0 },
00188 KCmdLineLastOption
00189 };
00190
00191 extern "C"
00192 KDE_EXPORT int kdemain( int argc, char * argv[] )
00193 {
00194 bool restored = false;
00195 for (int arg = 1; arg < argc; arg++)
00196 {
00197 if (! qstrcmp(argv[arg], "-session"))
00198 {
00199 restored = true;
00200 break;
00201 }
00202 }
00203
00204 if (! restored)
00205 {
00206
00207
00208
00209 QCString multiHead = getenv("KDE_MULTIHEAD");
00210 if (multiHead.lower() == "true")
00211 {
00212
00213 Display* dpy = XOpenDisplay( NULL );
00214 if ( !dpy )
00215 {
00216 fprintf(stderr, "%s: FATAL ERROR while trying to open display %s\n",
00217 argv[0], XDisplayName(NULL ) );
00218 exit (1);
00219 }
00220
00221 int number_of_screens = ScreenCount( dpy );
00222 KWinInternal::screen_number = DefaultScreen( dpy );
00223 int pos;
00224 QCString display_name = XDisplayString( dpy );
00225 XCloseDisplay( dpy );
00226 dpy = 0;
00227
00228 if ((pos = display_name.findRev('.')) != -1 )
00229 display_name.remove(pos,10);
00230
00231 QCString envir;
00232 if (number_of_screens != 1)
00233 {
00234 for (int i = 0; i < number_of_screens; i++ )
00235 {
00236
00237
00238 if ( i != KWinInternal::screen_number && fork() == 0 )
00239 {
00240 KWinInternal::screen_number = i;
00241
00242
00243 break;
00244 }
00245 }
00246
00247
00248 envir.sprintf("DISPLAY=%s.%d", display_name.data(), KWinInternal::screen_number);
00249
00250 if (putenv( strdup(envir.data())) )
00251 {
00252 fprintf(stderr,
00253 "%s: WARNING: unable to set DISPLAY environment variable\n",
00254 argv[0]);
00255 perror("putenv()");
00256 }
00257 }
00258 }
00259 }
00260
00261 KGlobal::locale()->setMainCatalogue("kwin");
00262
00263 KAboutData aboutData( "kwin", I18N_NOOP("KWin"),
00264 version, description, KAboutData::License_GPL,
00265 I18N_NOOP("(c) 1999-2005, The KDE Developers"));
00266 aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
00267 aboutData.addAuthor("Cristian Tibirna",0, "tibirna@kde.org");
00268 aboutData.addAuthor("Daniel M. Duley",0, "mosfet@kde.org");
00269 aboutData.addAuthor("Luboš Luňák", I18N_NOOP( "Maintainer" ), "l.lunak@kde.org");
00270
00271 KCmdLineArgs::init(argc, argv, &aboutData);
00272 KCmdLineArgs::addCmdLineOptions( args );
00273
00274 if (signal(SIGTERM, KWinInternal::sighandler) == SIG_IGN)
00275 signal(SIGTERM, SIG_IGN);
00276 if (signal(SIGINT, KWinInternal::sighandler) == SIG_IGN)
00277 signal(SIGINT, SIG_IGN);
00278 if (signal(SIGHUP, KWinInternal::sighandler) == SIG_IGN)
00279 signal(SIGHUP, SIG_IGN);
00280
00281 KApplication::disableAutoDcopRegistration();
00282 KWinInternal::Application a;
00283 KWinInternal::SessionManaged weAreIndeed;
00284 KWinInternal::SessionSaveDoneHelper helper;
00285
00286 fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, 1);
00287
00288 QCString appname;
00289 if (KWinInternal::screen_number == 0)
00290 appname = "kwin";
00291 else
00292 appname.sprintf("kwin-screen-%d", KWinInternal::screen_number);
00293
00294 DCOPClient* client = a.dcopClient();
00295 client->registerAs( appname.data(), false);
00296 client->setDefaultObject( "KWinInterface" );
00297
00298 return a.exec();
00299 }
00300
00301 #include "main.moc"