Adapt for recent util/icccm renaming.
[free-sw/xcb/demo] / xcb-test.c
1 /*
2  * Copyright (C) 2001-2002 Bart Massey and Jamey Sharp.
3  * All Rights Reserved.  See the file COPYING in this directory
4  * for licensing information.
5  */
6
7 #define TEST_GET_WINDOW_ATTRIBUTES
8 #define TEST_GET_GEOMETRY
9 #define TEST_QUERY_TREE
10 #undef TEST_THREADS
11 #define VERBOSE
12 #undef SUPERVERBOSE
13 #define TEST_ICCCM
14
15 #ifdef TEST_THREADS
16 #include <pthread.h>
17 #endif
18
19 #ifdef TEST_ICCCM
20 #include <string.h>
21 #endif
22
23 #include <stdlib.h>
24
25 #include <xcb/xcb.h>
26 #include <xcb/xcb_aux.h>
27 #include "reply_formats.h"
28
29 #ifdef VERBOSE
30 #include <stdio.h>
31 #endif
32
33 void try_events(xcb_connection_t *c);
34 void wait_events(xcb_connection_t *c);
35
36 static xcb_connection_t *c;
37 static xcb_window_t window;
38
39 int main(int argc, char **argv)
40 {
41     uint32_t mask = 0;
42     uint32_t values[6];
43     xcb_drawable_t d;
44     xcb_screen_t *root;
45 #ifdef TEST_GET_GEOMETRY
46     xcb_get_geometry_cookie_t geom[3];
47     xcb_get_geometry_reply_t *geomrep[3];
48 #endif
49 #ifdef TEST_QUERY_TREE
50     xcb_query_tree_cookie_t tree[3];
51     xcb_query_tree_reply_t *treerep[3];
52 #endif
53 #ifdef TEST_GET_WINDOW_ATTRIBUTES
54     xcb_get_window_attributes_cookie_t attr[1];
55     xcb_get_window_attributes_reply_t *attrrep[1];
56 #endif
57 #ifdef TEST_ICCCM
58     xcb_intern_atom_cookie_t atom[2];
59     xcb_intern_atom_reply_t *atomrep[2];
60 #endif
61 #ifdef TEST_THREADS
62     pthread_t event_thread;
63 #endif
64     int screen_num;
65
66     c = xcb_connect(0, &screen_num);
67     root = xcb_aux_get_screen(c, screen_num);
68
69 #ifdef TEST_THREADS
70 # ifdef VERBOSE
71     printf("main() thread ID: %ld\n", pthread_self());
72 # endif
73     /* don't do this cast. */
74     pthread_create(&event_thread, 0, (void *(*)(void *))wait_events, c);
75 #endif
76
77 #if 1
78     window = xcb_generate_id(c);
79 #else
80     window = 0; /* should be an invalid ID */
81 #endif
82
83     mask |= XCB_CW_BACK_PIXEL;
84     values[0] = root->white_pixel;
85
86     mask |= XCB_CW_BORDER_PIXEL;
87     values[1] = root->black_pixel;
88
89     mask |= XCB_CW_BACKING_STORE;
90     values[2] = XCB_BACKING_STORE_ALWAYS;
91
92     mask |= XCB_CW_OVERRIDE_REDIRECT;
93     values[3] = 0;
94
95     mask |= XCB_CW_EVENT_MASK;
96     values[4] = XCB_EVENT_MASK_BUTTON_RELEASE
97         | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_STRUCTURE_NOTIFY
98         | XCB_EVENT_MASK_ENTER_WINDOW | XCB_EVENT_MASK_LEAVE_WINDOW;
99
100     mask |= XCB_CW_DONT_PROPAGATE;
101     values[5] = XCB_EVENT_MASK_BUTTON_PRESS;
102
103     xcb_create_window(c, /* depth */ 0,
104         window, root->root,
105         /* x */ 20, /* y */ 200, /* width */ 150, /* height */ 150,
106         /* border_width */ 10, /* class */ XCB_WINDOW_CLASS_INPUT_OUTPUT,
107         /* visual */ root->root_visual, mask, values);
108 #ifdef TEST_ICCCM
109     atom[0] = xcb_intern_atom(c, 0, sizeof("WM_PROTOCOLS")-1, "WM_PROTOCOLS");
110     atom[1] = xcb_intern_atom(c, 0, sizeof("WM_DELETE_WINDOW")-1, "WM_DELETE_WINDOW");
111     atomrep[1] = xcb_intern_atom_reply(c, atom[1], 0);
112     atomrep[0] = xcb_intern_atom_reply(c, atom[0], 0);
113     {
114         xcb_atom_t XA_WM_NAME = { 39 };
115         xcb_atom_t XA_STRING = { 31 };
116         xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, XA_WM_NAME, XA_STRING, 8, strlen(argv[0]), argv[0]);
117     }
118     if(atomrep[0] && atomrep[1])
119     {
120         xcb_atom_t WM_PROTOCOLS = atomrep[0]->atom;
121         xcb_atom_t WM_DELETE_WINDOW = atomrep[1]->atom;
122         xcb_atom_t XA_ATOM = { 4 };
123         xcb_change_property(c, XCB_PROP_MODE_REPLACE, window, WM_PROTOCOLS, XA_ATOM, 32, 1, &WM_DELETE_WINDOW);
124     }
125     free(atomrep[0]);
126     free(atomrep[1]);
127 #endif
128     try_events(c);
129
130     xcb_map_window(c, window);
131     xcb_flush(c);
132
133     /* Send off a collection of requests */
134 #ifdef TEST_GET_WINDOW_ATTRIBUTES
135     attr[0] = xcb_get_window_attributes(c, window);
136 #endif
137 #ifdef TEST_GET_GEOMETRY
138     geom[0] = xcb_get_geometry(c, root->root);
139     geom[1] = xcb_get_geometry(c, window);
140 #endif
141 #ifdef TEST_QUERY_TREE
142 # ifdef SUPERVERBOSE /* this produces a lot of output :) */
143     tree[0] = xcb_query_tree(c, root->root);
144 # endif
145     tree[1] = xcb_query_tree(c, window);
146 #endif
147
148     /* Start reading replies and possibly events */
149 #ifdef TEST_GET_GEOMETRY
150     geomrep[0] = xcb_get_geometry_reply(c, geom[0], 0);
151     formatGetGeometryReply(root->root, geomrep[0]);
152     free(geomrep[0]);
153 #endif
154
155 #ifdef TEST_QUERY_TREE
156 # ifdef SUPERVERBOSE /* this produces a lot of output :) */
157     treerep[0] = xcb_query_tree_reply(c, tree[0], 0);
158     formatQueryTreeReply(root->root, treerep[0]);
159     free(treerep[0]);
160 # endif
161 #endif
162
163 #ifdef TEST_GET_GEOMETRY
164     geomrep[1] = xcb_get_geometry_reply(c, geom[1], 0);
165     formatGetGeometryReply(window, geomrep[1]);
166     free(geomrep[1]);
167 #endif
168
169     try_events(c);
170
171     /* Mix in some more requests */
172 #ifdef TEST_QUERY_TREE
173     treerep[1] = xcb_query_tree_reply(c, tree[1], 0);
174     formatQueryTreeReply(window, treerep[1]);
175
176     if(treerep[1] && treerep[1]->parent && treerep[1]->parent != root->root)
177     {
178         tree[2] = xcb_query_tree(c, treerep[1]->parent);
179
180 # ifdef TEST_GET_GEOMETRY
181         geom[2] = xcb_get_geometry(c, treerep[1]->parent);
182         geomrep[2] = xcb_get_geometry_reply(c, geom[2], 0);
183         formatGetGeometryReply(treerep[1]->parent, geomrep[2]);
184         free(geomrep[2]);
185 # endif
186
187         treerep[2] = xcb_query_tree_reply(c, tree[2], 0);
188         formatQueryTreeReply(treerep[1]->parent, treerep[2]);
189         free(treerep[2]);
190     }
191
192     free(treerep[1]);
193 #endif
194
195     try_events(c);
196
197     /* Get the last reply of the first batch */
198 #if 1 /* if 0, leaves a reply in the reply queue */
199 #ifdef TEST_GET_WINDOW_ATTRIBUTES
200     attrrep[0] = xcb_get_window_attributes_reply(c, attr[0], 0);
201     formatGetWindowAttributesReply(window, attrrep[0]);
202     free(attrrep[0]);
203 #endif
204 #endif
205
206 #ifdef TEST_THREADS
207     pthread_join(event_thread, 0);
208 #else
209     wait_events(c);
210 #endif
211     xcb_disconnect(c);
212     exit(0);
213     /*NOTREACHED*/
214 }
215
216 int show_event(xcb_generic_event_t *e)
217 {
218     int ret = 1;
219     if(!formatEvent(e))
220         return 0;
221
222     if(e->response_type == XCB_BUTTON_RELEASE)
223         ret = 0; /* They clicked, therefore, we're done. */
224     free(e);
225     return ret;
226 }
227
228 void try_events(xcb_connection_t *c)
229 {
230     xcb_generic_event_t *e;
231     while((e = xcb_poll_for_event(c)) && show_event(e))
232         /* empty statement */ ;
233 }
234
235 void wait_events(xcb_connection_t *c)
236 {
237     xcb_generic_event_t *e;
238 #ifdef TEST_THREADS
239 # ifdef VERBOSE
240     printf("wait_events() thread ID: %ld\n", pthread_self());
241 # endif
242 #endif
243     while((e = xcb_wait_for_event(c)) && show_event(e))
244         /* empty statement */ ;
245 }