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