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