6 #include <xcb/damage.h>
7 #include <xcb/render.h>
8 #include <xcb/xfixes.h>
9 #include <xcb/composite.h>
11 typedef xcb_void_cookie_t
12 (*query_version_func_t)(xcb_connection_t *c,
19 query_version_func_t ver;
23 } d_extension_query_t;
28 xcb_intern_atom_cookie_t ck;
32 query_extension(d_display_t *dpy, d_extension_query_t *q)
34 const xcb_query_extension_reply_t *rep;
36 xcb_prefetch_extension_data(dpy->conn, q->xcb);
37 rep = xcb_get_extension_data(dpy->conn, q->xcb);
38 q->ext->present = rep && rep->present;
39 q->ext->error = rep && rep->first_error;
40 q->ext->event = rep && rep->first_event;
41 q->ext->opcode = rep && rep->major_opcode;
43 if (q->ext->present) {
44 q->ck = q->ver(dpy->conn, q->major, q->minor);
49 query_atom(d_display_t *dpy, d_atom_query_t *q)
51 q->ck = xcb_intern_atom(dpy->conn, FALSE, strlen(q->name), q->name);
55 query_statics(d_display_t *dpy)
57 d_extension_query_t extensions[] = {
60 .xcb = &xcb_xfixes_id,
61 .ver = (query_version_func_t)xcb_xfixes_query_version,
62 .major = XCB_XFIXES_MAJOR_VERSION,
63 .minor = XCB_XFIXES_MINOR_VERSION
67 .xcb = &xcb_render_id,
68 .ver = (query_version_func_t)xcb_render_query_version,
69 .major = XCB_RENDER_MAJOR_VERSION,
70 .minor = XCB_RENDER_MINOR_VERSION
74 .xcb = &xcb_damage_id,
75 .ver = (query_version_func_t)xcb_damage_query_version,
76 .major = XCB_DAMAGE_MAJOR_VERSION,
77 .minor = XCB_DAMAGE_MINOR_VERSION
80 .ext = &dpy->composite,
81 .xcb = &xcb_composite_id,
82 .ver = (query_version_func_t)xcb_composite_query_version,
83 .major = XCB_COMPOSITE_MAJOR_VERSION,
84 .minor = XCB_COMPOSITE_MINOR_VERSION
88 d_atom_query_t atoms[] = {
89 { .atom = &dpy->a.atom,
91 { .atom = &dpy->a.cardinal,
93 { .atom = &dpy->a.utf8_string,
94 .name = "UTF8_STRING" },
95 { .atom = &dpy->a.string,
97 { .atom = &dpy->a.pixmap,
99 { .atom = &dpy->a.net_wm_window_type,
100 .name = "_NET_WM_WINDOW_TYPE" },
101 { .atom = &dpy->a.net_wm_window_type_desktop,
102 .name = "_NET_WM_WINDOW_TYPE_DESKTOP" },
103 { .atom = &dpy->a.net_wm_window_type_dock,
104 .name = "_NET_WM_WINDOW_TYPE_DOCK" },
105 { .atom = &dpy->a.net_wm_window_type_normal,
106 .name = "_NET_WM_WINDOW_TYPE_NORMAL" },
107 { .atom = &dpy->a.net_wm_window_type_dialog,
108 .name = "_NET_WM_WINDOW_TYPE_DIALOG" },
109 { .atom = &dpy->a.net_wm_window_type_toolbar,
110 .name = "_NET_WM_WINDOW_TYPE_TOOLBAR" },
111 { .atom = &dpy->a.net_wm_window_type_menu,
112 .name = "_NET_WM_WINDOW_TYPE_MENU" },
113 { .atom = &dpy->a.net_wm_window_type_utility,
114 .name = "_NET_WM_WINDOW_TYPE_UTILITY" },
115 { .atom = &dpy->a.net_wm_window_type_splash,
116 .name = "_NET_WM_WINDOW_TYPE_SPLAH" },
117 { .atom = &dpy->a.net_wm_window_type_tooltip,
118 .name = "_NET_WM_WINDOW_TYPE_TOOLTIP" },
119 { .atom = &dpy->a.net_wm_window_type_combo,
120 .name = "_NET_WM_WINDOW_TYPE_COMBO" },
121 { .atom = &dpy->a.net_wm_window_type_dropdown_menu,
122 .name = "_NET_WM_WINDOW_TYPE_DROPDOWN_MENU" },
123 { .atom = &dpy->a.net_wm_window_type_popup_menu,
124 .name = "_NET_WM_WINDOW_TYPE_POPUP_MENU" },
125 { .atom = &dpy->a.net_wm_window_type_notification,
126 .name = "_NET_WM_WINDOW_TYPE_NOTIFICATION" },
131 for (i = 0; extensions[i].ext != NULL; ++i)
132 query_extension(dpy, &extensions[i]);
133 for (i = 0; atoms[i].atom != NULL; ++i)
134 query_atom(dpy, &atoms[i]);
139 display_open(const char *name)
141 d_display_t *dpy = NULL;
142 xcb_connection_t *conn;
144 conn = xcb_connect(name, NULL);
146 dpy = malloc(sizeof(d_display_t));
156 display_ref(d_display_t *dpy)
162 display_unref(d_display_t *dpy)
164 if (dpy && --dpy->ref == 0) {
165 xcb_disconnect(dpy->conn);
171 display_error(d_display_t *dpy, xcb_generic_error_t *ev)
173 const int major_opcode = ((xcb_request_error_t*)ev)->major_opcode;
174 const int minor_opcode = ((xcb_request_error_t*)ev)->minor_opcode;
175 const char *name, *req;
177 /* XXX check if we should ignore it (ev->full_sequence) */
182 switch (ev->error_code) {
183 case XCB_REQUEST: name = "BadRequest"; break;
184 case XCB_VALUE: name = "BadValue"; break;
185 case XCB_WINDOW: name = "BadWindow"; break;
186 case XCB_PIXMAP: name = "BadPixmap"; break;
187 case XCB_MATCH: name = "BadMatch"; break;
188 case XCB_DRAWABLE: name = "BadDrawable"; break;
189 case XCB_G_CONTEXT: name = "BadGC"; break;
193 switch (ev->error_code - dpy->xfixes.error) {
194 case XCB_XFIXES_BAD_REGION: name = "BadRegion"; break;
198 switch (ev->error_code - dpy->damage.error) {
199 case XCB_DAMAGE_BAD_DAMAGE: name = "BadDamage"; break;
203 switch (ev->error_code - dpy->render.error) {
204 case XCB_RENDER_PICT_FORMAT: name = "BadPictFormat"; break;
205 case XCB_RENDER_PICT_OP: name = "BadPictOp"; break;
206 case XCB_RENDER_PICTURE: name = "BadPicture"; break;
207 case XCB_RENDER_GLYPH_SET: name = "BadGlyphSet"; break;
208 case XCB_RENDER_GLYPH: name = "BadGlyph"; break;
212 if (major_opcode <= 127)
213 switch (major_opcode) {
214 case 1: req = "CreateWindow"; break;
215 case 2: req = "ChangeWindowAttributes"; break;
216 case 3: req = "GetWindowAttributes"; break;
217 case 14: req = "GetGeometry"; break;
218 case 15: req = "QueryTree"; break;
219 case 18: req = "ChangeProperty"; break;
220 case 20: req = "GetProperty"; break;
221 case 22: req = "SetSelectionOwner"; break;
222 case 23: req = "GetSelectionOwner"; break;
223 case 53: req = "CreatePixmap"; break;
224 case 54: req = "FreePixmap"; break;
225 case 55: req = "CreateGC"; break;
226 case 56: req = "ChangeGC"; break;
227 case 60: req = "FreeGC"; break;
228 case 72: req = "PutImage"; break;
233 printf("XError: %s %s!\n",
236 printf("XError: %s major opcode %d minor opcode %d!\n",
237 name, major_opcode, minor_opcode);
239 printf("XError: code %d major opcode %d minor opcode %d!\n",
240 ev->error_code, major_opcode, minor_opcode);