• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • twin
 

twin

  • twin
main.cpp
1/*****************************************************************
2 KWin - the KDE window manager
3 This file is part of the KDE project.
4
5Copyright (C) 1999, 2000 Matthias Ettrich <ettrich@kde.org>
6Copyright (C) 2003 Lubos Lunak <l.lunak@kde.org>
7
8You can Freely distribute this program under the GNU General Public
9License. See the file "COPYING" for the exact licensing terms.
10******************************************************************/
11
12#include <tdeconfig.h>
13
14#include "main.h"
15
16#include <tdelocale.h>
17#include <tdeglobal.h>
18#include <kdebug.h>
19#include <stdlib.h>
20#include <tdecmdlineargs.h>
21#include <tdeaboutdata.h>
22#include <dcopclient.h>
23#include <dcopref.h>
24#include <unistd.h>
25#include <signal.h>
26#include <fcntl.h>
27
28#include "atoms.h"
29#include "options.h"
30#include "sm.h"
31
32#define INT8 _X11INT8
33#define INT32 _X11INT32
34#include <X11/Xproto.h>
35#undef INT8
36#undef INT32
37
38namespace KWinInternal
39{
40
41Options* options;
42
43Atoms* atoms;
44
45int screen_number = -1;
46bool disable_twin_composition_manager = false;
47
48static bool initting = FALSE;
49
50static
51int x11ErrorHandler(Display *d, XErrorEvent *e)
52 {
53 char msg[80], req[80], number[80];
54 bool ignore_badwindow = TRUE; //maybe temporary
55
56 if (initting &&
57 (
58 e->request_code == X_ChangeWindowAttributes
59 || e->request_code == X_GrabKey
60 )
61 && (e->error_code == BadAccess))
62 {
63 fputs(i18n("[twin] it looks like there's already a window manager running. twin not started.\n").local8Bit(), stderr);
64 exit(1);
65 }
66
67 if (ignore_badwindow && (e->error_code == BadWindow || e->error_code == BadColor))
68 return 0;
69
70 XGetErrorText(d, e->error_code, msg, sizeof(msg));
71 sprintf(number, "%d", e->request_code);
72 XGetErrorDatabaseText(d, "XRequest", number, "<unknown>", req, sizeof(req));
73
74 fprintf(stderr, "[twin] %s(0x%lx): %s\n", req, e->resourceid, msg);
75
76 if (initting)
77 {
78 fputs(i18n("[twin] failure during initialization; aborting").local8Bit(), stderr);
79 exit(1);
80 }
81 return 0;
82 }
83
84Application::Application( )
85: TDEApplication( ), owner( screen_number )
86 {
87 TDECmdLineArgs* args = TDECmdLineArgs::parsedArgs();
88 if (!config()->isImmutable() && args->isSet("lock"))
89 {
90 config()->setReadOnly(true);
91 config()->reparseConfiguration();
92 }
93
94 if (screen_number == -1) {
95 screen_number = DefaultScreen(tqt_xdisplay());
96 }
97
98 if (args->isSet( "disablecompositionmanager" )) {
99 disable_twin_composition_manager = true;
100 }
101
102 if( !owner.claim( args->isSet( "replace" ), true ))
103 {
104 Display* dpy = tqt_xdisplay();
105 Window w;
106 Atom a;
107 static char net_wm_sm[] = "WM_Sxx";
108
109 snprintf (net_wm_sm, sizeof (net_wm_sm), "WM_S%d", screen_number);
110 a = XInternAtom (dpy, net_wm_sm, False);
111
112 w = XGetSelectionOwner (dpy, a);
113
114 if (w != None)
115 {
116 Atom actual;
117 int format;
118 unsigned long n, left;
119 unsigned char *data;
120 Atom twinRunningAtom = XInternAtom (dpy, "_KDE_WM_IS_KWIN", True);
121
122 int result = XGetWindowProperty (dpy, w, twinRunningAtom, 0L, 1L, False,
123 XA_ATOM, &actual, &format,
124 &n, &left, &data);
125
126 if (result == Success && data != None && format == 32 )
127 {
128 Atom a;
129 a = *(long*)data;
130 XFree ( (void *) data);
131 if( !owner.claim( true, true ))
132 {
133 fputs(i18n("[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
134 ::exit(1);
135 }
136 }
137 else
138 {
139 fputs(i18n("[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
140 ::exit(1);
141 }
142 }
143 else
144 {
145 fputs(i18n("[twin] unable to claim manager selection, another wm running? (try using --replace)\n").local8Bit(), stderr);
146 ::exit(1);
147 }
148 }
149 connect( &owner, TQ_SIGNAL( lostOwnership()), TQ_SLOT( lostSelection()));
150
151 // if there was already twin running, it saved its configuration after loosing the selection -> reread
152 config()->reparseConfiguration();
153
154 initting = TRUE; // startup....
155
156 // install X11 error handler
157 XSetErrorHandler( x11ErrorHandler );
158
159 // check whether another windowmanager is running
160 XSelectInput(tqt_xdisplay(), tqt_xrootwin(), SubstructureRedirectMask );
161 syncX(); // trigger error now
162
163 options = new Options;
164 atoms = new Atoms;
165
166 // Signal that we are The KWin!
167 Atom kde_wm_system_modal_notification;
168 kde_wm_system_modal_notification = XInternAtom(tqt_xdisplay(), "_KDE_WM_IS_KWIN", False);
169 XChangeProperty(tqt_xdisplay(), owner.ownerWindow(), kde_wm_system_modal_notification, XA_INTEGER, 32, PropModeReplace, (unsigned char *) "TRUE", 1L);
170
171 // create workspace.
172 (void) new Workspace( isSessionRestored() );
173
174 syncX(); // trigger possible errors, there's still a chance to abort
175
176 DCOPRef ref( "kded", "kded" );
177 ref.send( "unloadModule", TQCString( "kdetrayproxy" ));
178
179 initting = FALSE; // startup done, we are up and running now.
180
181 dcopClient()->send( "ksplash", "", "upAndRunning(TQString)", TQString("wm started"));
182 XEvent e;
183 e.xclient.type = ClientMessage;
184 e.xclient.message_type = XInternAtom( tqt_xdisplay(), "_KDE_SPLASH_PROGRESS", False );
185 e.xclient.display = tqt_xdisplay();
186 e.xclient.window = tqt_xrootwin();
187 e.xclient.format = 8;
188 strcpy( e.xclient.data.b, "wm started" );
189 XSendEvent( tqt_xdisplay(), tqt_xrootwin(), False, SubstructureNotifyMask, &e );
190 }
191
192Application::~Application()
193 {
194 delete Workspace::self();
195 if( owner.ownerWindow() != None ) // if there was no --replace (no new WM)
196 {
197 XSetInputFocus( tqt_xdisplay(), PointerRoot, RevertToPointerRoot, get_tqt_x_time() );
198 DCOPRef ref( "kded", "kded" );
199 if( !ref.send( "loadModule", TQCString( "kdetrayproxy" )))
200 kdWarning( 176 ) << "Loading of kdetrayproxy failed." << endl;
201 }
202 delete options;
203 }
204
205void Application::lostSelection()
206 {
207 delete Workspace::self();
208 // remove windowmanager privileges
209 XSelectInput(tqt_xdisplay(), tqt_xrootwin(), PropertyChangeMask );
210 DCOPRef ref( "kded", "kded" );
211 if( !ref.send( "loadModule", TQCString( "kdetrayproxy" )))
212 kdWarning( 176 ) << "Loading of kdetrayproxy failed." << endl;
213 quit();
214 }
215
216bool Application::x11EventFilter( XEvent *e )
217 {
218 if ( Workspace::self()->workspaceEvent( e ) )
219 return TRUE;
220 return TDEApplication::x11EventFilter( e );
221 }
222
223static void sighandler(int)
224 {
225 TQApplication::exit();
226 }
227
228
229} // namespace
230
231static const char version[] = "3.0";
232static const char description[] = I18N_NOOP( "TDE window manager" );
233
234static TDECmdLineOptions args[] =
235 {
236 { "lock", I18N_NOOP("Disable configuration options"), 0 },
237 { "replace", I18N_NOOP("Replace already-running ICCCM2.0-compliant window manager"), 0 },
238 { "disablecompositionmanager", I18N_NOOP("Do not start composition manager"), 0 },
239 TDECmdLineLastOption
240 };
241
242extern "C"
243TDE_EXPORT int kdemain( int argc, char * argv[] )
244 {
245 bool restored = false;
246 for (int arg = 1; arg < argc; arg++)
247 {
248 if (! qstrcmp(argv[arg], "-session"))
249 {
250 restored = true;
251 break;
252 }
253 }
254
255 if (! restored)
256 {
257 // we only do the multihead fork if we are not restored by the session
258 // manager, since the session manager will register multiple twins,
259 // one for each screen...
260 TQCString multiHead = getenv("TDE_MULTIHEAD");
261 if (multiHead.lower() == "true")
262 {
263
264 Display* dpy = XOpenDisplay( NULL );
265 if ( !dpy )
266 {
267 fprintf(stderr, "%s: FATAL ERROR while trying to open display %s\n",
268 argv[0], XDisplayName(NULL ) );
269 exit (1);
270 }
271
272 int number_of_screens = ScreenCount( dpy );
273 KWinInternal::screen_number = DefaultScreen( dpy );
274 int pos; // temporarily needed to reconstruct DISPLAY var if multi-head
275 TQCString display_name = XDisplayString( dpy );
276 XCloseDisplay( dpy );
277 dpy = 0;
278
279 if ((pos = display_name.findRev('.')) != -1 )
280 display_name.remove(pos,10); // 10 is enough to be sure we removed ".s"
281
282 TQCString envir;
283 if (number_of_screens != 1)
284 {
285 for (int i = 0; i < number_of_screens; i++ )
286 {
287 // if execution doesn't pass by here, then twin
288 // acts exactly as previously
289 if ( i != KWinInternal::screen_number && fork() == 0 )
290 {
291 KWinInternal::screen_number = i;
292 // break here because we are the child process, we don't
293 // want to fork() anymore
294 break;
295 }
296 }
297 // in the next statement, display_name shouldn't contain a screen
298 // number. If it had it, it was removed at the "pos" check
299 envir.sprintf("DISPLAY=%s.%d", display_name.data(), KWinInternal::screen_number);
300
301 if (putenv( strdup(envir.data())) )
302 {
303 fprintf(stderr,
304 "[twin] %s: WARNING: unable to set DISPLAY environment variable\n",
305 argv[0]);
306 perror("[twin] putenv()");
307 }
308 }
309 }
310 }
311
312 TDEGlobal::locale()->setMainCatalogue("twin");
313
314 TDEAboutData aboutData( "twin", I18N_NOOP("TWin"),
315 version, description, TDEAboutData::License_GPL,
316 I18N_NOOP("(c) 1999-2005, The KDE Developers"));
317 aboutData.addAuthor("Matthias Ettrich",0, "ettrich@kde.org");
318 aboutData.addAuthor("Cristian Tibirna",0, "tibirna@kde.org");
319 aboutData.addAuthor("Daniel M. Duley",0, "mosfet@kde.org");
320 aboutData.addAuthor("Luboš Luňák", I18N_NOOP( "Maintainer" ), "l.lunak@kde.org");
321
322 TDECmdLineArgs::init(argc, argv, &aboutData);
323 TDECmdLineArgs::addCmdLineOptions( args );
324
325 if (signal(SIGTERM, KWinInternal::sighandler) == SIG_IGN)
326 signal(SIGTERM, SIG_IGN);
327 if (signal(SIGINT, KWinInternal::sighandler) == SIG_IGN)
328 signal(SIGINT, SIG_IGN);
329 if (signal(SIGHUP, KWinInternal::sighandler) == SIG_IGN)
330 signal(SIGHUP, SIG_IGN);
331
332 TDEApplication::disableAutoDcopRegistration();
333 KWinInternal::Application a;
334 KWinInternal::SessionManaged weAreIndeed;
335 KWinInternal::SessionSaveDoneHelper helper;
336
337 fcntl(ConnectionNumber(tqt_xdisplay()), F_SETFD, 1);
338
339 TQCString appname;
340 if (KWinInternal::screen_number == 0)
341 appname = "twin";
342 else
343 appname.sprintf("twin-screen-%d", KWinInternal::screen_number);
344
345 TDEGlobal::locale()->insertCatalogue("twin_lib");
346
347 DCOPClient* client = a.dcopClient();
348 client->registerAs( appname.data(), false);
349 client->setDefaultObject( "KWinInterface" );
350
351 return a.exec();
352 }
353
354#include "main.moc"

twin

Skip menu "twin"
  • Main Page
  • Alphabetical List
  • Class List
  • File List
  • Class Members

twin

Skip menu "twin"
  • kate
  • libkonq
  • twin
  •   lib
Generated for twin by doxygen 1.9.4
This website is maintained by Timothy Pearson.