Replace another Sync -> Flush
[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 <X11/XCB/xcb.h>
26 #include <X11/XCB/xcb_aux.h>
27 #include "reply_formats.h"
28
29 #ifdef VERBOSE
30 #include <stdio.h>
31 #endif
32
33 void try_events(XCBConnection *c);
34 void wait_events(XCBConnection *c);
35
36 static XCBConnection *c;
37 static XCBWINDOW window;
38
39 int main(int argc, char **argv)
40 {
41     CARD32 mask = 0;
42     CARD32 values[6];
43     XCBDRAWABLE d;
44     XCBSCREEN *root;
45 #ifdef TEST_GET_GEOMETRY
46     XCBGetGeometryCookie geom[3];
47     XCBGetGeometryRep *geomrep[3];
48 #endif
49 #ifdef TEST_QUERY_TREE
50     XCBQueryTreeCookie tree[3];
51     XCBQueryTreeRep *treerep[3];
52 #endif
53 #ifdef TEST_GET_WINDOW_ATTRIBUTES
54     XCBGetWindowAttributesCookie attr[1];
55     XCBGetWindowAttributesRep *attrrep[1];
56 #endif
57 #ifdef TEST_ICCCM
58     XCBInternAtomCookie atom[2];
59     XCBInternAtomRep *atomrep[2];
60 #endif
61 #ifdef TEST_THREADS
62     pthread_t event_thread;
63 #endif
64     int screen_num;
65
66     c = XCBConnect(0, &screen_num);
67     root = XCBAuxGetScreen(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 = XCBWINDOWNew(c);
79 #else
80     window = 0; /* should be an invalid ID */
81 #endif
82
83     mask |= XCBCWBackPixel;
84     values[0] = root->white_pixel;
85
86     mask |= XCBCWBorderPixel;
87     values[1] = root->black_pixel;
88
89     mask |= XCBCWBackingStore;
90     values[2] = XCBBackingStoreAlways;
91
92     mask |= XCBCWOverrideRedirect;
93     values[3] = 0;
94
95     mask |= XCBCWEventMask;
96     values[4] = XCBEventMaskButtonRelease
97         | XCBEventMaskExposure | XCBEventMaskStructureNotify
98         | XCBEventMaskEnterWindow | XCBEventMaskLeaveWindow;
99
100     mask |= XCBCWDontPropagate;
101     values[5] = XCBEventMaskButtonPress;
102
103     XCBCreateWindow(c, /* depth */ 0,
104         window, root->root,
105         /* x */ 20, /* y */ 200, /* width */ 150, /* height */ 150,
106         /* border_width */ 10, /* class */ XCBWindowClassInputOutput,
107         /* visual */ root->root_visual, mask, values);
108 #ifdef TEST_ICCCM
109     atom[0] = XCBInternAtom(c, 0, sizeof("WM_PROTOCOLS")-1, "WM_PROTOCOLS");
110     atom[1] = XCBInternAtom(c, 0, sizeof("WM_DELETE_WINDOW")-1, "WM_DELETE_WINDOW");
111     atomrep[1] = XCBInternAtomReply(c, atom[1], 0);
112     atomrep[0] = XCBInternAtomReply(c, atom[0], 0);
113     {
114         XCBATOM XA_WM_NAME = { 39 };
115         XCBATOM XA_STRING = { 31 };
116         XCBChangeProperty(c, XCBPropModeReplace, window, XA_WM_NAME, XA_STRING, 8, strlen(argv[0]), argv[0]);
117     }
118     if(atomrep[0] && atomrep[1])
119     {
120         XCBATOM WM_PROTOCOLS = atomrep[0]->atom;
121         XCBATOM WM_DELETE_WINDOW = atomrep[1]->atom;
122         XCBATOM XA_ATOM = { 4 };
123         XCBChangeProperty(c, XCBPropModeReplace, 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     XCBMapWindow(c, window);
131     XCBFlush(c);
132
133     /* Send off a collection of requests */
134 #ifdef TEST_GET_WINDOW_ATTRIBUTES
135     attr[0] = XCBGetWindowAttributes(c, window);
136 #endif
137 #ifdef TEST_GET_GEOMETRY
138     d.window = root->root;
139     geom[0] = XCBGetGeometry(c, d);
140     d.window = window;
141     geom[1] = XCBGetGeometry(c, d);
142 #endif
143 #ifdef TEST_QUERY_TREE
144 # ifdef SUPERVERBOSE /* this produces a lot of output :) */
145     tree[0] = XCBQueryTree(c, root->root);
146 # endif
147     tree[1] = XCBQueryTree(c, window);
148 #endif
149
150     /* Start reading replies and possibly events */
151 #ifdef TEST_GET_GEOMETRY
152     geomrep[0] = XCBGetGeometryReply(c, geom[0], 0);
153     formatGetGeometryReply(root->root, geomrep[0]);
154     free(geomrep[0]);
155 #endif
156
157 #ifdef TEST_QUERY_TREE
158 # ifdef SUPERVERBOSE /* this produces a lot of output :) */
159     treerep[0] = XCBQueryTreeReply(c, tree[0], 0);
160     formatQueryTreeReply(root->root, treerep[0]);
161     free(treerep[0]);
162 # endif
163 #endif
164
165 #ifdef TEST_GET_GEOMETRY
166     geomrep[1] = XCBGetGeometryReply(c, geom[1], 0);
167     formatGetGeometryReply(window, geomrep[1]);
168     free(geomrep[1]);
169 #endif
170
171     try_events(c);
172
173     /* Mix in some more requests */
174 #ifdef TEST_QUERY_TREE
175     treerep[1] = XCBQueryTreeReply(c, tree[1], 0);
176     formatQueryTreeReply(window, treerep[1]);
177
178     if(treerep[1] && treerep[1]->parent.xid && treerep[1]->parent.xid != root->root.xid)
179     {
180         tree[2] = XCBQueryTree(c, treerep[1]->parent);
181
182 # ifdef TEST_GET_GEOMETRY
183         d.window = treerep[1]->parent;
184         geom[2] = XCBGetGeometry(c, d);
185         geomrep[2] = XCBGetGeometryReply(c, geom[2], 0);
186         formatGetGeometryReply(treerep[1]->parent, geomrep[2]);
187         free(geomrep[2]);
188 # endif
189
190         treerep[2] = XCBQueryTreeReply(c, tree[2], 0);
191         formatQueryTreeReply(treerep[1]->parent, treerep[2]);
192         free(treerep[2]);
193     }
194
195     free(treerep[1]);
196 #endif
197
198     try_events(c);
199
200     /* Get the last reply of the first batch */
201 #if 1 /* if 0, leaves a reply in the reply queue */
202 #ifdef TEST_GET_WINDOW_ATTRIBUTES
203     attrrep[0] = XCBGetWindowAttributesReply(c, attr[0], 0);
204     formatGetWindowAttributesReply(window, attrrep[0]);
205     free(attrrep[0]);
206 #endif
207 #endif
208
209 #ifdef TEST_THREADS
210     pthread_join(event_thread, 0);
211 #else
212     wait_events(c);
213 #endif
214     XCBDisconnect(c);
215     exit(0);
216     /*NOTREACHED*/
217 }
218
219 int show_event(XCBGenericEvent *e)
220 {
221     int ret = 1;
222     if(!formatEvent(e))
223         return 0;
224
225     if(e->response_type == XCBButtonRelease)
226         ret = 0; /* They clicked, therefore, we're done. */
227     free(e);
228     return ret;
229 }
230
231 void try_events(XCBConnection *c)
232 {
233     XCBGenericEvent *e;
234     while((e = XCBPollForEvent(c, 0)) && show_event(e))
235         /* empty statement */ ;
236 }
237
238 void wait_events(XCBConnection *c)
239 {
240     XCBGenericEvent *e;
241 #ifdef TEST_THREADS
242 # ifdef VERBOSE
243     printf("wait_events() thread ID: %ld\n", pthread_self());
244 # endif
245 #endif
246     while((e = XCBWaitForEvent(c)) && show_event(e))
247         /* empty statement */ ;
248 }