#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)
dpy->conn = conn;
dpy->ref = 1;
- query_extensions(dpy);
+ query_statics(dpy);
}
return dpy;
}
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;