]> icculus.org git repositories - dana/openbox.git/blob - src/openbox.cc
make it shutdown on signals
[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     instance->shutdown();
75
76     break;
77   case SIGFPE:
78   case SIGSEGV:
79     printf("Caught signal %d. Aborting and dumping core.", signal);
80     abort();
81   }
82 }
83
84
85 Openbox::Openbox(int argc, char **argv)
86 {
87   struct sigaction action;
88
89   _state = State_Starting;
90
91   Openbox::instance = this;
92
93   _displayreq = (char*) 0;
94   _argv0 = argv[0];
95
96   parseCommandLine(argc, argv);
97
98   // open the X display (and gets some info about it, and its screens)
99   otk::OBDisplay::initialize(_displayreq);
100   assert(otk::OBDisplay::display);
101     
102   // set up the signal handler
103   action.sa_handler = Openbox::signalHandler;
104   action.sa_mask = sigset_t();
105   action.sa_flags = SA_NOCLDSTOP | SA_NODEFER;
106   sigaction(SIGPIPE, &action, (struct sigaction *) 0);
107   sigaction(SIGSEGV, &action, (struct sigaction *) 0);
108   sigaction(SIGFPE, &action, (struct sigaction *) 0);
109   sigaction(SIGTERM, &action, (struct sigaction *) 0);
110   sigaction(SIGINT, &action, (struct sigaction *) 0);
111   sigaction(SIGHUP, &action, (struct sigaction *) 0);
112
113
114   
115   _state = State_Normal; // done starting
116 }
117
118
119 Openbox::~Openbox()
120 {
121   // close the X display
122   otk::OBDisplay::destroy();
123 }
124
125
126 void Openbox::parseCommandLine(int argc, char **argv)
127 {
128   bool err = false;
129
130   for (int i = 1; i < argc; ++i) {
131     std::string arg(argv[i]);
132
133     if (arg == "-display") {
134       if (++i >= argc)
135         err = true;
136       else
137         _displayreq = argv[i];
138     } else if (arg == "-rc") {
139       if (++i >= argc)
140         err = true;
141       else
142         _rcfilepath = argv[i];
143     } else if (arg == "-menu") {
144       if (++i >= argc)
145         err = true;
146       else
147         _menufilepath = argv[i];
148     } else if (arg == "-version") {
149       showVersion();
150       ::exit(0);
151     } else if (arg == "-help") {
152       showHelp();
153       ::exit(0);
154     } else
155       err = true;
156
157     if (err) {
158       showHelp();
159       exit(1);
160     }
161   }
162 }
163
164
165 void Openbox::showVersion()
166 {
167   printf(_("Openbox - version %s\n"), OPENBOX_VERSION);
168   printf("    (c) 2002 - 2002 Ben Jansens\n\n");
169 }
170
171
172 void Openbox::showHelp()
173 {
174   showVersion(); // show the version string and copyright
175
176   // print program usage and command line options
177   printf(_("Usage: %s [OPTIONS...]\n\
178   Options:\n\
179   -display <string>  use display connection.\n\
180   -rc <string>       use alternate resource file.\n\
181   -menu <string>     use alternate menu file.\n\
182   -version           display version and exit.\n\
183   -help              display this help text and exit.\n\n"), _argv0);
184
185   printf(_("Compile time options:\n\
186   Debugging: %s\n\
187   Shape:     %s\n\
188   Xinerama:  %s\n"),
189 #ifdef    DEBUG
190          _("yes"),
191 #else // !DEBUG
192          _("no"),
193 #endif // DEBUG
194
195 #ifdef    SHAPE
196          _("yes"),
197 #else // !SHAPE
198          _("no"),
199 #endif // SHAPE
200
201 #ifdef    XINERAMA
202          _("yes")
203 #else // !XINERAMA
204          _("no")
205 #endif // XINERAMA
206     );
207 }
208
209
210 void Openbox::eventLoop()
211 {
212   while (_state == State_Normal) {
213     if (XPending(otk::OBDisplay::display)) {
214       XEvent e;
215       XNextEvent(otk::OBDisplay::display, &e);
216       process_event(&e);
217     } else {
218       _timermanager.fire();
219     }
220   }
221 }
222
223
224 }
225