kwin Library API Documentation

main.cpp

00001 /*****************************************************************
00002  KWin - the KDE window manager
00003  This file is part of the KDE project.
00004 
00005 Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
00006 Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
00007 
00008 You can Freely distribute this program under the GNU General Public
00009 License. See the file "COPYING" for the exact licensing terms.
00010 ******************************************************************/
00011 
00012 //#define QT_CLEAN_NAMESPACE
00013 #include <kconfig.h>
00014 
00015 #include "main.h"
00016 
00017 #include <klocale.h>
00018 #include <stdlib.h>
00019 #include <kcmdlineargs.h>
00020 #include <kaboutdata.h>
00021 #include <dcopclient.h>
00022 #include <unistd.h>
00023 #include <signal.h>
00024 #include <fcntl.h>
00025 
00026 #include "atoms.h"
00027 #include "options.h"
00028 #include "sm.h"
00029 
00030 #define INT8 _X11INT8
00031 #define INT32 _X11INT32
00032 #include <X11/Xproto.h>
00033 #undef INT8
00034 #undef INT32
00035 
00036 extern Time qt_x_time;
00037 
00038 namespace KWinInternal
00039 {
00040 
00041 Options* options;
00042 
00043 Atoms* atoms;
00044 
00045 int screen_number = -1;
00046 
00047 static bool initting = FALSE;
00048 
00049 static
00050 int x11ErrorHandler(Display *d, XErrorEvent *e)
00051     {
00052     char msg[80], req[80], number[80];
00053     bool ignore_badwindow = TRUE; //maybe temporary
00054 
00055     if (initting &&
00056         (
00057          e->request_code == X_ChangeWindowAttributes
00058          || e->request_code == X_GrabKey
00059          )
00060         && (e->error_code == BadAccess)) 
00061         {
00062         fputs(i18n("kwin: it looks like there's already a window manager running. kwin not started.\n").local8Bit(), stderr);
00063         exit(1);
00064         }
00065 
00066     if (ignore_badwindow && (e->error_code == BadWindow || e->error_code == BadColor))
00067         return 0;
00068 
00069     XGetErrorText(d, e->error_code, msg, sizeof(msg));
00070     sprintf(number, "%d", e->request_code);
00071     XGetErrorDatabaseText(d, "XRequest", number, "<unknown>", req, sizeof(req));
00072 
00073     fprintf(stderr, "kwin: %s(0x%lx): %s\n", req, e->resourceid, msg);
00074 
00075     if (initting) 
00076         {
00077         fputs(i18n("kwin: failure during initialization; aborting").local8Bit(), stderr);
00078         exit(1);
00079         }
00080     return 0;
00081     }
00082 
00083 Application::Application( )
00084 : KApplication( ), owner( screen_number )
00085     {
00086     KCmdLineArgs* args = KCmdLineArgs::parsedArgs();
00087     if (!config()->isImmutable() && args->isSet("lock"))
00088         {
00089         config()->setReadOnly(true);
00090         config()->reparseConfiguration();
00091         }
00092 
00093     if (screen_number == -1)
00094         screen_number = DefaultScreen(qt_xdisplay());
00095 
00096     if( !owner.claim( args->isSet( "replace" ), true ))
00097         {
00098         fputs(i18n("kwin: unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
00099         ::exit(1);
00100         }
00101     connect( &owner, SIGNAL( lostOwnership()), SLOT( lostSelection()));
00102     
00103     // if there was already kwin running, it saved its configuration after loosing the selection -> reread
00104     config()->reparseConfiguration();
00105 
00106     initting = TRUE; // startup....
00107 
00108     // install X11 error handler
00109     XSetErrorHandler( x11ErrorHandler );
00110 
00111     // check  whether another windowmanager is running
00112     XSelectInput(qt_xdisplay(), qt_xrootwin(), SubstructureRedirectMask  );
00113     syncX(); // trigger error now
00114 
00115     options = new Options;
00116     atoms = new Atoms;
00117 
00118     // create workspace.
00119     (void) new Workspace( isSessionRestored() );
00120 
00121     syncX(); // trigger possible errors, there's still a chance to abort
00122 
00123     initting = FALSE; // startup done, we are up and running now.
00124     dcopClient()->send( "ksplash", "", "upAndRunning(QString)", QString("wm started"));
00125     }
00126 
00127 
00128 Application::~Application()
00129     {
00130     delete Workspace::self();
00131     if( owner.ownerWindow() != None ) // if there was no --replace (no new WM)
00132         XSetInputFocus( qt_xdisplay(), PointerRoot, RevertToPointerRoot, qt_x_time );
00133     delete options;
00134     }
00135 
00136 void Application::lostSelection()
00137     {
00138     delete Workspace::self();
00139     // remove windowmanager privileges
00140     XSelectInput(qt_xdisplay(), qt_xrootwin(), PropertyChangeMask );
00141     quit();
00142     }
00143 
00144 bool Application::x11EventFilter( XEvent *e )
00145     {
00146     if ( Workspace::self()->workspaceEvent( e ) )
00147              return TRUE;
00148     return KApplication::x11EventFilter( e );
00149     }
00150 
00151 static void sighandler(int) 
00152     {
00153     QApplication::exit();
00154     }
00155 
00156 
00157 } // namespace
00158 
00159 static const char version[] = "3.0";
00160 static const char description[] = I18N_NOOP( "KDE window manager" );
00161 
00162 static KCmdLineOptions args[] =
00163     {
00164         { "lock", I18N_NOOP("Disable configuration options"), 0 },
00165         { "replace", I18N_NOOP("Replace already-running ICCCM2.0-compliant window manager"), 0 },
00166         KCmdLineLastOption
00167     };
00168 
00169 extern "C"
00170 KDE_EXPORT int kdemain( int argc, char * argv[] )
00171     {
00172     bool restored = false;
00173     for (int arg = 1; arg < argc; arg++) 
00174         {
00175         if (! qstrcmp(argv[arg], "-session")) 
00176             {
00177             restored = true;
00178             break;
00179             }
00180         }
00181 
00182     if (! restored) 
00183         {
00184         // we only do the multihead fork if we are not restored by the session
00185     // manager, since the session manager will register multiple kwins,
00186         // one for each screen...
00187         QCString multiHead = getenv("KDE_MULTIHEAD");
00188         if (multiHead.lower() == "true") 
00189             {
00190 
00191             Display* dpy = XOpenDisplay( NULL );
00192             if ( !dpy ) 
00193                 {
00194                 fprintf(stderr, "%s: FATAL ERROR while trying to open display %s\n",
00195                         argv[0], XDisplayName(NULL ) );
00196                 exit (1);
00197                 }
00198 
00199             int number_of_screens = ScreenCount( dpy );
00200             KWinInternal::screen_number = DefaultScreen( dpy );
00201             int pos; // temporarily needed to reconstruct DISPLAY var if multi-head
00202             QCString display_name = XDisplayString( dpy );
00203             XCloseDisplay( dpy );
00204             dpy = 0;
00205 
00206             if ((pos = display_name.findRev('.')) != -1 )
00207                 display_name.remove(pos,10); // 10 is enough to be sure we removed ".s"
00208 
00209             QCString envir;
00210             if (number_of_screens != 1) 
00211                 {
00212                 for (int i = 0; i < number_of_screens; i++ ) 
00213                     {
00214             // if execution doesn't pass by here, then kwin
00215             // acts exactly as previously
00216                     if ( i != KWinInternal::screen_number && fork() == 0 ) 
00217                         {
00218                         KWinInternal::screen_number = i;
00219             // break here because we are the child process, we don't
00220             // want to fork() anymore
00221                         break;
00222                         }
00223                     }
00224         // in the next statement, display_name shouldn't contain a screen
00225         //   number. If it had it, it was removed at the "pos" check
00226                 envir.sprintf("DISPLAY=%s.%d", display_name.data(), KWinInternal::screen_number);
00227 
00228                 if (putenv( strdup(envir.data())) ) 
00229                     {
00230                     fprintf(stderr,
00231                             "%s: WARNING: unable to set DISPLAY environment variable\n",
00232                             argv[0]);
00233                     perror("putenv()");
00234                     }
00235                 }
00236             }
00237         }
00238 
00239     KAboutData aboutData( "kwin", I18N_NOOP("KWin"),
00240                           version, description, KAboutData::License_GPL,
00241                           I18N_NOOP("(c) 1999-2003, The KDE Developers"));
00242     aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
00243     aboutData.addAuthor("Cristian Tibirna",0, "tibirna@kde.org");
00244     aboutData.addAuthor("Daniel M. Duley",0, "mosfet@kde.org");
00245     aboutData.addAuthor("Lubos Lunak", 0, "l.lunak@kde.org");
00246 
00247     KCmdLineArgs::init(argc, argv, &aboutData);
00248     KCmdLineArgs::addCmdLineOptions( args );
00249 
00250     if (signal(SIGTERM, KWinInternal::sighandler) == SIG_IGN)
00251         signal(SIGTERM, SIG_IGN);
00252     if (signal(SIGINT, KWinInternal::sighandler) == SIG_IGN)
00253         signal(SIGINT, SIG_IGN);
00254     if (signal(SIGHUP, KWinInternal::sighandler) == SIG_IGN)
00255         signal(SIGHUP, SIG_IGN);
00256 
00257     KApplication::disableAutoDcopRegistration();
00258     KWinInternal::Application a;
00259     KWinInternal::SessionManaged weAreIndeed;
00260     KWinInternal::SessionSaveDoneHelper helper;
00261 
00262     fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, 1);
00263 
00264     QCString appname;
00265     if (KWinInternal::screen_number == 0)
00266         appname = "kwin";
00267     else
00268         appname.sprintf("kwin-screen-%d", KWinInternal::screen_number);
00269 
00270     DCOPClient* client = a.dcopClient();
00271     client->registerAs( appname.data(), false);
00272     client->setDefaultObject( "KWinInterface" );
00273 
00274     return a.exec();
00275     }
00276 
00277 #include "main.moc"
KDE Logo
This file is part of the documentation for kwin Library Version 3.3.90.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Tue Apr 5 03:59:39 2005 by doxygen 1.3.9.1 written by Dimitri van Heesch, © 1997-2003