check for composite version 0.3
[dana/dcompmgr.git] / dcompmgr.c
index db14b2d..542f1ad 100644 (file)
@@ -1,30 +1,36 @@
 #include "screen.h"
 #include "window.h"
+#include "display.h"
 #include "gettext.h"
 
 #include <glib.h>
 #include <stdio.h>
+#include <stdlib.h>
 #include <string.h>
 #include <xcb/xcb.h>
 
+typedef struct {
+    int foo;
+} d_options_t;
+
 static gint
-all_screens(xcb_connection_t *conn, d_screen_t **list)
+all_screens(d_display_t *dpy, d_screen_t **list)
 {
     static const xcb_setup_t *setup;
     xcb_screen_iterator_t it;
     int count, i;
     d_screen_t sc;
 
-    setup = xcb_get_setup(conn);
+    setup = xcb_get_setup(dpy->conn);
 
     count = i = 0;
     for (it = xcb_setup_roots_iterator(setup); it.rem; xcb_screen_next(&it)) {
         sc.super = *it.data;
-        sc.conn = conn;
+        sc.dpy = dpy;
         sc.num = i++;
         if (screen_register(&sc)) {
             ++count;
-            *list = g_renew(d_screen_t, *list, count);
+            *list = realloc(*list, sizeof(d_screen_t)*count);
             (*list)[count-1] = sc;
             printf(_("managing screen %d\n"), sc.num);
         }
@@ -32,7 +38,7 @@ all_screens(xcb_connection_t *conn, d_screen_t **list)
     return count;
 }
 
-d_screen_t*
+static d_screen_t*
 screen_from_root(d_screen_t *list, int n, xcb_window_t root)
 {
     int i;
@@ -42,51 +48,148 @@ screen_from_root(d_screen_t *list, int n, xcb_window_t root)
     return NULL;
 }
 
+static
+void read_options(int argc, char **argv, d_options_t *opts)
+{
+    opts->foo = argc && argv;
+}
+
 int
 main(int argc, char **argv)
 {
-    xcb_connection_t    *conn;
+    d_display_t         *dpy;
     d_screen_t          *screens = NULL;
     int                  nscreens;
     xcb_generic_event_t *ev;
+    d_options_t          opts;
+
+    read_options(argc, argv, &opts);
 
-    conn = xcb_connect(NULL, NULL);
-    if (!conn) {
+    dpy = display_open(NULL);
+    if (!dpy) {
         printf(_("Unable to connect to display\n"));
         return 1;
     }
 
-    nscreens = all_screens(conn, &screens);
+    if (!dpy->composite.present) {
+        printf(_("no composite extension present on the display\n"));
+        display_unref(dpy);
+        return 1;
+    }
+    if (!dpy->xfixes.present) {
+        printf(_("no xfixes extension present on the display\n"));
+        display_unref(dpy);
+        return 1;
+    }
+    if (!dpy->damage.present) {
+        printf(_("no damage extension present on the display\n"));
+        display_unref(dpy);
+        return 1;
+    }
+    if (!dpy->render.present) {
+        printf(_("no render extension present on the display\n"));
+        display_unref(dpy);
+        return 1;
+    }
+    if (dpy->composite.major_version <= 0 && dpy->composite.minor_version < 3)
+    {
+        printf(_("composite extension does not support the overlay window"));
+        display_unref(dpy);
+        return 1;
+    }
+
+    nscreens = all_screens(dpy, &screens);
     if (nscreens < 1) {
         printf(_("found no screens to run on\n"));
-        xcb_disconnect(conn);
+        display_unref(dpy);
         return 0;
     }
 
-    while (ev = xcb_wait_for_event(conn)) {
-        printf("event\n");
-        switch (ev->response_type & ~0x80) {
-        case XCB_CREATE_WINDOW:
+    while ((ev = xcb_wait_for_event(dpy->conn))) {
+        printf("event %d\n", ev->response_type);
+
+        if (!ev->response_type) {
+            display_error(dpy, (xcb_generic_error_t*)ev);
+            free(ev);
+            continue;
+        }
+
+        switch (ev->response_type) {
+        case XCB_CREATE_NOTIFY:
         {
-            xcb_create_notify_event_t *cev = (xcb_create_notify_event_t*)ev;
-            d_screen_t *sc = screen_from_root(screens, nscreens, cev->parent);
-            screen_add_window(sc, cev);
+            xcb_create_notify_event_t *cev;
+            d_screen_t *sc;
+
+            cev = (xcb_create_notify_event_t*)ev;
+            sc = screen_from_root(screens, nscreens, cev->parent);
+            if (!sc) break;
+            screen_add_window(sc, cev->window);
+            break;
         }
-        case XCB_DESTROY_WINDOW:
+        case XCB_DESTROY_NOTIFY:
         {
-            xcb_destroy_notify_event_t *dev = (xcb_destroy_notify_event_t*)ev;
-            d_screen_t *sc = screen_from_root(screens, nscreens, dev->event);
-            d_window_t *w = screen_find_window(sc, dev->window);
-            screen_hide_window(sc, w);
+            xcb_destroy_notify_event_t *dev;
+            d_screen_t *sc;
+            d_window_t *w;
+
+            dev = (xcb_destroy_notify_event_t*)ev;
+            sc = screen_from_root(screens, nscreens, dev->event);
+            if (!sc) break;
+            w = screen_find_window(sc, dev->window);
+            w->hide(w);
             screen_remove_window(sc, w);
+            break;
+        }
+        case XCB_REPARENT_NOTIFY:
+        {
+            xcb_reparent_notify_event_t *rev;
+            d_screen_t *sc;
+            d_window_t *w;
+
+            rev = (xcb_reparent_notify_event_t*)ev;
+            sc = screen_from_root(screens, nscreens, rev->event);
+            if (!sc) break;
+            w = screen_find_window(sc, rev->window);
+            if (rev->parent == sc->super.root)
+                screen_add_window(sc, rev->window);
+            else {
+                w->hide(w);
+                screen_remove_window(sc, w);
+            }
+            break;
+        }
+        case XCB_MAP_NOTIFY:
+        {
+            xcb_map_notify_event_t *mev;
+            d_screen_t *sc;
+            d_window_t *w;
+
+            mev = (xcb_map_notify_event_t*)ev;
+            sc = screen_from_root(screens, nscreens, mev->event);
+            if (!sc) break;
+            w = screen_find_window(sc, mev->window);
+            window_show(w);
+            break;
+        }
+        case XCB_UNMAP_NOTIFY:
+        {
+            xcb_unmap_notify_event_t *mev;
+            d_screen_t *sc;
+            d_window_t *w;
+
+            mev = (xcb_unmap_notify_event_t*)ev;
+            sc = screen_from_root(screens, nscreens, mev->event);
+            if (!sc) break;
+            w = screen_find_window(sc, mev->window);
+            window_hide(w);
+            break;
         }
-        case XCB_REPARENT_WINDOW:
         default:
             break;
         }
         free(ev);
     }
 
-    xcb_disconnect(conn);
+    display_unref(dpy);
     return 0;
 }