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. keep in mind that XCB, like the
171 <a href="http://tronche.com/gui/x/xlib/introduction">Xlib</a>
172 library, isn't what post programmers wanting to write X
173 applications are looking for. They should use a much higher
174 level GUI toolkit like Motif,
175 <a href="http://www.lesstif.org">LessTiff</a>,
176 <a href="http://www.gtk.org">GTK</a>,
177 <a href="http://www.trolltech.com">QT</a> or
178 <a href="http://www.enlightenment.org">EWL</a>, or use
179 <a href="http://cairographics.org">Cairo</a>.
181 we need to start somewhere. More than this, knowing how things
182 work down below is never a bad idea.
185 After reading this tutorial, one should be able to write very
186 simple graphical programs, but not programs with descent user
187 interfaces. For such programs, one of the previously mentioned
188 library should be used.
191 But what is XCB? Xlib has been
192 the standard C binding for the <a href="http://www.xfree86.org">X
193 Window System</a> protocol for many years now. It is an
194 excellent piece of work, but there are applications for which it
195 is not ideal, for example
197 <li><b>Small platforms</b>: Xlib is a large piece of code, and
198 it's difficult to make it smaller</li>
199 <li><b>Latency hiding</b>: Xlib requests requiring a reply are
200 effectively synchronous: they block until the reply appears,
201 whether the result is needed immediately or not.</li>
202 <li><b>Direct access to the protocol</b>: Xlib does quite a
203 bit of caching, layering, and similar optimizations. While this
204 is normally a feature, it makes it difficult to simply emit
205 specified X protocol requests and process specific
207 <li><b>Threaded applications</b>: While Xlib does attempt to
208 support multithreading, the API makes this difficult and
210 <li><b>New extensions</b>: The Xlib infrastructure provides
211 limited support for the new creation of X extension client side
216 For these reasons, among others, XCB, an X C binding, has been
217 designed to solve the above problems and thus provide a base for
219 <li>Toolkit implementation.</li>
220 <li>Direct protocol-level programming.</li>
221 <li>Lightweight emulation of commonly used portions of the
222 Xlib API (in progress)</li>
226 <li class="title"><a name="Xmodel">The client and server model of the X window system</a></li>
228 The X Window System was developed with one major goal:
229 flexibility. The idea was that the way things look is one thing,
230 but the way things work is another matter. Thus, the lower
231 levels provide the tools required to draw windows, handle user
232 input, allow drawing graphics using colors (or black and white
233 screens), etc. To this point, a decision was made to separate
234 the system into two parts. A client that decides what to do, and
235 a server that actually draws on the screen and reads user input
236 in order to send it to the client for processing.
239 This model is the complete opposite of what is used to when
240 dealing with clients and servers. In our case, the user seats
241 near the machine controlled by the server, while the client
242 might be running on a remote machine. The server controls the
243 screens, mouse and keyboard. A client may connect to the server,
244 request that it draws a window (or several windows), and ask the
245 server to send it any input the user sends to these
246 windows. Thus, several clients may connect to a single X server
247 (one might be running an mail software, one running a WWW
248 browser, etc). When input is sent by the user to some window,
249 the server sends a message to the client controlling this window
250 for processing. The client decides what to do with this input,
251 and sends the server requests for drawing in the window.
254 The whole session is carried out using the X message
255 protocol. This protocol was originally carried over the TCP/IP
256 protocol suite, allowing the client to run on any machine
257 connected to the same network that the server is. Later on, the
258 X servers were extended to allow clients running on the local
259 machine with more optimized access to the server (note that an X
260 protocol message may be several hundreds of KB in size), such as
261 using shared memory, or using Unix domain sockets (a method for
262 creating a logical channel on a Unix system between two processes).
264 <li class="title"><a name="asynch">GUI programming: the asynchronous model</a></li>
266 Unlike conventional computer programs, that carry some serial
267 nature, a GUI program usually uses an asynchronous programming
268 model, also known as "event-driven programming". This means that
269 that program mostly sits idle, waiting for events sent by the X
270 server, and then acts upon these events. An event may say "The
271 user pressed the 1st button mouse in spot (x,y)", or "The window
272 you control needs to be redrawn". In order for the program to be
273 responsive to the user input, as well as to refresh requests, it
274 needs to handle each event in a rather short period of time
275 (e.g. less that 200 milliseconds, as a rule of thumb).
278 This also implies that the program may not perform operations
279 that might take a long time while handling an event (such as
280 opening a network connection to some remote server, or
281 connecting to a database server, or even performing a long file
282 copy operation). Instead, it needs to perform all these
283 operations in an asynchronous manner. This may be done by using
284 various asynchronous models to perform the longish operations,
285 or by performing them in a different process or thread.
288 So the way a GUI program looks is something like that:
290 <li>Perform initialization routines.</li>
291 <li>Connect to the X server.</li>
292 <li>Perform X-related initialization.</li>
293 <li>While not finished:</li>
295 <li>Receive the next event from the X server.</li>
296 <li>Handle the event, possibly sending various drawing
297 requests to the X server.</li>
298 <li>If the event was a quit message, exit the loop.</li>
300 <li>Close down the connection to the X server. </li>
301 <li>Perform cleanup operations.</li>
305 <li class="title"><a name="notions">Basic XCB notions</a></li>
307 XCB has been created to eliminate the needs of
308 programs to actually implement the X protocol layer. This
309 library gives a program a very low-level access to any X
310 server. Since the protocol is standardized, a client using any
311 implementation of XCB may talk with any X server (the same
312 occurs for Xlib, of course). We now give a brief description of
313 the basic XCB notions. They will be detailed later.
316 <li class="subtitle"><a name="conn">The X Connection</a></li>
318 The major notion of using XCB is the X Connection. This is a
319 structure representing the connection we have open with a
320 given X server. It hides a queue of messages coming from the
321 server, and a queue of pending requests that our client
322 intends to send to the server. In XCB, this structure is named
323 'XCBConnection'. When we open a connection to an X server, the
324 library returns a pointer to such a structure. Later, we
325 supply this pointer to any XCB function that should send
326 messages to the X server or receive messages from this server.
328 <li class="subtitle"><a name="requestsreplies">Requests and
329 replies: the Xlib killers</a></li>
331 To ask informations to the X server, we have to make a request
332 and ask for a reply. With Xlib, these two tasks are
333 automatically done: Xlib locks the system, sends a request,
334 waits for a reply from the X server and unlocks. This is
335 annoying, especially if one makes a lot of requests to the X
336 server. Indeed, Xlib has to wait for the end of a reply
337 before asking for the next request (because of the locks that
338 Xlib sends). For example, here is a time-line of N=4
339 requests/replies with Xlib, with a round-trip latency
340 <b>T_round_trip</b> that is 5 times long as the time required
341 to write or read a request/reply (<b>T_write/T_read</b>):
344 W-----RW-----RW-----RW-----R
347 <li>W: Writing request</li>
348 <li>-: Stalled, waiting for data</li>
349 <li>R: Reading reply</li>
352 The total time is N * (T_write + T_round_trip + T_read).
355 With XCB, we can suppress most of the round-trips as the
356 requests and the replies are not locked. We usually send a
357 request, then XCB returns to us a <b>cookie</b>, which is an
358 identifier. Then, later, we ask for a reply using this
359 <b>cookie</b> and XCB returns a
360 pointer to that reply. Hence, with XCB, we can send a lot of
361 requests, and later in the program, ask for all the replies
362 when we need them. Here is the time-line for 4
363 requests/replies when we use this property of XCB:
369 The total time is N * T_write + max (0, T_round_trip - (N-1) *
370 T_write) + N * T_read. Which can be considerably faster than
371 all those Xlib round-trips.
374 Here is a program that computes the time to create 500 atoms
375 with Xlib and XCB. It shows the Xlib way, the bad XCB way
376 (which is similar to Xlib) and the good XCB way. On my
377 computer, XCB is 25 times faster than Xlib.
380 #include <stdlib.h>
381 #include <stdio.h>
382 #include <string.h>
383 #include <sys/time.h>
385 #include <X11/XCB/xcb.h>
387 #include <X11/Xlib.h>
392 struct timeval timev;
394 gettimeofday(&timev, NULL);
396 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
404 XCBInternAtomCookie *cs;
417 c = XCBConnectBasic ();
420 atoms = (XCBATOM *)malloc (count * sizeof (atoms));
421 names = (char **)malloc (count * sizeof (char *));
424 for (i = 0; i < count; ++i)
428 sprintf (buf, "NAME%d", i);
429 names[i] = strdup (buf);
435 for (i = 0; i < count; ++i)
436 atoms[i] = XCBInternAtomReply (c,
445 printf ("bad use time : %f\n", diff);
450 cs = (XCBInternAtomCookie *) malloc (count * sizeof(XCBInternAtomCookie));
451 for(i = 0; i < count; ++i)
452 cs[i] = XCBInternAtom (c, 0, strlen(names[i]), names[i]);
454 for(i = 0; i < count; ++i)
458 r = XCBInternAtomReply(c, cs[i], 0);
465 printf ("good use time : %f\n", end - start);
466 printf ("ratio : %f\n", diff / (end - start));
470 for (i = 0; i < count; ++i)
480 disp = XOpenDisplay (getenv("DISPLAY"));
482 atoms_x = (Atom *)malloc (count * sizeof (atoms_x));
486 for (i = 0; i < count; ++i)
487 atoms_x[i] = XInternAtom(disp, names[i], 0);
490 diff_x = end - start;
491 printf ("Xlib use time : %f\n", diff_x);
492 printf ("ratio : %f\n", diff_x / diff);
497 XCloseDisplay (disp);
502 <li class="subtitle"><a name="gc">The Graphic Context</a></li>
504 When we perform various drawing operations (graphics, text,
505 etc), we may specify various options for controlling how the
506 data will be drawn (what foreground and background colors to
507 use, how line edges will be connected, what font to use when
508 drawing some text, etc). In order to avoid the need to supply
509 hundreds of parameters to each drawing function, a graphical
510 context structure is used. We set the various drawing options
511 in this structure, and then we pass a pointer to this
512 structure to any drawing routines. This is rather handy, as we
513 often need to perform several drawing requests with the same
514 options. Thus, we would initialize a graphical context, set
515 the desired options, and pass this structure to all drawing
519 Note that graphic contexts have no client-side structure in
520 XCB, they're just XIDs. Xlib has a client-side structure
521 because it caches the GC contents so it can avoid making
522 redundant requests, but of course XCB doesn't do that.
524 <li class="subtitle"><a name="events">Events</a></li>
526 A structure is used to pass events received from the X
527 server. XCB supports exactly the events specified in the
528 protocol (33 events). This structure contains the type
529 of event received, as well as the data associated with the
530 event (e.g. position on the screen where the event was
531 generated, mouse button associated with the event, region of
532 the screen associated with a "redraw" event, etc). The way to
533 read the event's data epends on the event type.
537 <li class="title"><a name="use">Using XCB-based programs</a></li>
540 <li class="subtitle"><a name="inst">Installation of XCB</a></li>
542 To build XCB from source, you need to have installed at
546 <li>pkgconfig 0.15.0</li>
547 <li>automake 1.7</li>
548 <li>autoconf 2.50</li>
549 <li><a href="http://www.check.org">check</a></li>
550 <li><a href="http://xmlsoft.org/XSLT/">xsltproc</a></li>
553 You have to checkout in CVS the following modules:
556 <li>Xproto from xlibs</li>
557 <li>Xau from xlibs</li>
562 Note that Xproto and xcb-proto exist only to install header
563 files, so typing 'make' or 'make all' will produce the message
564 "Nothing to be done for 'all'". That's normal.
566 <li class="subtitle"><a name="comp">Compiling XCB-based programs</a></li>
568 Compiling XCB-based programs requires linking them with the XCB
569 library. This is easily done thanks to pkgconfig:
572 gcc -Wall prog.c -o prog `pkg-config --cflags --libs xcb`
575 <li class="title"><a name="openconn">Opening and closing the connection to an X server</a></li>
577 An X program first needs to open the connection to the X
578 server. There is a function that opens a connection. It requires
579 the display name, or NULL. In the latter case, the display name
580 will be the one in the environment variable DISPLAY.
583 XCBConnection *XCBConnect (const char *displayname,
587 The second parameter returns the screen number used for the
588 connection. The returned structure describes an XCB connection
589 and is opaque. Here is how the connection can be opened:
592 #include <X11/XCB/xcb.h>
595 main (int argc, char *argv[])
599 /* Open the connection to the X server. use the DISPLAY environment variable as the default display name */
600 c = XCBConnect (NULL, NULL);
606 To close a connection, it suffices to use:
609 void XCBDisconnect (XCBConnection *c);
617 <li>XOpenDisplay ()</li>
622 <li>XCBConnect ()</li>
627 <li>XCloseDisplay ()</li>
632 <li>XCBDisconnect ()</li>
638 <li class="title"><a name="screen">Checking basic information about a connection</a></li>
640 Once we opened a connection to an X server, we should check some
641 basic informations about it: what screens it has, what is the
642 size (width and height) of the screen, how many colors it
643 supports (black and white ? grey scale ?, 256 colors ? more ?),
644 and so on. We get such informations from the XCBSCREEN
650 XCBCOLORMAP default_colormap;
653 CARD32 current_input_masks;
654 CARD16 width_in_pixels;
655 CARD16 height_in_pixels;
656 CARD16 width_in_millimeters;
657 CARD16 height_in_millimeters;
658 CARD16 min_installed_maps;
659 CARD16 max_installed_maps;
660 XCBVISUALID root_visual;
664 CARD8 allowed_depths_len;
668 We could retrieve the first screen of the connection by using the
672 XCBSCREENIter XCBConnSetupSuccessRepRootsIter (XCBConnSetupSuccessRep *R);
675 Here is a small program that shows how to use this function:
678 #include <stdio.h>
680 #include <X11/XCB/xcb.h>
683 main (int argc, char *argv[])
690 /* Open the connection to the X server. Use the DISPLAY environment variable */
691 c = XCBConnect (NULL, &screen_nbr);
693 /* Get the screen #screen_nbr */
694 iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
695 for (; iter.rem; --screen_nbr, XCBSCREENNext (&iter))
703 printf ("Informations of screen %ld:\n", screen->root.xid);
704 printf (" width.........: %d\n", screen->width_in_pixels);
705 printf (" height........: %d\n", screen->height_in_pixels);
706 printf (" white pixel...: %ld\n", screen->white_pixel);
707 printf (" black pixel...: %ld\n", screen->black_pixel);
713 <li class="title"><a name="helloworld">Creating a basic window - the "hello world" program</a></li>
715 After we got some basic informations about our screen, we can
716 create our first window. In the X Window System, a window is
717 characterized by an Id. So, in XCB, a window is of type:
725 We first ask for a new Id for our window, with this function:
728 XCBWINDOW XCBWINDOWNew(XCBConnection *c);
731 Then, XCB supplies the following function to create new windows:
734 XCBVoidCookie XCBCreateWindow (XCBConnection *c, /* Pointer to the XCBConnection structure */
735 CARD8 depth, /* Depth of the screen */
736 XCBWINDOW wid, /* Id of the window */
737 XCBWINDOW parent, /* Id of an existing window that should be the parent of the new window */
738 INT16 x, /* X position of the top-left corner of the window (in pixels) */
739 INT16 y, /* Y position of the top-left corner of the window (in pixels) */
740 CARD16 width, /* Width of the window (in pixels) */
741 CARD16 height, /* Height of the window (in pixels) */
742 CARD16 border_width, /* Width of the window's border (in pixels) */
746 const CARD32 *value_list);
749 The fact that we created the window does not mean that it will
750 be drawn on screen. By default, newly created windows are not
751 mapped on the screen (they are invisible). In order to make our
752 window visible, we use the function <span class="code">XCBMapWindow()</span>, whose
756 XCBVoidCookie XCBMapWindow (XCBConnection *c, XCBWINDOW window);
759 Finally, here is a small program to create a window of size
760 150x150 pixels, positioned at the top-left corner of the screen:
763 #include <unistd.h>
765 #include <X11/XCB/xcb.h>
768 main (int argc, char *argv[])
774 /* Open the connection to the X server */
775 c = XCBConnect (NULL, NULL);
777 /* Get the first screen */
778 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
780 /* Ask for our window's Id */
781 win.window = XCBWINDOWNew(c);
783 /* Create the window */
784 XCBCreateWindow (c, /* Connection */
786 win.window, /* window Id */
787 screen->root, /* parent window */
789 150, 150, /* width, height */
790 10, /* border_width */
791 InputOutput, /* class */
792 screen->root_visual, /* visual */
793 0, NULL); /* masks, not used yet */
795 /* Map the window on the screen */
796 XCBMapWindow (c, win.window);
806 In this code, you see one more function - <span class="code">XCBSync()</span>, not explained
807 yet. It is used to flush all the pending requests. More
808 precisely, there are 2 functions that do such things. The first
809 one is <span class="code">XCBFlush()</span>:
812 int XCBFlush (XCBConnection *c);
815 This function flushes all pending requests to the X server (much
816 like the <span class="code">fflush()</span> function is used to
817 flush standard output). The second function is
818 <span class="code">XCBSync()</span>:
821 int XCBSync(XCBConnection *c, XCBGenericError **e);
824 This functions also flushes all pending requests to the X
825 server, and then waits until the X server finishing processing
826 these requests. In a normal program, this will not be necessary
827 (we'll see why when we get to write a normal X program), but for
828 now, we put it there.
831 The window that is created by the above code has a default
832 background (gray). This one can be set to a specific color,
833 thanks to the two last parameters of
834 <span class="code">XCBCreateWindow()</span>, which are not
835 described yet. See the subsections
836 <a href="#winconf">Configuring a window</a> or
837 <a href="#winconf">Registering for event types using event masks</a>
838 for exemples on how to use these parameters. In addition, as no
839 events are handled, you have to make a Ctrl-C to interrupt the
843 <b>TODO</b>: one should tell what these functions return and
844 about the generic error
852 <li>XCreateWindow ()</li>
857 <li>XCBWINDOWNew ()</li>
858 <li>XCBCreateWindow ()</li>
863 <li class="title"><a name="drawing">Drawing in a window</a></li>
865 Drawing in a window can be done using various graphical
866 functions (drawing pixels, lines, rectangles, etc). In order to
867 draw in a window, we first need to define various general
868 drawing parameters (what line width to use, which color to draw
869 with, etc). This is done using a graphical context.
872 <li class="subtitle"><a name="allocgc">Allocating a Graphics Context</a></li>
874 As we said, a graphical context defines several attributes to
875 be used with the various drawing functions. For this, we
876 define a graphical context. We can use more than one graphical
877 context with a single window, in order to draw in multiple
878 styles (different colors, different line widths, etc). In XCB,
879 a Graphics Context is, as a window, characterized by an Id:
887 We first ask the X server to attribute an Id to our graphic
888 context with this function:
891 XCBGCONTEXT XCBGCONTEXTNew (XCBConnection *c);
894 Then, we set the attributes of the graphic context with this function:
897 XCBVoidCookie XCBCreateGC (XCBConnection *c,
899 XCBDRAWABLE drawable,
901 const CARD32 *value_list);
904 We give now an example on how to allocate a graphic context
905 that specifies that each drawing functions that use it will
906 draw in foreground with a black color.
909 #include <X11/XCB/xcb.h>
912 main (int argc, char *argv[])
921 /* Open the connection to the X server and get the first screen */
922 c = XCBConnect (NULL, NULL);
923 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
925 /* Create a black graphic context for drawing in the foreground */
926 win.window = screen->root;
927 black = XCBGCONTEXTNew (c);
929 value[0] = screen->black_pixel;
930 XCBCreateGC (c, black, win, mask, value);
936 Note should be taken regarding the role of "value_mask" and
937 "value_list" in the prototype of <span class="code">XCBCreateGC()</span>. Since a
938 graphic context has many attributes, and since we often just
939 want to define a few of them, we need to be able to tell the
940 <span class="code">XCBCreateGC()</span> which attributes we
941 want to set. This is what the "value_mask" parameter is
942 for. We then use the "value_list" parameter to specify actual
943 values for the attribute we defined in "value_mask". Thus, for
944 each constant used in "value_list", we will use the matching
945 constant in "value_mask". In this case, we define a graphic
946 context with one attribute: when drawing (a point, a line,
947 etc), the foreground color will be black. The rest of the
948 attributes of this graphic context will be set to their
952 See the next Subsection for more details.
960 <li>XCreateGC ()</li>
965 <li>XCBGCONTEXTNew ()</li>
966 <li>XCBCreateGC ()</li>
971 <li class="subtitle"><a name="changegc">Changing the attributes of a Graphics Context</a></li>
973 Once we have allocated a Graphic Context, we may need to
974 change its attributes (for example, changing the foreground
975 color we use to draw a line, or changing the attributes of the
976 font we use to display strings. See Subsections Drawing with a
977 color and Assigning a Font to a Graphic Context). This is done
978 by using this function:
981 XCBVoidCookie XCBChangeGC (XCBConnection *c, /* The XCB Connection */
982 XCBGCONTEXT gc, /* The Graphic Context */
983 CARD32 value_mask, /* Components of the Graphic Context that have to be set */
984 const CARD32 *value_list); /* Value as specified by value_mask */
987 The <span class="code">value_mask</span> parameter could take
993 <li>GCForeground</li>
994 <li>GCBackground</li>
1003 <li>GCTileStipXOrigin</li>
1004 <li>GCTileStipYOrigin</li>
1006 <li>GCSubwindowMode</li>
1007 <li>GCGraphicsExposures</li>
1008 <li>GCClipXOrigin</li>
1009 <li>GCClipYOrigin</li>
1011 <li>GCDashOffset</li>
1016 It is possible to set several attributes at the same
1017 time (for example setting the attributes of a font and the
1018 color which will be used to display a string), by OR'ing these
1019 values in <span class="code">value_mask</span>. Then
1020 <span class="code">value_list</span> has to be an array which
1021 lists the value for the respective attributes. See Subsection
1022 Drawing with a color to have an example.
1025 <b>TODO</b>: set the links of the 3 subsections, once they will
1029 <b>TODO</b>: give an example which sets several attributes.
1031 <li class="subtitle"><a name="drawingprim">Drawing primitives: point, line, box, circle,...</a></li>
1033 After we have created a Graphic Context, we can draw on a
1034 window using this Graphic Context, with a set of XCB
1035 functions, collectively called "drawing primitive". Let see
1039 To draw a point, or several points, we use
1042 XCBVoidCookie XCBPolyPoint (XCBConnection *c, /* The connection to the X server */
1043 BYTE coordinate_mode, /* Coordinate mode, usually set to CoordModeOrigin */
1044 XCBDRAWABLE drawable, /* The drawable on which we want to draw the point(s) */
1045 XCBGCONTEXT gc, /* The Graphic Context we use to draw the point(s) */
1046 CARD32 points_len, /* The number of points */
1047 const XCBPOINT *points); /* An array of points */
1050 The <span class="code">coordinate_mode</span> parameter
1051 specifies the coordinate mode. Available values are
1054 <li><span class="code">CoordModeOrigin</span></li>
1055 <li><span class="code">CoordModePrevious</span></li>
1058 The <span class="code">XCBPOINT</span> type is just a
1059 structure with two fields (the coordinates of the point):
1068 You could see an example in xpoints.c. <b>TODO</b> Set the link.
1071 To draw a line, or a polygonal line, we use
1074 XCBVoidCookie XCBPolyLine (XCBConnection *c, /* The connection to the X server */
1075 BYTE coordinate_mode, /* Coordinate mode, usually set to CoordModeOrigin */
1076 XCBDRAWABLE drawable, /* The drawable on which we want to draw the line(s) */
1077 XCBGCONTEXT gc, /* The Graphic Context we use to draw the line(s) */
1078 CARD32 points_len, /* The number of points in the polygonal line */
1079 const XCBPOINT *points); /* An array of points */
1082 This function will draw the line between the first and the
1083 second points, then the line between the second and the third
1087 To draw a segment, or several segments, we use
1090 XCBVoidCookie XCBPolySegment (XCBConnection *c, /* The connection to the X server */
1091 XCBDRAWABLE drawable, /* The drawable on which we want to draw the segment(s) */
1092 XCBGCONTEXT gc, /* The Graphic Context we use to draw the segment(s) */
1093 CARD32 segments_len, /* The number of segments */
1094 const XCBSEGMENT *segments); /* An array of segments */
1097 The <span class="code">XCBSEGMENT</span> type is just a
1098 structure with four fields (the coordinates of the two points
1099 that define the segment):
1110 To draw a rectangle, or several rectangles, we use
1113 XCBVoidCookie XCBPolyRectangle (XCBConnection *c, /* The connection to the X server */
1114 XCBDRAWABLE drawable, /* The drawable on which we want to draw the rectangle(s) */
1115 XCBGCONTEXT gc, /* The Graphic Context we use to draw the rectangle(s) */
1116 CARD32 rectangles_len, /* The number of rectangles */
1117 const XCBRECTANGLE *rectangles); /* An array of rectangles */
1120 The <span class="code">XCBRECTANGLE</span> type is just a
1121 structure with four fields (the coordinates of the top-left
1122 corner of the rectangle, and its width and height):
1133 <b>TODO</b>: there's no coordinate_mode. Is it normal ?
1136 To draw an elliptical arc, or several elliptical arcs, we use
1139 XCBVoidCookie XCBPolyArc (XCBConnection *c, /* The connection to the X server */
1140 XCBDRAWABLE drawable, /* The drawable on which we want to draw the arc(s) */
1141 XCBGCONTEXT gc, /* The Graphic Context we use to draw the arc(s) */
1142 CARD32 arcs_len, /* The number of arcs */
1143 const XCBARC *arcs); /* An array of arcs */
1146 The <span class="code">XCBARC</span> type is a structure with
1151 INT16 x; /* Top left x coordinate of the rectangle surrounding the ellipse */
1152 INT16 y; /* Top left y coordinate of the rectangle surrounding the ellipse */
1153 CARD16 width; /* Width of the rectangle surrounding the ellipse */
1154 CARD16 height; /* Height of the rectangle surrounding the ellipse */
1155 INT16 angle1; /* Angle at which the arc begins */
1156 INT16 angle2; /* Angle at which the arc ends */
1161 Note: the angles are expressed in units of 1/64 of a degree,
1162 so to have an angle of 90 degrees, starting at 0,
1163 <span class="code">angle1 = 0</span> and
1164 <span class="code">angle2 = 90 << 6</span>. Positive angles
1165 indicate counterclockwise motion, while negative angles
1166 indicate clockwise motion.
1170 <b>TODO</b>: there's no coordinate_mode. Is it normal ?
1173 <b>TODO</b>: I think that (x,y) should be the center of the
1174 ellipse, and (width, height) the radius. It's more logical.
1177 The corresponding function which fill inside the geometrical
1178 object are listed below, without further explanation, as they
1179 are used as the above functions.
1182 To Fill a polygon defined by the points given as arguments ,
1186 XCBVoidCookie XCBFillPoly (XCBConnection *c,
1187 XCBDRAWABLE drawable,
1190 CARD8 coordinate_mode,
1192 const XCBPOINT *points);
1195 The <span class="code">shape</span> parameter specifies a
1196 shape that helps the server to improve performance. Available
1200 <li><span class="code">Complex</span></li>
1201 <li><span class="code">Convex</span></li>
1202 <li><span class="code">Nonconvex</span></li>
1205 To fill one or several rectangles, we use
1208 XCBVoidCookie XCBPolyFillRectangle (XCBConnection *c,
1209 XCBDRAWABLE drawable,
1211 CARD32 rectangles_len,
1212 const XCBRECTANGLE *rectangles);
1215 To fill one or several arcs, we use
1218 XCBVoidCookie XCBPolyFillArc (XCBConnection *c,
1219 XCBDRAWABLE drawable,
1222 const XCBARC *arcs);
1226 To illustrate these functions, here is an example that draws
1227 four points, a polygonal line, two segments, two rectangles
1228 and two arcs. Remark that we use events for the first time, as
1229 an introduction to the next section.
1232 #include <stdlib.h>
1233 #include <stdio.h>
1235 #include <X11/XCB/xcb.h>
1237 /* Get the depth of the screen. Needed in order to draw something */
1239 get_depth(XCBConnection *c,
1242 XCBDRAWABLE drawable;
1243 XCBGetGeometryRep *geom;
1246 drawable.window = root->root;
1247 geom = XCBGetGeometryReply (c, XCBGetGeometry(c, drawable), 0);
1251 perror ("GetGeometry(root) failed");
1255 depth = geom->depth;
1262 main (int argc, char *argv[])
1267 XCBGCONTEXT foreground;
1272 /* geometric objects */
1273 XCBPOINT points[] = {
1279 XCBPOINT polyline[] = {
1285 XCBSEGMENT segments[] = {
1287 {110, 25, 130, 60}};
1289 XCBRECTANGLE rectangles[] = {
1294 {10, 100, 60, 40, 0, 90 << 6},
1295 {90, 100, 55, 40, 0, 270 << 6}};
1297 /* Open the connection to the X server */
1298 c = XCBConnect (NULL, NULL);
1300 /* Get the first screen */
1301 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
1303 /* Create black (foregroung) graphic context */
1304 win.window = screen->root;
1306 foreground = XCBGCONTEXTNew (c);
1307 mask = GCForeground | GCGraphicsExposures;
1308 values[0] = screen->black_pixel;
1310 XCBCreateGC (c, foreground, win, mask, values);
1312 /* Ask for our window's Id */
1313 win.window = XCBWINDOWNew(c);
1315 /* Create the window */
1316 mask = XCBCWBackPixel | XCBCWEventMask;
1317 values[0] = screen->white_pixel;
1318 values[1] = ExposureMask;
1319 XCBCreateWindow (c, /* Connection */
1321 win.window, /* window Id */
1322 screen->root, /* parent window */
1324 150, 150, /* width, height */
1325 10, /* border_width */
1326 InputOutput, /* class */
1327 screen->root_visual, /* visual */
1328 mask, values); /* masks */
1330 /* Map the window on the screen */
1331 XCBMapWindow (c, win.window);
1334 /* We flush the request */
1337 while ((e = XCBWaitEvent (c)))
1339 switch (e->response_type)
1343 /* We draw the points */
1344 XCBPolyPoint (c, CoordModeOrigin, win, foreground, 4, points);
1346 /* We draw the polygonal line */
1347 XCBPolyLine (c, CoordModeOrigin, win, foreground, 4, polyline);
1349 /* We draw the segements */
1350 XCBPolySegment (c, win, foreground, 2, segments);
1352 /* We draw the rectangles */
1353 XCBPolyRectangle (c, win, foreground, 2, rectangles);
1355 /* We draw the arcs */
1356 XCBPolyArc (c, win, foreground, 2, arcs);
1358 /* We flush the request */
1365 /* Unknown event type, ignore it */
1369 /* Free the Generic Event */
1377 <li class="title"><a name="xevents">X Events</a></li>
1379 In an X program, everything is driven by events. Event painting
1380 on the screen is sometimes done as a response to an event (an
1381 <span class="code">Expose</span> event). If part of a program's
1382 window that was hidden, gets exposed (e.g. the window was raised
1383 above other widows), the X server will send an "expose" event to
1384 let the program know it should repaint that part of the
1385 window. User input (key presses, mouse movement, etc) is also
1386 received as a set of events.
1389 <li class="subtitle"><a name="register">Registering for event types using event masks</a></li>
1391 During the creation of a window, you should give it what kind
1392 of events it wishes to receive. Thus, you may register for
1393 various mouse (also called pointer) events, keyboard events,
1394 expose events, and so on. This is done for optimizing the
1395 server-to-client connection (i.e. why send a program (that
1396 might even be running at the other side of the globe) an event
1397 it is not interested in ?)
1400 In XCB, you use the "value_mask" and "value_list" data in the
1401 <span class="code">XCBCreateWindow()</span> function to
1402 register for events. Here is how we register for
1403 <span class="code">Expose</span> event when creating a window:
1406 mask = XCBCWEventMask;
1407 valwin[0] = ExposureMask;
1408 win.window = XCBWINDOWNew (c);
1409 XCBCreateWindow (c, depth, win.window, root->root,
1411 InputOutput, root->root_visual,
1415 <span class="code">ExposureMask</span> is a constant defined
1416 in the "X.h" header file. If we wanted to register to several
1417 event types, we can logically "or" them, as follows:
1420 mask = XCBCWEventMask;
1421 valwin[0] = ExposureMask | ButtonPressMask;
1422 win.window = XCBWINDOWNew (c);
1423 XCBCreateWindow (c, depth, win.window, root->root,
1425 InputOutput, root->root_visual,
1429 This registers for <span class="code">Expose</span> events as
1430 well as for mouse button presses insode the created
1431 window. You should note that a mask may represent several
1435 The values that a mask could take are given
1436 by the <span class="code">XCBCW</span> enumeration:
1440 XCBCWBackPixmap = 1L<<0,
1441 XCBCWBackPixel = 1L<<1,
1442 XCBCWBorderPixmap = 1L<<2,
1443 XCBCWBorderPixel = 1L<<3,
1444 XCBCWBitGravity = 1L<<4,
1445 XCBCWWinGravity = 1L<<5,
1446 XCBCWBackingStore = 1L<<6,
1447 XCBCWBackingPlanes = 1L<<7,
1448 XCBCWBackingPixel = 1L<<8,
1449 XCBCWOverrideRedirect = 1L<<9,
1450 XCBCWSaveUnder = 1L<<10,
1451 XCBCWEventMask = 1L<<11,
1452 XCBCWDontPropagate = 1L<<12,
1453 XCBCWColormap = 1L<<13,
1454 XCBCWCursor = 1L<<14
1458 <p>Note: we must be careful when setting the values of the valwin
1459 parameter, as they have to follow the order the
1460 <span class="code">XCBCW</span> enumeration. Here is an
1465 mask = XCBCWEventMask | XCBCWBackPixmap;
1466 valwin[0] = None; /* for XCBCWBackPixmap (whose value is 1) */
1467 valwin[1] = ExposureMask | ButtonPressMask; /* for XCBCWEventMask, whose value (2048) */
1468 /* is superior to the one of XCBCWBackPixmap */
1471 If the window has already been created, we can use the
1472 <span class="code">XCBConfigureWindow()</span> function to set
1473 the events that the window will receive. The subsection
1474 <a href="#winconf">Configuring a window</a> shows its
1475 prototype. As an example, here is a piece of code that
1476 configures the window to receive the
1477 <span class="code">Expose</span> and
1478 <span class="code">ButtonPressMask</span> events:
1481 const static CARD32 values[] = { ExposureMask | ButtonPressMask };
1483 /* The connection c and the window win are supposed to be defined */
1485 XCBConfigureWindow (c, win, XCBCWEventMask, values);
1489 Note: A common bug programmers do is adding code to handle new
1490 event types in their program, while forgetting to add the
1491 masks for these events in the creation of the window. Such a
1492 programmer then should sit down for hours debugging his
1493 program, wondering "Why doesn't my program notice that I
1494 released the button?", only to find that they registered for
1495 button press events but not for button release events.
1498 <li class="subtitle"><a name="loop">Receiving events: writing the events loop</a></li>
1500 After we have registered for the event types we are interested
1501 in, we need to enter a loop of receiving events and handling
1502 them. There are two ways to receive events: a blocking way and
1507 <span class="code">XCBWaitEvent (XCBConnection *c)</span>
1508 is the blocking way. It waits (so blocks...) until an event is
1509 queued in the X server. Then it retrieves it into a newly
1510 allocated structure (it dequeues it from the queue) and returns
1511 it. This structure has to be freed. The function returns
1512 <span class="code">NULL</span> if an error occurs.
1516 <span class="code">XCBPollForEvent (XCBConnection *c, int
1517 *error)</span> is the non blocking way. It looks at the event
1518 queue and returns (and dequeues too) an existing event into
1519 a newly allocated structure. This structure has to be
1520 freed. It returns <span class="code">NULL</span> if there is
1521 no event. If an error occurs, the parameter <span
1522 class="code">error</span> will be filled with the error
1527 There are various ways to write such a loop. We present two
1528 ways to write such a loop, with the two functions above. The
1529 first one uses <span class="code">XCBWaitEvent</span>, which
1530 is similar to an event Xlib loop using only <span
1531 class="code">XNextEvent</span>:
1536 while ((e = XCBWaitEvent (c)))
1538 switch (e->response_type)
1542 /* Handle the Expose event type */
1543 XCBExposeEvent *ev = (XCBExposeEvent *)e;
1549 case XCBButtonPress:
1551 /* Handle the ButtonPress event type */
1552 XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
1560 /* Unknown event type, ignore it */
1564 /* Free the Generic Event */
1569 You will certainly want to use <span
1570 class="code">XCBPollForEvent(XCBConnection *c, int
1571 *error)</span> if, in Xlib, you use <span
1572 class="code">XPending</span>:
1575 while (XPending (display))
1581 /* Manage your event */
1585 Such a loop in XCB looks like:
1588 XCBGenericEvent *ev;
1590 while ((ev = XCBPollForEvent (conn, 0)))
1592 /* Manage your event */
1596 The events are managed in the same way as with <span
1597 class="code">XCBWaitEvent</span>.
1598 Obviously, we will need to give the user some way of
1599 terminating the program. This is usually done by handling a
1600 special "quit" event, as we will soon see.
1608 <li>XNextEvent ()</li>
1613 <li>XCBWaitEvent ()</li>
1618 <li>XPending ()</li>
1619 <li>XNextEvent ()</li>
1624 <li>XCBPollForEvent ()</li>
1630 <li class="subtitle"><a name="expose">Expose events</a></li>
1632 The <span class="code">Expose</span> event is one of the most
1633 basic (and most used) events an application may receive. It
1634 will be sent to us in one of several cases:
1636 <li>A window that covered part of our window has moved
1637 away, exposing part (or all) of our window.</li>
1638 <li>Our window was raised above other windows.</li>
1639 <li>Our window mapped for the first time.</li>
1640 <li>Our window was de-iconified.</li>
1644 You should note the implicit assumption hidden here: the
1645 contents of our window is lost when it is being obscured
1646 (covered) by either windows. One may wonder why the X server
1647 does not save this contents. The answer is: to save
1648 memory. After all, the number of windows on a display at a
1649 given time may be very large, and storing the contents of all
1650 of them might require a lot of memory. Actually, there is a
1651 way to tell the X server to store the contents of a window in
1652 special cases, as we will see later.
1655 When we get an <span class="code">Expose</span> event, we
1656 should take the event's data from the members of the following
1661 BYTE response_type; /* The type of the event, here it is XCBExpose */
1664 XCBWINDOW window; /* The Id of the window that receives the event (in case */
1665 /* our application registered for events on several windows */
1666 CARD16 x; /* The x coordinate of the top-left part of the window that needs to be redrawn */
1667 CARD16 y; /* The y coordinate of the top-left part of the window that needs to be redrawn */
1668 CARD16 width; /* The width of the part of the window that needs to be redrawn */
1669 CARD16 height; /* The height of the part of the window that needs to be redrawn */
1673 <li class="subtitle"><a name="userinput">Getting user input</a></li>
1675 User input traditionally comes from two sources: the mouse
1676 and the keyboard. Various event types exist to notify us of
1677 user input (a key being presses on the keyboard, a key being
1678 released on the keyboard, the mouse moving over our window,
1679 the mouse entering (or leaving) our window, and so on.
1682 <li class="subsubtitle"><a name="mousepressrelease">Mouse button press and release events</a></li>
1684 The first event type we will deal with is a mouse
1685 button-press (or button-release) event in our window. In
1686 order to register to such an event type, we should add one
1687 (or more) of the following masks when we create our window:
1690 <li><span class="code">ButtonPressMask</span>: notify us
1691 of any button that was pressed in one of our windows.</li>
1692 <li><span class="code">ButtonReleaseMask</span>: notify us
1693 of any button that was released in one of our windows.</li>
1696 The structure to be checked for in our events loop is the
1697 same for these two events, and is the following:
1701 BYTE response_type; /* The type of the event, here it is XCBButtonPressEvent or XCBButtonReleaseEvent */
1704 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1710 INT16 event_x; /* The x coordinate where the mouse has been pressed in the window */
1711 INT16 event_y; /* The y coordinate where the mouse has been pressed in the window */
1712 CARD16 state; /* A mask of the buttons (or keys) during the event */
1714 } XCBButtonPressEvent;
1716 typedef XCBButtonPressEvent XCBButtonReleaseEvent;
1719 The <span class="code">time</span> field may be used to calculate "double-click"
1720 situations by an application (e.g. if the mouse button was
1721 clicked two times in a duration shorter than a given amount
1722 of time, assume this was a double click).
1725 The <span class="code">state</span> field is a mask of the buttons held down during
1726 the event. It is a bitwise OR of any of the following:
1729 <li><span class="code">Button1Mask</span></li>
1730 <li><span class="code">Button2Mask</span></li>
1731 <li><span class="code">Button3Mask</span></li>
1732 <li><span class="code">Button4Mask</span></li>
1733 <li><span class="code">Button5Mask</span></li>
1734 <li><span class="code">ShiftMask</span></li>
1735 <li><span class="code">LockMask</span></li>
1736 <li><span class="code">ControlMask</span></li>
1737 <li><span class="code">Mod1Mask</span></li>
1738 <li><span class="code">Mod2Mask</span></li>
1739 <li><span class="code">Mod3Mask</span></li>
1740 <li><span class="code">Mod4Mask</span></li>
1741 <li><span class="code">Mod5Mask</span></li>
1744 Their names are self explanatory, where the first 5 refer to
1745 the mouse buttons that are being pressed, while the rest
1746 refer to various "special keys" that are being pressed (Mod1
1747 is usually the 'Alt' key or the 'Meta' key).
1750 <b>TODO:</b> Problem: it seems that the state does not
1751 change when clicking with various buttons.
1753 <li class="subsubtitle"><a name="mousemvnt">Mouse movement events</a></li>
1755 Similar to mouse button press and release events, we also
1756 can be notified of various mouse movement events. These can
1757 be split into two families. One is of mouse pointer
1758 movement while no buttons are pressed, and the second is a
1759 mouse pointer motion while one (or more) of the buttons are
1760 pressed (this is sometimes called "a mouse drag operation",
1761 or just "dragging"). The following event masks may be added
1762 during the creation of our window:
1765 <li><span class="code">PointerMotionMask</span>: events of
1766 the pointer moving in one of the windows controlled by our
1767 application, while no mouse button is held pressed.</li>
1768 <li><span class="code">ButtonMotionMask</span>: Events of
1769 the pointer moving while one or more of the mouse buttons
1770 is held pressed.</li>
1771 <li><span class="code">Button1MotionMask</span>: same as
1772 <span class="code">ButtonMotionMask</span>, but only when
1773 the 1st mouse button is held pressed.</li>
1774 <li><span class="code">Button2MotionMask</span>,
1775 <span class="code">Button3MotionMask</span>,
1776 <span class="code">Button4MotionMask</span>,
1777 <span class="code">Button5MotionMask</span>: same as
1778 <span class="code">Button1MotionMask</span>, but
1779 respectively for 2nd, 3rd, 4th and 5th mouse button.</li>
1782 The structure to be checked for in our events loop is the
1783 same for these events, and is the following:
1787 BYTE response_type; /* The type of the event */
1790 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1796 INT16 event_x; /* The x coordinate of the mouse when the event was generated */
1797 INT16 event_y; /* The y coordinate of the mouse when the event was generated */
1798 CARD16 state; /* A mask of the buttons (or keys) during the event */
1800 } XCBMotionNotifyEvent;
1802 <li class="subsubtitle"><a name="mouseenter">Mouse pointer enter and leave events</a></li>
1804 Another type of event that applications might be interested
1805 at, is a mouse pointer entering a window the program
1806 controls, or leaving such a window. Some programs use these
1807 events to show the user tht the applications is now in
1808 focus. In order to register for such an event type, we
1809 should add one (or more) of the following masks when we
1813 <li><span class="code">EnterWindowMask</span>: notify us
1814 when the mouse pointer enters any of our controlled
1816 <li><span class="code">LeaveWindowMask</span>: notify us
1817 when the mouse pointer leaves any of our controlled
1821 The structure to be checked for in our events loop is the
1822 same for these two events, and is the following:
1826 BYTE response_type; /* The type of the event */
1829 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1835 INT16 event_x; /* The x coordinate of the mouse when the event was generated */
1836 INT16 event_y; /* The y coordinate of the mouse when the event was generated */
1837 CARD16 state; /* A mask of the buttons (or keys) during the event */
1838 BYTE mode; /* The number of mouse button that was clicked */
1839 BYTE same_screen_focus;
1840 } XCBEnterNotifyEvent;
1842 typedef XCBEnterNotifyEvent XCBLeaveNotifyEvent;
1844 <li class="subsubtitle"><a name="focus">The keyboard focus</a></li>
1846 There may be many windows on a screen, but only a single
1847 keyboard attached to them. How does the X server then know
1848 which window should be sent a given keyboard input ? This is
1849 done using the keyboard focus. Only a single window on the
1850 screen may have the keyboard focus at a given time. There
1851 is a XCB function that allow a program to set the keyboard
1852 focus to a given window. The user can usually set the
1853 keyboard ficus using the window manager (often by clicking
1854 on the title bar of the desired window). Once our window
1855 has the keyboard focus, every key press or key release will
1856 cause an event to be sent to our program (if it regsitered
1857 for these event types...).
1859 <li class="subsubtitle"><a name="keypress">Keyboard press and release events</a></li>
1861 If a window controlled by our program currently holds the
1862 keyboard focus, it can receive key press and key release
1863 events. So, we should add one (or more) of the following
1864 masks when we create our window:
1867 <li><span class="code">KeyPressMask</span>: notify us when
1868 a key was pressed while any of our controlled windows had
1869 the keyboard focus.</li>
1870 <li><span class="code">KeyReleaseMask</span>: notify us
1871 when a key was released while any of our controlled
1872 windows had the keyboard focus.</li>
1875 The structure to be checked for in our events loop is the
1876 same for these two events, and is the following:
1880 BYTE response_type; /* The type of the event */
1883 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1895 typedef XCBKeyPressEvent XCBKeyReleaseEvent;
1898 The <span class="code">detail</span> field refer to the
1899 physical key on the keyboard.
1902 <b>TODO:</b> Talk about getting the ASCII code from the key code.
1905 <li class="subtitle"><a name="eventex">X events: a complete example</a></li>
1907 As an example for handling events, we show a program that
1908 creates a window, enter an events loop and check for all the
1909 events described above, and write on the terminal the relevant
1910 characteristics of the event. With this code, it should be
1911 easy to add drawing operations, like those which have been
1915 #include <malloc.h>
1916 #include <stdio.h>
1918 #include <X11/XCB/xcb.h>
1921 main (int argc, char *argv[])
1930 /* Open the connection to the X server */
1931 c = XCBConnect (NULL, NULL);
1933 /* Get the first screen */
1934 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
1936 /* Ask for our window's Id */
1937 win.window = XCBWINDOWNew(c);
1939 /* Create the window */
1940 mask = XCBCWBackPixel | XCBCWEventMask;
1941 values[0] = screen->white_pixel;
1942 values[1] = ExposureMask | ButtonPressMask | ButtonReleaseMask |
1943 PointerMotionMask | EnterWindowMask | LeaveWindowMask |
1944 KeyPressMask | KeyReleaseMask;
1945 XCBCreateWindow (c, /* Connection */
1947 win.window, /* window Id */
1948 screen->root, /* parent window */
1950 150, 150, /* width, height */
1951 10, /* border_width */
1952 InputOutput, /* class */
1953 screen->root_visual, /* visual */
1954 mask, values); /* masks */
1956 /* Map the window on the screen */
1957 XCBMapWindow (c, win.window);
1960 while ((e = XCBWaitEvent (c)))
1962 switch (e->response_type)
1966 XCBExposeEvent *ev = (XCBExposeEvent *)e;
1968 printf ("Window %ld exposed. Region to be redrawn at location (%d,%d), with dimension (%d,%d)\n",
1969 ev->window.xid, ev->x, ev->y, ev->width, ev->height);
1972 case XCBButtonPress:
1974 XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
1977 if ((ev->state | Button1Mask) == Button1Mask)
1979 if ((ev->state | Button2Mask) == Button2Mask)
1981 if ((ev->state | Button3Mask) == Button3Mask)
1983 if ((ev->state | Button4Mask) == Button4Mask)
1985 if ((ev->state | Button5Mask) == Button5Mask)
1988 switch (ev->detail.id)
1992 printf ("Wheel Button up in window %ld, at coordinates (%d,%d)\n",
1993 ev->event.xid, ev->event_x, ev->event_y);
1998 printf ("Wheel Button down in window %ld, at coordinates (%d,%d)\n",
1999 ev->event.xid, ev->event_x, ev->event_y);
2003 printf ("Button %d pressed in window %ld, at coordinates (%d,%d)\n",
2004 ev->detail.id, ev->event.xid, ev->event_x, ev->event_y);
2008 case XCBButtonRelease:
2010 XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e;
2013 if ((ev->state | Button1Mask) == Button1Mask)
2015 if ((ev->state | Button2Mask) == Button2Mask)
2017 if ((ev->state | Button3Mask) == Button3Mask)
2019 if ((ev->state | Button4Mask) == Button4Mask)
2021 if ((ev->state | Button5Mask) == Button5Mask)
2024 printf ("Button %d released in window %ld, at coordinates (%d,%d)\n",
2025 ev->detail.id, ev->event.xid, ev->event_x, ev->event_y);
2028 case XCBMotionNotify:
2030 XCBMotionNotifyEvent *ev = (XCBMotionNotifyEvent *)e;
2032 printf ("Mouse moved in window %ld, at coordinates (%d,%d)\n",
2033 ev->event.xid, ev->event_x, ev->event_y);
2036 case XCBEnterNotify:
2038 XCBEnterNotifyEvent *ev = (XCBEnterNotifyEvent *)e;
2040 printf ("Mouse entered window %ld, at coordinates (%d,%d)\n",
2041 ev->event.xid, ev->event_x, ev->event_y);
2044 case XCBLeaveNotify:
2046 XCBLeaveNotifyEvent *ev = (XCBLeaveNotifyEvent *)e;
2048 printf ("Mouse leaved window %ld, at coordinates (%d,%d)\n",
2049 ev->event.xid, ev->event_x, ev->event_y);
2054 XCBKeyPressEvent *ev = (XCBKeyPressEvent *)e;
2056 printf ("Key pressed in window %ld\n",
2062 XCBKeyReleaseEvent *ev = (XCBKeyReleaseEvent *)e;
2064 printf ("Key releaseed in window %ld\n",
2070 /* Unknown event type, ignore it */
2074 /* Free the Generic Event */
2082 <li class="title"><a name="font">Handling text and fonts</a></li>
2084 Besides drawing graphics on a window, we often want to draw
2085 text. Text strings have two major properties: the characters to
2086 be drawn and the font with which they are drawn. In order to
2087 draw text, we need to first request the X server to load a
2088 font. We then assign a font to a Graphic Context, and finally, we
2089 draw the text in a window, using the Graphic Context.
2092 <li class="subtitle"><a name="fontstruct">The Font structure</a></li>
2094 In order to support flexible fonts, a font structure is
2095 defined. You know what ? Its an Id:
2103 It is used to contain information about a font, and is passed
2104 to several functions that handle fonts selection and text drawing.
2107 <li class="title"><a name="wm">Interacting with the window manager</a></li>
2109 After we have seen how to create windows and draw on them, we
2110 take one step back, and look at how our windows are interacting
2111 with their environment (the full screen and the other
2112 windows). First of all, our application needs to interact with
2113 the window manager. The window manager is responsible to
2114 decorating drawn windows (i.e. adding a frame, an iconify
2115 button, a system menu, a title bar, etc), as well as handling
2116 icons shown when windows are being iconified. It also handles
2117 ordering of windows on the screen, and other administrative
2118 tasks. We need to give it various hints as to how we want it to
2119 treat our application's windows.
2122 <li class="subtitle"><a name="wmprop">Window properties</a></li>
2124 Many of the parameters communicated to the window manager are
2125 passed using data called "properties". These properties are
2126 attached by the X server to different windows, and are stores
2127 in a format that makes it possible to read them from different
2128 machines that may use different architectures (remember that
2129 an X client program may run on a remote machine).
2132 The property and its type (a string, an integer, etc) are
2133 Id. Their type are <span class="code">XCBATOM</span>:
2141 To change the property of a window, we use the following
2145 XCBVoidCookie XCBChangeProperty (XCBConnection *c, /* Connection to the X server */
2146 CARD8 mode, /* Property mode */
2147 XCBWINDOW window, /* Window */
2148 XCBATOM property, /* Property to change */
2149 XCBATOM type, /* Type of the property */
2150 CARD8 format, /* Format of the property (8, 16, 32) */
2151 CARD32 data_len, /* Length of the data parameter */
2152 const void *data); /* Data */
2155 The <span class="code">mode</span> parameter coud be one of
2156 the following value (defined in the X.h header file):
2159 <li>PropModeReplace</li>
2160 <li>PropModePrepend</li>
2161 <li>PropModeAppend</li>
2164 <li class="subtitle"><a name="wmname">Setting the window name and icon name</a></li>
2166 The firt thing we want to do would be to set the name for our
2167 window. This is done using the
2168 <span class="code">XCBChangeProperty()</span> function. This
2169 name may be used by the window manager as the title of the
2170 window (in the title bar), in a task list, etc. The property
2171 atom to use to set the name of a window is
2172 <span class="code">WM_NAME</span> (and
2173 <span class="code">WM_ICON_NAME</span> for the iconified
2174 window) and its type is <span class="code">STRING</span>. Here
2175 is an example of utilization:
2178 #include <string.h>
2180 #include <X11/XCB/xcb.h>
2181 #include <X11/XCB/xcb_atom.h>
2184 main (int argc, char *argv[])
2189 char *title = "Hello World !";
2190 char *title_icon = "Hello World ! (iconified)";
2194 /* Open the connection to the X server */
2195 c = XCBConnect (NULL, NULL);
2197 /* Get the first screen */
2198 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2200 /* Ask for our window's Id */
2201 win.window = XCBWINDOWNew(c);
2203 /* Create the window */
2204 XCBCreateWindow (c, /* Connection */
2206 win.window, /* window Id */
2207 screen->root, /* parent window */
2209 250, 150, /* width, height */
2210 10, /* border_width */
2211 InputOutput, /* class */
2212 screen->root_visual, /* visual */
2213 0, NULL); /* masks, not used */
2215 /* Set the title of the window */
2216 XCBChangeProperty(c, PropModeReplace, win.window,
2218 strlen(title), title);
2220 /* Set the title of the window icon */
2221 XCBChangeProperty(c, PropModeReplace, win.window,
2222 WM_ICON_NAME, STRING, 8,
2223 strlen(title_icon), title_icon);
2225 /* Map the window on the screen */
2226 XCBMapWindow (c, win.window);
2236 <p>Note: the use of the atoms needs our program to be compiled
2237 and linked against xcb_atom, so that we have to use
2241 gcc prog.c -o prog `pkg-config --cflags --libs xcb_atom`
2245 for the program to compile fine.
2249 <li class="title"><a name="winop">Simple window operations</a></li>
2251 One more thing we can do to our window is manipulate them on the
2252 screen (resize them, move them, raise or lower them, iconify
2253 them, and so on). Some window operations functions are supplied
2254 by XCB for this purpose.
2257 <li class="subtitle"><a name="winmap">Mapping and un-mapping a window</a></li>
2259 The first pair of operations we can apply on a window is
2260 mapping it, or un-mapping it. Mapping a window causes the
2261 window to appear on the screen, as we have seen in our simple
2262 window program example. Un-mapping it causes it to be removed
2263 from the screen (although the window as a logical entity still
2264 exists). This gives the effect of making a window hidden
2265 (unmapped) and shown again (mapped). For example, if we have a
2266 dialog box window in our program, instead of creating it every
2267 time the user asks to open it, we can create the window once,
2268 in an un-mapped mode, and when the user asks to open it, we
2269 simply map the window on the screen. When the user clicked the
2270 'OK' or 'Cancel' button, we simply un-map the window. This is
2271 much faster than creating and destroying the window, however,
2272 the cost is wasted resources, both on the client side, and on
2276 To map a window, you use the following function:
2279 XCBVoidCookie XCBMapWindow(XCBConnection *c, XCBWINDOW window);
2282 To have a simple example, see the <a href="#helloworld">example</a>
2283 above. The mapping operation will cause an
2284 <span class="code">Expose</span> event to be sent to our
2285 application, unless the window is completely covered by other
2289 Un-mapping a window is also simple. You use the function
2292 XCBVoidCookie XCBUnmapWindow(XCBConnection *c, XCBWINDOW window);
2295 The utilization of this function is the same as
2296 <span class="code">XCBMapWindow()</span>.
2298 <li class="subtitle"><a name="winconf">Configuring a window</a></li>
2300 As we have seen when we have created our first window, in the
2301 X Events subsection, we can set some attributes to the window
2302 (that is, the position, the size, the events the window will
2303 receive, etc). If we want to modify them, but the window is
2304 already created, we can change them by using the following
2308 XCBVoidCookie XCBConfigureWindow (XCBConnection *c, /* The connection to the X server*/
2309 XCBWINDOW window, /* The window to configure */
2310 CARD16 value_mask, /* The mask */
2311 const CARD32 *value_list); /* The values to set */
2314 We set the <span class="code">value_mask</span> to one or
2315 several mask values that are in the X.h header:
2317 <li><span class="code">CWX</span>: new x coordinate of the window's top left corner</li>
2318 <li><span class="code">CWY</span>: new y coordinate of the window's top left corner</li>
2319 <li><span class="code">CWWidth</span>: new width of the window</li>
2320 <li><span class="code">CWHeight</span>: new height of the window</li>
2321 <li><span class="code">CWBorderWidth</span>: new width of the border of the window</li>
2322 <li><span class="code">CWSibling</span></li>
2323 <li><span class="code">CWStackMode</span>: the new stacking order</li>
2327 We then give to <span class="code">value_mask</span> the new
2328 value. We now describe how to use
2329 <span class="code">XCBConfigureWindow</span> in some useful
2332 <li class="subtitle"><a name="winmove">Moving a window around the screen</a></li>
2334 An operation we might want to do with windows is to move them
2335 to a different location. This can be done like this:
2338 const static CARD32 values[] = { 10, 20 };
2340 /* The connection c and the window win are supposed to be defined */
2342 /* Move the window to coordinates x = 10 and y = 20 */
2343 XCBConfigureWindow (c, win, CWX | CWY, values);
2346 Note that when the window is moved, it might get partially
2347 exposed or partially hidden by other windows, and thus we
2348 might get <span class="code">Expose</span> events due to this
2351 <li class="subtitle"><a name="winsize">Resizing a window</a></li>
2353 Yet another operation we can do is to change the size of a
2354 window. This is done using the following code:
2357 const static CARD32 values[] = { 200, 300 };
2359 /* The connection c and the window win are supposed to be defined */
2361 /* Resize the window to width = 10 and height = 20 */
2362 XCBConfigureWindow (c, win, CWWidth | CWHeight, values);
2365 We can also combine the move and resize operations using one
2366 single call to <span class="code">XCBConfigureWindow</span>:
2369 const static CARD32 values[] = { 10, 20, 200, 300 };
2371 /* The connection c and the window win are supposed to be defined */
2373 /* Move the window to coordinates x = 10 and y = 20 */
2374 /* and resize the window to width = 10 and height = 20 */
2375 XCBConfigureWindow (c, win, CWX | CWY | CWWidth | CWHeight, values);
2377 <li class="subtitle"><a name="winstack">Changing windows stacking order: raise and lower</a></li>
2379 Until now, we changed properties of a single window. We'll see
2380 that there are properties that relate to the window and other
2381 windows. One of hem is the stacking order. That is, the order
2382 in which the windows are layered on top of each other. The
2383 front-most window is said to be on the top of the stack, while
2384 the back-most window is at the bottom of the stack. Here is
2385 how to manipulate our windows stack order:
2388 const static CARD32 values[] = { Above };
2390 /* The connection c and the window win are supposed to be defined */
2392 /* Move the window on the top of the stack */
2393 XCBConfigureWindow (c, win, CWStackMode, values);
2396 const static CARD32 values[] = { Below };
2398 /* The connection c and the window win are supposed to be defined */
2400 /* Move the window on the bottom of the stack */
2401 XCBConfigureWindow (c, win, CWStackMode, values);
2403 <li class="subtitle"><a name="wingetinfo">Getting information about a window</a></li>
2405 Just like we can set various attributes of our windows, we can
2406 also ask the X server supply the current values of these
2407 attributes. For example, we can check where a window is
2408 located on the screen, what is its current size, whether it is
2409 mapped or not, etc. The structure that contains some of this
2415 CARD8 depth; /* depth of the window */
2418 XCBWINDOW root; /* Id of the root window *>
2419 INT16 x; /* X coordinate of the window's location */
2420 INT16 y; /* Y coordinate of the window's location */
2421 CARD16 width; /* Width of the window */
2422 CARD16 height; /* Height of the window */
2423 CARD16 border_width; /* Width of the window's border */
2424 } XCBGetGeometryRep;
2427 XCB fill this structure with two functions:
2430 XCBGetGeometryCookie XCBGetGeometry (XCBConnection *c,
2431 XCBDRAWABLE drawable);
2432 XCBGetGeometryRep *XCBGetGeometryReply (XCBConnection *c,
2433 XCBGetGeometryCookie cookie,
2434 XCBGenericError **e);
2437 You use them as follows:
2442 XCBGetGeometryRep *geom;
2444 /* You initialize c and win */
2446 geom = XCBGetGeometryReply (c, XCBGetGeometry (c, win), 0);
2448 /* Do something with the fields of geom */
2453 Remark that you have to free the structure, as
2454 <span class="code">XCBGetGeometryReply</span> allocates a
2458 One problem is that the returned location of the window is
2459 relative to its parent window. This makes these coordinates
2460 rather useless for any window manipulation functions, like
2461 moving it on the screen. In order to overcome this problem, we
2462 need to take a two-step operation. First, we find out the Id
2463 of the parent window of our window. We then translate the
2464 above relative coordinates to the screen coordinates.
2467 To get the Id of the parent window, we need this structure:
2476 XCBWINDOW parent; /* Id of the parent window */
2477 CARD16 children_len;
2482 To fill this structure, we use these two functions:
2485 XCBQueryTreeCookie XCBQueryTree (XCBConnection *c,
2487 XCBQueryTreeRep *XCBQueryTreeReply (XCBConnection *c,
2488 XCBQueryTreeCookie cookie,
2489 XCBGenericError **e);
2492 The translated coordinates will be found in this structure:
2501 CARD16 dst_x; /* Translated x coordinate */
2502 CARD16 dst_y; /* Translated y coordinate */
2503 } XCBTranslateCoordinatesRep;
2506 As usual, we need two functions to fill this structure:
2509 XCBTranslateCoordinatesCookie XCBTranslateCoordinates (XCBConnection *c,
2510 XCBWINDOW src_window,
2511 XCBWINDOW dst_window,
2514 XCBTranslateCoordinatesRep *XCBTranslateCoordinatesReply (XCBConnection *c,
2515 XCBTranslateCoordinatesCookie cookie,
2516 XCBGenericError **e);
2519 We use them as follows:
2524 XCBGetGeometryRep *geom;
2525 XCBQueryTreeRep *tree;
2526 XCBTranslateCoordinatesRep *trans;
2528 /* You initialize c and win */
2530 geom = XCBGetGeometryReply (c, XCBGetGeometry (c, win), 0);
2534 tree = XCBQueryTreeReply (c, XCBQueryTree (c, win), 0);
2538 trans = XCBTranslateCoordinatesReply (c,
2539 XCBTranslateCoordinates (c,
2542 geom->x, geom->y),
2547 /* the translated coordinates are in trans->dst_x and trans->dst_y */
2554 Of course, as for <span class="code">geom</span>,
2555 <span class="code">tree</span> and
2556 <span class="code">trans</span> have to be freed.
2559 The work is a bit hard, but XCB is a very low-level library.
2562 <b>TODO:</b> the utilization of these functions should be a
2563 prog, which displays the coordinates of the window.
2566 There is another structure that gives informations about our window:
2571 CARD8 backing_store;
2574 XCBVISUALID visual; /* Visual of the window */
2578 CARD32 backing_planes;
2579 CARD32 backing_pixel;
2581 BOOL map_is_installed;
2582 CARD8 map_state; /* Map state of the window */
2583 BOOL override_redirect;
2584 XCBCOLORMAP colormap; /* Colormap of the window */
2585 CARD32 all_event_masks;
2586 CARD32 your_event_mask;
2587 CARD16 do_not_propagate_mask;
2588 } XCBGetWindowAttributesRep;
2591 XCB supplies these two functions to fill it:
2594 XCBGetWindowAttributesCookie XCBGetWindowAttributes (XCBConnection *c,
2596 XCBGetWindowAttributesRep *XCBGetWindowAttributesReply (XCBConnection *c,
2597 XCBGetWindowAttributesCookie cookie,
2598 XCBGenericError **e);
2601 You use them as follows:
2606 XCBGetWindowAttributesRep *attr;
2608 /* You initialize c and win */
2610 attr = XCBGetWindowAttributesReply (c, XCBGetWindowAttributes (c, win), 0);
2615 /* Do something with the fields of attr */
2620 As for <span class="code">geom</span>,
2621 <span class="code">attr</span> has to be freed.
2624 <li class="title"><a name="usecolor">Using colors to paint the rainbow</a></li>
2626 Up until now, all our painting operation were done using black
2627 and white. We will (finally) see now how to draw using colors.
2630 <li class="subtitle"><a name="colormap">Color maps</a></li>
2632 In the beginning, there were not enough colors. Screen
2633 controllers could only support a limited number of colors
2634 simultaneously (initially 2, then 4, 16 and 256). Because of
2635 this, an application could not just ask to draw in a "light
2636 purple-red" color, and expect that color to be available. Each
2637 application allocated the colors it needed, and when all the
2638 color entries (4, 16, 256 colors) were in use, the next color
2639 allocation would fail.
2642 Thus, the notion of "a color map" was introduced. A color map
2643 is a table whose size is the same as the number of
2644 simultaneous colors a given screen controller. Each entry
2645 contained the RGB (Red, Green and Blue) values of a different
2646 color (all colors can be drawn using some combination of red,
2647 green and blue). When an application wants to draw on the
2648 screen, it does not specify which color to use. Rather, it
2649 specifies which color entry of some color map to be used
2650 during this drawing. Change the value in this color map entry
2651 and the drawing will use a different color.
2654 In order to be able to draw using colors that got something to
2655 do with what the programmer intended, color map allocation
2656 functions are supplied. You could ask to allocate entry for a
2657 color with a set of RGB values. If one already existed, you
2658 would get its index in the table. If none existed, and the
2659 table was not full, a new cell would be allocated to contain
2660 the given RGB values, and its index returned. If the table was
2661 full, the procedure would fail. You could then ask to get a
2662 color map entry with a color that is closest to the one you
2663 were asking for. This would mean that the actual drawing on
2664 the screen would be done using colors similar to what you
2665 wanted, but not the same.
2668 On today's more modern screens where one runs an X server with
2669 support for 16 million colors, this limitation looks a little
2670 silly, but remember that there are still older computers with
2671 older graphics cards out there. Using color map, support for
2672 these screen becomes transparent to you. On a display
2673 supporting 16 million colors, any color entry allocation
2674 request would succeed. On a display supporting a limited
2675 number of colors, some color allocation requests would return
2676 similar colors. It won't look as good, but your application
2679 <li class="subtitle"><a name="colormapalloc">Allocating and freeing Color Maps</a></li>
2681 When you draw using XCB, you can choose to use the standard
2682 color map of the screen your window is displayed on, or you
2683 can allocate a new color map and apply it to a window. In the
2684 latter case, each time the mouse moves onto your window, the
2685 screen color map will be replaced by your window's color map,
2686 and you'll see all the other windows on screen change their
2687 colors into something quite bizzare. In fact, this is the
2688 effect you get with X applications that use the "-install"
2689 command line option.
2692 In XCB, a color map is (as often in X) an Id:
2700 In order to access the screen's default color map, you just
2701 have to retrieve the <span class="code">default_colormap</span>
2702 field of the <span class="code">XCBSCREEN</span> structure
2704 <a href="#screen">Checking basic information about a connection</a>):
2707 #include <stdio.h>
2709 #include <X11/XCB/xcb.h>
2712 main (int argc, char *argv[])
2716 XCBCOLORMAP colormap;
2718 /* Open the connection to the X server and get the first screen */
2719 c = XCBConnect (NULL, NULL);
2720 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2722 colormap = screen->default_colormap;
2728 This will return the color map used by default on the first
2729 screen (again, remember that an X server may support several
2730 different screens, each of which might have its own resources).
2733 The other option, that of allocating a new colormap, works as
2734 follows. We first ask the X server to give an Id to our color
2735 map, with this function:
2738 XCBCOLORMAP XCBCOLORMAPNew (XCBConnection *c);
2741 Then, we create the color map with
2744 XCBVoidCookie XCBCreateColormap (XCBConnection *c, /* Pointer to the XCBConnection structure */
2745 BYTE alloc, /* Colormap entries to be allocated (AllocNone or AllocAll) */
2746 XCBCOLORMAP mid, /* Id of the color map */
2747 XCBWINDOW window, /* Window on whose screen the colormap will be created */
2748 XCBVISUALID visual); /* Id of the visual supported by the screen */
2751 Here is an example of creation of a new color map:
2754 #include <X11/XCB/xcb.h>
2757 main (int argc, char *argv[])
2764 /* Open the connection to the X server and get the first screen */
2765 c = XCBConnect (NULL, NULL);
2766 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2768 /* We create the window win here*/
2770 cmap = XCBCOLORMAPNew (c);
2771 XCBCreateColormap (c, AllocNone, cmap, win, screen->root_visual);
2777 Note that the window parameter is only used to allow the X
2778 server to create the color map for the given screen. We can
2779 then use this color map for any window drawn on the same screen.
2782 To free a color map, it suffices to use this function:
2785 XCBVoidCookie XCBFreeColormap (XCBConnection *c, /* The connection */
2786 XCBCOLORMAP cmap); /* The color map */
2794 <li>XCreateColormap ()</li>
2799 <li>XCBCOLORMAPNew ()</li>
2800 <li>XCBCreateColormap ()</li>
2805 <li>XFreeColormap ()</li>
2810 <li>XCBFreeColormap ()</li>
2815 <li class="subtitle"><a name="alloccolor">Allocating and freeing a color entry</a></li>
2817 Once we got access to some color map, we can start allocating
2818 colors. The informations related to a color are stored in the
2819 following structure:
2827 CARD16 red; /* The red component */
2828 CARD16 green; /* The green component */
2829 CARD16 blue; /* The blue component */
2831 CARD32 pixel; /* The entry in the color map, supplied by the X server */
2835 XCB supplies these two functions to fill it:
2838 XCBAllocColorCookie XCBAllocColor (XCBConnection *c,
2843 XCBAllocColorRep *XCBAllocColorReply (XCBConnection *c,
2844 XCBAllocColorCookie cookie,
2845 XCBGenericError **e);
2848 The fuction <span class="code">XCBAllocColor()</span> takes the
2849 3 RGB components as parameters (red, green and blue). Here is an
2850 example of using these functions:
2853 #include <malloc.h>
2855 #include <X11/XCB/xcb.h>
2858 main (int argc, char *argv[])
2864 XCBAllocColorRep *rep;
2866 /* Open the connection to the X server and get the first screen */
2867 c = XCBConnect (NULL, NULL);
2868 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2870 /* We create the window win here*/
2872 cmap = XCBCOLORMAPNew (c);
2873 XCBCreateColormap (c, AllocNone, cmap, win, screen->root_visual);
2875 rep = XCBAllocColorReply (c, XCBAllocColor (c, cmap, 65535, 0, 0), 0);
2880 /* Do something with r->pixel or the components */
2888 As <span class="code">XCBAllocColorReply()</span> allocates
2889 memory, you have to free <span class="code">rep</span>.
2892 <b>TODO</b>: Talk about freeing colors.
2895 <li class="title"><a name="pixmaps">X Bitmaps and Pixmaps</a></li>
2897 One thing many so-called "Multi-Media" applications need to do,
2898 is display images. In the X world, this is done using bitmaps
2899 and pixmaps. We have already seen some usage of them when
2900 setting an icon for our application. Lets study them further,
2901 and see how to draw these images inside a window, along side the
2902 simple graphics and text we have seen so far.
2905 One thing to note before delving further, is that XCB (nor Xlib)
2906 supplies no means of manipulating popular image formats, such as
2907 gif, png, jpeg or tiff. It is up to the programmer (or to higher
2908 level graphics libraries) to translate these image formats into
2909 formats that the X server is familiar with (x bitmaps and x
2913 <li class="subtitle"><a name="pixmapswhat">What is a X Bitmap? An X Pixmap?</a></li>
2915 An X bitmap is a two-color image stored in a format specific
2916 to the X window system. When stored in a file, the bitmap data
2917 looks like a C source file. It contains variables defining the
2918 width and the height of the bitmap, an array containing the
2919 bit values of the bitmap (the size of the array is
2920 weight*height), and an optional hot-spot location (that will
2921 be explained later, when discussing mouse cursors).
2924 An X pixmap is a format used to stored images in the memory of
2925 an X server. This format can store both black and white images
2926 (such as x bitmaps) as well as color images. It is the only
2927 image format supported by the X protocol, and any image to be
2928 drawn on screen, should be first translated into this format.
2931 In actuality, an X pixmap can be thought of as a window that
2932 does not appear on the screen. Many graphics operations that
2933 work on windows, will also work on pixmaps. Indeed, the type
2934 of X pixmap in XCB is an Id like a window:
2942 In order to make the difference between a window and a pixmap,
2943 XCB introduces a drawable type, which is a <b>union</b>
2952 in order to avoid confusion between a window and a pixmap. The
2953 operations that will work indifferently on a window or a pixmap
2954 will require a <span class="code">XCBDRAWABLE</span>
2958 Remark: In Xlib, there is no specific difference between a
2959 <span class="code">Drawable</span>, a
2960 <span class="code">Pixmap</span> or a
2961 <span class="code">Window</span>: all are 32 bit long
2965 <li class="subtitle"><a name="pixmapscreate">Creating a pixmap</a></li>
2967 Sometimes we want to create an un-initialized pixmap, so we
2968 can later draw into it. This is useful for image drawing
2969 programs (creating a new empty canvas will cause the creation
2970 of a new pixmap on which the drawing can be stored). It is
2971 also useful when reading various image formats: we load the
2972 image data into memory, create a pixmap on the server, and
2973 then draw the decoded image data onto that pixmap.
2976 To create a new pixmap, we first ask the X server to give an
2977 Id to our pixmap, with this function:
2980 XCBPIXMAP XCBPIXMAPNew (XCBConnection *c);
2983 Then, XCB supplies the following function to create new pixmaps:
2986 XCBVoidCookie XCBCreatePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
2987 CARD8 depth, /* Depth of the screen */
2988 XCBPIXMAP pid, /* Id of the pixmap */
2989 XCBDRAWABLE drawable,
2990 CARD16 width, /* Width of the window (in pixels) */
2991 CARD16 height); /* Height of the window (in pixels) */
2994 <b>TODO</b>: Explain the drawable parameter, and give an
2995 example (like xpoints.c)
2997 <li class="subtitle"><a name="pixmapsdraw"></a>Drawing a pixmap in a window</li>
2999 Once we got a handle to a pixmap, we can draw it on some
3000 window, using the following function:
3003 XCBVoidCookie XCBCopyArea (XCBConnection *c, /* Pointer to the XCBConnection structure */
3004 XCBDRAWABLE src_drawable, /* The Drawable we want to paste */
3005 XCBDRAWABLE dst_drawable, /* The Drawable on which we copy the previous Drawable */
3006 XCBGCONTEXT gc, /* A Graphic Context */
3007 INT16 src_x, /* Top left x coordinate of the region we want to copy */
3008 INT16 src_y, /* Top left y coordinate of the region we want to copy */
3009 INT16 dst_x, /* Top left x coordinate of the region where we want to copy */
3010 INT16 dst_y, /* Top left y coordinate of the region where we want to copy */
3011 CARD16 width, /* Width of the region we want to copy */
3012 CARD16 height); /* Height of the region we want to copy */
3015 As you can see, we could copy the whole pixmap, as well as
3016 only a given rectangle of the pixmap. This is useful to
3017 optimize the drawing speed: we could copy only what we have
3018 modified in the pixmap.
3021 <b>One important note should be made</b>: it is possible to
3022 create pixmaps with different depths on the same screen. When
3023 we perform copy operations (a pixmap onto a window, etc), we
3024 should make sure that both source and target have the same
3025 depth. If they have a different depth, the operation would
3026 fail. The exception to this is if we copy a specific bit plane
3027 of the source pixmap using the
3028 <span class="code">XCBCopyPlane</span> function. In such an
3029 event, we can copy a specific plain to the target window (in
3030 actuality, setting a specific bit in the color of each pixel
3031 copied). This can be used to generate strange graphic effects
3032 in widow, but that is beyond the scope of this tutorial.
3034 <li class="subtitle"><a name="pixmapsfree"></a>Freeing a pixmap</li>
3036 Finally, when we are done using a given pixmap, we should free
3037 it, in order to free resources of the X server. This is done
3038 using this function:
3041 XCBVoidCookie XCBFreePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
3042 XCBPIXMAP pixmap); /* A given pixmap */
3045 Of course, after having freed it, we must not try accessing
3049 <b>TODO</b>: Give an example, or a link to xpoints.c
3052 <li class="title"><a name="translation">Translation of basic Xlib functions and macros</a></li>
3054 The problem when you want to port an Xlib program to XCB is that
3055 you don't know if the Xlib function that you want to "translate"
3056 is a X Window one or an Xlib macro. In that section, we describe
3057 a way to translate the usual functions or macros that Xlib
3058 provides. It's usually just a member of a structure.
3061 <li class="subtitle"><a name="displaystructure">Members of the Display structure</a></li>
3062 In this section, we look at how to translate the macros that
3063 return some members of the <span class="code">Display</span>
3064 structure. They are obtained by using a function that requires a
3065 <span class="code">XCBConnection *</span> or a member of the
3066 <span class="code">XCBConnSetupSuccessRep</span> structure
3067 (via the function <span class="code">XCBGetSetup</span>), or
3068 a function that requires that structure.
3070 <li class="subtitle"><a name="ConnectionNumber">ConnectionNumber</a></li>
3072 This number is the file descriptor that connects the client
3073 to the server. You just have to use that function:
3076 int XCBGetFileDescriptor(XCBConnection *c);
3078 <li class="subtitle"><a name="DefaultScreen"></a>DefaultScreen</li>
3080 That number is not stored by XCB. It is returned in the
3081 second parameter of the function <span class="code"><a href="#openconn">XCBConnect</a></span>.
3082 Hence, you have to store it yourself if you want to use
3083 it. Then, to get the <span class="code">XCBSCREEN</span>
3084 structure, you have to iterate on the screens.
3085 The equivalent function of the Xlib's
3086 <span class="code">ScreenOfDisplay</span> function can be
3087 found <a href="#ScreenOfDisplay">below</a>. OK, here is the
3088 small piece of code to get that number:
3092 int screen_default_nbr;
3094 /* you pass the name of the display you want to XCBConnect */
3096 c = XCBConnect (display_name, &screen_default_nbr);
3098 /* screen_default_nbr contains now the number of the default screen */
3100 <li class="subtitle"><a name="QLength"></a>QLength</li>
3104 <li class="subtitle"><a name="ScreenCount"></a>ScreenCount</li>
3106 You get the count of screens with the functions
3107 <span class="code">XCBGetSetup</span>
3109 <span class="code">XCBConnSetupSuccessRepRootsIter</span>
3110 (if you need to iterate):
3116 /* you init the connection */
3118 screen_count = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).rem;
3120 /* screen_count contains now the count of screens */
3123 If you don't want to iterate over the screens, a better way
3124 to get that number is to use
3125 <span class="code">XCBConnSetupSuccessRepRootsLength</span>:
3131 /* you init the connection */
3133 screen_count = XCBConnSetupSuccessRepRootsLength (XCBGetSetup (c));
3135 /* screen_count contains now the count of screens */
3137 <li class="subtitle"><a name="ServerVendor"></a>ServerVendor</li>
3139 You get the name of the vendor of the server hardware with
3140 the functions <span class="code">XCBGetSetup</span>
3143 class="code">XCBConnSetupSuccessRepVendor</span>. Beware
3144 that, unlike Xlib, the string returned by XCB is not
3145 necessarily null-terminaled:
3149 char *vendor = NULL;
3152 /* you init the connection */
3153 length = XCBConnSetupSuccessRepVendorLength (XCBGetSetup (c));
3154 vendor = (char *)malloc (length + 1);
3156 memcpy (vendor, XCBConnSetupSuccessRepVendor (XCBGetSetup (c)), length);
3157 vendor[length] = '\0';
3159 /* vendor contains now the name of the vendor. Must be freed when not used anymore */
3161 <li class="subtitle"><a name="ProtocolVersion"></a>ProtocolVersion</li>
3163 You get the major version of the protocol in the
3164 <span class="code">XCBConnSetupSuccessRep</span>
3165 structure, with the function <span class="code">XCBGetSetup</span>:
3169 CARD16 protocol_major_version;
3171 /* you init the connection */
3173 protocol_major_version = XCBGetSetup (c)->protocol_major_version;
3175 /* protocol_major_version contains now the major version of the protocol */
3177 <li class="subtitle"><a name="ProtocolRevision"></a>ProtocolRevision</li>
3179 You get the minor version of the protocol in the
3180 <span class="code">XCBConnSetupSuccessRep</span>
3181 structure, with the function <span class="code">XCBGetSetup</span>:
3185 CARD16 protocol_minor_version;
3187 /* you init the connection */
3189 protocol_minor_version = XCBGetSetup (c)->protocol_minor_version;
3191 /* protocol_minor_version contains now the minor version of the protocol */
3193 <li class="subtitle"><a name="VendorRelease"></a>VendorRelease</li>
3195 You get the number of the release of the server hardware in the
3196 <span class="code">XCBConnSetupSuccessRep</span>
3197 structure, with the function <span class="code">XCBGetSetup</span>:
3201 CARD32 release_number;
3203 /* you init the connection */
3205 release_number = XCBGetSetup (c)->release_number;
3207 /* release_number contains now the number of the release of the server hardware */
3209 <li class="subtitle"><a name="DisplayString"></a>DisplayString</li>
3211 The name of the display is not stored in XCB. You have to
3212 store it by yourself.
3214 <li class="subtitle"><a name="BitmapUnit"></a>BitmapUnit</li>
3216 You get the bitmap scanline unit in the
3217 <span class="code">XCBConnSetupSuccessRep</span>
3218 structure, with the function <span class="code">XCBGetSetup</span>:
3222 CARD8 bitmap_format_scanline_unit;
3224 /* you init the connection */
3226 bitmap_format_scanline_unit = XCBGetSetup (c)->bitmap_format_scanline_unit;
3228 /* bitmap_format_scanline_unit contains now the bitmap scanline unit */
3230 <li class="subtitle"><a name="BitmapBitOrder"></a>BitmapBitOrder</li>
3232 You get the bitmap bit order in the
3233 <span class="code">XCBConnSetupSuccessRep</span>
3234 structure, with the function <span class="code">XCBGetSetup</span>:
3238 CARD8 bitmap_format_bit_order;
3240 /* you init the connection */
3242 bitmap_format_bit_order = XCBGetSetup (c)->bitmap_format_bit_order;
3244 /* bitmap_format_bit_order contains now the bitmap bit order */
3246 <li class="subtitle"><a name="BitmapPad"></a>BitmapPad</li>
3248 You get the bitmap scanline pad in the
3249 <span class="code">XCBConnSetupSuccessRep</span>
3250 structure, with the function <span class="code">XCBGetSetup</span>:
3254 CARD8 bitmap_format_scanline_pad;
3256 /* you init the connection */
3258 bitmap_format_scanline_pad = XCBGetSetup (c)->bitmap_format_scanline_pad;
3260 /* bitmap_format_scanline_pad contains now the bitmap scanline pad */
3262 <li class="subtitle"><a name="ImageByteOrder"></a>ImageByteOrder</li>
3264 You get the image byte order in the
3265 <span class="code">XCBConnSetupSuccessRep</span>
3266 structure, with the function <span class="code">XCBGetSetup</span>:
3270 CARD8 image_byte_order;
3272 /* you init the connection */
3274 image_byte_order = XCBGetSetup (c)->image_byte_order;
3276 /* image_byte_order contains now the image byte order */
3279 <li class="subtitle"><a name="screenofdisplay">ScreenOfDisplay related functions</a></li>
3281 in Xlib, <span class="code">ScreenOfDisplay</span> returns a
3282 <span class="code">Screen</span> structure that contains
3283 several characteristics of your screen. XCB has a similar
3284 structure (<span class="code">XCBSCREEN</span>),
3285 but the way to obtain it is a bit different. With
3286 Xlib, you just provide the number of the screen and you grab it
3287 from an array. With XCB, you iterate over all the screens to
3288 obtain the one you want. The complexity of this operation is
3289 O(n). So the best is to store this structure if you use
3290 it often. See <a href="#ScreenOfDisplay">ScreenOfDisplay</a> just below.
3293 Xlib provides generally two functions to obtain the characteristics
3294 related to the screen. One with the display and the number of
3295 the screen, which calls <span class="code">ScreenOfDisplay</span>,
3296 and the other that uses the <span class="code">Screen</span> structure.
3297 This might be a bit confusing. As mentioned above, with XCB, it
3298 is better to store the <span class="code">XCBSCREEN</span>
3299 structure. Then, you have to read the members of this
3300 structure. That's why the Xlib functions are put by pairs (or
3301 more) as, with XCB, you will use the same code.
3304 <li class="subtitle"><a name="ScreenOfDisplay">ScreenOfDisplay</a></li>
3306 This function returns the Xlib <span class="code">Screen</span>
3307 structure. With XCB, you iterate over all the screens and
3308 once you get the one you want, you return it:
3310 <pre class="code"><a name="ScreenOfDisplay"></a>
3311 XCBSCREEN *ScreenOfDisplay (XCBConnection *c,
3316 iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
3317 for (; iter.rem; --screen, XCBSCREENNext (&iter))
3325 As mentioned above, you might want to store the value
3326 returned by this function.
3329 All the functions below will use the result of that
3330 function, as they just grab a specific member of the
3331 <span class="code">XCBSCREEN</span> structure.
3333 <li class="subtitle"><a name="DefaultScreenOfDisplay"></a>DefaultScreenOfDisplay</li>
3335 It is the default screen that you obtain when you connect to
3336 the X server. It suffices to call the <a href="#ScreenOfDisplay">ScreenOfDisplay</a>
3337 function above with the connection and the number of the
3342 int screen_default_nbr;
3343 XCBSCREEN *default_screen; /* the returned default screen */
3345 /* you pass the name of the display you want to XCBConnect */
3347 c = XCBConnect (display_name, &screen_default_nbr);
3348 default_screen = ScreenOfDisplay (c, screen_default_nbr);
3350 /* default_screen contains now the default root window, or a NULL window if no screen is found */
3352 <li class="subtitle"><a name="RootWindow">RootWindow / RootWindowOfScreen</a></li>
3359 XCBWINDOW root_window = { 0 }; /* the returned window */
3361 /* you init the connection and screen_nbr */
3363 screen = ScreenOfDisplay (c, screen_nbr);
3365 root_window = screen->root;
3367 /* root_window contains now the root window, or a NULL window if no screen is found */
3369 <li class="subtitle"><a name="DefaultRootWindow">DefaultRootWindow</a></li>
3371 It is the root window of the default screen. So, you call
3372 <a name="ScreenOfDisplay">ScreenOfDisplay</a> with the
3373 default screen number and you get the
3374 <a href="#RootWindow">root window</a> as above:
3379 int screen_default_nbr;
3380 XCBWINDOW root_window = { 0 }; /* the returned root window */
3382 /* you pass the name of the display you want to XCBConnect */
3384 c = XCBConnect (display_name, &screen_default_nbr);
3385 screen = ScreenOfDisplay (c, screen_default_nbr);
3387 root_window = screen->root;
3389 /* root_window contains now the default root window, or a NULL window if no screen is found */
3391 <li class="subtitle"><a name="DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a></li>
3393 While a Visual is, in Xlib, a structure, in XCB, there are
3394 two types: <span class="code">XCBVISUALID</span>, which is
3395 the Id of the visual, and <span class="code">XCBVISUALTYPE</span>,
3396 which corresponds to the Xlib Visual. To get the Id of the
3397 visual of a screen, just get the
3398 <span class="code">root_visual</span>
3399 member of a <span class="code">XCBSCREEN</span>:
3405 XCBVISUALID root_visual = { 0 }; /* the returned visual Id */
3407 /* you init the connection and screen_nbr */
3409 screen = ScreenOfDisplay (c, screen_nbr);
3411 root_visual = screen->root_visual;
3413 /* root_visual contains now the value of the Id of the visual, or a NULL visual if no screen is found */
3416 To get the <span class="code">XCBVISUALTYPE</span>
3417 structure, it's a bit less easy. You have to get the
3418 <span class="code">XCBSCREEN</span> structure that you want,
3419 get its <span class="code">root_visual</span> member,
3420 then iterate over the <span class="code">XCBDEPTH</span>s
3421 and the <span class="code">XCBVISUALTYPE</span>s, and compare
3422 the <span class="code">XCBVISUALID</span> of these <span class="code">XCBVISUALTYPE</span>s:
3423 with <span class="code">root_visual</span>:
3429 XCBVISUALID root_visual = { 0 };
3430 XCBVISUATYPE *visual_type = NULL; /* the returned visual type */
3432 /* you init the connection and screen_nbr */
3434 screen = ScreenOfDisplay (c, screen_nbr);
3437 XCBDEPTHIter depth_iter;
3439 depth_iter = XCBSCREENAllowedDepthsIter (screen);
3440 for (; depth_iter.rem; XCBDEPTHNext (&depth_iter))
3442 XCBVISUALTYPEIter visual_iter;
3444 visual_iter = XCBDEPTHVisualsIter (depth_iter.data);
3445 for (; visual_iter.rem; XCBVISUALTYPENext (&visual_iter))
3447 if (screen->root_visual.id == visual_iter.data->visual_id.id)
3449 visual_type = visual_iter.data;
3456 /* visual_type contains now the visual structure, or a NULL visual structure if no screen is found */
3458 <li class="subtitle"><a name="DefaultGC">DefaultGC / DefaultGCOfScreen</a></li>
3460 This default Graphic Context is just a newly created Graphic
3461 Context, associated to the root window of a
3462 <span class="code">XCBSCREEN</span>,
3463 using the black white pixels of that screen:
3469 XCBGCONTEXT gc = { 0 }; /* the returned default graphic context */
3471 /* you init the connection and screen_nbr */
3473 screen = ScreenOfDisplay (c, screen_nbr);
3480 gc = XCBGCONTEXTNew (c);
3481 draw.window = screen->root;
3482 mask = GCForeground | GCBackground;
3483 values[0] = screen->black_pixel;
3484 values[1] = screen->white_pixel;
3485 XCBCreateGC (c, gc, draw, mask, values);
3488 /* gc contains now the default graphic context */
3490 <li class="subtitle"><a name="BlackPixel">BlackPixel / BlackPixelOfScreen</a></li>
3492 It is the Id of the black pixel, which is in the structure
3493 of an <span class="code">XCBSCREEN</span>.
3499 CARD32 black_pixel = 0; /* the returned black pixel */
3501 /* you init the connection and screen_nbr */
3503 screen = ScreenOfDisplay (c, screen_nbr);
3505 black_pixel = screen->black_pixel;
3507 /* black_pixel contains now the value of the black pixel, or 0 if no screen is found */
3509 <li class="subtitle"><a name="WhitePixel">WhitePixel / WhitePixelOfScreen</a></li>
3511 It is the Id of the white pixel, which is in the structure
3512 of an <span class="code">XCBSCREEN</span>.
3518 CARD32 white_pixel = 0; /* the returned white pixel */
3520 /* you init the connection and screen_nbr */
3522 screen = ScreenOfDisplay (c, screen_nbr);
3524 white_pixel = screen->white_pixel;
3526 /* white_pixel contains now the value of the white pixel, or 0 if no screen is found */
3528 <li class="subtitle"><a name="DisplayWidth">DisplayWidth / WidthOfScreen</a></li>
3530 It is the width in pixels of the screen that you want, and
3531 which is in the structure of the corresponding
3532 <span class="code">XCBSCREEN</span>.
3538 CARD32 width_in_pixels = 0; /* the returned width in pixels */
3540 /* you init the connection and screen_nbr */
3542 screen = ScreenOfDisplay (c, screen_nbr);
3544 width_in_pixels = screen->width_in_pixels;
3546 /* width_in_pixels contains now the width in pixels, or 0 if no screen is found */
3548 <li class="subtitle"><a name="DisplayHeight">DisplayHeight / HeightOfScreen</a></li>
3550 It is the height in pixels of the screen that you want, and
3551 which is in the structure of the corresponding
3552 <span class="code">XCBSCREEN</span>.
3558 CARD32 height_in_pixels = 0; /* the returned height in pixels */
3560 /* you init the connection and screen_nbr */
3562 screen = ScreenOfDisplay (c, screen_nbr);
3564 height_in_pixels = screen->height_in_pixels;
3566 /* height_in_pixels contains now the height in pixels, or 0 if no screen is found */
3568 <li class="subtitle"><a name="DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a></li>
3570 It is the width in millimeters of the screen that you want, and
3571 which is in the structure of the corresponding
3572 <span class="code">XCBSCREEN</span>.
3578 CARD32 width_in_millimeters = 0; /* the returned width in millimeters */
3580 /* you init the connection and screen_nbr */
3582 screen = ScreenOfDisplay (c, screen_nbr);
3584 width_in_millimeters = screen->width_in_millimeters;
3586 /* width_in_millimeters contains now the width in millimeters, or 0 if no screen is found */
3588 <li class="subtitle"><a name="DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a></li>
3590 It is the height in millimeters of the screen that you want, and
3591 which is in the structure of the corresponding
3592 <span class="code">XCBSCREEN</span>.
3598 CARD32 height_in_millimeters = 0; /* the returned height in millimeters */
3600 /* you init the connection and screen_nbr */
3602 screen = ScreenOfDisplay (c, screen_nbr);
3604 height_in_millimeters = screen->height_in_millimeters;
3606 /* height_in_millimeters contains now the height in millimeters, or 0 if no screen is found */
3608 <li class="subtitle"><a name="DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a></li>
3610 It is the depth (in bits) of the root window of the
3611 screen. You get it from the <span class="code">XCBSCREEN</span> structure.
3617 CARD8 root_depth = 0; /* the returned depth of the root window */
3619 /* you init the connection and screen_nbr */
3621 screen = ScreenOfDisplay (c, screen_nbr);
3623 root_depth = screen->root_depth;
3625 /* root_depth contains now the depth of the root window, or 0 if no screen is found */
3627 <li class="subtitle"><a name="DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a></li>
3629 This is the default colormap of the screen (and not the
3630 (default) colormap of the default screen !). As usual, you
3631 get it from the <span class="code">XCBSCREEN</span> structure:
3637 XCBCOLORMAP default_colormap = { 0 }; /* the returned default colormap */
3639 /* you init the connection and screen_nbr */
3641 screen = ScreenOfDisplay (c, screen_nbr);
3643 default_colormap = screen->default_colormap;
3645 /* default_colormap contains now the default colormap, or a NULL colormap if no screen is found */
3647 <li class="subtitle"><a name="MinCmapsOfScreen"></a>MinCmapsOfScreen</li>
3649 You get the minimum installed colormaps in the <span class="code">XCBSCREEN</span> structure:
3655 CARD16 min_installed_maps = 0; /* the returned minimum installed colormaps */
3657 /* you init the connection and screen_nbr */
3659 screen = ScreenOfDisplay (c, screen_nbr);
3661 min_installed_maps = screen->min_installed_maps;
3663 /* min_installed_maps contains now the minimum installed colormaps, or 0 if no screen is found */
3665 <li class="subtitle"><a name="MaxCmapsOfScreen"></a>MaxCmapsOfScreen</li>
3667 You get the maximum installed colormaps in the <span class="code">XCBSCREEN</span> structure:
3673 CARD16 max_installed_maps = 0; /* the returned maximum installed colormaps */
3675 /* you init the connection and screen_nbr */
3677 screen = ScreenOfDisplay (c, screen_nbr);
3679 max_installed_maps = screen->max_installed_maps;
3681 /* max_installed_maps contains now the maximum installed colormaps, or 0 if no screen is found */
3683 <li class="subtitle"><a name="DoesSaveUnders"></a>DoesSaveUnders</li>
3685 You know if <span class="code">save_unders</span> is set,
3686 by looking in the <span class="code">XCBSCREEN</span> structure:
3692 BOOL save_unders = 0; /* the returned value of save_unders */
3694 /* you init the connection and screen_nbr */
3696 screen = ScreenOfDisplay (c, screen_nbr);
3698 save_unders = screen->save_unders;
3700 /* save_unders contains now the value of save_unders, or FALSE if no screen is found */
3702 <li class="subtitle"><a name="DoesBackingStore"></a>DoesBackingStore</li>
3704 You know the value of <span class="code">backing_stores</span>,
3705 by looking in the <span class="code">XCBSCREEN</span> structure:
3711 BYTE backing_stores = 0; /* the returned value of backing_stores */
3713 /* you init the connection and screen_nbr */
3715 screen = ScreenOfDisplay (c, screen_nbr);
3717 backing_stores = screen->backing_stores;
3719 /* backing_stores contains now the value of backing_stores, or FALSE if no screen is found */
3721 <li class="subtitle"><a name="EventMaskOfScreen"></a>EventMaskOfScreen</li>
3723 To get the current input masks,
3724 you look in the <span class="code">XCBSCREEN</span> structure:
3730 CARD32 current_input_masks = 0; /* the returned value of current input masks */
3732 /* you init the connection and screen_nbr */
3734 screen = ScreenOfDisplay (c, screen_nbr);
3736 current_input_masks = screen->current_input_masks;
3738 /* current_input_masks contains now the value of the current input masks, or FALSE if no screen is found */
3741 <li class="subtitle"><a name="misc">Miscellaneous macros</a></li>
3743 <li class="subtitle"><a name="DisplayOfScreen"></a>DisplayOfScreen</li>
3745 in Xlib, the <span class="code">Screen</span> structure
3746 stores its associated <span class="code">Display</span>
3747 structure. This is not the case in the X Window protocol,
3748 hence, it's also not the case in XCB. So you have to store
3751 <li class="subtitle"><a name="DisplayCells"></a>DisplayCells / CellsOfScreen</li>
3753 To get the colormap entries,
3754 you look in the <span class="code">XCBVISUALTYPE</span>
3755 structure, that you grab like <a class="subsection" href="#DefaultVisual">here</a>:
3759 XCBVISUALTYPE *visual_type;
3760 CARD16 colormap_entries = 0; /* the returned value of the colormap entries */
3762 /* you init the connection and visual_type */
3765 colormap_entries = visual_type->colormap_entries;
3767 /* colormap_entries contains now the value of the colormap entries, or FALSE if no screen is found */