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 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.0.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Fri Aug 13 21:47:05 2004 by doxygen 1.3.8 written by Dimitri van Heesch, © 1997-2003