]> icculus.org git repositories - dana/openbox.git/blob - openbox/openbox.c
speed up workspace switching by causing the minimal number of expose events (none...
[dana/openbox.git] / openbox / openbox.c
1 #include "openbox.h"
2 #include "event.h"
3 #include "client.h"
4 #include "xerror.h"
5 #include "prop.h"
6 #include "screen.h"
7 #include "focus.h"
8 #include "extensions.h"
9 #include "gettext.h"
10 #include "keyboard.h"
11 #include "pointer.h"
12 #include "engine.h"
13 #include "python.h"
14 #include "hooks.h"
15 #include "clientwrap.h"
16 #include "openboxwrap.h"
17 #include "configwrap.h"
18 #include "themerc.h"
19 #include "timer.h"
20 #include "../render/render.h"
21 #include "../render/font.h"
22
23 #ifdef HAVE_FCNTL_H
24 #  include <fcntl.h>
25 #endif
26 #ifdef HAVE_SYS_SELECT_H
27 #  include <sys/select.h>
28 #endif
29 #ifdef HAVE_SIGNAL_H
30 #  include <signal.h>
31 #endif
32 #ifdef HAVE_STDLIB_H
33 #  include <stdlib.h>
34 #endif
35 #ifdef HAVE_SYS_WAIT_H
36 #  include <sys/types.h>
37 #  include <sys/wait.h>
38 #endif
39 #ifdef HAVE_LOCALE_H
40 #  include <locale.h>
41 #endif
42
43 #include <X11/cursorfont.h>
44
45 Display *ob_display  = NULL;
46 int      ob_screen;
47 Window   ob_root;
48 State    ob_state;
49 gboolean ob_shutdown = FALSE;
50 gboolean ob_restart  = FALSE;
51 char    *ob_restart_path = NULL;
52 gboolean ob_remote   = FALSE;
53 gboolean ob_sync     = TRUE;
54 Cursors  ob_cursors;
55
56 void signal_handler(int signal);
57
58 int main(int argc, char **argv)
59 {
60     struct sigaction action;
61     sigset_t sigset;
62
63     ob_state = State_Starting;
64
65     /* initialize the locale */
66     if (!setlocale(LC_ALL, ""))
67         g_warning("Couldn't set locale from environment.\n");
68     bindtextdomain(PACKAGE, LOCALEDIR);
69     bind_textdomain_codeset(PACKAGE, "UTF-8");
70     textdomain(PACKAGE);
71
72     /* set up signal handler */
73     sigemptyset(&sigset);
74     action.sa_handler = signal_handler;
75     action.sa_mask = sigset;
76     action.sa_flags = SA_NOCLDSTOP | SA_NODEFER;
77     sigaction(SIGUSR1, &action, (struct sigaction *) NULL);
78     sigaction(SIGPIPE, &action, (struct sigaction *) NULL);
79     sigaction(SIGSEGV, &action, (struct sigaction *) NULL);
80     sigaction(SIGFPE, &action, (struct sigaction *) NULL);
81     sigaction(SIGTERM, &action, (struct sigaction *) NULL);
82     sigaction(SIGINT, &action, (struct sigaction *) NULL);
83     sigaction(SIGHUP, &action, (struct sigaction *) NULL);
84     sigaction(SIGCHLD, &action, (struct sigaction *) NULL);
85
86     /* anything that died while we were restarting won't give us a SIGCHLD */
87     while (waitpid(-1, NULL, WNOHANG) > 0);
88      
89     /* XXX parse out command line args */
90     (void)argc;(void)argv;
91
92     ob_display = XOpenDisplay(NULL);
93     if (ob_display == NULL) {
94         /* print a message and exit */
95         g_critical("Failed to open the display.");
96         exit(1);
97     }
98     if (fcntl(ConnectionNumber(ob_display), F_SETFD, 1) == -1) {
99         /* print a message and exit */
100         g_critical("Failed to set display as close-on-exec.");
101         exit(1);
102     }
103           
104     ob_screen = DefaultScreen(ob_display);
105     ob_root = RootWindow(ob_display, ob_screen);
106
107     /* XXX fork self onto other screens */
108      
109     XSynchronize(ob_display, ob_sync);
110
111     /* check for locale support */
112     if (!XSupportsLocale())
113         g_warning("X server does not support locale.");
114     if (!XSetLocaleModifiers(""))
115         g_warning("Cannot set locale modifiers for the X server.");
116
117     /* set our error handler */
118     XSetErrorHandler(xerror_handler);
119
120     /* set the DISPLAY environment variable for any lauched children, to the
121        display we're using, so they open in the right place. */
122     putenv(g_strdup_printf("DISPLAY=%s", DisplayString(ob_display)));
123
124     ob_cursors.left_ptr = XCreateFontCursor(ob_display, XC_left_ptr);
125     ob_cursors.ll_angle = XCreateFontCursor(ob_display, XC_ll_angle);
126     ob_cursors.lr_angle = XCreateFontCursor(ob_display, XC_lr_angle);
127
128     prop_startup(); /* get atoms values for the display */
129     extensions_query_all(); /* find which extensions are present */
130      
131     if (screen_annex()) { /* it will be ours! */
132         timer_startup();
133         render_startup();
134         font_startup();
135         themerc_startup();
136         engine_startup(themerc_engine);
137         python_startup();
138         configwrap_startup();
139         openboxwrap_startup();
140         clientwrap_startup();
141         hooks_startup();
142         event_startup();
143         screen_startup();
144         focus_startup();
145         client_startup();
146         keyboard_startup();
147         pointer_startup();
148           
149         /* load the user's settings */
150         if (!python_import("rc"))
151             g_warning("ERROR LOADING RC FILE");
152
153         HOOKFIRE(startup, "()");
154
155         /* get all the existing windows */
156         client_manage_all();
157
158         ob_state = State_Running;
159         while (!ob_shutdown) {
160             event_loop();
161         }
162         ob_state = State_Exiting;
163
164         client_unmanage_all();
165
166         HOOKFIRE(shutdown, "()");
167
168         pointer_shutdown();
169         keyboard_shutdown();
170         client_shutdown();
171         screen_shutdown();
172         event_shutdown();
173         hooks_shutdown();
174         clientwrap_shutdown();
175         openboxwrap_shutdown();
176         configwrap_shutdown();
177         python_shutdown();
178         engine_shutdown();
179         themerc_shutdown();
180         render_shutdown();
181         timer_shutdown();
182     }
183           
184     XCloseDisplay(ob_display);
185
186     /* XXX if (ob_restart) */
187      
188     return 0;
189 }
190
191 void signal_handler(int signal)
192 {
193     switch (signal) {
194     case SIGUSR1:
195         g_message("Caught SIGUSR1 signal. Restarting.");
196         ob_shutdown = ob_restart = TRUE;
197         break;
198
199     case SIGCHLD:
200         wait(NULL);
201         break;
202
203     case SIGHUP:
204     case SIGINT:
205     case SIGTERM:
206     case SIGPIPE:
207         g_message("Caught signal %d. Exiting.", signal);
208         ob_shutdown = TRUE;
209         break;
210
211     case SIGFPE:
212     case SIGSEGV:
213         g_error("Caught signal %d. Aborting and dumping core.", signal);
214     }
215 }