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