]> git.sur5r.net Git - i3/i3/blobdiff - src/mainx.c
huge change: implement RandR instead of Xinerama
[i3/i3] / src / mainx.c
index 9c38c4acd74b2c9c45f356b518fc9807c171234e..8130c0744b2272cbbeaea0ae2eea9c51d0c46e82 100644 (file)
@@ -3,13 +3,12 @@
  *
  * i3 - an improved dynamic tiling window manager
  *
- * © 2009 Michael Stapelberg and contributors
+ * © 2009-2010 Michael Stapelberg and contributors
  *
  * See file LICENSE for license information.
  *
  */
 #include <stdio.h>
-#include <assert.h>
 #include <stdlib.h>
 #include <string.h>
 #include <sys/types.h>
@@ -31,7 +30,6 @@
 #include <xcb/xcb_property.h>
 #include <xcb/xcb_keysyms.h>
 #include <xcb/xcb_icccm.h>
-#include <xcb/xinerama.h>
 
 #include <ev.h>
 
 #include "table.h"
 #include "util.h"
 #include "xcb.h"
-#include "xinerama.h"
+#include "randr.h"
 #include "manage.h"
 #include "ipc.h"
 #include "log.h"
+#include "sighandler.h"
 
 xcb_connection_t *global_conn;
 
@@ -150,6 +149,7 @@ int main(int argc, char *argv[], char *env[]) {
         int i, screens, opt;
         char *override_configpath = NULL;
         bool autostart = true;
+        bool only_check_config = false;
         xcb_connection_t *conn;
         xcb_property_handlers_t prophs;
         xcb_intern_atom_cookie_t atom_cookies[NUM_ATOMS];
@@ -170,7 +170,7 @@ int main(int argc, char *argv[], char *env[]) {
 
         start_argv = argv;
 
-        while ((opt = getopt_long(argc, argv, "c:vahld:V", long_options, &option_index)) != -1) {
+        while ((opt = getopt_long(argc, argv, "c:Cvahld:V", long_options, &option_index)) != -1) {
                 switch (opt) {
                         case 'a':
                                 LOG("Autostart disabled using -a\n");
@@ -179,6 +179,10 @@ int main(int argc, char *argv[], char *env[]) {
                         case 'c':
                                 override_configpath = sstrdup(optarg);
                                 break;
+                        case 'C':
+                                LOG("Checking configuration file only (-C)\n");
+                                only_check_config = true;
+                                break;
                         case 'v':
                                 printf("i3 version " I3_VERSION " © 2009 Michael Stapelberg and contributors\n");
                                 exit(EXIT_SUCCESS);
@@ -193,13 +197,14 @@ int main(int argc, char *argv[], char *env[]) {
                                 /* DEPRECATED, ignored for the next 3 versions (3.e, 3.f, 3.g) */
                                 break;
                         default:
-                                fprintf(stderr, "Usage: %s [-c configfile] [-d loglevel] [-a] [-v] [-V]\n", argv[0]);
+                                fprintf(stderr, "Usage: %s [-c configfile] [-d loglevel] [-a] [-v] [-V] [-C]\n", argv[0]);
                                 fprintf(stderr, "\n");
                                 fprintf(stderr, "-a: disable autostart\n");
                                 fprintf(stderr, "-v: display version and exit\n");
                                 fprintf(stderr, "-V: enable verbose mode\n");
                                 fprintf(stderr, "-d <loglevel>: enable debug loglevel <loglevel>\n");
                                 fprintf(stderr, "-c <configfile>: use the provided configfile instead\n");
+                                fprintf(stderr, "-C: check configuration file and exit\n");
                                 exit(EXIT_FAILURE);
                 }
         }
@@ -218,6 +223,10 @@ int main(int argc, char *argv[], char *env[]) {
                 die("Cannot open display\n");
 
         load_configuration(conn, override_configpath, false);
+        if (only_check_config) {
+                LOG("Done checking configuration file. Exiting.\n");
+                exit(0);
+        }
 
         /* Create the initial container on the first workspace. This used to
          * be part of init_table, but since it possibly requires an X
@@ -248,6 +257,9 @@ int main(int argc, char *argv[], char *env[]) {
         REQUEST_ATOM(UTF8_STRING);
         REQUEST_ATOM(WM_STATE);
         REQUEST_ATOM(WM_CLIENT_LEADER);
+        REQUEST_ATOM(_NET_CURRENT_DESKTOP);
+        REQUEST_ATOM(_NET_ACTIVE_WINDOW);
+        REQUEST_ATOM(_NET_WORKAREA);
 
         /* TODO: this has to be more beautiful somewhen */
         int major, minor, error;
@@ -282,7 +294,7 @@ int main(int argc, char *argv[], char *env[]) {
         }
 
         /* Initialize event loop using libev */
-        struct ev_loop *loop = ev_default_loop(0);
+        struct ev_loop *loop = ev_loop_new(0);
         if (loop == NULL)
                 die("Could not initialize libev. Bad LIBEV_FLAGS?\n");
 
@@ -410,6 +422,9 @@ int main(int argc, char *argv[], char *env[]) {
         GET_ATOM(UTF8_STRING);
         GET_ATOM(WM_STATE);
         GET_ATOM(WM_CLIENT_LEADER);
+        GET_ATOM(_NET_CURRENT_DESKTOP);
+        GET_ATOM(_NET_ACTIVE_WINDOW);
+        GET_ATOM(_NET_WORKAREA);
 
         xcb_property_set_handler(&prophs, atoms[_NET_WM_WINDOW_TYPE], UINT_MAX, handle_window_type, NULL);
         /* TODO: In order to comply with EWMH, we have to watch _NET_WM_STRUT_PARTIAL */
@@ -454,9 +469,14 @@ int main(int argc, char *argv[], char *env[]) {
                 }
         }
 
-        /* check for Xinerama */
-        DLOG("Checking for Xinerama...\n");
-        initialize_xinerama(conn);
+        DLOG("Checking for XRandR...\n");
+        int randr_base;
+        initialize_randr(conn, &randr_base);
+
+        xcb_event_set_handler(&evenths,
+                              randr_base + XCB_RANDR_SCREEN_CHANGE_NOTIFY,
+                              handle_screen_change,
+                              NULL);
 
         xcb_flush(conn);
 
@@ -467,14 +487,14 @@ int main(int argc, char *argv[], char *env[]) {
                 return 1;
         }
 
-        i3Screen *screen = get_screen_containing(reply->root_x, reply->root_y);
+        Output *screen = get_screen_containing(reply->root_x, reply->root_y);
         if (screen == NULL) {
                 ELOG("ERROR: No screen at %d x %d, starting on the first screen\n",
                     reply->root_x, reply->root_y);
-                screen = TAILQ_FIRST(virtual_screens);
+                screen = get_first_output();
         }
 
-        DLOG("Starting on %d\n", screen->current_workspace);
+        DLOG("Starting on %p\n", screen->current_workspace);
         c_ws = screen->current_workspace;
 
         manage_existing_windows(conn, &prophs, root);
@@ -494,6 +514,7 @@ int main(int argc, char *argv[], char *env[]) {
         /* Handle the events which arrived until now */
         xcb_check_cb(NULL, NULL, 0);
 
+        setup_signal_handler();
         /* Ungrab the server to receive events and enter libev’s eventloop */
         xcb_ungrab_server(conn);
         ev_loop(loop, 0);