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 <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;
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
00104 config()->reparseConfiguration();
00105
00106 initting = TRUE;
00107
00108
00109 XSetErrorHandler( x11ErrorHandler );
00110
00111
00112 XSelectInput(qt_xdisplay(), qt_xrootwin(), SubstructureRedirectMask );
00113 syncX();
00114
00115
options =
new Options;
00116 atoms =
new Atoms;
00117
00118
00119 (
void)
new Workspace( isSessionRestored() );
00120
00121 syncX();
00122
00123 initting = FALSE;
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 )
00132 XSetInputFocus( qt_xdisplay(), PointerRoot, RevertToPointerRoot, qt_x_time );
00133
delete options;
00134 }
00135
00136
void Application::lostSelection()
00137 {
00138
delete Workspace::self();
00139
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 }
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
00185
00186
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;
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);
00208
00209 QCString envir;
00210
if (number_of_screens != 1)
00211 {
00212
for (
int i = 0; i < number_of_screens; i++ )
00213 {
00214
00215
00216
if ( i != KWinInternal::screen_number && fork() == 0 )
00217 {
00218 KWinInternal::screen_number = i;
00219
00220
00221
break;
00222 }
00223 }
00224
00225
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"