WE DONT USE BASE DISPLAY FOR ANYTHING ANY MORE!!@^!*@*!! YAY
[dana/openbox.git] / src / openbox.cc
1 // -*- mode: C++; indent-tabs-mode: nil; -*-
2
3 #ifdef HAVE_CONFIG_H
4 # include "../config.h"
5 #endif
6
7 #include "../version.h"
8 #include "openbox.hh"
9 #include "otk/display.hh"
10
11 extern "C" {
12 #ifdef    HAVE_STDIO_H
13 #  include <stdio.h>
14 #endif // HAVE_STDIO_H
15
16 #ifdef    HAVE_STDLIB_H
17 #  include <stdlib.h>
18 #endif // HAVE_STDLIB_H
19
20 #ifdef    HAVE_SIGNAL_H
21 #  include <signal.h>
22 #endif // HAVE_SIGNAL_H
23
24 #ifdef    HAVE_FCNTL_H
25 #  include <fcntl.h>
26 #endif // HAVE_FCNTL_H
27
28 #ifdef    HAVE_UNISTD_H
29 #  include <sys/types.h>
30 #  include <unistd.h>
31 #endif // HAVE_UNISTD_H
32
33 #ifdef    HAVE_SYS_SELECT_H
34 #  include <sys/select.h>
35 #endif // HAVE_SYS_SELECT_H
36
37 #include "gettext.h"
38 #define _(str) gettext(str)
39 }
40
41 namespace ob {
42
43
44 Openbox *Openbox::instance = (Openbox *) 0;
45
46
47 int Openbox::xerrorHandler(Display *d, XErrorEvent *e)
48 {
49 #ifdef DEBUG
50   char errtxt[128];
51
52   XGetErrorText(d, e->error_code, errtxt, 128);
53   printf("X Error: %s\n", errtxt);
54 #else
55   (void)d;
56   (void)e;
57 #endif
58
59   return false;
60 }
61
62
63 void Openbox::signalHandler(int signal)
64 {
65   switch (signal) {
66   case SIGHUP:
67     // XXX: Do something with HUP? Really shouldn't, we get this when X shuts
68     //      down and hangs-up on us.
69     
70   case SIGINT:
71   case SIGTERM:
72   case SIGPIPE:
73     printf("Caught signal %d. Exiting.", signal);
74     // XXX: Make Openbox exit
75     break;
76   case SIGFPE:
77   case SIGSEGV:
78     printf("Caught signal %d. Aborting and dumping core.", signal);
79     abort();
80   }
81 }
82
83
84 Openbox::Openbox(int argc, char **argv)
85 {
86   struct sigaction action;
87
88   _state = State_Starting;
89
90   Openbox::instance = this;
91
92   _displayreq = (char*) 0;
93   _argv0 = argv[0];
94
95   parseCommandLine(argc, argv);
96
97   // open the X display (and gets some info about it, and its screens)
98   otk::OBDisplay::initialize(_displayreq);
99   assert(otk::OBDisplay::display);
100     
101   // set up the signal handler
102   action.sa_handler = Openbox::signalHandler;
103   action.sa_mask = sigset_t();
104   action.sa_flags = SA_NOCLDSTOP | SA_NODEFER;
105   sigaction(SIGPIPE, &action, (struct sigaction *) 0);
106   sigaction(SIGSEGV, &action, (struct sigaction *) 0);
107   sigaction(SIGFPE, &action, (struct sigaction *) 0);
108   sigaction(SIGTERM, &action, (struct sigaction *) 0);
109   sigaction(SIGINT, &action, (struct sigaction *) 0);
110   sigaction(SIGHUP, &action, (struct sigaction *) 0);
111
112
113   
114   _state = State_Normal; // done starting
115 }
116
117
118 Openbox::~Openbox()
119 {
120   // close the X display
121   otk::OBDisplay::destroy();
122 }
123
124
125 void Openbox::parseCommandLine(int argc, char **argv)
126 {
127   bool err = false;
128
129   for (int i = 1; i < argc; ++i) {
130     std::string arg(argv[i]);
131
132     if (arg == "-display") {
133       if (++i >= argc)
134         err = true;
135       else
136         _displayreq = argv[i];
137     } else if (arg == "-rc") {
138       if (++i >= argc)
139         err = true;
140       else
141         _rcfilepath = argv[i];
142     } else if (arg == "-menu") {
143       if (++i >= argc)
144         err = true;
145       else
146         _menufilepath = argv[i];
147     } else if (arg == "-version") {
148       showVersion();
149       ::exit(0);
150     } else if (arg == "-help") {
151       showHelp();
152       ::exit(0);
153     } else
154       err = true;
155
156     if (err) {
157       showHelp();
158       exit(1);
159     }
160   }
161 }
162
163
164 void Openbox::showVersion()
165 {
166   printf(_("Openbox - version %s\n"), OPENBOX_VERSION);
167   printf("    (c) 2002 - 2002 Ben Jansens\n\n");
168 }
169
170
171 void Openbox::showHelp()
172 {
173   showVersion(); // show the version string and copyright
174
175   // print program usage and command line options
176   printf(_("Usage: %s [OPTIONS...]\n\
177   Options:\n\
178   -display <string>  use display connection.\n\
179   -rc <string>       use alternate resource file.\n\
180   -menu <string>     use alternate menu file.\n\
181   -version           display version and exit.\n\
182   -help              display this help text and exit.\n\n"), _argv0);
183
184   printf(_("Compile time options:\n\
185   Debugging: %s\n\
186   Shape:     %s\n\
187   Xinerama:  %s\n"),
188 #ifdef    DEBUG
189          _("yes"),
190 #else // !DEBUG
191          _("no"),
192 #endif // DEBUG
193
194 #ifdef    SHAPE
195          _("yes"),
196 #else // !SHAPE
197          _("no"),
198 #endif // SHAPE
199
200 #ifdef    XINERAMA
201          _("yes")
202 #else // !XINERAMA
203          _("no")
204 #endif // XINERAMA
205     );
206 }
207
208
209 void Openbox::eventLoop()
210 {
211   const int xfd = ConnectionNumber(otk::OBDisplay::display);
212
213   while (_state == State_Normal) {
214     if (XPending(otk::OBDisplay::display)) {
215       XEvent e;
216       XNextEvent(otk::OBDisplay::display, &e);
217       process_event(&e);
218     } else {
219       fd_set rfds;
220       timeval now, tm, *timeout = (timeval *) 0;
221
222       FD_ZERO(&rfds);
223       FD_SET(xfd, &rfds);
224
225 /*      if (! timerList.empty()) {
226         const BTimer* const timer = timerList.top();
227
228         gettimeofday(&now, 0);
229         tm = timer->timeRemaining(now);
230
231         timeout = &tm;
232       }
233
234       select(xfd + 1, &rfds, 0, 0, timeout);
235
236       // check for timer timeout
237       gettimeofday(&now, 0);
238
239       // there is a small chance for deadlock here:
240       // *IF* the timer list keeps getting refreshed *AND* the time between
241       // timer->start() and timer->shouldFire() is within the timer's period
242       // then the timer will keep firing.  This should be VERY near impossible.
243       while (! timerList.empty()) {
244         BTimer *timer = timerList.top();
245         if (! timer->shouldFire(now))
246           break;
247
248         timerList.pop();
249
250         timer->fireTimeout();
251         timer->halt();
252         if (timer->isRecurring())
253           timer->start();
254           }*/
255     }
256   }
257 }
258
259
260 }
261