1811f5b0dc10323e32d621d6f6e5605693de44ba
[dana/dcompmgr.git] / display.c
1 #include "display.h"
2 #include <stdlib.h>
3 #include <stdio.h>
4
5 #include <xcb/damage.h>
6 #include <xcb/render.h>
7 #include <xcb/xfixes.h>
8 #include <xcb/composite.h>
9
10 static void
11 query_extensions(d_display_t *dpy)
12 {
13     xcb_xfixes_query_version_cookie_t      fixes_version_cookie;
14     xcb_render_query_version_cookie_t      render_version_cookie;
15     xcb_composite_query_version_cookie_t   composite_version_cookie;
16     xcb_damage_query_version_cookie_t      damage_version_cookie;
17     xcb_render_query_pict_formats_cookie_t render_formats_cookie;
18
19     const xcb_query_extension_reply_t *rep;
20
21     xcb_prefetch_extension_data(dpy->conn, &xcb_xfixes_id);
22     xcb_prefetch_extension_data(dpy->conn, &xcb_render_id);
23     xcb_prefetch_extension_data(dpy->conn, &xcb_composite_id);
24     xcb_prefetch_extension_data(dpy->conn, &xcb_damage_id);
25
26     rep = xcb_get_extension_data(dpy->conn, &xcb_xfixes_id);
27     dpy->xfixes = rep && rep->present;
28     dpy->xfixes_error = rep && rep->first_error;
29     dpy->xfixes_event = rep && rep->first_event;
30     dpy->xfixes_opcode = rep && rep->major_opcode;
31
32     rep = xcb_get_extension_data(dpy->conn, &xcb_render_id);
33     dpy->render = rep && rep->present;
34     dpy->render_error = rep && rep->first_error;
35     dpy->render_event = rep && rep->first_event;
36     dpy->render_opcode = rep && rep->major_opcode;
37
38     rep = xcb_get_extension_data(dpy->conn, &xcb_composite_id);
39     dpy->composite = rep && rep->present;
40     dpy->composite_error = rep && rep->first_error;
41     dpy->composite_event = rep && rep->first_event;
42     dpy->composite_opcode = rep && rep->major_opcode;
43
44     rep = xcb_get_extension_data(dpy->conn, &xcb_damage_id);
45     dpy->damage = rep && rep->present;
46     dpy->damage_error = rep && rep->first_error;
47     dpy->damage_event = rep && rep->first_event;
48     dpy->damage_opcode = rep && rep->major_opcode;
49 }
50
51
52 d_display_t*
53 display_open(const char *name)
54 {
55     d_display_t *dpy = NULL;
56     xcb_connection_t *conn;
57
58     conn = xcb_connect(name, NULL);
59     if (conn) {
60         dpy = malloc(sizeof(d_display_t));
61         dpy->conn = conn;
62         dpy->ref = 1;
63
64         query_extensions(dpy);
65     }
66     return dpy;
67 }
68
69 void
70 display_ref(d_display_t *dpy)
71 {
72     ++dpy->ref;
73 }
74
75 void
76 display_unref(d_display_t *dpy)
77 {
78     if (dpy && --dpy->ref == 0) {
79         xcb_disconnect(dpy->conn);
80         free(dpy);
81     }
82 }
83
84 void
85 display_error(d_display_t *dpy, xcb_generic_error_t *ev)
86 {
87     const int major_opcode = ((xcb_request_error_t*)ev)->major_opcode;
88     const int minor_opcode = ((xcb_request_error_t*)ev)->minor_opcode;
89     const char *name, *req;
90
91     /* XXX check if we should ignore it (ev->full_sequence) */
92
93     (void)dpy;
94
95     name = NULL;
96     switch (ev->error_code) {
97     case XCB_REQUEST:   name = "BadRequest";   break;
98     case XCB_VALUE:     name = "BadValue";     break;
99     case XCB_WINDOW:    name = "BadWindow";    break;
100     case XCB_PIXMAP:    name = "BadPixmap";    break;
101     case XCB_MATCH:     name = "BadMatch";     break;
102     case XCB_DRAWABLE:  name = "BadDrawable";  break;
103     case XCB_G_CONTEXT: name = "BadGC";        break;
104     default: break;
105     }
106     if (!name)
107         switch (ev->error_code - dpy->xfixes_error) {
108         case XCB_XFIXES_BAD_REGION: name = "BadRegion"; break;
109         default: break;
110         }
111     if (!name)
112         switch (ev->error_code - dpy->damage_error) {
113         case XCB_DAMAGE_BAD_DAMAGE: name = "BadDamage"; break;
114         default: break;
115         }
116     if (!name)
117         switch (ev->error_code - dpy->render_error) {
118         case XCB_RENDER_PICT_FORMAT: name = "BadPictFormat"; break;
119         case XCB_RENDER_PICT_OP:     name = "BadPictOp"; break;
120         case XCB_RENDER_PICTURE:     name = "BadPicture"; break;
121         case XCB_RENDER_GLYPH_SET:   name = "BadGlyphSet"; break;
122         case XCB_RENDER_GLYPH:       name = "BadGlyph"; break;
123         default: break;
124         }
125
126     if (major_opcode <= 127)
127         switch (major_opcode) {
128         case 1:  req = "CreateWindow";           break;
129         case 2:  req = "ChangeWindowAttributes"; break;
130         case 3:  req = "GetWindowAttributes";    break;
131         case 14: req = "GetGeometry";            break;
132         case 15: req = "QueryTree";              break;
133         case 18: req = "ChangeProperty";         break;
134         case 20: req = "GetProperty";            break;
135         case 22: req = "SetSelectionOwner";      break;
136         case 23: req = "GetSelectionOwner";      break;
137         case 53: req = "CreatePixmap";           break;
138         case 54: req = "FreePixmap";             break;
139         case 55: req = "CreateGC";               break;
140         case 56: req = "ChangeGC";               break;
141         case 60: req = "FreeGC";                 break;
142         case 72: req = "PutImage";               break;
143         default: break; 
144         }
145
146     if (name && req)
147         printf("XError: %s %s!\n",
148                name, req);
149     else if (name)
150         printf("XError: %s major opcode %d minor opcode %d!\n",
151                name, major_opcode, minor_opcode);
152     else
153         printf("XError: code %d major opcode %d minor opcode %d!\n",
154                ev->error_code, major_opcode, minor_opcode);
155
156     abort();
157 }