making some nice batch-query stuff for initializing the display statics
[dana/dcompmgr.git] / display.c
index 1811f5b..c937103 100644 (file)
--- a/display.c
+++ b/display.c
@@ -1,5 +1,6 @@
 #include "display.h"
 #include <stdlib.h>
+#include <string.h>
 #include <stdio.h>
 
 #include <xcb/damage.h>
 #include <xcb/xfixes.h>
 #include <xcb/composite.h>
 
+typedef xcb_void_cookie_t
+(*query_version_func_t)(xcb_connection_t *c,
+                        uint32_t major,
+                        uint32_t minor);
+
+typedef struct {
+    d_display_ext_t      *ext;
+    xcb_extension_t      *xcb;
+    query_version_func_t  ver;
+    int                   major;
+    int                   minor;
+    xcb_void_cookie_t     ck;
+} d_extension_query_t;
+
+typedef struct {
+    xcb_atom_t               *atom;
+    const char               *name;
+    xcb_intern_atom_cookie_t  ck;
+} d_atom_query_t;
+
 static void
-query_extensions(d_display_t *dpy)
+query_extension(d_display_t *dpy, d_extension_query_t *q)
 {
-    xcb_xfixes_query_version_cookie_t      fixes_version_cookie;
-    xcb_render_query_version_cookie_t      render_version_cookie;
-    xcb_composite_query_version_cookie_t   composite_version_cookie;
-    xcb_damage_query_version_cookie_t      damage_version_cookie;
-    xcb_render_query_pict_formats_cookie_t render_formats_cookie;
-
     const xcb_query_extension_reply_t *rep;
 
-    xcb_prefetch_extension_data(dpy->conn, &xcb_xfixes_id);
-    xcb_prefetch_extension_data(dpy->conn, &xcb_render_id);
-    xcb_prefetch_extension_data(dpy->conn, &xcb_composite_id);
-    xcb_prefetch_extension_data(dpy->conn, &xcb_damage_id);
-
-    rep = xcb_get_extension_data(dpy->conn, &xcb_xfixes_id);
-    dpy->xfixes = rep && rep->present;
-    dpy->xfixes_error = rep && rep->first_error;
-    dpy->xfixes_event = rep && rep->first_event;
-    dpy->xfixes_opcode = rep && rep->major_opcode;
-
-    rep = xcb_get_extension_data(dpy->conn, &xcb_render_id);
-    dpy->render = rep && rep->present;
-    dpy->render_error = rep && rep->first_error;
-    dpy->render_event = rep && rep->first_event;
-    dpy->render_opcode = rep && rep->major_opcode;
-
-    rep = xcb_get_extension_data(dpy->conn, &xcb_composite_id);
-    dpy->composite = rep && rep->present;
-    dpy->composite_error = rep && rep->first_error;
-    dpy->composite_event = rep && rep->first_event;
-    dpy->composite_opcode = rep && rep->major_opcode;
-
-    rep = xcb_get_extension_data(dpy->conn, &xcb_damage_id);
-    dpy->damage = rep && rep->present;
-    dpy->damage_error = rep && rep->first_error;
-    dpy->damage_event = rep && rep->first_event;
-    dpy->damage_opcode = rep && rep->major_opcode;
+    xcb_prefetch_extension_data(dpy->conn, q->xcb);
+    rep = xcb_get_extension_data(dpy->conn, q->xcb);
+    q->ext->present = rep && rep->present;
+    q->ext->error   = rep && rep->first_error;
+    q->ext->event   = rep && rep->first_event;
+    q->ext->opcode  = rep && rep->major_opcode;
+
+    if (q->ext->present) {
+        q->ck = q->ver(dpy->conn, q->major, q->minor);
+    }
+}
+
+static void
+query_atom(d_display_t *dpy, d_atom_query_t *q)
+{
+    q->ck = xcb_intern_atom(dpy->conn, FALSE, strlen(q->name), q->name);
 }
 
+static void
+query_statics(d_display_t *dpy)
+{
+    d_extension_query_t extensions[] = {
+        {
+            .ext = &dpy->xfixes,
+            .xcb = &xcb_xfixes_id,
+            .ver = (query_version_func_t)xcb_xfixes_query_version,
+            .major = XCB_XFIXES_MAJOR_VERSION,
+            .minor = XCB_XFIXES_MINOR_VERSION
+        },
+        {
+            .ext = &dpy->render,
+            .xcb = &xcb_render_id,
+            .ver = (query_version_func_t)xcb_render_query_version,
+            .major = XCB_RENDER_MAJOR_VERSION,
+            .minor = XCB_RENDER_MINOR_VERSION
+        },
+        {
+            .ext = &dpy->damage,
+            .xcb = &xcb_damage_id,
+            .ver = (query_version_func_t)xcb_damage_query_version,
+            .major = XCB_DAMAGE_MAJOR_VERSION,
+            .minor = XCB_DAMAGE_MINOR_VERSION
+        },
+        {
+            .ext = &dpy->composite,
+            .xcb = &xcb_composite_id,
+            .ver = (query_version_func_t)xcb_composite_query_version,
+            .major = XCB_COMPOSITE_MAJOR_VERSION,
+            .minor = XCB_COMPOSITE_MINOR_VERSION
+        },
+        { .ext = NULL }
+    };
+    d_atom_query_t atoms[] = {
+        { .atom = &dpy->a.atom,
+          .name = "ATOM" },
+        { .atom = &dpy->a.cardinal,
+          .name = "CARDINAL" },
+        { .atom = &dpy->a.utf8_string,
+          .name = "UTF8_STRING" },
+        { .atom = &dpy->a.string,
+          .name = "STRING" },
+        { .atom = &dpy->a.pixmap,
+          .name = "PIXMAP" },
+        { .atom = &dpy->a.net_wm_window_type,
+          .name = "_NET_WM_WINDOW_TYPE" },
+        { .atom = &dpy->a.net_wm_window_type_desktop,
+          .name = "_NET_WM_WINDOW_TYPE_DESKTOP" },
+        { .atom = &dpy->a.net_wm_window_type_dock,
+          .name = "_NET_WM_WINDOW_TYPE_DOCK" },
+        { .atom = &dpy->a.net_wm_window_type_normal,
+          .name = "_NET_WM_WINDOW_TYPE_NORMAL" },
+        { .atom = &dpy->a.net_wm_window_type_dialog,
+          .name = "_NET_WM_WINDOW_TYPE_DIALOG" },
+        { .atom = &dpy->a.net_wm_window_type_toolbar,
+          .name = "_NET_WM_WINDOW_TYPE_TOOLBAR" },
+        { .atom = &dpy->a.net_wm_window_type_menu,
+          .name = "_NET_WM_WINDOW_TYPE_MENU" },
+        { .atom = &dpy->a.net_wm_window_type_utility,
+          .name = "_NET_WM_WINDOW_TYPE_UTILITY" },
+        { .atom = &dpy->a.net_wm_window_type_splash,
+          .name = "_NET_WM_WINDOW_TYPE_SPLAH" },
+        { .atom = &dpy->a.net_wm_window_type_tooltip,
+          .name = "_NET_WM_WINDOW_TYPE_TOOLTIP" },
+        { .atom = &dpy->a.net_wm_window_type_combo,
+          .name = "_NET_WM_WINDOW_TYPE_COMBO" },
+        { .atom = &dpy->a.net_wm_window_type_dropdown_menu,
+          .name = "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU" },
+        { .atom = &dpy->a.net_wm_window_type_popup_menu,
+          .name = "_NET_WM_WINDOW_TYPE_POPUP_MENU" },
+        { .atom = &dpy->a.net_wm_window_type_notification,
+          .name = "_NET_WM_WINDOW_TYPE_NOTIFICATION" },
+        { .atom = NULL }
+    };
+    int i;
+
+    for (i = 0; extensions[i].ext != NULL; ++i)
+        query_extension(dpy, &extensions[i]);
+    for (i = 0; atoms[i].atom != NULL; ++i)
+        query_atom(dpy, &atoms[i]);
+
+}
 
 d_display_t*
 display_open(const char *name)
@@ -61,7 +147,7 @@ display_open(const char *name)
         dpy->conn = conn;
         dpy->ref = 1;
 
-        query_extensions(dpy);
+        query_statics(dpy);
     }
     return dpy;
 }
@@ -104,17 +190,17 @@ display_error(d_display_t *dpy, xcb_generic_error_t *ev)
     default: break;
     }
     if (!name)
-        switch (ev->error_code - dpy->xfixes_error) {
+        switch (ev->error_code - dpy->xfixes.error) {
         case XCB_XFIXES_BAD_REGION: name = "BadRegion"; break;
         default: break;
         }
     if (!name)
-        switch (ev->error_code - dpy->damage_error) {
+        switch (ev->error_code - dpy->damage.error) {
         case XCB_DAMAGE_BAD_DAMAGE: name = "BadDamage"; break;
         default: break;
         }
     if (!name)
-        switch (ev->error_code - dpy->render_error) {
+        switch (ev->error_code - dpy->render.error) {
         case XCB_RENDER_PICT_FORMAT: name = "BadPictFormat"; break;
         case XCB_RENDER_PICT_OP:     name = "BadPictOp"; break;
         case XCB_RENDER_PICTURE:     name = "BadPicture"; break;