]> git.sur5r.net Git - i3/i3/blob - src/main.c
Revert "Use ev_signal to avoid async-unsafe functions (Thanks Markus)"
[i3/i3] / src / main.c
1 #undef I3__FILE__
2 #define I3__FILE__ "main.c"
3 /*
4  * vim:ts=4:sw=4:expandtab
5  *
6  * i3 - an improved dynamic tiling window manager
7  * © 2009-2012 Michael Stapelberg and contributors (see also: LICENSE)
8  *
9  * main.c: Initialization, main loop
10  *
11  */
12 #include <ev.h>
13 #include <fcntl.h>
14 #include <sys/types.h>
15 #include <sys/socket.h>
16 #include <sys/un.h>
17 #include <sys/time.h>
18 #include <sys/resource.h>
19 #include <sys/mman.h>
20 #include <sys/stat.h>
21 #include "all.h"
22
23 #include "sd-daemon.h"
24
25 /* The original value of RLIMIT_CORE when i3 was started. We need to restore
26  * this before starting any other process, since we set RLIMIT_CORE to
27  * RLIM_INFINITY for i3 debugging versions. */
28 struct rlimit original_rlimit_core;
29
30 /** The number of file descriptors passed via socket activation. */
31 int listen_fds;
32
33 static int xkb_event_base;
34
35 int xkb_current_group;
36
37 extern Con *focused;
38
39 char **start_argv;
40
41 xcb_connection_t *conn;
42 /* The screen (0 when you are using DISPLAY=:0) of the connection 'conn' */
43 int conn_screen;
44
45 /* Display handle for libstartup-notification */
46 SnDisplay *sndisplay;
47
48 /* The last timestamp we got from X11 (timestamps are included in some events
49  * and are used for some things, like determining a unique ID in startup
50  * notification). */
51 xcb_timestamp_t last_timestamp = XCB_CURRENT_TIME;
52
53 xcb_screen_t *root_screen;
54 xcb_window_t root;
55
56 /* Color depth, visual id and colormap to use when creating windows and
57  * pixmaps. Will use 32 bit depth and an appropriate visual, if available,
58  * otherwise the root window’s default (usually 24 bit TrueColor). */
59 uint8_t root_depth;
60 xcb_visualid_t visual_id;
61 xcb_colormap_t colormap;
62
63 struct ev_loop *main_loop;
64
65 xcb_key_symbols_t *keysyms;
66
67 /* Those are our connections to X11 for use with libXcursor and XKB */
68 Display *xlibdpy, *xkbdpy;
69
70 /* The list of key bindings */
71 struct bindings_head *bindings;
72
73 /* The list of exec-lines */
74 struct autostarts_head autostarts = TAILQ_HEAD_INITIALIZER(autostarts);
75
76 /* The list of exec_always lines */
77 struct autostarts_always_head autostarts_always = TAILQ_HEAD_INITIALIZER(autostarts_always);
78
79 /* The list of assignments */
80 struct assignments_head assignments = TAILQ_HEAD_INITIALIZER(assignments);
81
82 /* The list of workspace assignments (which workspace should end up on which
83  * output) */
84 struct ws_assignments_head ws_assignments = TAILQ_HEAD_INITIALIZER(ws_assignments);
85
86 /* We hope that those are supported and set them to true */
87 bool xcursor_supported = true;
88 bool xkb_supported = true;
89
90 /* This will be set to true when -C is used so that functions can behave
91  * slightly differently. We don’t want i3-nagbar to be started when validating
92  * the config, for example. */
93 bool only_check_config = false;
94
95 /*
96  * This callback is only a dummy, see xcb_prepare_cb and xcb_check_cb.
97  * See also man libev(3): "ev_prepare" and "ev_check" - customise your event loop
98  *
99  */
100 static void xcb_got_event(EV_P_ struct ev_io *w, int revents) {
101     /* empty, because xcb_prepare_cb and xcb_check_cb are used */
102 }
103
104 /*
105  * Flush before blocking (and waiting for new events)
106  *
107  */
108 static void xcb_prepare_cb(EV_P_ ev_prepare *w, int revents) {
109     xcb_flush(conn);
110 }
111
112 /*
113  * Instead of polling the X connection socket we leave this to
114  * xcb_poll_for_event() which knows better than we can ever know.
115  *
116  */
117 static void xcb_check_cb(EV_P_ ev_check *w, int revents) {
118     xcb_generic_event_t *event;
119
120     while ((event = xcb_poll_for_event(conn)) != NULL) {
121         if (event->response_type == 0) {
122             if (event_is_ignored(event->sequence, 0))
123                 DLOG("Expected X11 Error received for sequence %x\n", event->sequence);
124             else {
125                 xcb_generic_error_t *error = (xcb_generic_error_t*)event;
126                 DLOG("X11 Error received (probably harmless)! sequence 0x%x, error_code = %d\n",
127                      error->sequence, error->error_code);
128             }
129             free(event);
130             continue;
131         }
132
133         /* Strip off the highest bit (set if the event is generated) */
134         int type = (event->response_type & 0x7F);
135
136         handle_event(type, event);
137
138         free(event);
139     }
140 }
141
142
143 /*
144  * When using xmodmap to change the keyboard mapping, this event
145  * is only sent via XKB. Therefore, we need this special handler.
146  *
147  */
148 static void xkb_got_event(EV_P_ struct ev_io *w, int revents) {
149     DLOG("Handling XKB event\n");
150     XkbEvent ev;
151
152     /* When using xmodmap, every change (!) gets an own event.
153      * Therefore, we just read all events and only handle the
154      * mapping_notify once. */
155     bool mapping_changed = false;
156     while (XPending(xkbdpy)) {
157         XNextEvent(xkbdpy, (XEvent*)&ev);
158         /* While we should never receive a non-XKB event,
159          * better do sanity checking */
160         if (ev.type != xkb_event_base)
161             continue;
162
163         if (ev.any.xkb_type == XkbMapNotify) {
164             mapping_changed = true;
165             continue;
166         }
167
168         if (ev.any.xkb_type != XkbStateNotify) {
169             ELOG("Unknown XKB event received (type %d)\n", ev.any.xkb_type);
170             continue;
171         }
172
173         /* See The XKB Extension: Library Specification, section 14.1 */
174         /* We check if the current group (each group contains
175          * two levels) has been changed. Mode_switch activates
176          * group XkbGroup2Index */
177         if (xkb_current_group == ev.state.group)
178             continue;
179
180         xkb_current_group = ev.state.group;
181
182         if (ev.state.group == XkbGroup2Index) {
183             DLOG("Mode_switch enabled\n");
184             grab_all_keys(conn, true);
185         }
186
187         if (ev.state.group == XkbGroup1Index) {
188             DLOG("Mode_switch disabled\n");
189             ungrab_all_keys(conn);
190             grab_all_keys(conn, false);
191         }
192     }
193
194     if (!mapping_changed)
195         return;
196
197     DLOG("Keyboard mapping changed, updating keybindings\n");
198     xcb_key_symbols_free(keysyms);
199     keysyms = xcb_key_symbols_alloc(conn);
200
201     xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
202
203     ungrab_all_keys(conn);
204     DLOG("Re-grabbing...\n");
205     translate_keysyms();
206     grab_all_keys(conn, (xkb_current_group == XkbGroup2Index));
207     DLOG("Done\n");
208 }
209
210 /*
211  * Exit handler which destroys the main_loop. Will trigger cleanup handlers.
212  *
213  */
214 static void i3_exit(void) {
215 /* We need ev >= 4 for the following code. Since it is not *that* important (it
216  * only makes sure that there are no i3-nagbar instances left behind) we still
217  * support old systems with libev 3. */
218 #if EV_VERSION_MAJOR >= 4
219     ev_loop_destroy(main_loop);
220 #endif
221
222     if (*shmlogname != '\0') {
223         fprintf(stderr, "Closing SHM log \"%s\"\n", shmlogname);
224         fflush(stderr);
225         shm_unlink(shmlogname);
226     }
227 }
228
229 /*
230  * (One-shot) Handler for all signals with default action "Term", see signal(7)
231  *
232  * Unlinks the SHM log and re-raises the signal.
233  *
234  */
235 static void handle_signal(int sig, siginfo_t *info, void *data) {
236     fprintf(stderr, "Received signal %d, terminating\n", sig);
237     if (*shmlogname != '\0') {
238         fprintf(stderr, "Closing SHM log \"%s\"\n", shmlogname);
239         shm_unlink(shmlogname);
240     }
241     fflush(stderr);
242     raise(sig);
243 }
244
245 int main(int argc, char *argv[]) {
246     /* Keep a symbol pointing to the I3_VERSION string constant so that we have
247      * it in gdb backtraces. */
248     const char *i3_version __attribute__ ((unused)) = I3_VERSION;
249     char *override_configpath = NULL;
250     bool autostart = true;
251     char *layout_path = NULL;
252     bool delete_layout_path = false;
253     bool force_xinerama = false;
254     char *fake_outputs = NULL;
255     bool disable_signalhandler = false;
256     static struct option long_options[] = {
257         {"no-autostart", no_argument, 0, 'a'},
258         {"config", required_argument, 0, 'c'},
259         {"version", no_argument, 0, 'v'},
260         {"moreversion", no_argument, 0, 'm'},
261         {"more-version", no_argument, 0, 'm'},
262         {"more_version", no_argument, 0, 'm'},
263         {"help", no_argument, 0, 'h'},
264         {"layout", required_argument, 0, 'L'},
265         {"restart", required_argument, 0, 0},
266         {"force-xinerama", no_argument, 0, 0},
267         {"force_xinerama", no_argument, 0, 0},
268         {"disable-signalhandler", no_argument, 0, 0},
269         {"shmlog-size", required_argument, 0, 0},
270         {"shmlog_size", required_argument, 0, 0},
271         {"get-socketpath", no_argument, 0, 0},
272         {"get_socketpath", no_argument, 0, 0},
273         {"fake_outputs", required_argument, 0, 0},
274         {"fake-outputs", required_argument, 0, 0},
275         {0, 0, 0, 0}
276     };
277     int option_index = 0, opt;
278
279     setlocale(LC_ALL, "");
280
281     /* Get the RLIMIT_CORE limit at startup time to restore this before
282      * starting processes. */
283     getrlimit(RLIMIT_CORE, &original_rlimit_core);
284
285     /* Disable output buffering to make redirects in .xsession actually useful for debugging */
286     if (!isatty(fileno(stdout)))
287         setbuf(stdout, NULL);
288
289     srand(time(NULL));
290
291     /* Init logging *before* initializing debug_build to guarantee early
292      * (file) logging. */
293     init_logging();
294
295     /* On non-release builds, disable SHM logging by default. */
296     shmlog_size = (is_debug_build() ? 25 * 1024 * 1024 : 0);
297
298     start_argv = argv;
299
300     while ((opt = getopt_long(argc, argv, "c:CvmaL:hld:V", long_options, &option_index)) != -1) {
301         switch (opt) {
302             case 'a':
303                 LOG("Autostart disabled using -a\n");
304                 autostart = false;
305                 break;
306             case 'L':
307                 FREE(layout_path);
308                 layout_path = sstrdup(optarg);
309                 delete_layout_path = false;
310                 break;
311             case 'c':
312                 FREE(override_configpath);
313                 override_configpath = sstrdup(optarg);
314                 break;
315             case 'C':
316                 LOG("Checking configuration file only (-C)\n");
317                 only_check_config = true;
318                 break;
319             case 'v':
320                 printf("i3 version " I3_VERSION " © 2009-2012 Michael Stapelberg and contributors\n");
321                 exit(EXIT_SUCCESS);
322                 break;
323             case 'm':
324                 printf("Binary i3 version:  " I3_VERSION " © 2009-2012 Michael Stapelberg and contributors\n");
325                 display_running_version();
326                 exit(EXIT_SUCCESS);
327                 break;
328             case 'V':
329                 set_verbosity(true);
330                 break;
331             case 'd':
332                 LOG("Enabling debug logging\n");
333                 set_debug_logging(true);
334                 break;
335             case 'l':
336                 /* DEPRECATED, ignored for the next 3 versions (3.e, 3.f, 3.g) */
337                 break;
338             case 0:
339                 if (strcmp(long_options[option_index].name, "force-xinerama") == 0 ||
340                     strcmp(long_options[option_index].name, "force_xinerama") == 0) {
341                     force_xinerama = true;
342                     ELOG("Using Xinerama instead of RandR. This option should be "
343                          "avoided at all cost because it does not refresh the list "
344                          "of screens, so you cannot configure displays at runtime. "
345                          "Please check if your driver really does not support RandR "
346                          "and disable this option as soon as you can.\n");
347                     break;
348                 } else if (strcmp(long_options[option_index].name, "disable-signalhandler") == 0) {
349                     disable_signalhandler = true;
350                     break;
351                 } else if (strcmp(long_options[option_index].name, "get-socketpath") == 0 ||
352                            strcmp(long_options[option_index].name, "get_socketpath") == 0) {
353                     char *socket_path = root_atom_contents("I3_SOCKET_PATH");
354                     if (socket_path) {
355                         printf("%s\n", socket_path);
356                         exit(EXIT_SUCCESS);
357                     }
358
359                     exit(EXIT_FAILURE);
360                 } else if (strcmp(long_options[option_index].name, "shmlog-size") == 0 ||
361                            strcmp(long_options[option_index].name, "shmlog_size") == 0) {
362                     shmlog_size = atoi(optarg);
363                     /* Re-initialize logging immediately to get as many
364                      * logmessages as possible into the SHM log. */
365                     init_logging();
366                     LOG("Limiting SHM log size to %d bytes\n", shmlog_size);
367                     break;
368                 } else if (strcmp(long_options[option_index].name, "restart") == 0) {
369                     FREE(layout_path);
370                     layout_path = sstrdup(optarg);
371                     delete_layout_path = true;
372                     break;
373                 } else if (strcmp(long_options[option_index].name, "fake-outputs") == 0 ||
374                            strcmp(long_options[option_index].name, "fake_outputs") == 0) {
375                     LOG("Initializing fake outputs: %s\n", optarg);
376                     fake_outputs = sstrdup(optarg);
377                     break;
378                 }
379                 /* fall-through */
380             default:
381                 fprintf(stderr, "Usage: %s [-c configfile] [-d all] [-a] [-v] [-V] [-C]\n", argv[0]);
382                 fprintf(stderr, "\n");
383                 fprintf(stderr, "\t-a          disable autostart ('exec' lines in config)\n");
384                 fprintf(stderr, "\t-c <file>   use the provided configfile instead\n");
385                 fprintf(stderr, "\t-C          validate configuration file and exit\n");
386                 fprintf(stderr, "\t-d all      enable debug output\n");
387                 fprintf(stderr, "\t-L <file>   path to the serialized layout during restarts\n");
388                 fprintf(stderr, "\t-v          display version and exit\n");
389                 fprintf(stderr, "\t-V          enable verbose mode\n");
390                 fprintf(stderr, "\n");
391                 fprintf(stderr, "\t--force-xinerama\n"
392                                 "\tUse Xinerama instead of RandR.\n"
393                                 "\tThis option should only be used if you are stuck with the\n"
394                                 "\told nVidia closed source driver (older than 302.17), which does\n"
395                                 "\tnot support RandR.\n");
396                 fprintf(stderr, "\n");
397                 fprintf(stderr, "\t--get-socketpath\n"
398                                 "\tRetrieve the i3 IPC socket path from X11, print it, then exit.\n");
399                 fprintf(stderr, "\n");
400                 fprintf(stderr, "\t--shmlog-size <limit>\n"
401                                 "\tLimits the size of the i3 SHM log to <limit> bytes. Setting this\n"
402                                 "\tto 0 disables SHM logging entirely.\n"
403                                 "\tThe default is %d bytes.\n", shmlog_size);
404                 fprintf(stderr, "\n");
405                 fprintf(stderr, "If you pass plain text arguments, i3 will interpret them as a command\n"
406                                 "to send to a currently running i3 (like i3-msg). This allows you to\n"
407                                 "use nice and logical commands, such as:\n"
408                                 "\n"
409                                 "\ti3 border none\n"
410                                 "\ti3 floating toggle\n"
411                                 "\ti3 kill window\n"
412                                 "\n");
413                 exit(EXIT_FAILURE);
414         }
415     }
416
417     /* If the user passes more arguments, we act like i3-msg would: Just send
418      * the arguments as an IPC message to i3. This allows for nice semantic
419      * commands such as 'i3 border none'. */
420     if (!only_check_config && optind < argc) {
421         /* We enable verbose mode so that the user knows what’s going on.
422          * This should make it easier to find mistakes when the user passes
423          * arguments by mistake. */
424         set_verbosity(true);
425
426         LOG("Additional arguments passed. Sending them as a command to i3.\n");
427         char *payload = NULL;
428         while (optind < argc) {
429             if (!payload) {
430                 payload = sstrdup(argv[optind]);
431             } else {
432                 char *both;
433                 sasprintf(&both, "%s %s", payload, argv[optind]);
434                 free(payload);
435                 payload = both;
436             }
437             optind++;
438         }
439         DLOG("Command is: %s (%zd bytes)\n", payload, strlen(payload));
440         char *socket_path = root_atom_contents("I3_SOCKET_PATH");
441         if (!socket_path) {
442             ELOG("Could not get i3 IPC socket path\n");
443             return 1;
444         }
445
446         int sockfd = socket(AF_LOCAL, SOCK_STREAM, 0);
447         if (sockfd == -1)
448             err(EXIT_FAILURE, "Could not create socket");
449
450         struct sockaddr_un addr;
451         memset(&addr, 0, sizeof(struct sockaddr_un));
452         addr.sun_family = AF_LOCAL;
453         strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1);
454         if (connect(sockfd, (const struct sockaddr*)&addr, sizeof(struct sockaddr_un)) < 0)
455             err(EXIT_FAILURE, "Could not connect to i3");
456
457         if (ipc_send_message(sockfd, strlen(payload), I3_IPC_MESSAGE_TYPE_COMMAND,
458                              (uint8_t*)payload) == -1)
459             err(EXIT_FAILURE, "IPC: write()");
460
461         uint32_t reply_length;
462         uint8_t *reply;
463         int ret;
464         if ((ret = ipc_recv_message(sockfd, I3_IPC_MESSAGE_TYPE_COMMAND,
465                                     &reply_length, &reply)) != 0) {
466             if (ret == -1)
467                 err(EXIT_FAILURE, "IPC: read()");
468             return 1;
469         }
470         printf("%.*s\n", reply_length, reply);
471         return 0;
472     }
473
474     /* Enable logging to handle the case when the user did not specify --shmlog-size */
475     init_logging();
476
477     /* Try to enable core dumps by default when running a debug build */
478     if (is_debug_build()) {
479         struct rlimit limit = { RLIM_INFINITY, RLIM_INFINITY };
480         setrlimit(RLIMIT_CORE, &limit);
481
482         /* The following code is helpful, but not required. We thus don’t pay
483          * much attention to error handling, non-linux or other edge cases. */
484         char cwd[PATH_MAX];
485         LOG("CORE DUMPS: You are running a development version of i3, so coredumps were automatically enabled (ulimit -c unlimited).\n");
486         if (getcwd(cwd, sizeof(cwd)) != NULL)
487             LOG("CORE DUMPS: Your current working directory is \"%s\".\n", cwd);
488         int patternfd;
489         if ((patternfd = open("/proc/sys/kernel/core_pattern", O_RDONLY)) >= 0) {
490             memset(cwd, '\0', sizeof(cwd));
491             if (read(patternfd, cwd, sizeof(cwd)) > 0)
492                 /* a trailing newline is included in cwd */
493                 LOG("CORE DUMPS: Your core_pattern is: %s", cwd);
494             close(patternfd);
495         }
496     }
497
498     LOG("i3 " I3_VERSION " starting\n");
499
500     conn = xcb_connect(NULL, &conn_screen);
501     if (xcb_connection_has_error(conn))
502         errx(EXIT_FAILURE, "Cannot open display\n");
503
504     sndisplay = sn_xcb_display_new(conn, NULL, NULL);
505
506     /* Initialize the libev event loop. This needs to be done before loading
507      * the config file because the parser will install an ev_child watcher
508      * for the nagbar when config errors are found. */
509     main_loop = EV_DEFAULT;
510     if (main_loop == NULL)
511             die("Could not initialize libev. Bad LIBEV_FLAGS?\n");
512
513     root_screen = xcb_aux_get_screen(conn, conn_screen);
514     root = root_screen->root;
515
516     /* By default, we use the same depth and visual as the root window, which
517      * usually is TrueColor (24 bit depth) and the corresponding visual.
518      * However, we also check if a 32 bit depth and visual are available (for
519      * transparency) and use it if so. */
520     root_depth = root_screen->root_depth;
521     visual_id = root_screen->root_visual;
522     colormap = root_screen->default_colormap;
523
524     DLOG("root_depth = %d, visual_id = 0x%08x.\n", root_depth, visual_id);
525
526     xcb_get_geometry_cookie_t gcookie = xcb_get_geometry(conn, root);
527     xcb_query_pointer_cookie_t pointercookie = xcb_query_pointer(conn, root);
528
529     load_configuration(conn, override_configpath, false);
530     if (only_check_config) {
531         LOG("Done checking configuration file. Exiting.\n");
532         exit(0);
533     }
534
535     if (config.ipc_socket_path == NULL) {
536         /* Fall back to a file name in /tmp/ based on the PID */
537         if ((config.ipc_socket_path = getenv("I3SOCK")) == NULL)
538             config.ipc_socket_path = get_process_filename("ipc-socket");
539         else
540             config.ipc_socket_path = sstrdup(config.ipc_socket_path);
541     }
542
543     uint32_t mask = XCB_CW_EVENT_MASK;
544     uint32_t values[] = { XCB_EVENT_MASK_SUBSTRUCTURE_REDIRECT |
545                           XCB_EVENT_MASK_BUTTON_PRESS |
546                           XCB_EVENT_MASK_STRUCTURE_NOTIFY |         /* when the user adds a screen (e.g. video
547                                                                            projector), the root window gets a
548                                                                            ConfigureNotify */
549                           XCB_EVENT_MASK_POINTER_MOTION |
550                           XCB_EVENT_MASK_PROPERTY_CHANGE |
551                           XCB_EVENT_MASK_ENTER_WINDOW };
552     xcb_void_cookie_t cookie;
553     cookie = xcb_change_window_attributes_checked(conn, root, mask, values);
554     check_error(conn, cookie, "Another window manager seems to be running");
555
556     xcb_get_geometry_reply_t *greply = xcb_get_geometry_reply(conn, gcookie, NULL);
557     if (greply == NULL) {
558         ELOG("Could not get geometry of the root window, exiting\n");
559         return 1;
560     }
561     DLOG("root geometry reply: (%d, %d) %d x %d\n", greply->x, greply->y, greply->width, greply->height);
562
563     /* Place requests for the atoms we need as soon as possible */
564     #define xmacro(atom) \
565         xcb_intern_atom_cookie_t atom ## _cookie = xcb_intern_atom(conn, 0, strlen(#atom), #atom);
566     #include "atoms.xmacro"
567     #undef xmacro
568
569     /* Initialize the Xlib connection */
570     xlibdpy = xkbdpy = XOpenDisplay(NULL);
571
572     /* Try to load the X cursors and initialize the XKB extension */
573     if (xlibdpy == NULL) {
574         ELOG("ERROR: XOpenDisplay() failed, disabling libXcursor/XKB support\n");
575         xcursor_supported = false;
576         xkb_supported = false;
577     } else if (fcntl(ConnectionNumber(xlibdpy), F_SETFD, FD_CLOEXEC) == -1) {
578         ELOG("Could not set FD_CLOEXEC on xkbdpy\n");
579         return 1;
580     } else {
581         xcursor_load_cursors();
582         /*init_xkb();*/
583     }
584
585     /* Set a cursor for the root window (otherwise the root window will show no
586        cursor until the first client is launched). */
587     if (xcursor_supported)
588         xcursor_set_root_cursor(XCURSOR_CURSOR_POINTER);
589     else xcb_set_root_cursor(XCURSOR_CURSOR_POINTER);
590
591     if (xkb_supported) {
592         int errBase,
593             major = XkbMajorVersion,
594             minor = XkbMinorVersion;
595
596         if (fcntl(ConnectionNumber(xkbdpy), F_SETFD, FD_CLOEXEC) == -1) {
597             fprintf(stderr, "Could not set FD_CLOEXEC on xkbdpy\n");
598             return 1;
599         }
600
601         int i1;
602         if (!XkbQueryExtension(xkbdpy,&i1,&xkb_event_base,&errBase,&major,&minor)) {
603             fprintf(stderr, "XKB not supported by X-server\n");
604             return 1;
605         }
606         /* end of ugliness */
607
608         if (!XkbSelectEvents(xkbdpy, XkbUseCoreKbd,
609                              XkbMapNotifyMask | XkbStateNotifyMask,
610                              XkbMapNotifyMask | XkbStateNotifyMask)) {
611             fprintf(stderr, "Could not set XKB event mask\n");
612             return 1;
613         }
614     }
615
616     /* Setup NetWM atoms */
617     #define xmacro(name) \
618         do { \
619             xcb_intern_atom_reply_t *reply = xcb_intern_atom_reply(conn, name ## _cookie, NULL); \
620             if (!reply) { \
621                 ELOG("Could not get atom " #name "\n"); \
622                 exit(-1); \
623             } \
624             A_ ## name = reply->atom; \
625             free(reply); \
626         } while (0);
627     #include "atoms.xmacro"
628     #undef xmacro
629
630     property_handlers_init();
631
632     ewmh_setup_hints();
633
634     keysyms = xcb_key_symbols_alloc(conn);
635
636     xcb_numlock_mask = aio_get_mod_mask_for(XCB_NUM_LOCK, keysyms);
637
638     translate_keysyms();
639     grab_all_keys(conn, false);
640
641     bool needs_tree_init = true;
642     if (layout_path) {
643         LOG("Trying to restore the layout from %s...", layout_path);
644         needs_tree_init = !tree_restore(layout_path, greply);
645         if (delete_layout_path)
646             unlink(layout_path);
647         free(layout_path);
648     }
649     if (needs_tree_init)
650         tree_init(greply);
651
652     free(greply);
653
654     /* Setup fake outputs for testing */
655     if (fake_outputs == NULL && config.fake_outputs != NULL)
656         fake_outputs = config.fake_outputs;
657
658     if (fake_outputs != NULL) {
659         fake_outputs_init(fake_outputs);
660         FREE(fake_outputs);
661         config.fake_outputs = NULL;
662     } else if (force_xinerama || config.force_xinerama) {
663         /* Force Xinerama (for drivers which don't support RandR yet, esp. the
664          * nVidia binary graphics driver), when specified either in the config
665          * file or on command-line */
666         xinerama_init();
667     } else {
668         DLOG("Checking for XRandR...\n");
669         randr_init(&randr_base);
670     }
671
672     scratchpad_fix_resolution();
673
674     xcb_query_pointer_reply_t *pointerreply;
675     Output *output = NULL;
676     if (!(pointerreply = xcb_query_pointer_reply(conn, pointercookie, NULL))) {
677         ELOG("Could not query pointer position, using first screen\n");
678     } else {
679         DLOG("Pointer at %d, %d\n", pointerreply->root_x, pointerreply->root_y);
680         output = get_output_containing(pointerreply->root_x, pointerreply->root_y);
681         if (!output) {
682             ELOG("ERROR: No screen at (%d, %d), starting on the first screen\n",
683                  pointerreply->root_x, pointerreply->root_y);
684             output = get_first_output();
685         }
686
687         con_focus(con_descend_focused(output_get_content(output->con)));
688     }
689
690     tree_render();
691
692     /* Create the UNIX domain socket for IPC */
693     int ipc_socket = ipc_create_socket(config.ipc_socket_path);
694     if (ipc_socket == -1) {
695         ELOG("Could not create the IPC socket, IPC disabled\n");
696     } else {
697         free(config.ipc_socket_path);
698         struct ev_io *ipc_io = scalloc(sizeof(struct ev_io));
699         ev_io_init(ipc_io, ipc_new_client, ipc_socket, EV_READ);
700         ev_io_start(main_loop, ipc_io);
701     }
702
703     /* Also handle the UNIX domain sockets passed via socket activation. The
704      * parameter 1 means "remove the environment variables", we don’t want to
705      * pass these to child processes. */
706     listen_fds = sd_listen_fds(0);
707     if (listen_fds < 0)
708         ELOG("socket activation: Error in sd_listen_fds\n");
709     else if (listen_fds == 0)
710         DLOG("socket activation: no sockets passed\n");
711     else {
712         int flags;
713         for (int fd = SD_LISTEN_FDS_START;
714              fd < (SD_LISTEN_FDS_START + listen_fds);
715              fd++) {
716             DLOG("socket activation: also listening on fd %d\n", fd);
717
718             /* sd_listen_fds() enables FD_CLOEXEC by default.
719              * However, we need to keep the file descriptors open for in-place
720              * restarting, therefore we explicitly disable FD_CLOEXEC. */
721             if ((flags = fcntl(fd, F_GETFD)) < 0 ||
722                 fcntl(fd, F_SETFD, flags & ~FD_CLOEXEC) < 0) {
723                 ELOG("Could not disable FD_CLOEXEC on fd %d\n", fd);
724             }
725
726             struct ev_io *ipc_io = scalloc(sizeof(struct ev_io));
727             ev_io_init(ipc_io, ipc_new_client, fd, EV_READ);
728             ev_io_start(main_loop, ipc_io);
729         }
730     }
731
732     /* Set up i3 specific atoms like I3_SOCKET_PATH and I3_CONFIG_PATH */
733     x_set_i3_atoms();
734
735     struct ev_io *xcb_watcher = scalloc(sizeof(struct ev_io));
736     struct ev_io *xkb = scalloc(sizeof(struct ev_io));
737     struct ev_check *xcb_check = scalloc(sizeof(struct ev_check));
738     struct ev_prepare *xcb_prepare = scalloc(sizeof(struct ev_prepare));
739
740     ev_io_init(xcb_watcher, xcb_got_event, xcb_get_file_descriptor(conn), EV_READ);
741     ev_io_start(main_loop, xcb_watcher);
742
743
744     if (xkb_supported) {
745         ev_io_init(xkb, xkb_got_event, ConnectionNumber(xkbdpy), EV_READ);
746         ev_io_start(main_loop, xkb);
747
748         /* Flush the buffer so that libev can properly get new events */
749         XFlush(xkbdpy);
750     }
751
752     ev_check_init(xcb_check, xcb_check_cb);
753     ev_check_start(main_loop, xcb_check);
754
755     ev_prepare_init(xcb_prepare, xcb_prepare_cb);
756     ev_prepare_start(main_loop, xcb_prepare);
757
758     xcb_flush(conn);
759
760     /* What follows is a fugly consequence of X11 protocol race conditions like
761      * the following: In an i3 in-place restart, i3 will reparent all windows
762      * to the root window, then exec() itself. In the new process, it calls
763      * manage_existing_windows. However, in case any application sent a
764      * generated UnmapNotify message to the WM (as GIMP does), this message
765      * will be handled by i3 *after* managing the window, thus i3 thinks the
766      * window just closed itself. In reality, the message was sent in the time
767      * period where i3 wasn’t running yet.
768      *
769      * To prevent this, we grab the server (disables processing of any other
770      * connections), then discard all pending events (since we didn’t do
771      * anything, there cannot be any meaningful responses), then ungrab the
772      * server. */
773     xcb_grab_server(conn);
774     {
775         xcb_aux_sync(conn);
776         xcb_generic_event_t *event;
777         while ((event = xcb_poll_for_event(conn)) != NULL) {
778             free(event);
779         }
780         manage_existing_windows(root);
781     }
782     xcb_ungrab_server(conn);
783
784     struct sigaction action;
785
786     action.sa_sigaction = handle_signal;
787     action.sa_flags = SA_NODEFER | SA_RESETHAND | SA_SIGINFO;
788     sigemptyset(&action.sa_mask);
789
790     if (!disable_signalhandler)
791         setup_signal_handler();
792     else {
793         /* Catch all signals with default action "Core", see signal(7) */
794         if (sigaction(SIGQUIT, &action, NULL) == -1 ||
795             sigaction(SIGILL, &action, NULL) == -1 ||
796             sigaction(SIGABRT, &action, NULL) == -1 ||
797             sigaction(SIGFPE, &action, NULL) == -1 ||
798             sigaction(SIGSEGV, &action, NULL) == -1)
799             ELOG("Could not setup signal handler");
800     }
801
802     /* Catch all signals with default action "Term", see signal(7) */
803     if (sigaction(SIGHUP, &action, NULL) == -1 ||
804         sigaction(SIGINT, &action, NULL) == -1 ||
805         sigaction(SIGALRM, &action, NULL) == -1 ||
806         sigaction(SIGUSR1, &action, NULL) == -1 ||
807         sigaction(SIGUSR2, &action, NULL) == -1)
808         ELOG("Could not setup signal handler");
809
810     /* Ignore SIGPIPE to survive errors when an IPC client disconnects
811      * while we are sending him a message */
812     signal(SIGPIPE, SIG_IGN);
813
814     /* Autostarting exec-lines */
815     if (autostart) {
816         struct Autostart *exec;
817         TAILQ_FOREACH(exec, &autostarts, autostarts) {
818             LOG("auto-starting %s\n", exec->command);
819             start_application(exec->command, exec->no_startup_id);
820         }
821     }
822
823     /* Autostarting exec_always-lines */
824     struct Autostart *exec_always;
825     TAILQ_FOREACH(exec_always, &autostarts_always, autostarts_always) {
826         LOG("auto-starting (always!) %s\n", exec_always->command);
827         start_application(exec_always->command, exec_always->no_startup_id);
828     }
829
830     /* Start i3bar processes for all configured bars */
831     Barconfig *barconfig;
832     TAILQ_FOREACH(barconfig, &barconfigs, configs) {
833         char *command = NULL;
834         sasprintf(&command, "%s --bar_id=%s --socket=\"%s\"",
835                 barconfig->i3bar_command ? barconfig->i3bar_command : "i3bar",
836                 barconfig->id, current_socketpath);
837         LOG("Starting bar process: %s\n", command);
838         start_application(command, true);
839         free(command);
840     }
841
842     /* Make sure to destroy the event loop to invoke the cleeanup callbacks
843      * when calling exit() */
844     atexit(i3_exit);
845
846     ev_loop(main_loop, 0);
847 }