1 <!DOCTYPE html public "-//W3C//DTD HTML 4.01 Transitional//EN"
2 "http://www.w3.org/TR/html4/loose.dtd">
7 <title>Basic Graphics Programming With The XCB Library</title>
8 <link href="xcb.css" rel="stylesheet" type="text/css" />
13 Basic Graphics Programming With The XCB Library
17 <li><a class="section" href="#intro">Introduction</a></li>
18 <li><a class="section" href="#Xmodel">The client and server model of the X window system</a></li>
19 <li><a class="section" href="#asynch">GUI programming: the asynchronous model</a></li>
20 <li><a class="section" href="#notions">Basic XCB notions</a></li>
22 <li><a class="subsection" href="#conn">The X Connection</a></li>
23 <li><a class="subsection" href="#requestsreplies">Requests and replies: the Xlib killers</a></li>
24 <li><a class="subsection" href="#gc">The Graphics Context</a></li>
25 <li>Object handles</li>
26 <li>Memory allocation for XCB structures</li>
27 <li><a class="subsection" href="#events">Events</a></li>
29 <li><a class="section" href="#use">Using XCB-based programs</a></li>
31 <li><a class="subsection" href="#inst">Installation of XCB</a></li>
32 <li><a class="subsection" href="#comp">Compiling XCB-based programs</a></li>
34 <li><a class="section" href="#openconn">Opening and closing the connection to an X server</a></li>
35 <li><a class="section" href="#screen">Checking basic information about a connection</a></li>
36 <li><a class="section" href="#helloworld">Creating a basic window - the "hello world" program</a></li>
37 <li><a class="section" href="#drawing">Drawing in a window</a></li>
39 <li><a class="subsection" href="#allocgc">Allocating a Graphics Context</a></li>
40 <li><a class="subsection" href="#changegc">Changing the attributes of a Graphics Context</a></li>
41 <li><a class="subsection" href="#drawingprim">Drawing primitives: point, line, box, circle,...</a></li>
43 <li><a class="section" href="#xevents">X Events</a></li>
45 <li><a class="subsection" href="#register">Registering for event types using event masks</a></li>
46 <li><a class="subsection" href="#loop">Receiving events: writing the events loop</a></li>
47 <li><a class="subsection" href="#expose">Expose events</a></li>
48 <li><a class="subsection" href="#userinput">Getting user input</a></li>
50 <li><a class="subsubsection" href="#mousepressrelease">Mouse button press and release events</a></li>
51 <li><a class="subsubsection" href="#mousemvnt">Mouse movement events</a></li>
52 <li><a class="subsubsection" href="#mouseenter">Mouse pointer enter and leave events</a></li>
53 <li><a class="subsubsection" href="#focus">The keyboard focus</a></li>
54 <li><a class="subsubsection" href="#keypress">Keyboard press and release events</a></li>
56 <li><a class="subsection" href="#eventex">X events: a complete example</a></li>
58 <li><a class="section" href="#font">Handling text and fonts</a></li>
60 <li><a class="subsection" href="#fontstruct">The Font structure</a></li>
61 <li>Loading a Font</li>
62 <li>Assigning a Font to a Graphic Context</li>
63 <li>Drawing text in a window</li>
65 <li>Windows hierarchy</li>
67 <li>Root, parent and child windows</li>
68 <li>Events propagation</li>
70 <li><a class="section" href="#wm">Interacting with the window manager</a></li>
72 <li><a class="subsection" href="#wmprop">Window properties</a></li>
73 <li><a class="subsection" href="#wmname">Setting the window name and icon name</a></li>
74 <li>Setting preferred window size(s)</li>
75 <li>Setting miscellaneous window manager hints</li>
76 <li>Setting an application's icon</li>
78 <li><a class="section" href="#winop">Simple window operations</a></li>
80 <li><a class="subsection" href="#winmap">Mapping and un-mapping a window</a></li>
81 <li><a class="subsection" href="#winconf">Configuring a window</a></li>
82 <li><a class="subsection" href="#winmove">Moving a window around the screen</a></li>
83 <li><a class="subsection" href="#winsize">Resizing a window</a></li>
84 <li><a class="subsection" href="#winstack">Changing windows stacking order: raise and lower</a></li>
85 <li>Iconifying and de-iconifying a window</li>
86 <li><a class="subsection" href="#wingetinfo">Getting informations about a window</a></li>
88 <li><a class="section" href="#usecolor">Using colors to paint the rainbow</a></li>
90 <li><a class="subsection" href="#colormap">Color maps</a></li>
91 <li><a class="subsection" href="#colormapalloc">Allocating and freeing Color Maps</a></li>
92 <li><a class="subsection" href="#alloccolor">Allocating and freeing a color entry</a></li>
93 <li>Drawing with a color</li>
95 <li><a class="section" href="#pixmaps">X Bitmaps and Pixmaps</a></li>
97 <li><a class="subsection" href="#pixmapswhat">What is a X Bitmap ? An X Pixmap ?</a></li>
98 <li>Loading a bitmap from a file</li>
99 <li>Drawing a bitmap in a window</li>
100 <li><a class="subsection" href="#pixmapscreate">Creating a pixmap</a></li>
101 <li><a class="subsection" href="#pixmapsdraw">Drawing a pixmap in a window</a></li>
102 <li><a class="subsection" href="#pixmapsfree">Freeing a pixmap</a></li>
104 <li>Messing with the mouse cursor</li>
106 <li>Creating and destroying a mouse cursor</li>
107 <li>Setting a window's mouse cursor</li>
109 <li><a class="subsection" href="#translation">Translation of basic Xlib functions and macros</a></li>
111 <li><a class="subsection" href="#displaystructure">Members of the Display structure</a></li>
113 <li><a class="subsection" href="#ConnectionNumber">ConnectionNumber</a></li>
114 <li><a class="subsection" href="#DefaultScreen">DefaultScreen</a></li>
115 <li><a class="subsection" href="#QLength">QLength</a></li>
116 <li><a class="subsection" href="#ScreenCount">ScreenCount</a></li>
117 <li><a class="subsection" href="#ServerVendor">ServerVendor</a></li>
118 <li><a class="subsection" href="#ProtocolVersion">ProtocolVersion</a></li>
119 <li><a class="subsection" href="#ProtocolRevision">ProtocolRevision</a></li>
120 <li><a class="subsection" href="#VendorRelease">VendorRelease</a></li>
121 <li><a class="subsection" href="#DisplayString">DisplayString</a></li>
122 <li><a class="subsection" href="#BitmapUnit">BitmapUnit</a></li>
123 <li><a class="subsection" href="#BitmapBitOrder">BitmapBitOrder</a></li>
124 <li><a class="subsection" href="#BitmapPad">BitmapPad</a></li>
125 <li><a class="subsection" href="#ImageByteOrder">ImageByteOrder</a></li>
127 <li><a class="subsection" href="#screenofdisplay">ScreenOfDisplay related functions</a></li>
129 <li><a class="subsection" href="#ScreenOfDisplay">ScreenOfDisplay</a></li>
130 <li><a class="subsection" href="#DefaultScreenOfDisplay">DefaultScreenOfDisplay</a></li>
131 <li><a class="subsection" href="#RootWindow">RootWindow / RootWindowOfScreen</a></li>
132 <li><a class="subsection" href="#DefaultRootWindow">DefaultRootWindow</a></li>
133 <li><a class="subsection" href="#DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a></li>
134 <li><a class="subsection" href="#DefaultGC">DefaultGC / DefaultGCOfScreen</a></li>
135 <li><a class="subsection" href="#BlackPixel">BlackPixel / BlackPixelOfScreen</a></li>
136 <li><a class="subsection" href="#WhitePixel">WhitePixel / WhitePixelOfScreen</a></li>
137 <li><a class="subsection" href="#DisplayWidth">DisplayWidth / WidthOfScreen</a></li>
138 <li><a class="subsection" href="#DisplayHeight">DisplayHeight / HeightOfScreen</a></li>
139 <li><a class="subsection" href="#DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a></li>
140 <li><a class="subsection" href="#DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a></li>
141 <li><a class="subsection" href="#DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a></li>
142 <li><a class="subsection" href="#DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a></li>
143 <li><a class="subsection" href="#MinCmapsOfScreen">MinCmapsOfScreen</a></li>
144 <li><a class="subsection" href="#MaxCmapsOfScreen">MaxCmapsOfScreen</a></li>
145 <li><a class="subsection" href="#DoesSaveUnders">DoesSaveUnders</a></li>
146 <li><a class="subsection" href="#DoesBackingStore">DoesBackingStore</a></li>
147 <li><a class="subsection" href="#EventMaskOfScreen">EventMaskOfScreen</a></li>
149 <li><a class="subsection" href="#misc">Miscellaneaous macros</a></li>
151 <li><a class="subsection" href="#DisplayOfScreen">DisplayOfScreen</a></li>
152 <li><a class="subsection" href="#DisplayCells">DisplayCells / CellsOfScreen</a></li>
157 <div class="section">
159 <li class="title"><a name="intro">Introduction</a></li>
161 This tutorial is based on the
162 <a href="http://users.actcom.co.il/~choo/lupg/tutorials/xlib-programming/xlib-programming.html">Xlib Tutorial</a>
163 written by <a href="mailto:choor@atcom.co.il">Guy Keren</a>. The
164 author allowed me to take some parts of his text, mainly the text which
165 deals with the X Windows generality.
168 This tutorial is intended to people who want to start to program
169 with the <a href="http://xcb.freedesktop.org">XCB</a>
170 library. As for the <a href="http://tronche.com/gui/x/xlib/introduction">Xlib</a>
171 library, it is useless and a real X
172 programmer should use a much higher level of abstraction, such
174 <a href="http://www.lesstif.org">LessTiff</a>,
175 <a href="http://www.gtk.org">GTK</a>,
176 <a href="http://www.trolltech.com">QT</a> or
177 <a href="http://www.enlightenment.org">EWL</a>. However,
178 we need to start somewhere. More than this, knowing how things
179 work down below is never a bad idea.
182 After reading this tutorial, one should be able to write very
183 simple graphical programs, but not programs with a descent user
184 interface. For such programs, one of the previously mentioned
185 library should be used.
188 But what is XCB ? Xlib has been
189 the standard C binding for the <a href="http://www.xfree86.org">X
190 Window System</a> protocol for many years now. It is an
191 excellent piece of work, but there are applications for which it
192 is not ideal, for example
194 <li><b>Small platforms</b>: Xlib is a large piece of code, and
195 it's difficult to make it smaller</li>
196 <li><b>Latency hiding</b>: Xlib requests requiring a reply are
197 effectively synchronous: they block until the reply appears,
198 whether the result is needed immediately or not.</li>
199 <li><b>Direct access to the protocol</b>: Xlib does quite a
200 bit of caching, layering, and similar optimizations. While this
201 is normally a feature, it makes it difficult to simply emit
202 specified X protocol requests and process specific
204 <li><b>Threaded applications</b>: While Xlib does attempt to
205 support multithreading, the API makes this difficult and
207 <li><b>New extensions</b>: The Xlib infrastructure provides
208 limited support for the new creation of X extension client side
213 For these reasons, among others, XCB, an X C binding, has been
214 designed to solve the above problems and thus provide a base for
216 <li>Toolkit implementation.</li>
217 <li>Direct protocol-level programming.</li>
218 <li>Lightweight emulation of commonly used portions of the
219 Xlib API (in progress)</li>
223 <li class="title"><a name="Xmodel">The client and server model of the X window system</a></li>
225 The X Window System was developed with one major goal:
226 flexibility. The idea was that the way things look is one thing,
227 but the way things work is another matter. Thus, the lower
228 levels provide the tools required to draw windows, handle user
229 input, allow drawing graphics using colors (or black and white
230 screens), etc. To this point, a decision was made to separate
231 the system into two parts. A client that decides what to do, and
232 a server that actually draws on the screen and reads user input
233 in order to send it to the client for processing.
236 This model is the complete opposite of what is used to when
237 dealing with clients and servers. In our case, the user seats
238 near the machine controlled by the server, while the client
239 might be running on a remote machine. The server controls the
240 screens, mouse and keyboard. A client may connect to the server,
241 request that it draws a window (or several windows), and ask the
242 server to send it any input the user sends to these
243 windows. Thus, several clients may connect to a single X server
244 (one might be running an mail software, one running a WWW
245 browser, etc). When input is sent by the user to some window,
246 the server sends a message to the client controlling this window
247 for processing. The client decides what to do with this input,
248 and sends the server requests for drawing in the window.
251 The whole session is carried out using the X message
252 protocol. This protocol was originally carried over the TCP/IP
253 protocol suite, allowing the client to run on any machine
254 connected to the same network that the server is. Later on, the
255 X servers were extended to allow clients running on the local
256 machine with more optimized access to the server (note that an X
257 protocol message may be several hundreds of KB in size), such as
258 using shred memory, or using Unix domain sockets (a method for
259 creating a logical channel on a Unix system between two processors).
261 <li class="title"><a name="asynch">GUI programming: the asynchronous model</a></li>
263 Unlike conventional computer programs, that carry some serial
264 nature, a GUI program usually uses an asynchronous programming
265 model, also known as "event-driven programming". This means that
266 that program mostly sits idle, waiting for events sent by the X
267 server, and then acts upon these events. An event may say "The
268 user pressed the 1st button mouse in spot (x,y)", or "The window
269 you control needs to be redrawn". In order for the program to e
270 responsive to the user input, as well as to refresh requests, it
271 needs to handle each event in a rather short period of time
272 (e.g. less that 200 milliseconds, as a rule of thumb).
275 This also implies that the program may not perform operations
276 that might take a long time while handling an event (such as
277 opening a network connection to some remote server, or
278 connecting to a database server, or even performing a long file
279 copy operation). Instead, it needs to perform all these
280 operations in an asynchronous manner. This may be done by using
281 various asynchronous models to perform the longish operations,
282 or by performing them in a different process or thread.
285 So the way a GUI program looks is something like that:
287 <li>Perform initialization routines.</li>
288 <li>Connect to the X server.</li>
289 <li>Perform X-related initialization.</li>
290 <li>While not finished:</li>
292 <li>Receive the next event from the X server.</li>
293 <li>Handle the event, possibly sending various drawing
294 requests to the X server.</li>
295 <li>If the event was a quit message, exit the loop.</li>
297 <li>Close down the connection to the X server. </li>
298 <li>Perform cleanup operations.</li>
302 <li class="title"><a name="notions">Basic XCB notions</a></li>
304 XCB has been created to eliminate the needs of
305 programs to actually implement the X protocol layer. This
306 library gives a program a very low-level access to any X
307 server. Since the protocol is standardized, a client using any
308 implementation of XCB may talk with any X server (the same
309 occurs for Xlib, of course). We now give a brief description of
310 the basic XCB notions. They will be detailed later.
313 <li class="subtitle"><a name="conn">The X Connection</a></li>
315 The major notion of using XCB is the X Connection. This is a
316 structure representing the connection we have open with a
317 given X server. It hides a queue of messages coming from the
318 server, and a queue of pending requests that our client
319 intends to send to the server. In XCB, this structure is named
320 'XCBConnection'. When we open a connection to an X server, the
321 library returns a pointer to such a structure. Later, we
322 supply this pointer to any XCB function that should send
323 messages to the X server or receive messages from this server.
325 <li class="subtitle"><a name="requestsreplies">Requests and
326 replies: the Xlib killers</a></li>
328 To ask informations to the X server, we have to make a request
329 and ask for a reply. With Xlib, these two tasks are
330 automatically done: Xlib locks the system, sends a request,
331 waits for a reply from the X server and unlocks. This is
332 annoying, especially if one makes a lot of requests to the X
333 server. Indeed, Xlib has to wait for the end of a reply
334 before asking for the next request (because of the locks that
335 Xlib sends). For example, here is a time-line of N=4
336 requests/replies with Xlib, with a round-trip latency
337 <b>T_round_trip</b> that is 5 times long as the time required
338 to write or read a request/reply (<b>T_write/T_read</b>):
341 W-----RW-----RW-----RW-----R
344 <li>W: Writing request</li>
345 <li>-: Stalled, waiting for data</li>
346 <li>R: Reading reply</li>
349 The total time is N * (T_write + T_round_trip + T_read).
352 With XCB, we can suppress most of the round-trips as the
353 requests and the replies are not locked. We usually send a
354 request, then XCB returns to us a <b>cookie</b>, which is an
355 identifier. Then, later, we ask for a reply using this
356 <b>cookie</b> and XCB returns a
357 pointer to that reply. Hence, with XCB, we can send a lot of
358 requests, and later in the program, ask for all the replies
359 when we need them. Here is the time-line for 4
360 requests/replies when we use this property of XCB:
366 The total time is N * T_write + max (0, T_round_trip - (N-1) *
367 T_write) + N * T_read. Which can be considerably faster than
368 all those Xlib round-trips.
371 Here is a program that computes the time to create 500 atoms
372 with Xlib and XCB. It shows the Xlib way, the bad XCB way
373 (which is similar to Xlib) and the good XCB way. On my
374 computer, XCB is 25 times faster than Xlib.
377 #include <stdlib.h>
378 #include <stdio.h>
379 #include <string.h>
380 #include <sys/time.h>
382 #include <X11/XCB/xcb.h>
384 #include <X11/Xlib.h>
389 struct timeval timev;
391 gettimeofday(&timev, NULL);
393 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
401 XCBInternAtomCookie *cs;
414 c = XCBConnectBasic ();
417 atoms = (XCBATOM *)malloc (count * sizeof (atoms));
418 names = (char **)malloc (count * sizeof (char *));
421 for (i = 0; i < count; ++i)
425 sprintf (buf, "NAME%d", i);
426 names[i] = strdup (buf);
432 for (i = 0; i < count; ++i)
433 atoms[i] = XCBInternAtomReply (c,
442 printf ("bad use time : %f\n", diff);
447 cs = (XCBInternAtomCookie *) malloc (count * sizeof(XCBInternAtomCookie));
448 for(i = 0; i < count; ++i)
449 cs[i] = XCBInternAtom (c, 0, strlen(names[i]), names[i]);
451 for(i = 0; i < count; ++i)
455 r = XCBInternAtomReply(c, cs[i], 0);
462 printf ("good use time : %f\n", end - start);
463 printf ("ratio : %f\n", diff / (end - start));
467 for (i = 0; i < count; ++i)
477 disp = XOpenDisplay (getenv("DISPLAY"));
479 atoms_x = (Atom *)malloc (count * sizeof (atoms_x));
483 for (i = 0; i < count; ++i)
484 atoms_x[i] = XInternAtom(disp, names[i], 0);
487 diff_x = end - start;
488 printf ("Xlib use time : %f\n", diff_x);
489 printf ("ratio : %f\n", diff_x / diff);
494 XCloseDisplay (disp);
499 <li class="subtitle"><a name="gc">The Graphic Context</a></li>
501 When we perform various drawing operations (graphics, text,
502 etc), we may specify various options for controlling how the
503 data will be drawn (what foreground and background colors to
504 use, how line edges will be connected, what font to use when
505 drawing some text, etc). In order to avoid the need to supply
506 hundreds of parameters to each drawing function, a graphical
507 context structure is used. We set the various drawing options
508 in this structure, and then, we pass a pointer to this
509 structure to any drawing routines. This is rather handy, as we
510 often need to perform several drawing requests with the same
511 options. Thus, we would initialize a graphical context, set
512 the desired options, and pass this structure to all drawing
516 Note that graphic contexts have no client-side structure in
517 XCB, they're just XIDs. Xlib has a client-side structure
518 because it caches the GC contents so it can avoid making
519 redundant requests, but of course XCB doesn't do that.
521 <li class="subtitle"><a name="events">Events</a></li>
523 A structure is used to pass events received from the X
524 server. XCB supports exactly the events specified in the
525 protocol (33 events). This structure contains the type
526 of event received, as well as the data associated with the
527 event (e.g. position on the screen where the event was
528 generated, mouse button associated with the event, region of
529 the screen associated with a "redraw" event, etc). The way to
530 read the event's data epends on the event type.
534 <li class="title"><a name="use">Using XCB-based programs</a></li>
537 <li class="subtitle"><a name="inst">Installation of XCB</a></li>
539 To build XCB from source, you need to have installed at
543 <li>pkgconfig 0.15.0</li>
544 <li>automake 1.7</li>
545 <li>autoconf 2.50</li>
546 <li><a href="http://www.check.org">check</a></li>
547 <li><a href="http://xmlsoft.org/XSLT/">xsltproc</a></li>
550 You have to checkout in CVS the following modules:
553 <li>Xproto from xlibs</li>
554 <li>Xau from xlibs</li>
559 Note that Xproto and xcb-proto exist only to install header
560 files, so typing 'make' or 'make all' will produce the message
561 "Nothing to be done for 'all'". That's normal.
563 <li class="subtitle"><a name="comp">Compiling XCB-based programs</a></li>
565 Compiling XCB-based programs requires linking them with the XCB
566 library. This is easily done thanks to pkgconfig:
569 gcc -Wall prog.c -o prog `pkg-config --cflags --libs xcb`
572 <li class="title"><a name="openconn">Opening and closing the connection to an X server</a></li>
574 An X program first needs to open the connection to the X
575 server. There is a function that opens a connection. It requires
576 the display name, or NULL. In the latter case, the display name
577 will be the one in the environment variable DISPLAY.
580 XCBConnection *XCBConnect (const char *displayname,
584 The second parameter returns the screen number used for the
585 connection. The returned structure describes an XCB connection
586 and is opaque. Here is how the connection can be opened:
589 #include <X11/XCB/xcb.h>
592 main (int argc, char *argv[])
596 /* Open the connection to the X server. use the DISPLAY environment variable as the default display name */
597 c = XCBConnect (NULL, NULL);
603 To close a connection, it suffices to use:
606 void XCBDisconnect (XCBConnection *c);
614 <li>XOpenDisplay ()</li>
619 <li>XCBConnect ()</li>
624 <li>XCloseDisplay ()</li>
629 <li>XCBDisconnect ()</li>
635 <li class="title"><a name="screen">Checking basic information about a connection</a></li>
637 Once we opened a connection to an X server, we should check some
638 basic informations about it: what screens it has, what is the
639 size (width and height) of the screen, how many colors it
640 supports (black and white ? grey scale ?, 256 colors ? more ?),
641 and so on. We get such informations from the XCBSCREEN
647 XCBCOLORMAP default_colormap;
650 CARD32 current_input_masks;
651 CARD16 width_in_pixels;
652 CARD16 height_in_pixels;
653 CARD16 width_in_millimeters;
654 CARD16 height_in_millimeters;
655 CARD16 min_installed_maps;
656 CARD16 max_installed_maps;
657 XCBVISUALID root_visual;
661 CARD8 allowed_depths_len;
665 We could retrieve the first screen of the connection by using the
669 XCBSCREENIter XCBConnSetupSuccessRepRootsIter (XCBConnSetupSuccessRep *R);
672 Here is a small program that shows how to use this function:
675 #include <stdio.h>
677 #include <X11/XCB/xcb.h>
680 main (int argc, char *argv[])
687 /* Open the connection to the X server. Use the DISPLAY environment variable */
688 c = XCBConnect (NULL, &screen_nbr);
690 /* Get the screen #screen_nbr */
691 iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
692 for (; iter.rem; --screen_nbr, XCBSCREENNext (&iter))
700 printf ("Informations of screen %ld:\n", screen->root.xid);
701 printf (" width.........: %d\n", screen->width_in_pixels);
702 printf (" height........: %d\n", screen->height_in_pixels);
703 printf (" white pixel...: %ld\n", screen->white_pixel);
704 printf (" black pixel...: %ld\n", screen->black_pixel);
710 <li class="title"><a name="helloworld">Creating a basic window - the "hello world" program</a></li>
712 After we got some basic informations about our screen, we can
713 create our first window. In the X Window System, a window is
714 characterized by an Id. So, in XCB, a window is of type:
722 We first ask for a new Id for our window, with this function:
725 XCBWINDOW XCBWINDOWNew(XCBConnection *c);
728 Then, XCB supplies the following function to create new windows:
731 XCBVoidCookie XCBCreateWindow (XCBConnection *c, /* Pointer to the XCBConnection structure */
732 CARD8 depth, /* Depth of the screen */
733 XCBWINDOW wid, /* Id of the window */
734 XCBWINDOW parent, /* Id of an existing window that should be the parent of the new window */
735 INT16 x, /* X position of the top-left corner of the window (in pixels) */
736 INT16 y, /* Y position of the top-left corner of the window (in pixels) */
737 CARD16 width, /* Width of the window (in pixels) */
738 CARD16 height, /* Height of the window (in pixels) */
739 CARD16 border_width, /* Width of the window's border (in pixels) */
743 const CARD32 *value_list);
746 The fact that we created the window does not mean that it will
747 be drawn on screen. By default, newly created windows are not
748 mapped on the screen (they are invisible). In order to make our
749 window visible, we use the function <span class="code">XCBMapWindow()</span>, whose
753 XCBVoidCookie XCBMapWindow (XCBConnection *c, XCBWINDOW window);
756 Finally, here is a small program to create a window of size
757 150x150 pixels, positioned at the top-left corner of the screen:
760 #include <unistd.h>
762 #include <X11/XCB/xcb.h>
765 main (int argc, char *argv[])
771 /* Open the connection to the X server */
772 c = XCBConnect (NULL, NULL);
774 /* Get the first screen */
775 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
777 /* Ask for our window's Id */
778 win.window = XCBWINDOWNew(c);
780 /* Create the window */
781 XCBCreateWindow (c, /* Connection */
783 win.window, /* window Id */
784 screen->root, /* parent window */
786 150, 150, /* width, height */
787 10, /* border_width */
788 InputOutput, /* class */
789 screen->root_visual, /* visual */
790 0, NULL); /* masks, not used yet */
792 /* Map the window on the screen */
793 XCBMapWindow (c, win.window);
803 In this code, you see one more function - <span class="code">XCBSync()</span>, not explained
804 yet. It is used to flush all the pending requests. More
805 precisely, there are 2 functions that do such things. The first
806 one is <span class="code">XCBFlush()</span>:
809 int XCBFlush (XCBConnection *c);
812 This function flushes all pending requests to the X server (much
813 like the <span class="code">fflush()</span> function is used to
814 flush standard output). The second function is
815 <span class="code">XCBSync()</span>:
818 int XCBSync(XCBConnection *c, XCBGenericError **e);
821 This functions also flushes all pending requests to the X
822 server, and then waits until the X server finishing processing
823 these requests. In a normal program, this will not be necessary
824 (we'll see why when we get to write a normal X program), but for
825 now, we put it there.
828 The window that is created by the above code has a default
829 background (gray). This one can be set to a specific color,
830 thanks to the two last parameters of
831 <span class="code">XCBCreateWindow()</span>, which are not
832 described yet. See the subsections
833 <a href="#winconf">Configuring a window</a> or
834 <a href="#winconf">Registering for event types using event masks</a>
835 for exemples on how to use these parameters. In addition, as no
836 events are handled, you have to make a Ctrl-C to interrupt the
840 <b>TODO</b>: one should tell what these functions return and
841 about the generic error
849 <li>XCreateWindow ()</li>
854 <li>XCBWINDOWNew ()</li>
855 <li>XCBCreateWindow ()</li>
860 <li class="title"><a name="drawing">Drawing in a window</a></li>
862 Drawing in a window can be done using various graphical
863 functions (drawing pixels, lines, rectangles, etc). In order to
864 draw in a window, we first need to define various general
865 drawing parameters (what line width to use, which color to draw
866 with, etc). This is done using a graphical context.
869 <li class="subtitle"><a name="allocgc">Allocating a Graphics Context</a></li>
871 As we said, a graphical context defines several attributes to
872 be used with the various drawing functions. For this, we
873 define a graphical context. We can use more than one graphical
874 context with a single window, in order to draw in multiple
875 styles (different colors, different line widths, etc). In XCB,
876 a Graphics Context is, as a window, characterized by an Id:
884 We first ask the X server to attribute an Id to our graphic
885 context with this function:
888 XCBGCONTEXT XCBGCONTEXTNew (XCBConnection *c);
891 Then, we set the attributes of the graphic context with this function:
894 XCBVoidCookie XCBCreateGC (XCBConnection *c,
896 XCBDRAWABLE drawable,
898 const CARD32 *value_list);
901 We give now an example on how to allocate a graphic context
902 that specifies that each drawing functions that use it will
903 draw in foreground with a black color.
906 #include <X11/XCB/xcb.h>
909 main (int argc, char *argv[])
918 /* Open the connection to the X server and get the first screen */
919 c = XCBConnect (NULL, NULL);
920 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
922 /* Create a black graphic context for drawing in the foreground */
923 win.window = screen->root;
924 black = XCBGCONTEXTNew (c);
926 value[0] = screen->black_pixel;
927 XCBCreateGC (c, black, win, mask, value);
933 Note should be taken regarding the role of "value_mask" and
934 "value_list" in the prototype of <span class="code">XCBCreateGC()</span>. Since a
935 graphic context has many attributes, and since we often just
936 want to define a few of them, we need to be able to tell the
937 <span class="code">XCBCreateGC()</span> which attributes we
938 want to set. This is what the "value_mask" parameter is
939 for. We then use the "value_list" parameter to specify actual
940 values for the attribute we defined in "value_mask". Thus, for
941 each constant used in "value_list", we will use the matching
942 constant in "value_mask". In this case, we define a graphic
943 context with one attribute: when drawing (a point, a line,
944 etc), the foreground color will be black. The rest of the
945 attributes of this graphic context will be set to their
949 See the next Subsection for more details.
957 <li>XCreateGC ()</li>
962 <li>XCBGCONTEXTNew ()</li>
963 <li>XCBCreateGC ()</li>
968 <li class="subtitle"><a name="changegc">Changing the attributes of a Graphics Context</a></li>
970 Once we have allocated a Graphic Context, we may need to
971 change its attributes (for example, changing the foreground
972 color we use to draw a line, or changing the attributes of the
973 font we use to display strings. See Subsections Drawing with a
974 color and Assigning a Font to a Graphic Context). This is done
975 by using this function:
978 XCBVoidCookie XCBChangeGC (XCBConnection *c, /* The XCB Connection */
979 XCBGCONTEXT gc, /* The Graphic Context */
980 CARD32 value_mask, /* Components of the Graphic Context that have to be set */
981 const CARD32 *value_list); /* Value as specified by value_mask */
984 The <span class="code">value_mask</span> parameter could take
990 <li>GCForeground</li>
991 <li>GCBackground</li>
1000 <li>GCTileStipXOrigin</li>
1001 <li>GCTileStipYOrigin</li>
1003 <li>GCSubwindowMode</li>
1004 <li>GCGraphicsExposures</li>
1005 <li>GCClipXOrigin</li>
1006 <li>GCClipYOrigin</li>
1008 <li>GCDashOffset</li>
1013 It is possible to set several attributes at the same
1014 time (for example setting the attributes of a font and the
1015 color which will be used to display a string), by OR'ing these
1016 values in <span class="code">value_mask</span>. Then
1017 <span class="code">value_list</span> has to be an array which
1018 lists the value for the respective attributes. See Subsection
1019 Drawing with a color to have an example.
1022 <b>TODO</b>: set the links of the 3 subsections, once they will
1026 <b>TODO</b>: give an example which sets several attributes.
1028 <li class="subtitle"><a name="drawingprim">Drawing primitives: point, line, box, circle,...</a></li>
1030 After we have created a Graphic Context, we can draw on a
1031 window using this Graphic Context, with a set of XCB
1032 functions, collectively called "drawing primitive". Let see
1036 To draw a point, or several points, we use
1039 XCBVoidCookie XCBPolyPoint (XCBConnection *c, /* The connection to the X server */
1040 BYTE coordinate_mode, /* Coordinate mode, usually set to CoordModeOrigin */
1041 XCBDRAWABLE drawable, /* The drawable on which we want to draw the point(s) */
1042 XCBGCONTEXT gc, /* The Graphic Context we use to draw the point(s) */
1043 CARD32 points_len, /* The number of points */
1044 const XCBPOINT *points); /* An array of points */
1047 The <span class="code">coordinate_mode</span> parameter
1048 specifies the coordinate mode. Available values are
1051 <li><span class="code">CoordModeOrigin</span></li>
1052 <li><span class="code">CoordModePrevious</span></li>
1055 The <span class="code">XCBPOINT</span> type is just a
1056 structure with two fields (the coordinates of the point):
1065 You could see an example in xpoints.c. <b>TODO</b> Set the link.
1068 To draw a line, or a polygonal line, we use
1071 XCBVoidCookie XCBPolyLine (XCBConnection *c, /* The connection to the X server */
1072 BYTE coordinate_mode, /* Coordinate mode, usually set to CoordModeOrigin */
1073 XCBDRAWABLE drawable, /* The drawable on which we want to draw the line(s) */
1074 XCBGCONTEXT gc, /* The Graphic Context we use to draw the line(s) */
1075 CARD32 points_len, /* The number of points in the polygonal line */
1076 const XCBPOINT *points); /* An array of points */
1079 This function will draw the line between the first and the
1080 second points, then the line between the second and the third
1084 To draw a segment, or several segments, we use
1087 XCBVoidCookie XCBPolySegment (XCBConnection *c, /* The connection to the X server */
1088 XCBDRAWABLE drawable, /* The drawable on which we want to draw the segment(s) */
1089 XCBGCONTEXT gc, /* The Graphic Context we use to draw the segment(s) */
1090 CARD32 segments_len, /* The number of segments */
1091 const XCBSEGMENT *segments); /* An array of segments */
1094 The <span class="code">XCBSEGMENT</span> type is just a
1095 structure with four fields (the coordinates of the two points
1096 that define the segment):
1107 To draw a rectangle, or several rectangles, we use
1110 XCBVoidCookie XCBPolyRectangle (XCBConnection *c, /* The connection to the X server */
1111 XCBDRAWABLE drawable, /* The drawable on which we want to draw the rectangle(s) */
1112 XCBGCONTEXT gc, /* The Graphic Context we use to draw the rectangle(s) */
1113 CARD32 rectangles_len, /* The number of rectangles */
1114 const XCBRECTANGLE *rectangles); /* An array of rectangles */
1117 The <span class="code">XCBRECTANGLE</span> type is just a
1118 structure with four fields (the coordinates of the top-left
1119 corner of the rectangle, and its width and height):
1130 <b>TODO</b>: there's no coordinate_mode. Is it normal ?
1133 To draw an elliptical arc, or several elliptical arcs, we use
1136 XCBVoidCookie XCBPolyArc (XCBConnection *c, /* The connection to the X server */
1137 XCBDRAWABLE drawable, /* The drawable on which we want to draw the arc(s) */
1138 XCBGCONTEXT gc, /* The Graphic Context we use to draw the arc(s) */
1139 CARD32 arcs_len, /* The number of arcs */
1140 const XCBARC *arcs); /* An array of arcs */
1143 The <span class="code">XCBARC</span> type is a structure with
1148 INT16 x; /* Top left x coordinate of the rectangle surrounding the ellipse */
1149 INT16 y; /* Top left y coordinate of the rectangle surrounding the ellipse */
1150 CARD16 width; /* Width of the rectangle surrounding the ellipse */
1151 CARD16 height; /* Height of the rectangle surrounding the ellipse */
1152 INT16 angle1; /* Angle at which the arc begins */
1153 INT16 angle2; /* Angle at which the arc ends */
1158 Note: the angles are expressed in units of 1/64 of a degree,
1159 so to have an angle of 90 degrees, starting at 0,
1160 <span class="code">angle1 = 0</span> and
1161 <span class="code">angle2 = 90 << 6</span>. Positive angles
1162 indicate counterclockwise motion, while negative angles
1163 indicate clockwise motion.
1167 <b>TODO</b>: there's no coordinate_mode. Is it normal ?
1170 <b>TODO</b>: I think that (x,y) should be the center of the
1171 ellipse, and (width, height) the radius. It's more logical.
1174 The corresponding function which fill inside the geometrical
1175 object are listed below, without further explanation, as they
1176 are used as the above functions.
1179 To Fill a polygon defined by the points given as arguments ,
1183 XCBVoidCookie XCBFillPoly (XCBConnection *c,
1184 XCBDRAWABLE drawable,
1187 CARD8 coordinate_mode,
1189 const XCBPOINT *points);
1192 The <span class="code">shape</span> parameter specifies a
1193 shape that helps the server to improve performance. Available
1197 <li><span class="code">Complex</span></li>
1198 <li><span class="code">Convex</span></li>
1199 <li><span class="code">Nonconvex</span></li>
1202 To fill one or several rectangles, we use
1205 XCBVoidCookie XCBPolyFillRectangle (XCBConnection *c,
1206 XCBDRAWABLE drawable,
1208 CARD32 rectangles_len,
1209 const XCBRECTANGLE *rectangles);
1212 To fill one or several arcs, we use
1215 XCBVoidCookie XCBPolyFillArc (XCBConnection *c,
1216 XCBDRAWABLE drawable,
1219 const XCBARC *arcs);
1223 To illustrate these functions, here is an example that draws
1224 four points, a polygonal line, two segments, two rectangles
1225 and two arcs. Remark that we use events for the first time, as
1226 an introduction to the next section.
1229 #include <stdlib.h>
1230 #include <stdio.h>
1232 #include <X11/XCB/xcb.h>
1234 /* Get the depth of the screen. Needed in order to draw something */
1236 get_depth(XCBConnection *c,
1239 XCBDRAWABLE drawable;
1240 XCBGetGeometryRep *geom;
1243 drawable.window = root->root;
1244 geom = XCBGetGeometryReply (c, XCBGetGeometry(c, drawable), 0);
1248 perror ("GetGeometry(root) failed");
1252 depth = geom->depth;
1259 main (int argc, char *argv[])
1264 XCBGCONTEXT foreground;
1269 /* geometric objects */
1270 XCBPOINT points[] = {
1276 XCBPOINT polyline[] = {
1282 XCBSEGMENT segments[] = {
1284 {110, 25, 130, 60}};
1286 XCBRECTANGLE rectangles[] = {
1291 {10, 100, 60, 40, 0, 90 << 6},
1292 {90, 100, 55, 40, 0, 270 << 6}};
1294 /* Open the connection to the X server */
1295 c = XCBConnect (NULL, NULL);
1297 /* Get the first screen */
1298 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
1300 /* Create black (foregroung) graphic context */
1301 win.window = screen->root;
1303 foreground = XCBGCONTEXTNew (c);
1304 mask = GCForeground | GCGraphicsExposures;
1305 values[0] = screen->black_pixel;
1307 XCBCreateGC (c, foreground, win, mask, values);
1309 /* Ask for our window's Id */
1310 win.window = XCBWINDOWNew(c);
1312 /* Create the window */
1313 mask = XCBCWBackPixel | XCBCWEventMask;
1314 values[0] = screen->white_pixel;
1315 values[1] = ExposureMask;
1316 XCBCreateWindow (c, /* Connection */
1318 win.window, /* window Id */
1319 screen->root, /* parent window */
1321 150, 150, /* width, height */
1322 10, /* border_width */
1323 InputOutput, /* class */
1324 screen->root_visual, /* visual */
1325 mask, values); /* masks */
1327 /* Map the window on the screen */
1328 XCBMapWindow (c, win.window);
1331 /* We flush the request */
1334 while ((e = XCBWaitEvent (c)))
1336 switch (e->response_type)
1340 /* We draw the points */
1341 XCBPolyPoint (c, CoordModeOrigin, win, foreground, 4, points);
1343 /* We draw the polygonal line */
1344 XCBPolyLine (c, CoordModeOrigin, win, foreground, 4, polyline);
1346 /* We draw the segements */
1347 XCBPolySegment (c, win, foreground, 2, segments);
1349 /* We draw the rectangles */
1350 XCBPolyRectangle (c, win, foreground, 2, rectangles);
1352 /* We draw the arcs */
1353 XCBPolyArc (c, win, foreground, 2, arcs);
1355 /* We flush the request */
1362 /* Unknown event type, ignore it */
1366 /* Free the Generic Event */
1374 <li class="title"><a name="xevents">X Events</a></li>
1376 In an X program, everything is driven by events. Event painting
1377 on the screen is sometimes done as a response to an event (an
1378 <span class="code">Expose</span> event). If part of a program's
1379 window that was hidden, gets exposed (e.g. the window was raised
1380 above other widows), the X server will send an "expose" event to
1381 let the program know it should repaint that part of the
1382 window. User input (key presses, mouse movement, etc) is also
1383 received as a set of events.
1386 <li class="subtitle"><a name="register">Registering for event types using event masks</a></li>
1388 During the creation of a window, you should give it what kind
1389 of events it wishes to receive. Thus, you may register for
1390 various mouse (also called pointer) events, keyboard events,
1391 expose events, and so on. This is done for optimizing the
1392 server-to-client connection (i.e. why send a program (that
1393 might even be running at the other side of the globe) an event
1394 it is not interested in ?)
1397 In XCB, you use the "value_mask" and "value_list" data in the
1398 <span class="code">XCBCreateWindow()</span> function to
1399 register for events. Here is how we register for
1400 <span class="code">Expose</span> event when creating a window:
1403 mask = XCBCWEventMask;
1404 valwin[0] = ExposureMask;
1405 win.window = XCBWINDOWNew (c);
1406 XCBCreateWindow (c, depth, win.window, root->root,
1408 InputOutput, root->root_visual,
1412 <span class="code">ExposureMask</span> is a constant defined
1413 in the "X.h" header file. If we wanted to register to several
1414 event types, we can logically "or" them, as follows:
1417 mask = XCBCWEventMask;
1418 valwin[0] = ExposureMask | ButtonPressMask;
1419 win.window = XCBWINDOWNew (c);
1420 XCBCreateWindow (c, depth, win.window, root->root,
1422 InputOutput, root->root_visual,
1426 This registers for <span class="code">Expose</span> events as
1427 well as for mouse button presses insode the created
1428 window. You should note that a mask may represent several
1432 The values that a mask could take are given
1433 by the <span class="code">XCBCW</span> enumeration:
1437 XCBCWBackPixmap = 1L<<0,
1438 XCBCWBackPixel = 1L<<1,
1439 XCBCWBorderPixmap = 1L<<2,
1440 XCBCWBorderPixel = 1L<<3,
1441 XCBCWBitGravity = 1L<<4,
1442 XCBCWWinGravity = 1L<<5,
1443 XCBCWBackingStore = 1L<<6,
1444 XCBCWBackingPlanes = 1L<<7,
1445 XCBCWBackingPixel = 1L<<8,
1446 XCBCWOverrideRedirect = 1L<<9,
1447 XCBCWSaveUnder = 1L<<10,
1448 XCBCWEventMask = 1L<<11,
1449 XCBCWDontPropagate = 1L<<12,
1450 XCBCWColormap = 1L<<13,
1451 XCBCWCursor = 1L<<14
1455 <p>Note: we must be careful when setting the values of the valwin
1456 parameter, as they have to follow the order the
1457 <span class="code">XCBCW</span> enumeration. Here is an
1462 mask = XCBCWEventMask | XCBCWBackPixmap;
1463 valwin[0] = None; /* for XCBCWBackPixmap (whose value is 1) */
1464 valwin[1] = ExposureMask | ButtonPressMask; /* for XCBCWEventMask, whose value (2048) */
1465 /* is superior to the one of XCBCWBackPixmap */
1468 If the window has already been created, we can use the
1469 <span class="code">XCBConfigureWindow()</span> function to set
1470 the events that the window will receive. The subsection
1471 <a href="#winconf">Configuring a window</a> shows its
1472 prototype. As an example, here is a piece of code that
1473 configures the window to receive the
1474 <span class="code">Expose</span> and
1475 <span class="code">ButtonPressMask</span> events:
1478 const static CARD32 values[] = { ExposureMask | ButtonPressMask };
1480 /* The connection c and the window win are supposed to be defined */
1482 XCBConfigureWindow (c, win, XCBCWEventMask, values);
1486 Note: A common bug programmers do is adding code to handle new
1487 event types in their program, while forgetting to add the
1488 masks for these events in the creation of the window. Such a
1489 programmer then should sit down for hours debugging his
1490 program, wondering "Why doesn't my program notice that I
1491 released the button?", only to find that they registered for
1492 button press events but not for button release events.
1495 <li class="subtitle"><a name="loop">Receiving events: writing the events loop</a></li>
1497 After we have registered for the event types we are interested
1498 in, we need to enter a loop of receiving events and handling
1499 them. There are two ways to receive events: a blocking way and
1504 <span class="code">XCBWaitEvent (XCBConnection *c)</span>
1505 is the blocking way. It waits (so blocks...) until an event is
1506 queued in the X server. Then it retrieves it into a newly
1507 allocated structure (it dequeues it from the queue) and returns
1508 it. This structure has to be freed. The function returns
1509 <span class="code">NULL</span> if an error occurs.
1513 <span class="code">XCBPollForEvent (XCBConnection *c, int
1514 *error)</span> is the non blocking way. It looks at the event
1515 queue and returns (and dequeues too) an existing event into
1516 a newly allocated structure. This structure has to be
1517 freed. It returns <span class="code">NULL</span> if there is
1518 no event. If an error occurs, the parameter <span
1519 class="code">error</span> will be filled with the error
1524 There are various ways to write such a loop. We present two
1525 ways to write such a loop, with the two functions above. The
1526 first one uses <span class="code">XCBWaitEvent</span>, which
1527 is similar to an event Xlib loop using only <span
1528 class="code">XNextEvent</span>:
1533 while ((e = XCBWaitEvent (c)))
1535 switch (e->response_type)
1539 /* Handle the Expose event type */
1540 XCBExposeEvent *ev = (XCBExposeEvent *)e;
1546 case XCBButtonPress:
1548 /* Handle the ButtonPress event type */
1549 XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
1557 /* Unknown event type, ignore it */
1561 /* Free the Generic Event */
1566 You will certainly want to use <span
1567 class="code">XCBPollForEvent(XCBConnection *c, int
1568 *error)</span> if, in Xlib, you use <span
1569 class="code">XPending</span>:
1572 while (XPending (display))
1578 /* Manage your event */
1582 Such a loop in XCB looks like:
1585 XCBGenericEvent *ev;
1587 while ((ev = XCBPollForEvent (conn, 0)))
1589 /* Manage your event */
1593 The events are managed in the same way as with <span
1594 class="code">XCBWaitEvent</span>.
1595 Obviously, we will need to give the user some way of
1596 terminating the program. This is usually done by handling a
1597 special "quit" event, as we will soon see.
1605 <li>XNextEvent ()</li>
1610 <li>XCBWaitEvent ()</li>
1615 <li>XPending ()</li>
1616 <li>XNextEvent ()</li>
1621 <li>XCBPollForEvent ()</li>
1627 <li class="subtitle"><a name="expose">Expose events</a></li>
1629 The <span class="code">Expose</span> event is one of the most
1630 basic (and most used) events an application may receive. It
1631 will be sent to us in one of several cases:
1633 <li>A window that covered part of our window has moved
1634 away, exposing part (or all) of our window.</li>
1635 <li>Our window was raised above other windows.</li>
1636 <li>Our window mapped for the first time.</li>
1637 <li>Our window was de-iconified.</li>
1641 You should note the implicit assumption hidden here: the
1642 contents of our window is lost when it is being obscured
1643 (covered) by either windows. One may wonder why the X server
1644 does not save this contents. The answer is: to save
1645 memory. After all, the number of windows on a display at a
1646 given time may be very large, and storing the contents of all
1647 of them might require a lot of memory. Actually, there is a
1648 way to tell the X server to store the contents of a window in
1649 special cases, as we will see later.
1652 When we get an <span class="code">Expose</span> event, we
1653 should take the event's data from the members of the following
1658 BYTE response_type; /* The type of the event, here it is XCBExpose */
1661 XCBWINDOW window; /* The Id of the window that receives the event (in case */
1662 /* our application registered for events on several windows */
1663 CARD16 x; /* The x coordinate of the top-left part of the window that needs to be redrawn */
1664 CARD16 y; /* The y coordinate of the top-left part of the window that needs to be redrawn */
1665 CARD16 width; /* The width of the part of the window that needs to be redrawn */
1666 CARD16 height; /* The height of the part of the window that needs to be redrawn */
1670 <li class="subtitle"><a name="userinput">Getting user input</a></li>
1672 User input traditionally comes from two sources: the mouse
1673 and the keyboard. Various event types exist to notify us of
1674 user input (a key being presses on the keyboard, a key being
1675 released on the keyboard, the mouse moving over our window,
1676 the mouse entering (or leaving) our window, and so on.
1679 <li class="subsubtitle"><a name="mousepressrelease">Mouse button press and release events</a></li>
1681 The first event type we will deal with is a mouse
1682 button-press (or button-release) event in our window. In
1683 order to register to such an event type, we should add one
1684 (or more) of the following masks when we create our window:
1687 <li><span class="code">ButtonPressMask</span>: notify us
1688 of any button that was pressed in one of our windows.</li>
1689 <li><span class="code">ButtonReleaseMask</span>: notify us
1690 of any button that was released in one of our windows.</li>
1693 The structure to be checked for in our events loop is the
1694 same for these two events, and is the following:
1698 BYTE response_type; /* The type of the event, here it is XCBButtonPressEvent or XCBButtonReleaseEvent */
1701 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1707 INT16 event_x; /* The x coordinate where the mouse has been pressed in the window */
1708 INT16 event_y; /* The y coordinate where the mouse has been pressed in the window */
1709 CARD16 state; /* A mask of the buttons (or keys) during the event */
1711 } XCBButtonPressEvent;
1713 typedef XCBButtonPressEvent XCBButtonReleaseEvent;
1716 The <span class="code">time</span> field may be used to calculate "double-click"
1717 situations by an application (e.g. if the mouse button was
1718 clicked two times in a duration shorter than a given amount
1719 of time, assume this was a double click).
1722 The <span class="code">state</span> field is a mask of the buttons held down during
1723 the event. It is a bitwise OR of any of the following:
1726 <li><span class="code">Button1Mask</span></li>
1727 <li><span class="code">Button2Mask</span></li>
1728 <li><span class="code">Button3Mask</span></li>
1729 <li><span class="code">Button4Mask</span></li>
1730 <li><span class="code">Button5Mask</span></li>
1731 <li><span class="code">ShiftMask</span></li>
1732 <li><span class="code">LockMask</span></li>
1733 <li><span class="code">ControlMask</span></li>
1734 <li><span class="code">Mod1Mask</span></li>
1735 <li><span class="code">Mod2Mask</span></li>
1736 <li><span class="code">Mod3Mask</span></li>
1737 <li><span class="code">Mod4Mask</span></li>
1738 <li><span class="code">Mod5Mask</span></li>
1741 Their names are self explanatory, where the first 5 refer to
1742 the mouse buttons that are being pressed, while the rest
1743 refer to various "special keys" that are being pressed (Mod1
1744 is usually the 'Alt' key or the 'Meta' key).
1747 <b>TODO:</b> Problem: it seems that the state does not
1748 change when clicking with various buttons.
1750 <li class="subsubtitle"><a name="mousemvnt">Mouse movement events</a></li>
1752 Similar to mouse button press and release events, we also
1753 can be notified of various mouse movement events. These can
1754 be split into two families. One is of mouse pointer
1755 movement while no buttons are pressed, and the second is a
1756 mouse pointer motion while one (or more) of the buttons are
1757 pressed (this is sometimes called "a mouse drag operation",
1758 or just "dragging"). The following event masks may be added
1759 during the creation of our window:
1762 <li><span class="code">PointerMotionMask</span>: events of
1763 the pointer moving in one of the windows controlled by our
1764 application, while no mouse button is held pressed.</li>
1765 <li><span class="code">ButtonMotionMask</span>: Events of
1766 the pointer moving while one or more of the mouse buttons
1767 is held pressed.</li>
1768 <li><span class="code">Button1MotionMask</span>: same as
1769 <span class="code">ButtonMotionMask</span>, but only when
1770 the 1st mouse button is held pressed.</li>
1771 <li><span class="code">Button2MotionMask</span>,
1772 <span class="code">Button3MotionMask</span>,
1773 <span class="code">Button4MotionMask</span>,
1774 <span class="code">Button5MotionMask</span>: same as
1775 <span class="code">Button1MotionMask</span>, but
1776 respectively for 2nd, 3rd, 4th and 5th mouse button.</li>
1779 The structure to be checked for in our events loop is the
1780 same for these events, and is the following:
1784 BYTE response_type; /* The type of the event */
1787 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1793 INT16 event_x; /* The x coordinate of the mouse when the event was generated */
1794 INT16 event_y; /* The y coordinate of the mouse when the event was generated */
1795 CARD16 state; /* A mask of the buttons (or keys) during the event */
1797 } XCBMotionNotifyEvent;
1799 <li class="subsubtitle"><a name="mouseenter">Mouse pointer enter and leave events</a></li>
1801 Another type of event that applications might be interested
1802 at, is a mouse pointer entering a window the program
1803 controls, or leaving such a window. Some programs use these
1804 events to show the user tht the applications is now in
1805 focus. In order to register for such an event type, we
1806 should add one (or more) of the following masks when we
1810 <li><span class="code">EnterWindowMask</span>: notify us
1811 when the mouse pointer enters any of our controlled
1813 <li><span class="code">LeaveWindowMask</span>: notify us
1814 when the mouse pointer leaves any of our controlled
1818 The structure to be checked for in our events loop is the
1819 same for these two events, and is the following:
1823 BYTE response_type; /* The type of the event */
1826 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1832 INT16 event_x; /* The x coordinate of the mouse when the event was generated */
1833 INT16 event_y; /* The y coordinate of the mouse when the event was generated */
1834 CARD16 state; /* A mask of the buttons (or keys) during the event */
1835 BYTE mode; /* The number of mouse button that was clicked */
1836 BYTE same_screen_focus;
1837 } XCBEnterNotifyEvent;
1839 typedef XCBEnterNotifyEvent XCBLeaveNotifyEvent;
1841 <li class="subsubtitle"><a name="focus">The keyboard focus</a></li>
1843 There may be many windows on a screen, but only a single
1844 keyboard attached to them. How does the X server then know
1845 which window should be sent a given keyboard input ? This is
1846 done using the keyboard focus. Only a single window on the
1847 screen may have the keyboard focus at a given time. There
1848 is a XCB function that allow a program to set the keyboard
1849 focus to a given window. The user can usually set the
1850 keyboard ficus using the window manager (often by clicking
1851 on the title bar of the desired window). Once our window
1852 has the keyboard focus, every key press or key release will
1853 cause an event to be sent to our program (if it regsitered
1854 for these event types...).
1856 <li class="subsubtitle"><a name="keypress">Keyboard press and release events</a></li>
1858 If a window controlled by our program currently holds the
1859 keyboard focus, it can receive key press and key release
1860 events. So, we should add one (or more) of the following
1861 masks when we create our window:
1864 <li><span class="code">KeyPressMask</span>: notify us when
1865 a key was pressed while any of our controlled windows had
1866 the keyboard focus.</li>
1867 <li><span class="code">KeyReleaseMask</span>: notify us
1868 when a key was released while any of our controlled
1869 windows had the keyboard focus.</li>
1872 The structure to be checked for in our events loop is the
1873 same for these two events, and is the following:
1877 BYTE response_type; /* The type of the event */
1880 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1892 typedef XCBKeyPressEvent XCBKeyReleaseEvent;
1895 The <span class="code">detail</span> field refer to the
1896 physical key on the keyboard.
1899 <b>TODO:</b> Talk about getting the ASCII code from the key code.
1902 <li class="subtitle"><a name="eventex">X events: a complete example</a></li>
1904 As an example for handling events, we show a program that
1905 creates a window, enter an events loop and check for all the
1906 events described above, and write on the terminal the relevant
1907 characteristics of the event. With this code, it should be
1908 easy to add drawing operations, like those which have been
1912 #include <malloc.h>
1913 #include <stdio.h>
1915 #include <X11/XCB/xcb.h>
1918 main (int argc, char *argv[])
1927 /* Open the connection to the X server */
1928 c = XCBConnect (NULL, NULL);
1930 /* Get the first screen */
1931 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
1933 /* Ask for our window's Id */
1934 win.window = XCBWINDOWNew(c);
1936 /* Create the window */
1937 mask = XCBCWBackPixel | XCBCWEventMask;
1938 values[0] = screen->white_pixel;
1939 values[1] = ExposureMask | ButtonPressMask | ButtonReleaseMask |
1940 PointerMotionMask | EnterWindowMask | LeaveWindowMask |
1941 KeyPressMask | KeyReleaseMask;
1942 XCBCreateWindow (c, /* Connection */
1944 win.window, /* window Id */
1945 screen->root, /* parent window */
1947 150, 150, /* width, height */
1948 10, /* border_width */
1949 InputOutput, /* class */
1950 screen->root_visual, /* visual */
1951 mask, values); /* masks */
1953 /* Map the window on the screen */
1954 XCBMapWindow (c, win.window);
1957 while ((e = XCBWaitEvent (c)))
1959 switch (e->response_type)
1963 XCBExposeEvent *ev = (XCBExposeEvent *)e;
1965 printf ("Window %ld exposed. Region to be redrawn at location (%d,%d), with dimension (%d,%d)\n",
1966 ev->window.xid, ev->x, ev->y, ev->width, ev->height);
1969 case XCBButtonPress:
1971 XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
1974 if ((ev->state | Button1Mask) == Button1Mask)
1976 if ((ev->state | Button2Mask) == Button2Mask)
1978 if ((ev->state | Button3Mask) == Button3Mask)
1980 if ((ev->state | Button4Mask) == Button4Mask)
1982 if ((ev->state | Button5Mask) == Button5Mask)
1985 switch (ev->detail.id)
1989 printf ("Wheel Button up in window %ld, at coordinates (%d,%d)\n",
1990 ev->event.xid, ev->event_x, ev->event_y);
1995 printf ("Wheel Button down in window %ld, at coordinates (%d,%d)\n",
1996 ev->event.xid, ev->event_x, ev->event_y);
2000 printf ("Button %d pressed in window %ld, at coordinates (%d,%d)\n",
2001 ev->detail.id, ev->event.xid, ev->event_x, ev->event_y);
2005 case XCBButtonRelease:
2007 XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e;
2010 if ((ev->state | Button1Mask) == Button1Mask)
2012 if ((ev->state | Button2Mask) == Button2Mask)
2014 if ((ev->state | Button3Mask) == Button3Mask)
2016 if ((ev->state | Button4Mask) == Button4Mask)
2018 if ((ev->state | Button5Mask) == Button5Mask)
2021 printf ("Button %d released in window %ld, at coordinates (%d,%d)\n",
2022 ev->detail.id, ev->event.xid, ev->event_x, ev->event_y);
2025 case XCBMotionNotify:
2027 XCBMotionNotifyEvent *ev = (XCBMotionNotifyEvent *)e;
2029 printf ("Mouse moved in window %ld, at coordinates (%d,%d)\n",
2030 ev->event.xid, ev->event_x, ev->event_y);
2033 case XCBEnterNotify:
2035 XCBEnterNotifyEvent *ev = (XCBEnterNotifyEvent *)e;
2037 printf ("Mouse entered window %ld, at coordinates (%d,%d)\n",
2038 ev->event.xid, ev->event_x, ev->event_y);
2041 case XCBLeaveNotify:
2043 XCBLeaveNotifyEvent *ev = (XCBLeaveNotifyEvent *)e;
2045 printf ("Mouse leaved window %ld, at coordinates (%d,%d)\n",
2046 ev->event.xid, ev->event_x, ev->event_y);
2051 XCBKeyPressEvent *ev = (XCBKeyPressEvent *)e;
2053 printf ("Key pressed in window %ld\n",
2059 XCBKeyReleaseEvent *ev = (XCBKeyReleaseEvent *)e;
2061 printf ("Key releaseed in window %ld\n",
2067 /* Unknown event type, ignore it */
2071 /* Free the Generic Event */
2079 <li class="title"><a name="font">Handling text and fonts</a></li>
2081 Besides drawing graphics on a window, we often want to draw
2082 text. Text strings have two major properties: the characters to
2083 be drawn and the font with which they are drawn. In order to
2084 draw text, we need to first request the X server to load a
2085 font. We the assign a font to a Graphic Context, and finally, we
2086 draw the text in a window, using the Graphic Context.
2089 <li class="subtitle"><a name="fontstruct">The Font structure</a></li>
2091 In order to support flexible fonts, a font structure is
2092 defined. You know what ? Its an Id:
2100 It is used to contain information about a font, and is passed
2101 to several functions that handle fonts selection and text drawing.
2104 <li class="title"><a name="wm">Interacting with the window manager</a></li>
2106 After we have seen how to create windows and draw on them, we
2107 take one step back, and look at how our windows are interacting
2108 with their environment (the full screen and the other
2109 windows). First of all, our application needs to interact with
2110 the window manager. The window manager is responsible to
2111 decorating drawn windows (i.e. adding a frame, an iconify
2112 button, a system menu, a title bar, etc), as well as handling
2113 icons shown when windows are being iconified. It also handles
2114 ordering of windows on the screen, and other administrative
2115 tasks. We need to give it various hints as to how we want it to
2116 treat our application's windows.
2119 <li class="subtitle"><a name="wmprop">Window properties</a></li>
2121 Many of the parameters communicated to the window manager are
2122 passed using data called "properties". These properties are
2123 attached by the X server to different windows, and are stores
2124 in a format that makes it possible to read them from different
2125 machines that may use different architectures (remember that
2126 an X client program may run on a remote machine).
2129 The property and its type (a string, an integer, etc) are
2130 Id. Their type are <span class="code">XCBATOM</span>:
2138 To change the property of a window, we use the following
2142 XCBVoidCookie XCBChangeProperty (XCBConnection *c, /* Connection to the X server */
2143 CARD8 mode, /* Property mode */
2144 XCBWINDOW window, /* Window */
2145 XCBATOM property, /* Property to change */
2146 XCBATOM type, /* Type of the property */
2147 CARD8 format, /* Format of the property (8, 16, 32) */
2148 CARD32 data_len, /* Length of the data parameter */
2149 const void *data); /* Data */
2152 The <span class="code">mode</span> parameter coud be one of
2153 the following value (defined in the X.h header file):
2156 <li>PropModeReplace</li>
2157 <li>PropModePrepend</li>
2158 <li>PropModeAppend</li>
2161 <li class="subtitle"><a name="wmname">Setting the window name and icon name</a></li>
2163 The firt thing we want to do would be to set the name for our
2164 window. This is done using the
2165 <span class="code">XCBChangeProperty()</span> function. This
2166 name may be used by the window manager as the title of the
2167 window (in the title bar), in a task list, etc. The property
2168 atom to use to set the name of a window is
2169 <span class="code">WM_NAME</span> (and
2170 <span class="code">WM_ICON_NAME</span> for the iconified
2171 window) and its type is <span class="code">STRING</span>. Here
2172 is an example of utilization:
2175 #include <string.h>
2177 #include <X11/XCB/xcb.h>
2178 #include <X11/XCB/xcb_atom.h>
2181 main (int argc, char *argv[])
2186 char *title = "Hello World !";
2187 char *title_icon = "Hello World ! (iconified)";
2191 /* Open the connection to the X server */
2192 c = XCBConnect (NULL, NULL);
2194 /* Get the first screen */
2195 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2197 /* Ask for our window's Id */
2198 win.window = XCBWINDOWNew(c);
2200 /* Create the window */
2201 XCBCreateWindow (c, /* Connection */
2203 win.window, /* window Id */
2204 screen->root, /* parent window */
2206 250, 150, /* width, height */
2207 10, /* border_width */
2208 InputOutput, /* class */
2209 screen->root_visual, /* visual */
2210 0, NULL); /* masks, not used */
2212 /* Set the title of the window */
2213 XCBChangeProperty(c, PropModeReplace, win.window,
2215 strlen(title), title);
2217 /* Set the title of the window icon */
2218 XCBChangeProperty(c, PropModeReplace, win.window,
2219 WM_ICON_NAME, STRING, 8,
2220 strlen(title_icon), title_icon);
2222 /* Map the window on the screen */
2223 XCBMapWindow (c, win.window);
2233 <p>Note: the use of the atoms needs our program to be compiled
2234 and linked against xcb_atom, so that we have to use
2238 gcc prog.c -o prog `pkg-config --cflags --libs xcb_atom`
2242 for the program to compile fine.
2246 <li class="title"><a name="winop">Simple window operations</a></li>
2248 One more thing we can do to our window is manipulate them on the
2249 screen (resize them, move them, raise or lower them, iconify
2250 them, and so on). Some window operations functions are supplied
2251 by XCB for this purpose.
2254 <li class="subtitle"><a name="winmap">Mapping and un-mapping a window</a></li>
2256 The first pair of operations we can apply on a window is
2257 mapping it, or un-mapping it. Mapping a window causes the
2258 window to appear on the screen, as we have seen in our simple
2259 window program example. Un-mapping it causes it to be removed
2260 from the screen (although the window as a logical entity still
2261 exists). This gives the effect of making a window hidden
2262 (unmapped) and shown again (mapped). For example, if we have a
2263 dialog box window in our program, instead of creating it every
2264 time the user asks to open it, we can create the window once,
2265 in an un-mapped mode, and when the user asks to open it, we
2266 simply map the window on the screen. When the user clicked the
2267 'OK' or 'Cancel' button, we simply un-map the window. This is
2268 much faster than creating and destroying the window, however,
2269 the cost is wasted resources, both on the client side, and on
2273 To map a window, you use the following function:
2276 XCBVoidCookie XCBMapWindow(XCBConnection *c, XCBWINDOW window);
2279 To have a simple example, see the <a href="#helloworld">example</a>
2280 above. The mapping operation will cause an
2281 <span class="code">Expose</span> event to be sent to our
2282 application, unless the window is completely covered by other
2286 Un-mapping a window is also simple. You use the function
2289 XCBVoidCookie XCBUnmapWindow(XCBConnection *c, XCBWINDOW window);
2292 The utilization of this function is the same as
2293 <span class="code">XCBMapWindow()</span>.
2295 <li class="subtitle"><a name="winconf">Configuring a window</a></li>
2297 As we have seen when we have created our first window, in the
2298 X Events subsection, we can set some attributes to the window
2299 (that is, the position, the size, the events the window will
2300 receive, etc). If we want to modify them, but the window is
2301 already created, we can change them by using hte following
2305 XCBVoidCookie XCBConfigureWindow (XCBConnection *c, /* The connection to the X server*/
2306 XCBWINDOW window, /* The window to configure */
2307 CARD16 value_mask, /* The mask */
2308 const CARD32 *value_list); /* The values to set */
2311 We set the <span class="code">value_mask</span> to one or
2312 several mask values that are in the X.h header:
2314 <li><span class="code">CWX</span>: new x coordinate of the window's top left corner</li>
2315 <li><span class="code">CWY</span>: new y coordinate of the window's top left corner</li>
2316 <li><span class="code">CWWidth</span>: new width of the window</li>
2317 <li><span class="code">CWHeight</span>: new height of the window</li>
2318 <li><span class="code">CWBorderWidth</span>: new width of the border of the window</li>
2319 <li><span class="code">CWSibling</span></li>
2320 <li><span class="code">CWStackMode</span>: the new stacking order</li>
2324 We then give to <span class="code">value_mask</span> the new
2325 value. We now describe how to use
2326 <span class="code">XCBConfigureWindow</span> in some useful
2329 <li class="subtitle"><a name="winmove">Moving a window around the screen</a></li>
2331 An operation we might want to do with windows is to move them
2332 to a different location. This can be done like this:
2335 const static CARD32 values[] = { 10, 20 };
2337 /* The connection c and the window win are supposed to be defined */
2339 /* Move the window to coordinates x = 10 and y = 20 */
2340 XCBConfigureWindow (c, win, CWX | CWY, values);
2343 Note that when the window is moved, it might get partially
2344 exposed or partially hidden by other windows, and thus we
2345 might get <span class="code">Expose</span> events due to this
2348 <li class="subtitle"><a name="winsize">Resizing a window</a></li>
2350 Yet another operation we can do is to change the size of a
2351 window. This is done using the following code:
2354 const static CARD32 values[] = { 200, 300 };
2356 /* The connection c and the window win are supposed to be defined */
2358 /* Resize the window to width = 10 and height = 20 */
2359 XCBConfigureWindow (c, win, CWWidth | CWHeight, values);
2362 We can also combine the move and resize operations using one
2363 single call to <span class="code">XCBConfigureWindow</span>:
2366 const static CARD32 values[] = { 10, 20, 200, 300 };
2368 /* The connection c and the window win are supposed to be defined */
2370 /* Move the window to coordinates x = 10 and y = 20 */
2371 /* and resize the window to width = 10 and height = 20 */
2372 XCBConfigureWindow (c, win, CWX | CWY | CWWidth | CWHeight, values);
2374 <li class="subtitle"><a name="winstack">Changing windows stacking order: raise and lower</a></li>
2376 Until now, we changed properties of a single window. We'll see
2377 that there are properties that relate to the window and other
2378 windows. One of hem is the stacking order. That is, the order
2379 in which the windows are layered on top of each other. The
2380 front-most window is said to be on the top of the stack, while
2381 the back-most window is at the bottom of the stack. Here is
2382 how to manipulate our windows stack order:
2385 const static CARD32 values[] = { Above };
2387 /* The connection c and the window win are supposed to be defined */
2389 /* Move the window on the top of the stack */
2390 XCBConfigureWindow (c, win, CWStackMode, values);
2393 const static CARD32 values[] = { Below };
2395 /* The connection c and the window win are supposed to be defined */
2397 /* Move the window on the bottom of the stack */
2398 XCBConfigureWindow (c, win, CWStackMode, values);
2400 <li class="subtitle"><a name="wingetinfo">Getting information about a window</a></li>
2402 Just like we can set various attributes of our windows, we can
2403 also ask the X server supply the current values of these
2404 attributes. For example, we can chewk where a window is
2405 located on the screen, what is its current size, wheter it is
2406 mapped or not, etc. The structure that contains some of this
2412 CARD8 depth; /* depth of the window */
2415 XCBWINDOW root; /* Id of the root window *>
2416 INT16 x; /* X coordinate of the window's location */
2417 INT16 y; /* Y coordinate of the window's location */
2418 CARD16 width; /* Width of the window */
2419 CARD16 height; /* Height of the window */
2420 CARD16 border_width; /* Width of the window's border */
2421 } XCBGetGeometryRep;
2424 XCB fill this structure with two functions:
2427 XCBGetGeometryCookie XCBGetGeometry (XCBConnection *c,
2428 XCBDRAWABLE drawable);
2429 XCBGetGeometryRep *XCBGetGeometryReply (XCBConnection *c,
2430 XCBGetGeometryCookie cookie,
2431 XCBGenericError **e);
2434 You use them as follows:
2439 XCBGetGeometryRep *geom;
2441 /* You initialize c and win */
2443 geom = XCBGetGeometryReply (c, XCBGetGeometry (c, win), 0);
2445 /* Do something with the fields of geom */
2450 Remark that you have to free the structure, as
2451 <span class="code">XCBGetGeometryReply</span> allocates a
2455 One problem is that the returned location of the window is
2456 relative to its parent window. This makes these coordinates
2457 rather useless for any window manipulation functions, like
2458 moving it on the screen. In order to overcome this problem, we
2459 need to take a two-step operation. First, we find out the Id
2460 of the parent window of our window. We then translate the
2461 above relative coordinates to the screen coordinates.
2464 To get the Id of the parent window, we need this structure:
2473 XCBWINDOW parent; /* Id of the parent window */
2474 CARD16 children_len;
2479 To fill this structure, we use these two functions:
2482 XCBQueryTreeCookie XCBQueryTree (XCBConnection *c,
2484 XCBQueryTreeRep *XCBQueryTreeReply (XCBConnection *c,
2485 XCBQueryTreeCookie cookie,
2486 XCBGenericError **e);
2489 The translated coordinates will be found in this structure:
2498 CARD16 dst_x; /* Translated x coordinate */
2499 CARD16 dst_y; /* Translated y coordinate */
2500 } XCBTranslateCoordinatesRep;
2503 As usual, we need two functions to fill this structure:
2506 XCBTranslateCoordinatesCookie XCBTranslateCoordinates (XCBConnection *c,
2507 XCBWINDOW src_window,
2508 XCBWINDOW dst_window,
2511 XCBTranslateCoordinatesRep *XCBTranslateCoordinatesReply (XCBConnection *c,
2512 XCBTranslateCoordinatesCookie cookie,
2513 XCBGenericError **e);
2516 We use them as follows:
2521 XCBGetGeometryRep *geom;
2522 XCBQueryTreeRep *tree;
2523 XCBTranslateCoordinatesRep *trans;
2525 /* You initialize c and win */
2527 geom = XCBGetGeometryReply (c, XCBGetGeometry (c, win), 0);
2531 tree = XCBQueryTreeReply (c, XCBQueryTree (c, win), 0);
2535 trans = XCBTranslateCoordinatesReply (c,
2536 XCBTranslateCoordinates (c,
2539 geom->x, geom->y),
2544 /* the translated coordinates are in trans->dst_x and trans->dst_y */
2551 Of course, as for <span class="code">geom</span>,
2552 <span class="code">tree</span> and
2553 <span class="code">trans</span> have to be freed.
2556 The work is a bit hard, but XCB is a very low-level library.
2559 <b>TODO:</b> the utilization of these functions should be a
2560 prog, which displays the coordinates of the window.
2563 There is another structure that gives informations about our window:
2568 CARD8 backing_store;
2571 XCBVISUALID visual; /* Visual of the window */
2575 CARD32 backing_planes;
2576 CARD32 backing_pixel;
2578 BOOL map_is_installed;
2579 CARD8 map_state; /* Map state of the window */
2580 BOOL override_redirect;
2581 XCBCOLORMAP colormap; /* Colormap of the window */
2582 CARD32 all_event_masks;
2583 CARD32 your_event_mask;
2584 CARD16 do_not_propagate_mask;
2585 } XCBGetWindowAttributesRep;
2588 XCB supplies these two functions to fill it:
2591 XCBGetWindowAttributesCookie XCBGetWindowAttributes (XCBConnection *c,
2593 XCBGetWindowAttributesRep *XCBGetWindowAttributesReply (XCBConnection *c,
2594 XCBGetWindowAttributesCookie cookie,
2595 XCBGenericError **e);
2598 You use them as follows:
2603 XCBGetWindowAttributesRep *attr;
2605 /* You initialize c and win */
2607 attr = XCBGetWindowAttributesReply (c, XCBGetWindowAttributes (c, win), 0);
2612 /* Do something with the fields of attr */
2617 As for <span class="code">geom</span>,
2618 <span class="code">attr</span> has to be freed.
2621 <li class="title"><a name="usecolor">Using colors to paint the rainbow</a></li>
2623 Up until now, all our painting operation were done using black
2624 and white. We will (finally) see now how to draw using colors.
2627 <li class="subtitle"><a name="colormap">Color maps</a></li>
2629 In the beginning, there were not enough colors. Screen
2630 controllers could only support a limited number of colors
2631 simultaneously (initially 2, then 4, 16 and 256). Because of
2632 this, an application could not just ask to draw in a "light
2633 purple-red" color, and expect that color to be available. Each
2634 application allocated the colors it needed, and when all the
2635 color entries (4, 16, 256 colors) were in use, the next color
2636 allocation would fail.
2639 Thus, the notion of "a color map" was introduced. A color map
2640 is a table whose size is the same as the number of
2641 simultaneous colors a given screen controller. Each entry
2642 contained the RGB (Red, Green and Blue) values of a different
2643 color (all colors can be drawn using some combination of red,
2644 green and blue). When an application wants to draw on the
2645 screen, it does not specify which color to use. Rather, it
2646 specifies which color entry of some color map to be used
2647 during this drawing. Change the value in this color map entry
2648 and the drawing will use a different color.
2651 In order to be able to draw using colors that got something to
2652 do with what the programmer intended, color map allocation
2653 functions are supplied. You could ask to allocate entry for a
2654 color with a set of RGB values. If one already existed, you
2655 would get its index in the table. If none existed, and the
2656 table was not full, a new cell would be allocated to contain
2657 the given RGB values, and its index returned. If the table was
2658 full, the procedure would fail. You could then ask to get a
2659 color map entry with a color that is closest to the one you
2660 were asking for. This would mean that the actual drawing on
2661 the screen would be done using colors similar to what you
2662 wanted, but not the same.
2665 On today's more modern screens where one runs an X server with
2666 support for 16 million colors, this limitation looks a little
2667 silly, but remember that there are still older computers with
2668 older graphics cards out there. Using color map, support for
2669 these screen becomes transparent to you. On a display
2670 supporting 16 million colors, any color entry allocation
2671 request would succeed. On a display supporting a limited
2672 number of colors, some color allocation requests would return
2673 similar colors. It won't look as good, but your application
2676 <li class="subtitle"><a name="colormapalloc">Allocating and freeing Color Maps</a></li>
2678 When you draw using XCB, you can choose to use the standard
2679 color map of the screen your window is displayed on, or you
2680 can allocate a new color map and apply it to a window. In the
2681 latter case, each time the mouse moves onto your window, the
2682 screen color map will be replaced by your window's color map,
2683 and you'll see all the other windows on screen change their
2684 colors into something quite bizzare. In fact, this is the
2685 effect you get with X applications that use the "-install"
2686 command line option.
2689 In XCB, a color map is (as often in X) an Id:
2697 In order to access the screen's default color map, you just
2698 have to retrieve the <span class="code">default_colormap</span>
2699 field of the <span class="code">XCBSCREEN</span> structure
2701 <a href="#screen">Checking basic information about a connection</a>):
2704 #include <stdio.h>
2706 #include <X11/XCB/xcb.h>
2709 main (int argc, char *argv[])
2713 XCBCOLORMAP colormap;
2715 /* Open the connection to the X server and get the first screen */
2716 c = XCBConnect (NULL, NULL);
2717 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2719 colormap = screen->default_colormap;
2725 This will return the color map used by default on the first
2726 screen (again, remember that an X server may support several
2727 different screens, each of which might have its own resources).
2730 The other option, that of allocating a new colormap, works as
2731 follows. We first ask the X server to give an Id to our color
2732 map, with this function:
2735 XCBCOLORMAP XCBCOLORMAPNew (XCBConnection *c);
2738 Then, we create the color map with
2741 XCBVoidCookie XCBCreateColormap (XCBConnection *c, /* Pointer to the XCBConnection structure */
2742 BYTE alloc, /* Colormap entries to be allocated (AllocNone or AllocAll) */
2743 XCBCOLORMAP mid, /* Id of the color map */
2744 XCBWINDOW window, /* Window on whose screen the colormap will be created */
2745 XCBVISUALID visual); /* Id of the visual supported by the screen */
2748 Here is an example of creation of a new color map:
2751 #include <X11/XCB/xcb.h>
2754 main (int argc, char *argv[])
2761 /* Open the connection to the X server and get the first screen */
2762 c = XCBConnect (NULL, NULL);
2763 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2765 /* We create the window win here*/
2767 cmap = XCBCOLORMAPNew (c);
2768 XCBCreateColormap (c, AllocNone, cmap, win, screen->root_visual);
2774 Note that the window parameter is only used to allow the X
2775 server to create the color map for the given screen. We can
2776 then use this color map for any window drawn on the same screen.
2779 To free a color map, it suffices to use this function:
2782 XCBVoidCookie XCBFreeColormap (XCBConnection *c, /* The connection */
2783 XCBCOLORMAP cmap); /* The color map */
2791 <li>XCreateColormap ()</li>
2796 <li>XCBCOLORMAPNew ()</li>
2797 <li>XCBCreateColormap ()</li>
2802 <li>XFreeColormap ()</li>
2807 <li>XCBFreeColormap ()</li>
2812 <li class="subtitle"><a name="alloccolor">Allocating and freeing a color entry</a></li>
2814 Once we got access to some color map, we can strat allocating
2815 colors. The informations related to a color are stored in the
2816 following structure:
2824 CARD16 red; /* The red component */
2825 CARD16 green; /* The green component */
2826 CARD16 blue; /* The blue component */
2828 CARD32 pixel; /* The entry in the color map, supplied by the X server */
2832 XCB supplies these two functions to fill it:
2835 XCBAllocColorCookie XCBAllocColor (XCBConnection *c,
2840 XCBAllocColorRep *XCBAllocColorReply (XCBConnection *c,
2841 XCBAllocColorCookie cookie,
2842 XCBGenericError **e);
2845 The fuction <span class="code">XCBAllocColor()</span> takes the
2846 3 RGB components as parameters (red, green and blue). Here is an
2847 example of using these functions:
2850 #include <malloc.h>
2852 #include <X11/XCB/xcb.h>
2855 main (int argc, char *argv[])
2861 XCBAllocColorRep *rep;
2863 /* Open the connection to the X server and get the first screen */
2864 c = XCBConnect (NULL, NULL);
2865 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2867 /* We create the window win here*/
2869 cmap = XCBCOLORMAPNew (c);
2870 XCBCreateColormap (c, AllocNone, cmap, win, screen->root_visual);
2872 rep = XCBAllocColorReply (c, XCBAllocColor (c, cmap, 65535, 0, 0), 0);
2877 /* Do something with r->pixel or the components */
2885 As <span class="code">XCBAllocColorReply()</span> allocates
2886 memory, you have to free <span class="code">rep</span>.
2889 <b>TODO</b>: Talk about freeing colors.
2892 <li class="title"><a name="pixmaps">X Bitmaps and Pixmaps</a></li>
2894 One thing many so-called "Multi-Media" applications need to od,
2895 is display images. In the X world, this is done using bitmaps
2896 and pixmaps. We have already seen some usage of them when
2897 setting an icon for our application. Lets study them further,
2898 and see how to draw these images inside a window, along side the
2899 simple graphics and text we have seen so far.
2902 One thing to note before delving further, is that XCB (nor Xlib)
2903 supplies no means of manipulating popular image formats, such as
2904 gif, png, jpeg or tiff. It is up to the programmer (or to higher
2905 level graphics libraries) to translate these image formats into
2906 formats that the X server is familiar with (x bitmaps and x
2910 <li class="subtitle"><a name="pixmapswhat">What is a X Bitmap ? An X Pixmap ?</a></li>
2912 An X bitmap is a two-color image stored in a format specific
2913 to the X window system. When stored in a file, the bitmap data
2914 looks like a C source file. It contains variables defining the
2915 width and the height of the bitmap, an array containing the
2916 bit values of the bitmap (the size of the array is
2917 weight*height), and an optional hot-spot location (that will
2918 be explained later, when discussing mouse cursors).
2921 An X pixmap is a format used to stored images in the memory of
2922 an X server. This format can store both black and white images
2923 (such as x bitmaps) as well as color images. It is the only
2924 image format supported by the X protocol, and any image to be
2925 drawn on screen, should be first translated into this format.
2928 In actuality, an X pixmap can be thought of as a window that
2929 does not appear on the screen. Many graphics operations that
2930 work on windows, will also work on pixmaps. Indeed, the type
2931 of X pixmap in XCB is an Id like a window:
2939 In order to make the difference between a window and a pixmap,
2940 XCB introduces a drawable type, which is a <b>union</b>
2949 in order to avoid confusion between a window and a pixmap.The
2950 operations that will work indifferently on a window or a pixmap
2951 will require a <span class="code">XCBDRAWABLE</span>
2955 Remark: In Xlib, there is no specific difference between a
2956 <span class="code">Drawable</span>, a
2957 <span class="code">Pixmap</span> or a
2958 <span class="code">Window</span>: all are 32 bit long
2962 <li class="subtitle"><a name="pixmapscreate">Creating a pixmap</a></li>
2964 Sometimes we want to create an un-initialized pixmap, so we
2965 can later draw into it. This is useful for image drawing
2966 programs (creating a new empty canvas will cause the creation
2967 of a new pixmap on which the drawing can be stored). It is
2968 also useful when reading various image formats: we load the
2969 image data into memory, create a pixmap on the server, and
2970 then draw the decoded image data onto that pixmap.
2973 To create a new pixmap, we first ask the X server to give an
2974 Id to our pixmap, with this function:
2977 XCBPIXMAP XCBPIXMAPNew (XCBConnection *c);
2980 Then, XCB supplies the following function to create new pixmaps:
2983 XCBVoidCookie XCBCreatePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
2984 CARD8 depth, /* Depth of the screen */
2985 XCBPIXMAP pid, /* Id of the pixmap */
2986 XCBDRAWABLE drawable,
2987 CARD16 width, /* Width of the window (in pixels) */
2988 CARD16 height); /* Height of the window (in pixels) */
2991 <b>TODO</b>: Explain the drawable parameter, and give an
2992 example (like xpoints.c)
2994 <li class="subtitle"><a name="pixmapsdraw"></a>Drawing a pixmap in a window</li>
2996 Once we got a handle to a pixmap, we can draw it on some
2997 window, using the following function:
3000 XCBVoidCookie XCBCopyArea (XCBConnection *c, /* Pointer to the XCBConnection structure */
3001 XCBDRAWABLE src_drawable, /* The Drawable we want to paste */
3002 XCBDRAWABLE dst_drawable, /* The Drawable on which we copy the previous Drawable */
3003 XCBGCONTEXT gc, /* A Graphic Context */
3004 INT16 src_x, /* Top left x coordinate of the region we want to copy */
3005 INT16 src_y, /* Top left y coordinate of the region we want to copy */
3006 INT16 dst_x, /* Top left x coordinate of the region where we want to copy */
3007 INT16 dst_y, /* Top left y coordinate of the region where we want to copy */
3008 CARD16 width, /* Width of the region we want to copy */
3009 CARD16 height); /* Height of the region we want to copy */
3012 As you can see, we could copy the whole pixmap, as well as
3013 only a given rectangle of the pixmap. This is useful to
3014 optimize the drawing speed: we could copy only what we have
3015 modified in the pixmap.
3018 <b>One important note should be made</b>: it is possible to
3019 create pixmaps with different depths on the same screen. When
3020 we perform copy operations (a pixmaap onto a window, etc), we
3021 should make sure that both source and target have the same
3022 depth. If they have a different depth, the operation would
3023 fail. The exception to this is if we copy a specific bit plane
3024 of the source pixmap using the
3025 <span class="code">XCBCopyPlane</span> function. In such an
3026 event, we can copy a specific plain to the target window (in
3027 actuality, setting a specific bit in the color of each pixel
3028 copied). This can be used to generate strange graphic effects
3029 in widow, but beyond the scope of this tutorial.
3031 <li class="subtitle"><a name="pixmapsfree"></a>Freeing a pixmap</li>
3033 Finally, when we are done using a given pixmap, we should free
3034 it, in order to free resources of the X server. This is done
3035 using this function:
3038 XCBVoidCookie XCBFreePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
3039 XCBPIXMAP pixmap); /* A given pixmap */
3042 Of course, after having freed it, we must not try accessing
3046 <b>TODO</b>: Give an example, or a link to xpoints.c
3049 <li class="title"><a name="translation">Translation of basic Xlib functions and macros</a></li>
3051 The problem when you want to port an Xlib program to XCB is that
3052 you don't know if the Xlib function that you want to "translate"
3053 is a X Window one or an Xlib macro. In that section, we describe
3054 a way to translate the usual functions or macros that Xlib
3055 provides. It's usually just a member of a structure.
3058 <li class="subtitle"><a name="displaystructure">Members of the Display structure</a></li>
3059 In this section, we look at how to translate the macros that
3060 returns some members of the <span class="code">Display</span>
3061 structure. They are obtain by using a function that requires a
3062 <span class="code">XCBConnection *</span> or a member of the
3063 <span class="code">XCBConnSetupSuccessRep</span> structure
3064 (via the function <span class="code">XCBGetSetup</span>), or
3065 a function that requires that structure.
3067 <li class="subtitle"><a name="ConnectionNumber">ConnectionNumber</a></li>
3069 This number is the file descriptor that connects the client
3070 to the server. You just have to use that function:
3073 int XCBGetFileDescriptor(XCBConnection *c);
3075 <li class="subtitle"><a name="DefaultScreen"></a>DefaultScreen</li>
3077 That number is not stored by XCB. It is returned in the
3078 second parameter of the function <span class="code"><a href="#openconn">XCBConnect</a></span>.
3079 Hence, you have to store it yourself if you want to use
3080 it. Then, to get the <span class="code">XCBSCREEN</span>
3081 structure, you have to iterate on the screens.
3082 The equivalent function of the Xlib's
3083 <span class="code">ScreenOfDisplay</span> function can be
3084 found <a href="#ScreenOfDisplay">below</a>. OK, here is the
3085 small piece of code to get that number:
3089 int screen_default_nbr;
3091 /* you pass the name of the display you want to XCBConnect */
3093 c = XCBConnect (display_name, &screen_default_nbr);
3095 /* screen_default_nbr contains now the number of the default screen */
3097 <li class="subtitle"><a name="QLength"></a>QLength</li>
3101 <li class="subtitle"><a name="ScreenCount"></a>ScreenCount</li>
3103 You get the count of screens with the functions
3104 <span class="code">XCBGetSetup</span>
3106 <span class="code">XCBConnSetupSuccessRepRootsIter</span>
3107 (if you need to iterate):
3113 /* you init the connection */
3115 screen_count = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).rem;
3117 /* screen_count contains now the count of screens */
3120 If you don't want to iterate over the screens, a better way
3121 to get that number is to use
3122 <span class="code">XCBConnSetupSuccessRepRootsLength</span>:
3128 /* you init the connection */
3130 screen_count = XCBConnSetupSuccessRepRootsLength (XCBGetSetup (c));
3132 /* screen_count contains now the count of screens */
3134 <li class="subtitle"><a name="ServerVendor"></a>ServerVendor</li>
3136 You get the name of the vendor of the server hardware with
3137 the functions <span class="code">XCBGetSetup</span>
3140 class="code">XCBConnSetupSuccessRepVendor</span>. Beware
3141 that, unlike Xlib, the string returned by XCB is not
3142 necessarily null-terminaled:
3146 char *vendor = NULL;
3149 /* you init the connection */
3150 length = XCBConnSetupSuccessRepVendorLength (XCBGetSetup (c));
3151 vendor = (char *)malloc (length + 1);
3153 memcpy (vendor, XCBConnSetupSuccessRepVendor (XCBGetSetup (c)), length);
3154 vendor[length] = '\0';
3156 /* vendor contains now the name of the vendor. Must be freed when not used anymore */
3158 <li class="subtitle"><a name="ProtocolVersion"></a>ProtocolVersion</li>
3160 You get the major version of the protocol in the
3161 <span class="code">XCBConnSetupSuccessRep</span>
3162 structure, with the function <span class="code">XCBGetSetup</span>:
3166 CARD16 protocol_major_version;
3168 /* you init the connection */
3170 protocol_major_version = XCBGetSetup (c)->protocol_major_version;
3172 /* protocol_major_version contains now the major version of the protocol */
3174 <li class="subtitle"><a name="ProtocolRevision"></a>ProtocolRevision</li>
3176 You get the minor version of the protocol in the
3177 <span class="code">XCBConnSetupSuccessRep</span>
3178 structure, with the function <span class="code">XCBGetSetup</span>:
3182 CARD16 protocol_minor_version;
3184 /* you init the connection */
3186 protocol_minor_version = XCBGetSetup (c)->protocol_minor_version;
3188 /* protocol_minor_version contains now the minor version of the protocol */
3190 <li class="subtitle"><a name="VendorRelease"></a>VendorRelease</li>
3192 You get the number of the release of the server hardware in the
3193 <span class="code">XCBConnSetupSuccessRep</span>
3194 structure, with the function <span class="code">XCBGetSetup</span>:
3198 CARD32 release_number;
3200 /* you init the connection */
3202 release_number = XCBGetSetup (c)->release_number;
3204 /* release_number contains now the number of the release of the server hardware */
3206 <li class="subtitle"><a name="DisplayString"></a>DisplayString</li>
3208 The name of the display is not stored in XCB. You have to
3209 store it by yourself.
3211 <li class="subtitle"><a name="BitmapUnit"></a>BitmapUnit</li>
3213 You get the bitmap scanline unit in the
3214 <span class="code">XCBConnSetupSuccessRep</span>
3215 structure, with the function <span class="code">XCBGetSetup</span>:
3219 CARD8 bitmap_format_scanline_unit;
3221 /* you init the connection */
3223 bitmap_format_scanline_unit = XCBGetSetup (c)->bitmap_format_scanline_unit;
3225 /* bitmap_format_scanline_unit contains now the bitmap scanline unit */
3227 <li class="subtitle"><a name="BitmapBitOrder"></a>BitmapBitOrder</li>
3229 You get the bitmap bit order in the
3230 <span class="code">XCBConnSetupSuccessRep</span>
3231 structure, with the function <span class="code">XCBGetSetup</span>:
3235 CARD8 bitmap_format_bit_order;
3237 /* you init the connection */
3239 bitmap_format_bit_order = XCBGetSetup (c)->bitmap_format_bit_order;
3241 /* bitmap_format_bit_order contains now the bitmap bit order */
3243 <li class="subtitle"><a name="BitmapPad"></a>BitmapPad</li>
3245 You get the bitmap scanline pad in the
3246 <span class="code">XCBConnSetupSuccessRep</span>
3247 structure, with the function <span class="code">XCBGetSetup</span>:
3251 CARD8 bitmap_format_scanline_pad;
3253 /* you init the connection */
3255 bitmap_format_scanline_pad = XCBGetSetup (c)->bitmap_format_scanline_pad;
3257 /* bitmap_format_scanline_pad contains now the bitmap scanline pad */
3259 <li class="subtitle"><a name="ImageByteOrder"></a>ImageByteOrder</li>
3261 You get the image byte order in the
3262 <span class="code">XCBConnSetupSuccessRep</span>
3263 structure, with the function <span class="code">XCBGetSetup</span>:
3267 CARD8 image_byte_order;
3269 /* you init the connection */
3271 image_byte_order = XCBGetSetup (c)->image_byte_order;
3273 /* image_byte_order contains now the image byte order */
3276 <li class="subtitle"><a name="screenofdisplay">ScreenOfDisplay related functions</a></li>
3278 in Xlib, <span class="code">ScreenOfDisplay</span> returns a
3279 <span class="code">Screen</span> structure that contains
3280 several characteristics of your screen. XCB has a similar
3281 structure (<span class="code">XCBSCREEN</span>),
3282 but the way to obtain it is a bit different. With
3283 Xlib, you just provide the number of the screen and you grab it
3284 from an array. With XCB, you iterate over all the screens to
3285 obtain the one you want. The complexity of this operation is
3286 O(n). So the best is to store this structure if you often use
3287 it. See <a href="#ScreenOfDisplay">ScreenOfDisplay</a> just below.
3290 Xlib provides generally two functions to obtain the characteristics
3291 related to the screen. One with the display and the number of
3292 the screen, which calls <span class="code">ScreenOfDisplay</span>,
3293 and the other that uses the <span class="code">Screen</span> structure.
3294 This might be a bit confusing. As mentioned above, with XCB, it
3295 is better to store the <span class="code">XCBSCREEN</span>
3296 structure. Then, you have to read the members of this
3297 structure. That's why the Xlib functions are put by pairs (or
3298 more) as, with XCB, you will use the same code.
3301 <li class="subtitle"><a name="ScreenOfDisplay">ScreenOfDisplay</a></li>
3303 This function returns the Xlib <span class="code">Screen</span>
3304 structure. With XCB, you iterate over all thee screens and
3305 once you get the one you want, you return it:
3307 <pre class="code"><a name="ScreenOfDisplay"></a>
3308 XCBSCREEN *ScreenOfDisplay (XCBConnection *c,
3313 iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
3314 for (; iter.rem; --screen, XCBSCREENNext (&iter))
3322 As mentioned above, you might want to store the value
3323 returned by this function.
3326 All the functions below will use the result of that
3327 fonction, as they just grab a specific member of the
3328 <span class="code">XCBSCREEN</span> structure.
3330 <li class="subtitle"><a name="DefaultScreenOfDisplay"></a>DefaultScreenOfDisplay</li>
3332 It is the default screen that you obtain when you connect to
3333 the X server. It suffices to call the <a href="#ScreenOfDisplay">ScreenOfDisplay</a>
3334 function above with the connection and the number of the
3339 int screen_default_nbr;
3340 XCBSCREEN *default_screen; /* the returned default screen */
3342 /* you pass the name of the display you want to XCBConnect */
3344 c = XCBConnect (display_name, &screen_default_nbr);
3345 default_screen = ScreenOfDisplay (c, screen_default_nbr);
3347 /* default_screen contains now the default root window, or a NULL window if no screen is found */
3349 <li class="subtitle"><a name="RootWindow">RootWindow / RootWindowOfScreen</a></li>
3356 XCBWINDOW root_window = { 0 }; /* the returned window */
3358 /* you init the connection and screen_nbr */
3360 screen = ScreenOfDisplay (c, screen_nbr);
3362 root_window = screen->root;
3364 /* root_window contains now the root window, or a NULL window if no screen is found */
3366 <li class="subtitle"><a name="DefaultRootWindow">DefaultRootWindow</a></li>
3368 It is the root window of the default screen. So, you call
3369 <a name="ScreenOfDisplay">ScreenOfDisplay</a> with the
3370 default screen number and you get the
3371 <a href="#RootWindow">root window</a> as above:
3376 int screen_default_nbr;
3377 XCBWINDOW root_window = { 0 }; /* the returned root window */
3379 /* you pass the name of the display you want to XCBConnect */
3381 c = XCBConnect (display_name, &screen_default_nbr);
3382 screen = ScreenOfDisplay (c, screen_default_nbr);
3384 root_window = screen->root;
3386 /* root_window contains now the default root window, or a NULL window if no screen is found */
3388 <li class="subtitle"><a name="DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a></li>
3390 While a Visual is, in Xlib, a structure, in XCB, there are
3391 two types: <span class="code">XCBVISUALID</span>, which is
3392 the Id of the visual, and <span class="code">XCBVISUALTYPE</span>,
3393 which corresponds to the Xlib Visual. To get the Id of the
3394 visual of a screen, just get the
3395 <span class="code">root_visual</span>
3396 member of a <span class="code">XCBSCREEN</span>:
3402 XCBVISUALID root_visual = { 0 }; /* the returned visual Id */
3404 /* you init the connection and screen_nbr */
3406 screen = ScreenOfDisplay (c, screen_nbr);
3408 root_visual = screen->root_visual;
3410 /* root_visual contains now the value of the Id of the visual, or a NULL visual if no screen is found */
3413 To get the <span class="code">XCBVISUALTYPE</span>
3414 structure, it's a bit less easier. You have to get the
3415 <span class="code">XCBSCREEN</span> structure that you want,
3416 get its <span class="code">root_visual</span> member,
3417 then iterate on the <span class="code">XCBDEPTH</span>s
3418 and the <span class="code">XCBVISUALTYPE</span>s, and compare
3419 the <span class="code">XCBVISUALID</span> of these <span class="code">XCBVISUALTYPE</span>s:
3420 with <span class="code">root_visual</span>:
3426 XCBVISUALID root_visual = { 0 };
3427 XCBVISUATYPE *visual_type = NULL; /* the returned visual type */
3429 /* you init the connection and screen_nbr */
3431 screen = ScreenOfDisplay (c, screen_nbr);
3434 XCBDEPTHIter depth_iter;
3436 depth_iter = XCBSCREENAllowedDepthsIter (screen);
3437 for (; depth_iter.rem; XCBDEPTHNext (&depth_iter))
3439 XCBVISUALTYPEIter visual_iter;
3441 visual_iter = XCBDEPTHVisualsIter (depth_iter.data);
3442 for (; visual_iter.rem; XCBVISUALTYPENext (&visual_iter))
3444 if (screen->root_visual.id == visual_iter.data->visual_id.id)
3446 visual_type = visual_iter.data;
3453 /* visual_type contains now the visual structure, or a NULL visual structure if no screen is found */
3455 <li class="subtitle"><a name="DefaultGC">DefaultGC / DefaultGCOfScreen</a></li>
3457 This default Graphic Context is just a newly created Graphic
3458 Context, associated to the root window of a
3459 <span class="code">XCBSCREEN</span>,
3460 using the black white pixels of that screen:
3466 XCBGCONTEXT gc = { 0 }; /* the returned default graphic context */
3468 /* you init the connection and screen_nbr */
3470 screen = ScreenOfDisplay (c, screen_nbr);
3477 gc = XCBGCONTEXTNew (c);
3478 draw.window = screen->root;
3479 mask = GCForeground | GCBackground;
3480 values[0] = screen->black_pixel;
3481 values[1] = screen->white_pixel;
3482 XCBCreateGC (c, gc, draw, mask, values);
3485 /* gc contains now the default graphic context */
3487 <li class="subtitle"><a name="BlackPixel">BlackPixel / BlackPixelOfScreen</a></li>
3489 It is the Id of the black pixel, which is in the structure
3490 of an <span class="code">XCBSCREEN</span>.
3496 CARD32 black_pixel = 0; /* the returned black pixel */
3498 /* you init the connection and screen_nbr */
3500 screen = ScreenOfDisplay (c, screen_nbr);
3502 black_pixel = screen->black_pixel;
3504 /* black_pixel contains now the value of the black pixel, or 0 if no screen is found */
3506 <li class="subtitle"><a name="WhitePixel">WhitePixel / WhitePixelOfScreen</a></li>
3508 It is the Id of the white pixel, which is in the structure
3509 of an <span class="code">XCBSCREEN</span>.
3515 CARD32 white_pixel = 0; /* the returned white pixel */
3517 /* you init the connection and screen_nbr */
3519 screen = ScreenOfDisplay (c, screen_nbr);
3521 white_pixel = screen->white_pixel;
3523 /* white_pixel contains now the value of the white pixel, or 0 if no screen is found */
3525 <li class="subtitle"><a name="DisplayWidth">DisplayWidth / WidthOfScreen</a></li>
3527 It is the width in pixels of the screen that you want, and
3528 which is in the structure of the corresponding
3529 <span class="code">XCBSCREEN</span>.
3535 CARD32 width_in_pixels = 0; /* the returned width in pixels */
3537 /* you init the connection and screen_nbr */
3539 screen = ScreenOfDisplay (c, screen_nbr);
3541 width_in_pixels = screen->width_in_pixels;
3543 /* width_in_pixels contains now the width in pixels, or 0 if no screen is found */
3545 <li class="subtitle"><a name="DisplayHeight">DisplayHeight / HeightOfScreen</a></li>
3547 It is the height in pixels of the screen that you want, and
3548 which is in the structure of the corresponding
3549 <span class="code">XCBSCREEN</span>.
3555 CARD32 height_in_pixels = 0; /* the returned height in pixels */
3557 /* you init the connection and screen_nbr */
3559 screen = ScreenOfDisplay (c, screen_nbr);
3561 height_in_pixels = screen->height_in_pixels;
3563 /* height_in_pixels contains now the height in pixels, or 0 if no screen is found */
3565 <li class="subtitle"><a name="DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a></li>
3567 It is the width in millimeters of the screen that you want, and
3568 which is in the structure of the corresponding
3569 <span class="code">XCBSCREEN</span>.
3575 CARD32 width_in_millimeters = 0; /* the returned width in millimeters */
3577 /* you init the connection and screen_nbr */
3579 screen = ScreenOfDisplay (c, screen_nbr);
3581 width_in_millimeters = screen->width_in_millimeters;
3583 /* width_in_millimeters contains now the width in millimeters, or 0 if no screen is found */
3585 <li class="subtitle"><a name="DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a></li>
3587 It is the height in millimeters of the screen that you want, and
3588 which is in the structure of the corresponding
3589 <span class="code">XCBSCREEN</span>.
3595 CARD32 height_in_millimeters = 0; /* the returned height in millimeters */
3597 /* you init the connection and screen_nbr */
3599 screen = ScreenOfDisplay (c, screen_nbr);
3601 height_in_millimeters = screen->height_in_millimeters;
3603 /* height_in_millimeters contains now the height in millimeters, or 0 if no screen is found */
3605 <li class="subtitle"><a name="DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a></li>
3607 It is the depth (in bits) of the root window of the
3608 screen. You get it from the <span class="code">XCBSCREEN</span> structure.
3614 CARD8 root_depth = 0; /* the returned depth of the root window */
3616 /* you init the connection and screen_nbr */
3618 screen = ScreenOfDisplay (c, screen_nbr);
3620 root_depth = screen->root_depth;
3622 /* root_depth contains now the depth of the root window, or 0 if no screen is found */
3624 <li class="subtitle"><a name="DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a></li>
3626 This is the default colormap of the screen (and not the
3627 (default) colormap of the default screen !). As usual, you
3628 get it from the <span class="code">XCBSCREEN</span> structure:
3634 XCBCOLORMAP default_colormap = { 0 }; /* the returned default colormap */
3636 /* you init the connection and screen_nbr */
3638 screen = ScreenOfDisplay (c, screen_nbr);
3640 default_colormap = screen->default_colormap;
3642 /* default_colormap contains now the default colormap, or a NULL colormap if no screen is found */
3644 <li class="subtitle"><a name="MinCmapsOfScreen"></a>MinCmapsOfScreen</li>
3646 You get the minimum installed colormaps in the <span class="code">XCBSCREEN</span> structure:
3652 CARD16 min_installed_maps = 0; /* the returned minimum installed colormaps */
3654 /* you init the connection and screen_nbr */
3656 screen = ScreenOfDisplay (c, screen_nbr);
3658 min_installed_maps = screen->min_installed_maps;
3660 /* min_installed_maps contains now the minimum installed colormaps, or 0 if no screen is found */
3662 <li class="subtitle"><a name="MaxCmapsOfScreen"></a>MaxCmapsOfScreen</li>
3664 You get the maximum installed colormaps in the <span class="code">XCBSCREEN</span> structure:
3670 CARD16 max_installed_maps = 0; /* the returned maximum installed colormaps */
3672 /* you init the connection and screen_nbr */
3674 screen = ScreenOfDisplay (c, screen_nbr);
3676 max_installed_maps = screen->max_installed_maps;
3678 /* max_installed_maps contains now the maximum installed colormaps, or 0 if no screen is found */
3680 <li class="subtitle"><a name="DoesSaveUnders"></a>DoesSaveUnders</li>
3682 You know if <span class="code">save_unders</span> is set,
3683 by looking in the <span class="code">XCBSCREEN</span> structure:
3689 BOOL save_unders = 0; /* the returned value of save_unders */
3691 /* you init the connection and screen_nbr */
3693 screen = ScreenOfDisplay (c, screen_nbr);
3695 save_unders = screen->save_unders;
3697 /* save_unders contains now the value of save_unders, or FALSE if no screen is found */
3699 <li class="subtitle"><a name="DoesBackingStore"></a>DoesBackingStore</li>
3701 You know the value of <span class="code">backing_stores</span>,
3702 by looking in the <span class="code">XCBSCREEN</span> structure:
3708 BYTE backing_stores = 0; /* the returned value of backing_stores */
3710 /* you init the connection and screen_nbr */
3712 screen = ScreenOfDisplay (c, screen_nbr);
3714 backing_stores = screen->backing_stores;
3716 /* backing_stores contains now the value of backing_stores, or FALSE if no screen is found */
3718 <li class="subtitle"><a name="EventMaskOfScreen"></a>EventMaskOfScreen</li>
3720 To get the current input masks,
3721 you look in the <span class="code">XCBSCREEN</span> structure:
3727 CARD32 current_input_masks = 0; /* the returned value of current input masks */
3729 /* you init the connection and screen_nbr */
3731 screen = ScreenOfDisplay (c, screen_nbr);
3733 current_input_masks = screen->current_input_masks;
3735 /* current_input_masks contains now the value of the current input masks, or FALSE if no screen is found */
3738 <li class="subtitle"><a name="misc">Miscellaneous macros</a></li>
3740 <li class="subtitle"><a name="DisplayOfScreen"></a>DisplayOfScreen</li>
3742 in Xlib, the <span class="code">Screen</span> structure
3743 stores its associated <span class="code">Display</span>
3744 structure. This is not the case in the X Window protocol,
3745 hence, it's also not the case in XCB. So you have to store
3748 <li class="subtitle"><a name="DisplayCells"></a>DisplayCells / CellsOfScreen</li>
3750 To get the colormap entries,
3751 you look in the <span class="code">XCBVISUALTYPE</span>
3752 structure, that you grab like <a class="subsection" href="#DefaultVisual">here</a>:
3756 XCBVISUALTYPE *visual_type;
3757 CARD16 colormap_entries = 0; /* the returned value of the colormap entries */
3759 /* you init the connection and visual_type */
3762 colormap_entries = visual_type->colormap_entries;
3764 /* colormap_entries contains now the value of the colormap entries, or FALSE if no screen is found */