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 <meta http-equiv="content-type" content="text/html; charset=iso-8859-1">
9 <link href="xcb.css" rel="stylesheet" type="text/css">
14 Basic Graphics Programming With The XCB Library
18 <li><a class="section" href="#intro">Introduction</a>
19 <li><a class="section" href="#Xmodel">The client and server model of the X window system</a>
20 <li><a class="section" href="#asynch">GUI programming: the asynchronous model</a>
21 <li><a class="section" href="#notions">Basic XCB notions</a>
23 <li><a class="subsection" href="#conn">The X Connection</a>
24 <li><a class="subsection" href="#requestsreplies">Requests and replies: the Xlib killers</a>
25 <li><a class="subsection" href="#gc">The Graphics Context</a>
27 <li>Memory allocation for XCB structures
28 <li><a class="subsection" href="#events">Events</a>
30 <li><a class="section" href="#use">Using XCB-based programs</a>
32 <li><a class="subsection" href="#inst">Installation of XCB</a>
33 <li><a class="subsection" href="#comp">Compiling XCB-based programs</a>
35 <li><a class="section" href="#openconn">Opening and closing the connection to an X server</a>
36 <li><a class="section" href="#screen">Checking basic information about a connection</a>
37 <li><a class="section" href="#helloworld">Creating a basic window - the "hello world" program</a>
38 <li><a class="section" href="#drawing">Drawing in a window</a>
40 <li><a class="subsection" href="#allocgc">Allocating a Graphics Context</a>
41 <li><a class="subsection" href="#changegc">Changing the attributes of a Graphics Context</a>
42 <li><a class="subsection" href="#drawingprim">Drawing primitives: point, line, box, circle,...</a>
44 <li><a class="section" href="#xevents">X Events</a>
46 <li><a class="subsection" href="#register">Registering for event types using event masks</a>
47 <li><a class="subsection" href="#loop">Receiving events: writing the events loop</a>
48 <li><a class="subsection" href="#expose">Expose events</a>
49 <li><a class="subsection" href="#userinput">Getting user input</a>
51 <li><a class="subsubsection" href="#mousepressrelease">Mouse button press and release events</a>
52 <li><a class="subsubsection" href="#mousemvnt">Mouse movement events</a>
53 <li><a class="subsubsection" href="#mouseenter">Mouse pointer enter and leave events</a>
54 <li><a class="subsubsection" href="#focus">The keyboard focus</a>
55 <li><a class="subsubsection" href="#keypress">Keyboard press and release events</a>
57 <li><a class="subsection" href="#eventex">X events: a complete example</a>
59 <li><a class="section" href="#font">Handling text and fonts</a>
61 <li><a class="subsection" href="#fontstruct">The Font structure</a>
63 <li>Assigning a Font to a Graphic Context
64 <li>Drawing text in a window
68 <li>Root, parent and child windows
69 <li>Events propagation
71 <li><a class="section" href="#wm">Interacting with the window manager</a>
73 <li><a class="subsection" href="#wmprop">Window properties</a>
74 <li><a class="subsection" href="#wmname">Setting the window name and icon name</a>
75 <li>Setting preferred window size(s)
76 <li>Setting miscellaneous window manager hints
77 <li>Setting an application's icon
79 <li><a class="section" href="#winop">Simple window operations</a>
81 <li><a class="subsection" href="#winmap">Mapping and un-mapping a window</a>
82 <li><a class="subsection" href="#winconf">Configuring a window</a>
83 <li><a class="subsection" href="#winmove">Moving a window around the screen</a>
84 <li><a class="subsection" href="#winsize">Resizing a window</a>
85 <li><a class="subsection" href="#winstack">Changing windows stacking order: raise and lower</a>
86 <li>Iconifying and de-iconifying a window
87 <li><a class="subsection" href="#wingetinfo">Getting informations about a window</a>
89 <li><a class="section" href="#usecolor">Using colors to paint the rainbow</a>
91 <li><a class="subsection" href="#colormap">Color maps</a>
92 <li><a class="subsection" href="#colormapalloc">Allocating and freeing Color Maps</a>
93 <li><a class="subsection" href="#alloccolor">Allocating and freeing a color entry</a>
94 <li>Drawing with a color
96 <li><a class="section" href="#pixmaps">X Bitmaps and Pixmaps</a>
98 <li><a class="subsection" href="#pixmapswhat">What is a X Bitmap ? An X Pixmap ?</a>
99 <li>Loading a bitmap from a file
100 <li>Drawing a bitmap in a window
101 <li><a class="subsection" href="#pixmapscreate">Creating a pixmap</a>
102 <li><a class="subsection" href="#pixmapsdraw">Drawing a pixmap in a window</a>
103 <li><a class="subsection" href="#pixmapsfree">Freeing a pixmap</a>
105 <li>Messing with the mouse cursor
107 <li>Creating and destroying a mouse cursor
108 <li>Setting a window's mouse cursor
110 <li><a class="subsection" href="#translation">Translation of basic Xlib functions and macros</a>
112 <li><a class="subsection" href="#displaystructure">Members of the Display structure</a>
114 <li><a class="subsection" href="#ConnectionNumber">ConnectionNumber</a>
115 <li><a class="subsection" href="#DefaultScreen">DefaultScreen</a>
116 <li><a class="subsection" href="#QLength">QLength</a>
117 <li><a class="subsection" href="#ScreenCount">ScreenCount</a>
118 <li><a class="subsection" href="#ServerVendor">ServerVendor</a>
119 <li><a class="subsection" href="#ProtocolVersion">ProtocolVersion</a>
120 <li><a class="subsection" href="#ProtocolRevision">ProtocolRevision</a>
121 <li><a class="subsection" href="#VendorRelease">VendorRelease</a>
122 <li><a class="subsection" href="#DisplayString">DisplayString</a>
123 <li><a class="subsection" href="#BitmapUnit">BitmapUnit</a>
124 <li><a class="subsection" href="#BitmapBitOrder">BitmapBitOrder</a>
125 <li><a class="subsection" href="#BitmapPad">BitmapPad</a>
126 <li><a class="subsection" href="#ImageByteOrder">ImageByteOrder</a>
128 <li><a class="subsection" href="#screenofdisplay">ScreenOfDisplay related functions</a>
130 <li><a class="subsection" href="#ScreenOfDisplay">ScreenOfDisplay</a>
131 <li><a class="subsection" href="#DefaultScreenOfDisplay">DefaultScreenOfDisplay</a>
132 <li><a class="subsection" href="#RootWindow">RootWindow / RootWindowOfScreen</a>
133 <li><a class="subsection" href="#DefaultRootWindow">DefaultRootWindow</a>
134 <li><a class="subsection" href="#DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a>
135 <li><a class="subsection" href="#DefaultGC">DefaultGC / DefaultGCOfScreen</a>
136 <li><a class="subsection" href="#BlackPixel">BlackPixel / BlackPixelOfScreen</a>
137 <li><a class="subsection" href="#WhitePixel">WhitePixel / WhitePixelOfScreen</a>
138 <li><a class="subsection" href="#DisplayWidth">DisplayWidth / WidthOfScreen</a>
139 <li><a class="subsection" href="#DisplayHeight">DisplayHeight / HeightOfScreen</a>
140 <li><a class="subsection" href="#DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a>
141 <li><a class="subsection" href="#DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a>
142 <li><a class="subsection" href="#DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a>
143 <li><a class="subsection" href="#DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a>
144 <li><a class="subsection" href="#MinCmapsOfScreen">MinCmapsOfScreen</a>
145 <li><a class="subsection" href="#MaxCmapsOfScreen">MaxCmapsOfScreen</a>
146 <li><a class="subsection" href="#DoesSaveUnders">DoesSaveUnders</a>
147 <li><a class="subsection" href="#DoesBackingStore">DoesBackingStore</a>
148 <li><a class="subsection" href="#EventMaskOfScreen">EventMaskOfScreen</a>
150 <li><a class="subsection" href="#misc">Miscellaneaous macros</a>
152 <li><a class="subsection" href="#DisplayOfScreen">DisplayOfScreen</a>
153 <li><a class="subsection" href="#DisplayCells">DisplayCells / CellsOfScreen</a>
158 <div class="section">
160 <li class="title"><a name="intro">Introduction</a>
162 This tutorial is based on the
163 <a href="http://users.actcom.co.il/~choo/lupg/tutorials/xlib-programming/xlib-programming.html">Xlib Tutorial</a>
164 written by <a href="mailto:choor@atcom.co.il">Guy Keren</a>. The
165 author allowed me to take some parts of his text, mainly the text which
166 deals with the X Windows generality.
169 This tutorial is intended to people who want to start to program
170 with the <a href="http://xcb.freedesktop.org">XCB</a>
171 library. keep in mind that XCB, like the
172 <a href="http://tronche.com/gui/x/xlib/introduction">Xlib</a>
173 library, isn't what post programmers wanting to write X
174 applications are looking for. They should use a much higher
175 level GUI toolkit like Motif,
176 <a href="http://www.lesstif.org">LessTiff</a>,
177 <a href="http://www.gtk.org">GTK</a>,
178 <a href="http://www.trolltech.com">QT</a> or
179 <a href="http://www.enlightenment.org">EWL</a>, or use
180 <a href="http://cairographics.org">Cairo</a>.
182 we need to start somewhere. More than this, knowing how things
183 work down below is never a bad idea.
186 After reading this tutorial, one should be able to write very
187 simple graphical programs, but not programs with descent user
188 interfaces. For such programs, one of the previously mentioned
189 library should be used.
192 But what is XCB? Xlib has been
193 the standard C binding for the <a href="http://www.xfree86.org">X
194 Window System</a> protocol for many years now. It is an
195 excellent piece of work, but there are applications for which it
196 is not ideal, for example
199 <li><b>Small platforms</b>: Xlib is a large piece of code, and
200 it's difficult to make it smaller
201 <li><b>Latency hiding</b>: Xlib requests requiring a reply are
202 effectively synchronous: they block until the reply appears,
203 whether the result is needed immediately or not.
204 <li><b>Direct access to the protocol</b>: Xlib does quite a
205 bit of caching, layering, and similar optimizations. While this
206 is normally a feature, it makes it difficult to simply emit
207 specified X protocol requests and process specific
209 <li><b>Threaded applications</b>: While Xlib does attempt to
210 support multithreading, the API makes this difficult and
212 <li><b>New extensions</b>: The Xlib infrastructure provides
213 limited support for the new creation of X extension client side
217 For these reasons, among others, XCB, an X C binding, has been
218 designed to solve the above problems and thus provide a base for
221 <li>Toolkit implementation.
222 <li>Direct protocol-level programming.
223 <li>Lightweight emulation of commonly used portions of the
224 Xlib API (in progress)
227 <li class="title"><a name="Xmodel">The client and server model of the X window system</a>
229 The X Window System was developed with one major goal:
230 flexibility. The idea was that the way things look is one thing,
231 but the way things work is another matter. Thus, the lower
232 levels provide the tools required to draw windows, handle user
233 input, allow drawing graphics using colors (or black and white
234 screens), etc. To this point, a decision was made to separate
235 the system into two parts. A client that decides what to do, and
236 a server that actually draws on the screen and reads user input
237 in order to send it to the client for processing.
240 This model is the complete opposite of what is used to when
241 dealing with clients and servers. In our case, the user seats
242 near the machine controlled by the server, while the client
243 might be running on a remote machine. The server controls the
244 screens, mouse and keyboard. A client may connect to the server,
245 request that it draws a window (or several windows), and ask the
246 server to send it any input the user sends to these
247 windows. Thus, several clients may connect to a single X server
248 (one might be running an mail software, one running a WWW
249 browser, etc). When input is sent by the user to some window,
250 the server sends a message to the client controlling this window
251 for processing. The client decides what to do with this input,
252 and sends the server requests for drawing in the window.
255 The whole session is carried out using the X message
256 protocol. This protocol was originally carried over the TCP/IP
257 protocol suite, allowing the client to run on any machine
258 connected to the same network that the server is. Later on, the
259 X servers were extended to allow clients running on the local
260 machine with more optimized access to the server (note that an X
261 protocol message may be several hundreds of KB in size), such as
262 using shared memory, or using Unix domain sockets (a method for
263 creating a logical channel on a Unix system between two processes).
265 <li class="title"><a name="asynch">GUI programming: the asynchronous model</a>
267 Unlike conventional computer programs, that carry some serial
268 nature, a GUI program usually uses an asynchronous programming
269 model, also known as "event-driven programming". This means that
270 that program mostly sits idle, waiting for events sent by the X
271 server, and then acts upon these events. An event may say "The
272 user pressed the 1st button mouse in spot (x,y)", or "The window
273 you control needs to be redrawn". In order for the program to be
274 responsive to the user input, as well as to refresh requests, it
275 needs to handle each event in a rather short period of time
276 (e.g. less that 200 milliseconds, as a rule of thumb).
279 This also implies that the program may not perform operations
280 that might take a long time while handling an event (such as
281 opening a network connection to some remote server, or
282 connecting to a database server, or even performing a long file
283 copy operation). Instead, it needs to perform all these
284 operations in an asynchronous manner. This may be done by using
285 various asynchronous models to perform the longish operations,
286 or by performing them in a different process or thread.
289 So the way a GUI program looks is something like that:
292 <li>Perform initialization routines.
293 <li>Connect to the X server.
294 <li>Perform X-related initialization.
295 <li>While not finished:
297 <li>Receive the next event from the X server.
298 <li>Handle the event, possibly sending various drawing
299 requests to the X server.
300 <li>If the event was a quit message, exit the loop.
302 <li>Close down the connection to the X server.
303 <li>Perform cleanup operations.
306 <li class="title"><a name="notions">Basic XCB notions</a>
308 XCB has been created to eliminate the needs of
309 programs to actually implement the X protocol layer. This
310 library gives a program a very low-level access to any X
311 server. Since the protocol is standardized, a client using any
312 implementation of XCB may talk with any X server (the same
313 occurs for Xlib, of course). We now give a brief description of
314 the basic XCB notions. They will be detailed later.
317 <li class="subtitle"><a name="conn">The X Connection</a>
319 The major notion of using XCB is the X Connection. This is a
320 structure representing the connection we have open with a
321 given X server. It hides a queue of messages coming from the
322 server, and a queue of pending requests that our client
323 intends to send to the server. In XCB, this structure is named
324 'XCBConnection'. When we open a connection to an X server, the
325 library returns a pointer to such a structure. Later, we
326 supply this pointer to any XCB function that should send
327 messages to the X server or receive messages from this server.
329 <li class="subtitle"><a name="requestsreplies">Requests and
330 replies: the Xlib killers</a>
332 To ask informations to the X server, we have to make a request
333 and ask for a reply. With Xlib, these two tasks are
334 automatically done: Xlib locks the system, sends a request,
335 waits for a reply from the X server and unlocks. This is
336 annoying, especially if one makes a lot of requests to the X
337 server. Indeed, Xlib has to wait for the end of a reply
338 before asking for the next request (because of the locks that
339 Xlib sends). For example, here is a time-line of N=4
340 requests/replies with Xlib, with a round-trip latency
341 <b>T_round_trip</b> that is 5 times long as the time required
342 to write or read a request/reply (<b>T_write/T_read</b>):
345 W-----RW-----RW-----RW-----R
348 <li>W: Writing request
349 <li>-: Stalled, waiting for data
353 The total time is N * (T_write + T_round_trip + T_read).
356 With XCB, we can suppress most of the round-trips as the
357 requests and the replies are not locked. We usually send a
358 request, then XCB returns to us a <b>cookie</b>, which is an
359 identifier. Then, later, we ask for a reply using this
360 <b>cookie</b> and XCB returns a
361 pointer to that reply. Hence, with XCB, we can send a lot of
362 requests, and later in the program, ask for all the replies
363 when we need them. Here is the time-line for 4
364 requests/replies when we use this property of XCB:
370 The total time is N * T_write + max (0, T_round_trip - (N-1) *
371 T_write) + N * T_read. Which can be considerably faster than
372 all those Xlib round-trips.
375 Here is a program that computes the time to create 500 atoms
376 with Xlib and XCB. It shows the Xlib way, the bad XCB way
377 (which is similar to Xlib) and the good XCB way. On my
378 computer, XCB is 25 times faster than Xlib.
381 #include <stdlib.h>
382 #include <stdio.h>
383 #include <string.h>
384 #include <sys/time.h>
386 #include <X11/XCB/xcb.h>
388 #include <X11/Xlib.h>
393 struct timeval timev;
395 gettimeofday(&timev, NULL);
397 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
405 XCBInternAtomCookie *cs;
418 c = XCBConnectBasic ();
421 atoms = (XCBATOM *)malloc (count * sizeof (atoms));
422 names = (char **)malloc (count * sizeof (char *));
425 for (i = 0; i < count; ++i)
429 sprintf (buf, "NAME%d", i);
430 names[i] = strdup (buf);
436 for (i = 0; i < count; ++i)
437 atoms[i] = XCBInternAtomReply (c,
446 printf ("bad use time : %f\n", diff);
451 cs = (XCBInternAtomCookie *) malloc (count * sizeof(XCBInternAtomCookie));
452 for(i = 0; i < count; ++i)
453 cs[i] = XCBInternAtom (c, 0, strlen(names[i]), names[i]);
455 for(i = 0; i < count; ++i)
459 r = XCBInternAtomReply(c, cs[i], 0);
466 printf ("good use time : %f\n", end - start);
467 printf ("ratio : %f\n", diff / (end - start));
471 for (i = 0; i < count; ++i)
481 disp = XOpenDisplay (getenv("DISPLAY"));
483 atoms_x = (Atom *)malloc (count * sizeof (atoms_x));
487 for (i = 0; i < count; ++i)
488 atoms_x[i] = XInternAtom(disp, names[i], 0);
491 diff_x = end - start;
492 printf ("Xlib use time : %f\n", diff_x);
493 printf ("ratio : %f\n", diff_x / diff);
498 XCloseDisplay (disp);
503 <li class="subtitle"><a name="gc">The Graphic Context</a>
505 When we perform various drawing operations (graphics, text,
506 etc), we may specify various options for controlling how the
507 data will be drawn (what foreground and background colors to
508 use, how line edges will be connected, what font to use when
509 drawing some text, etc). In order to avoid the need to supply
510 hundreds of parameters to each drawing function, a graphical
511 context structure is used. We set the various drawing options
512 in this structure, and then we pass a pointer to this
513 structure to any drawing routines. This is rather handy, as we
514 often need to perform several drawing requests with the same
515 options. Thus, we would initialize a graphical context, set
516 the desired options, and pass this structure to all drawing
520 Note that graphic contexts have no client-side structure in
521 XCB, they're just XIDs. Xlib has a client-side structure
522 because it caches the GC contents so it can avoid making
523 redundant requests, but of course XCB doesn't do that.
525 <li class="subtitle"><a name="events">Events</a>
527 A structure is used to pass events received from the X
528 server. XCB supports exactly the events specified in the
529 protocol (33 events). This structure contains the type
530 of event received, as well as the data associated with the
531 event (e.g. position on the screen where the event was
532 generated, mouse button associated with the event, region of
533 the screen associated with a "redraw" event, etc). The way to
534 read the event's data epends on the event type.
538 <li class="title"><a name="use">Using XCB-based programs</a>
541 <li class="subtitle"><a name="inst">Installation of XCB</a>
543 To build XCB from source, you need to have installed at
550 <li><a href="http://www.check.org">check</a>
551 <li><a href="http://xmlsoft.org/XSLT/">xsltproc</a>
554 You have to checkout in CVS the following modules:
557 <li>Xproto from xlibs
563 Note that Xproto and xcb-proto exist only to install header
564 files, so typing 'make' or 'make all' will produce the message
565 "Nothing to be done for 'all'". That's normal.
567 <li class="subtitle"><a name="comp">Compiling XCB-based programs</a>
569 Compiling XCB-based programs requires linking them with the XCB
570 library. This is easily done thanks to pkgconfig:
573 gcc -Wall prog.c -o prog `pkg-config --cflags --libs xcb`
576 <li class="title"><a name="openconn">Opening and closing the connection to an X server</a>
578 An X program first needs to open the connection to the X
579 server. There is a function that opens a connection. It requires
580 the display name, or NULL. In the latter case, the display name
581 will be the one in the environment variable DISPLAY.
584 XCBConnection *XCBConnect (const char *displayname,
588 The second parameter returns the screen number used for the
589 connection. The returned structure describes an XCB connection
590 and is opaque. Here is how the connection can be opened:
593 #include <X11/XCB/xcb.h>
596 main (int argc, char *argv[])
600 /* Open the connection to the X server. use the DISPLAY environment variable as the default display name */
601 c = XCBConnect (NULL, NULL);
607 To close a connection, it suffices to use:
610 void XCBDisconnect (XCBConnection *c);
639 <li class="title"><a name="screen">Checking basic information about a connection</a>
641 Once we opened a connection to an X server, we should check some
642 basic informations about it: what screens it has, what is the
643 size (width and height) of the screen, how many colors it
644 supports (black and white ? grey scale ?, 256 colors ? more ?),
645 and so on. We get such informations from the XCBSCREEN
651 XCBCOLORMAP default_colormap;
654 CARD32 current_input_masks;
655 CARD16 width_in_pixels;
656 CARD16 height_in_pixels;
657 CARD16 width_in_millimeters;
658 CARD16 height_in_millimeters;
659 CARD16 min_installed_maps;
660 CARD16 max_installed_maps;
661 XCBVISUALID root_visual;
665 CARD8 allowed_depths_len;
669 We could retrieve the first screen of the connection by using the
673 XCBSCREENIter XCBConnSetupSuccessRepRootsIter (XCBConnSetupSuccessRep *R);
676 Here is a small program that shows how to use this function:
679 #include <stdio.h>
681 #include <X11/XCB/xcb.h>
684 main (int argc, char *argv[])
691 /* Open the connection to the X server. Use the DISPLAY environment variable */
692 c = XCBConnect (NULL, &screen_nbr);
694 /* Get the screen #screen_nbr */
695 iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
696 for (; iter.rem; --screen_nbr, XCBSCREENNext (&iter))
704 printf ("Informations of screen %ld:\n", screen->root.xid);
705 printf (" width.........: %d\n", screen->width_in_pixels);
706 printf (" height........: %d\n", screen->height_in_pixels);
707 printf (" white pixel...: %ld\n", screen->white_pixel);
708 printf (" black pixel...: %ld\n", screen->black_pixel);
714 <li class="title"><a name="helloworld">Creating a basic window - the "hello world" program</a>
716 After we got some basic informations about our screen, we can
717 create our first window. In the X Window System, a window is
718 characterized by an Id. So, in XCB, a window is of type:
726 We first ask for a new Id for our window, with this function:
729 XCBWINDOW XCBWINDOWNew(XCBConnection *c);
732 Then, XCB supplies the following function to create new windows:
735 XCBVoidCookie XCBCreateWindow (XCBConnection *c, /* Pointer to the XCBConnection structure */
736 CARD8 depth, /* Depth of the screen */
737 XCBWINDOW wid, /* Id of the window */
738 XCBWINDOW parent, /* Id of an existing window that should be the parent of the new window */
739 INT16 x, /* X position of the top-left corner of the window (in pixels) */
740 INT16 y, /* Y position of the top-left corner of the window (in pixels) */
741 CARD16 width, /* Width of the window (in pixels) */
742 CARD16 height, /* Height of the window (in pixels) */
743 CARD16 border_width, /* Width of the window's border (in pixels) */
747 const CARD32 *value_list);
750 The fact that we created the window does not mean that it will
751 be drawn on screen. By default, newly created windows are not
752 mapped on the screen (they are invisible). In order to make our
753 window visible, we use the function <span class="code">XCBMapWindow()</span>, whose
757 XCBVoidCookie XCBMapWindow (XCBConnection *c, XCBWINDOW window);
760 Finally, here is a small program to create a window of size
761 150x150 pixels, positioned at the top-left corner of the screen:
764 #include <unistd.h>
766 #include <X11/XCB/xcb.h>
769 main (int argc, char *argv[])
775 /* Open the connection to the X server */
776 c = XCBConnect (NULL, NULL);
778 /* Get the first screen */
779 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
781 /* Ask for our window's Id */
782 win.window = XCBWINDOWNew(c);
784 /* Create the window */
785 XCBCreateWindow (c, /* Connection */
787 win.window, /* window Id */
788 screen->root, /* parent window */
790 150, 150, /* width, height */
791 10, /* border_width */
792 InputOutput, /* class */
793 screen->root_visual, /* visual */
794 0, NULL); /* masks, not used yet */
796 /* Map the window on the screen */
797 XCBMapWindow (c, win.window);
807 In this code, you see one more function - <span class="code">XCBSync()</span>, not explained
808 yet. It is used to flush all the pending requests. More
809 precisely, there are 2 functions that do such things. The first
810 one is <span class="code">XCBFlush()</span>:
813 int XCBFlush (XCBConnection *c);
816 This function flushes all pending requests to the X server (much
817 like the <span class="code">fflush()</span> function is used to
818 flush standard output). The second function is
819 <span class="code">XCBSync()</span>:
822 int XCBSync(XCBConnection *c, XCBGenericError **e);
825 This functions also flushes all pending requests to the X
826 server, and then waits until the X server finishing processing
827 these requests. In a normal program, this will not be necessary
828 (we'll see why when we get to write a normal X program), but for
829 now, we put it there.
832 The window that is created by the above code has a default
833 background (gray). This one can be set to a specific color,
834 thanks to the two last parameters of
835 <span class="code">XCBCreateWindow()</span>, which are not
836 described yet. See the subsections
837 <a href="#winconf">Configuring a window</a> or
838 <a href="#winconf">Registering for event types using event masks</a>
839 for exemples on how to use these parameters. In addition, as no
840 events are handled, you have to make a Ctrl-C to interrupt the
844 <b>TODO</b>: one should tell what these functions return and
845 about the generic error
859 <li>XCBCreateWindow ()
864 <li class="title"><a name="drawing">Drawing in a window</a>
866 Drawing in a window can be done using various graphical
867 functions (drawing pixels, lines, rectangles, etc). In order to
868 draw in a window, we first need to define various general
869 drawing parameters (what line width to use, which color to draw
870 with, etc). This is done using a graphical context.
873 <li class="subtitle"><a name="allocgc">Allocating a Graphics Context</a>
875 As we said, a graphical context defines several attributes to
876 be used with the various drawing functions. For this, we
877 define a graphical context. We can use more than one graphical
878 context with a single window, in order to draw in multiple
879 styles (different colors, different line widths, etc). In XCB,
880 a Graphics Context is, as a window, characterized by an Id:
888 We first ask the X server to attribute an Id to our graphic
889 context with this function:
892 XCBGCONTEXT XCBGCONTEXTNew (XCBConnection *c);
895 Then, we set the attributes of the graphic context with this function:
898 XCBVoidCookie XCBCreateGC (XCBConnection *c,
900 XCBDRAWABLE drawable,
902 const CARD32 *value_list);
905 We give now an example on how to allocate a graphic context
906 that specifies that each drawing functions that use it will
907 draw in foreground with a black color.
910 #include <X11/XCB/xcb.h>
913 main (int argc, char *argv[])
922 /* Open the connection to the X server and get the first screen */
923 c = XCBConnect (NULL, NULL);
924 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
926 /* Create a black graphic context for drawing in the foreground */
927 win.window = screen->root;
928 black = XCBGCONTEXTNew (c);
930 value[0] = screen->black_pixel;
931 XCBCreateGC (c, black, win, mask, value);
937 Note should be taken regarding the role of "value_mask" and
938 "value_list" in the prototype of <span class="code">XCBCreateGC()</span>. Since a
939 graphic context has many attributes, and since we often just
940 want to define a few of them, we need to be able to tell the
941 <span class="code">XCBCreateGC()</span> which attributes we
942 want to set. This is what the "value_mask" parameter is
943 for. We then use the "value_list" parameter to specify actual
944 values for the attribute we defined in "value_mask". Thus, for
945 each constant used in "value_list", we will use the matching
946 constant in "value_mask". In this case, we define a graphic
947 context with one attribute: when drawing (a point, a line,
948 etc), the foreground color will be black. The rest of the
949 attributes of this graphic context will be set to their
953 See the next Subsection for more details.
966 <li>XCBGCONTEXTNew ()
972 <li class="subtitle"><a name="changegc">Changing the attributes of a Graphics Context</a>
974 Once we have allocated a Graphic Context, we may need to
975 change its attributes (for example, changing the foreground
976 color we use to draw a line, or changing the attributes of the
977 font we use to display strings. See Subsections Drawing with a
978 color and Assigning a Font to a Graphic Context). This is done
979 by using this function:
982 XCBVoidCookie XCBChangeGC (XCBConnection *c, /* The XCB Connection */
983 XCBGCONTEXT gc, /* The Graphic Context */
984 CARD32 value_mask, /* Components of the Graphic Context that have to be set */
985 const CARD32 *value_list); /* Value as specified by value_mask */
988 The <span class="code">value_mask</span> parameter could take
1004 <li>GCTileStipXOrigin
1005 <li>GCTileStipYOrigin
1008 <li>GCGraphicsExposures
1017 It is possible to set several attributes at the same
1018 time (for example setting the attributes of a font and the
1019 color which will be used to display a string), by OR'ing these
1020 values in <span class="code">value_mask</span>. Then
1021 <span class="code">value_list</span> has to be an array which
1022 lists the value for the respective attributes. See Subsection
1023 Drawing with a color to have an example.
1026 <b>TODO</b>: set the links of the 3 subsections, once they will
1030 <b>TODO</b>: give an example which sets several attributes.
1032 <li class="subtitle"><a name="drawingprim">Drawing primitives: point, line, box, circle,...</a>
1034 After we have created a Graphic Context, we can draw on a
1035 window using this Graphic Context, with a set of XCB
1036 functions, collectively called "drawing primitive". Let see
1040 To draw a point, or several points, we use
1043 XCBVoidCookie XCBPolyPoint (XCBConnection *c, /* The connection to the X server */
1044 BYTE coordinate_mode, /* Coordinate mode, usually set to CoordModeOrigin */
1045 XCBDRAWABLE drawable, /* The drawable on which we want to draw the point(s) */
1046 XCBGCONTEXT gc, /* The Graphic Context we use to draw the point(s) */
1047 CARD32 points_len, /* The number of points */
1048 const XCBPOINT *points); /* An array of points */
1051 The <span class="code">coordinate_mode</span> parameter
1052 specifies the coordinate mode. Available values are
1055 <li><span class="code">CoordModeOrigin</span>
1056 <li><span class="code">CoordModePrevious</span>
1059 The <span class="code">XCBPOINT</span> type is just a
1060 structure with two fields (the coordinates of the point):
1069 You could see an example in xpoints.c. <b>TODO</b> Set the link.
1072 To draw a line, or a polygonal line, we use
1075 XCBVoidCookie XCBPolyLine (XCBConnection *c, /* The connection to the X server */
1076 BYTE coordinate_mode, /* Coordinate mode, usually set to CoordModeOrigin */
1077 XCBDRAWABLE drawable, /* The drawable on which we want to draw the line(s) */
1078 XCBGCONTEXT gc, /* The Graphic Context we use to draw the line(s) */
1079 CARD32 points_len, /* The number of points in the polygonal line */
1080 const XCBPOINT *points); /* An array of points */
1083 This function will draw the line between the first and the
1084 second points, then the line between the second and the third
1088 To draw a segment, or several segments, we use
1091 XCBVoidCookie XCBPolySegment (XCBConnection *c, /* The connection to the X server */
1092 XCBDRAWABLE drawable, /* The drawable on which we want to draw the segment(s) */
1093 XCBGCONTEXT gc, /* The Graphic Context we use to draw the segment(s) */
1094 CARD32 segments_len, /* The number of segments */
1095 const XCBSEGMENT *segments); /* An array of segments */
1098 The <span class="code">XCBSEGMENT</span> type is just a
1099 structure with four fields (the coordinates of the two points
1100 that define the segment):
1111 To draw a rectangle, or several rectangles, we use
1114 XCBVoidCookie XCBPolyRectangle (XCBConnection *c, /* The connection to the X server */
1115 XCBDRAWABLE drawable, /* The drawable on which we want to draw the rectangle(s) */
1116 XCBGCONTEXT gc, /* The Graphic Context we use to draw the rectangle(s) */
1117 CARD32 rectangles_len, /* The number of rectangles */
1118 const XCBRECTANGLE *rectangles); /* An array of rectangles */
1121 The <span class="code">XCBRECTANGLE</span> type is just a
1122 structure with four fields (the coordinates of the top-left
1123 corner of the rectangle, and its width and height):
1134 <b>TODO</b>: there's no coordinate_mode. Is it normal ?
1137 To draw an elliptical arc, or several elliptical arcs, we use
1140 XCBVoidCookie XCBPolyArc (XCBConnection *c, /* The connection to the X server */
1141 XCBDRAWABLE drawable, /* The drawable on which we want to draw the arc(s) */
1142 XCBGCONTEXT gc, /* The Graphic Context we use to draw the arc(s) */
1143 CARD32 arcs_len, /* The number of arcs */
1144 const XCBARC *arcs); /* An array of arcs */
1147 The <span class="code">XCBARC</span> type is a structure with
1152 INT16 x; /* Top left x coordinate of the rectangle surrounding the ellipse */
1153 INT16 y; /* Top left y coordinate of the rectangle surrounding the ellipse */
1154 CARD16 width; /* Width of the rectangle surrounding the ellipse */
1155 CARD16 height; /* Height of the rectangle surrounding the ellipse */
1156 INT16 angle1; /* Angle at which the arc begins */
1157 INT16 angle2; /* Angle at which the arc ends */
1162 Note: the angles are expressed in units of 1/64 of a degree,
1163 so to have an angle of 90 degrees, starting at 0,
1164 <span class="code">angle1 = 0</span> and
1165 <span class="code">angle2 = 90 << 6</span>. Positive angles
1166 indicate counterclockwise motion, while negative angles
1167 indicate clockwise motion.
1171 <b>TODO</b>: there's no coordinate_mode. Is it normal ?
1174 <b>TODO</b>: I think that (x,y) should be the center of the
1175 ellipse, and (width, height) the radius. It's more logical.
1178 The corresponding function which fill inside the geometrical
1179 object are listed below, without further explanation, as they
1180 are used as the above functions.
1183 To Fill a polygon defined by the points given as arguments ,
1187 XCBVoidCookie XCBFillPoly (XCBConnection *c,
1188 XCBDRAWABLE drawable,
1191 CARD8 coordinate_mode,
1193 const XCBPOINT *points);
1196 The <span class="code">shape</span> parameter specifies a
1197 shape that helps the server to improve performance. Available
1201 <li><span class="code">Complex</span>
1202 <li><span class="code">Convex</span>
1203 <li><span class="code">Nonconvex</span>
1206 To fill one or several rectangles, we use
1209 XCBVoidCookie XCBPolyFillRectangle (XCBConnection *c,
1210 XCBDRAWABLE drawable,
1212 CARD32 rectangles_len,
1213 const XCBRECTANGLE *rectangles);
1216 To fill one or several arcs, we use
1219 XCBVoidCookie XCBPolyFillArc (XCBConnection *c,
1220 XCBDRAWABLE drawable,
1223 const XCBARC *arcs);
1227 To illustrate these functions, here is an example that draws
1228 four points, a polygonal line, two segments, two rectangles
1229 and two arcs. Remark that we use events for the first time, as
1230 an introduction to the next section.
1233 #include <stdlib.h>
1234 #include <stdio.h>
1236 #include <X11/XCB/xcb.h>
1238 /* Get the depth of the screen. Needed in order to draw something */
1240 get_depth(XCBConnection *c,
1243 XCBDRAWABLE drawable;
1244 XCBGetGeometryRep *geom;
1247 drawable.window = root->root;
1248 geom = XCBGetGeometryReply (c, XCBGetGeometry(c, drawable), 0);
1252 perror ("GetGeometry(root) failed");
1256 depth = geom->depth;
1263 main (int argc, char *argv[])
1268 XCBGCONTEXT foreground;
1273 /* geometric objects */
1274 XCBPOINT points[] = {
1280 XCBPOINT polyline[] = {
1286 XCBSEGMENT segments[] = {
1288 {110, 25, 130, 60}};
1290 XCBRECTANGLE rectangles[] = {
1295 {10, 100, 60, 40, 0, 90 << 6},
1296 {90, 100, 55, 40, 0, 270 << 6}};
1298 /* Open the connection to the X server */
1299 c = XCBConnect (NULL, NULL);
1301 /* Get the first screen */
1302 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
1304 /* Create black (foregroung) graphic context */
1305 win.window = screen->root;
1307 foreground = XCBGCONTEXTNew (c);
1308 mask = GCForeground | GCGraphicsExposures;
1309 values[0] = screen->black_pixel;
1311 XCBCreateGC (c, foreground, win, mask, values);
1313 /* Ask for our window's Id */
1314 win.window = XCBWINDOWNew(c);
1316 /* Create the window */
1317 mask = XCBCWBackPixel | XCBCWEventMask;
1318 values[0] = screen->white_pixel;
1319 values[1] = ExposureMask;
1320 XCBCreateWindow (c, /* Connection */
1322 win.window, /* window Id */
1323 screen->root, /* parent window */
1325 150, 150, /* width, height */
1326 10, /* border_width */
1327 InputOutput, /* class */
1328 screen->root_visual, /* visual */
1329 mask, values); /* masks */
1331 /* Map the window on the screen */
1332 XCBMapWindow (c, win.window);
1335 /* We flush the request */
1338 while ((e = XCBWaitEvent (c)))
1340 switch (e->response_type)
1344 /* We draw the points */
1345 XCBPolyPoint (c, CoordModeOrigin, win, foreground, 4, points);
1347 /* We draw the polygonal line */
1348 XCBPolyLine (c, CoordModeOrigin, win, foreground, 4, polyline);
1350 /* We draw the segements */
1351 XCBPolySegment (c, win, foreground, 2, segments);
1353 /* We draw the rectangles */
1354 XCBPolyRectangle (c, win, foreground, 2, rectangles);
1356 /* We draw the arcs */
1357 XCBPolyArc (c, win, foreground, 2, arcs);
1359 /* We flush the request */
1366 /* Unknown event type, ignore it */
1370 /* Free the Generic Event */
1378 <li class="title"><a name="xevents">X Events</a>
1380 In an X program, everything is driven by events. Event painting
1381 on the screen is sometimes done as a response to an event (an
1382 <span class="code">Expose</span> event). If part of a program's
1383 window that was hidden, gets exposed (e.g. the window was raised
1384 above other widows), the X server will send an "expose" event to
1385 let the program know it should repaint that part of the
1386 window. User input (key presses, mouse movement, etc) is also
1387 received as a set of events.
1390 <li class="subtitle"><a name="register">Registering for event types using event masks</a>
1392 During the creation of a window, you should give it what kind
1393 of events it wishes to receive. Thus, you may register for
1394 various mouse (also called pointer) events, keyboard events,
1395 expose events, and so on. This is done for optimizing the
1396 server-to-client connection (i.e. why send a program (that
1397 might even be running at the other side of the globe) an event
1398 it is not interested in ?)
1401 In XCB, you use the "value_mask" and "value_list" data in the
1402 <span class="code">XCBCreateWindow()</span> function to
1403 register for events. Here is how we register for
1404 <span class="code">Expose</span> event when creating a window:
1407 mask = XCBCWEventMask;
1408 valwin[0] = ExposureMask;
1409 win.window = XCBWINDOWNew (c);
1410 XCBCreateWindow (c, depth, win.window, root->root,
1412 InputOutput, root->root_visual,
1416 <span class="code">ExposureMask</span> is a constant defined
1417 in the "X.h" header file. If we wanted to register to several
1418 event types, we can logically "or" them, as follows:
1421 mask = XCBCWEventMask;
1422 valwin[0] = ExposureMask | ButtonPressMask;
1423 win.window = XCBWINDOWNew (c);
1424 XCBCreateWindow (c, depth, win.window, root->root,
1426 InputOutput, root->root_visual,
1430 This registers for <span class="code">Expose</span> events as
1431 well as for mouse button presses insode the created
1432 window. You should note that a mask may represent several
1436 The values that a mask could take are given
1437 by the <span class="code">XCBCW</span> enumeration:
1441 XCBCWBackPixmap = 1L<<0,
1442 XCBCWBackPixel = 1L<<1,
1443 XCBCWBorderPixmap = 1L<<2,
1444 XCBCWBorderPixel = 1L<<3,
1445 XCBCWBitGravity = 1L<<4,
1446 XCBCWWinGravity = 1L<<5,
1447 XCBCWBackingStore = 1L<<6,
1448 XCBCWBackingPlanes = 1L<<7,
1449 XCBCWBackingPixel = 1L<<8,
1450 XCBCWOverrideRedirect = 1L<<9,
1451 XCBCWSaveUnder = 1L<<10,
1452 XCBCWEventMask = 1L<<11,
1453 XCBCWDontPropagate = 1L<<12,
1454 XCBCWColormap = 1L<<13,
1455 XCBCWCursor = 1L<<14
1459 <p>Note: we must be careful when setting the values of the valwin
1460 parameter, as they have to follow the order the
1461 <span class="code">XCBCW</span> enumeration. Here is an
1466 mask = XCBCWEventMask | XCBCWBackPixmap;
1467 valwin[0] = None; /* for XCBCWBackPixmap (whose value is 1) */
1468 valwin[1] = ExposureMask | ButtonPressMask; /* for XCBCWEventMask, whose value (2048) */
1469 /* is superior to the one of XCBCWBackPixmap */
1472 If the window has already been created, we can use the
1473 <span class="code">XCBConfigureWindow()</span> function to set
1474 the events that the window will receive. The subsection
1475 <a href="#winconf">Configuring a window</a> shows its
1476 prototype. As an example, here is a piece of code that
1477 configures the window to receive the
1478 <span class="code">Expose</span> and
1479 <span class="code">ButtonPressMask</span> events:
1482 const static CARD32 values[] = { ExposureMask | ButtonPressMask };
1484 /* The connection c and the window win are supposed to be defined */
1486 XCBConfigureWindow (c, win, XCBCWEventMask, values);
1490 Note: A common bug programmers do is adding code to handle new
1491 event types in their program, while forgetting to add the
1492 masks for these events in the creation of the window. Such a
1493 programmer then should sit down for hours debugging his
1494 program, wondering "Why doesn't my program notice that I
1495 released the button?", only to find that they registered for
1496 button press events but not for button release events.
1499 <li class="subtitle"><a name="loop">Receiving events: writing the events loop</a>
1501 After we have registered for the event types we are interested
1502 in, we need to enter a loop of receiving events and handling
1503 them. There are two ways to receive events: a blocking way and
1508 <span class="code">XCBWaitEvent (XCBConnection *c)</span>
1509 is the blocking way. It waits (so blocks...) until an event is
1510 queued in the X server. Then it retrieves it into a newly
1511 allocated structure (it dequeues it from the queue) and returns
1512 it. This structure has to be freed. The function returns
1513 <span class="code">NULL</span> if an error occurs.
1517 <span class="code">XCBPollForEvent (XCBConnection *c, int
1518 *error)</span> is the non blocking way. It looks at the event
1519 queue and returns (and dequeues too) an existing event into
1520 a newly allocated structure. This structure has to be
1521 freed. It returns <span class="code">NULL</span> if there is
1522 no event. If an error occurs, the parameter <span
1523 class="code">error</span> will be filled with the error
1528 There are various ways to write such a loop. We present two
1529 ways to write such a loop, with the two functions above. The
1530 first one uses <span class="code">XCBWaitEvent</span>, which
1531 is similar to an event Xlib loop using only <span
1532 class="code">XNextEvent</span>:
1537 while ((e = XCBWaitEvent (c)))
1539 switch (e->response_type)
1543 /* Handle the Expose event type */
1544 XCBExposeEvent *ev = (XCBExposeEvent *)e;
1550 case XCBButtonPress:
1552 /* Handle the ButtonPress event type */
1553 XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
1561 /* Unknown event type, ignore it */
1565 /* Free the Generic Event */
1570 You will certainly want to use <span
1571 class="code">XCBPollForEvent(XCBConnection *c, int
1572 *error)</span> if, in Xlib, you use <span
1573 class="code">XPending</span>:
1576 while (XPending (display))
1580 XNextEvent(d, &ev);
1582 /* Manage your event */
1586 Such a loop in XCB looks like:
1589 XCBGenericEvent *ev;
1591 while ((ev = XCBPollForEvent (conn, 0)))
1593 /* Manage your event */
1597 The events are managed in the same way as with <span
1598 class="code">XCBWaitEvent</span>.
1599 Obviously, we will need to give the user some way of
1600 terminating the program. This is usually done by handling a
1601 special "quit" event, as we will soon see.
1625 <li>XCBPollForEvent ()
1631 <li class="subtitle"><a name="expose">Expose events</a>
1633 The <span class="code">Expose</span> event is one of the most
1634 basic (and most used) events an application may receive. It
1635 will be sent to us in one of several cases:
1638 <li>A window that covered part of our window has moved
1639 away, exposing part (or all) of our window.
1640 <li>Our window was raised above other windows.
1641 <li>Our window mapped for the first time.
1642 <li>Our window was de-iconified.
1645 You should note the implicit assumption hidden here: the
1646 contents of our window is lost when it is being obscured
1647 (covered) by either windows. One may wonder why the X server
1648 does not save this contents. The answer is: to save
1649 memory. After all, the number of windows on a display at a
1650 given time may be very large, and storing the contents of all
1651 of them might require a lot of memory. Actually, there is a
1652 way to tell the X server to store the contents of a window in
1653 special cases, as we will see later.
1656 When we get an <span class="code">Expose</span> event, we
1657 should take the event's data from the members of the following
1662 BYTE response_type; /* The type of the event, here it is XCBExpose */
1665 XCBWINDOW window; /* The Id of the window that receives the event (in case */
1666 /* our application registered for events on several windows */
1667 CARD16 x; /* The x coordinate of the top-left part of the window that needs to be redrawn */
1668 CARD16 y; /* The y coordinate of the top-left part of the window that needs to be redrawn */
1669 CARD16 width; /* The width of the part of the window that needs to be redrawn */
1670 CARD16 height; /* The height of the part of the window that needs to be redrawn */
1674 <li class="subtitle"><a name="userinput">Getting user input</a>
1676 User input traditionally comes from two sources: the mouse
1677 and the keyboard. Various event types exist to notify us of
1678 user input (a key being presses on the keyboard, a key being
1679 released on the keyboard, the mouse moving over our window,
1680 the mouse entering (or leaving) our window, and so on.
1683 <li class="subsubtitle"><a name="mousepressrelease">Mouse button press and release events</a>
1685 The first event type we will deal with is a mouse
1686 button-press (or button-release) event in our window. In
1687 order to register to such an event type, we should add one
1688 (or more) of the following masks when we create our window:
1691 <li><span class="code">ButtonPressMask</span>: notify us
1692 of any button that was pressed in one of our windows.
1693 <li><span class="code">ButtonReleaseMask</span>: notify us
1694 of any button that was released in one of our windows.
1697 The structure to be checked for in our events loop is the
1698 same for these two events, and is the following:
1702 BYTE response_type; /* The type of the event, here it is XCBButtonPressEvent or XCBButtonReleaseEvent */
1705 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1711 INT16 event_x; /* The x coordinate where the mouse has been pressed in the window */
1712 INT16 event_y; /* The y coordinate where the mouse has been pressed in the window */
1713 CARD16 state; /* A mask of the buttons (or keys) during the event */
1715 } XCBButtonPressEvent;
1717 typedef XCBButtonPressEvent XCBButtonReleaseEvent;
1720 The <span class="code">time</span> field may be used to calculate "double-click"
1721 situations by an application (e.g. if the mouse button was
1722 clicked two times in a duration shorter than a given amount
1723 of time, assume this was a double click).
1726 The <span class="code">state</span> field is a mask of the buttons held down during
1727 the event. It is a bitwise OR of any of the following:
1730 <li><span class="code">Button1Mask</span>
1731 <li><span class="code">Button2Mask</span>
1732 <li><span class="code">Button3Mask</span>
1733 <li><span class="code">Button4Mask</span>
1734 <li><span class="code">Button5Mask</span>
1735 <li><span class="code">ShiftMask</span>
1736 <li><span class="code">LockMask</span>
1737 <li><span class="code">ControlMask</span>
1738 <li><span class="code">Mod1Mask</span>
1739 <li><span class="code">Mod2Mask</span>
1740 <li><span class="code">Mod3Mask</span>
1741 <li><span class="code">Mod4Mask</span>
1742 <li><span class="code">Mod5Mask</span>
1745 Their names are self explanatory, where the first 5 refer to
1746 the mouse buttons that are being pressed, while the rest
1747 refer to various "special keys" that are being pressed (Mod1
1748 is usually the 'Alt' key or the 'Meta' key).
1751 <b>TODO:</b> Problem: it seems that the state does not
1752 change when clicking with various buttons.
1754 <li class="subsubtitle"><a name="mousemvnt">Mouse movement events</a>
1756 Similar to mouse button press and release events, we also
1757 can be notified of various mouse movement events. These can
1758 be split into two families. One is of mouse pointer
1759 movement while no buttons are pressed, and the second is a
1760 mouse pointer motion while one (or more) of the buttons are
1761 pressed (this is sometimes called "a mouse drag operation",
1762 or just "dragging"). The following event masks may be added
1763 during the creation of our window:
1766 <li><span class="code">PointerMotionMask</span>: events of
1767 the pointer moving in one of the windows controlled by our
1768 application, while no mouse button is held pressed.
1769 <li><span class="code">ButtonMotionMask</span>: Events of
1770 the pointer moving while one or more of the mouse buttons
1772 <li><span class="code">Button1MotionMask</span>: same as
1773 <span class="code">ButtonMotionMask</span>, but only when
1774 the 1st mouse button is held pressed.
1775 <li><span class="code">Button2MotionMask</span>,
1776 <span class="code">Button3MotionMask</span>,
1777 <span class="code">Button4MotionMask</span>,
1778 <span class="code">Button5MotionMask</span>: same as
1779 <span class="code">Button1MotionMask</span>, but
1780 respectively for 2nd, 3rd, 4th and 5th mouse button.
1783 The structure to be checked for in our events loop is the
1784 same for these events, and is the following:
1788 BYTE response_type; /* The type of the event */
1791 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1797 INT16 event_x; /* The x coordinate of the mouse when the event was generated */
1798 INT16 event_y; /* The y coordinate of the mouse when the event was generated */
1799 CARD16 state; /* A mask of the buttons (or keys) during the event */
1801 } XCBMotionNotifyEvent;
1803 <li class="subsubtitle"><a name="mouseenter">Mouse pointer enter and leave events</a>
1805 Another type of event that applications might be interested
1806 at, is a mouse pointer entering a window the program
1807 controls, or leaving such a window. Some programs use these
1808 events to show the user tht the applications is now in
1809 focus. In order to register for such an event type, we
1810 should add one (or more) of the following masks when we
1814 <li><span class="code">EnterWindowMask</span>: notify us
1815 when the mouse pointer enters any of our controlled
1817 <li><span class="code">LeaveWindowMask</span>: notify us
1818 when the mouse pointer leaves any of our controlled
1822 The structure to be checked for in our events loop is the
1823 same for these two events, and is the following:
1827 BYTE response_type; /* The type of the event */
1830 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1836 INT16 event_x; /* The x coordinate of the mouse when the event was generated */
1837 INT16 event_y; /* The y coordinate of the mouse when the event was generated */
1838 CARD16 state; /* A mask of the buttons (or keys) during the event */
1839 BYTE mode; /* The number of mouse button that was clicked */
1840 BYTE same_screen_focus;
1841 } XCBEnterNotifyEvent;
1843 typedef XCBEnterNotifyEvent XCBLeaveNotifyEvent;
1845 <li class="subsubtitle"><a name="focus">The keyboard focus</a>
1847 There may be many windows on a screen, but only a single
1848 keyboard attached to them. How does the X server then know
1849 which window should be sent a given keyboard input ? This is
1850 done using the keyboard focus. Only a single window on the
1851 screen may have the keyboard focus at a given time. There
1852 is a XCB function that allow a program to set the keyboard
1853 focus to a given window. The user can usually set the
1854 keyboard ficus using the window manager (often by clicking
1855 on the title bar of the desired window). Once our window
1856 has the keyboard focus, every key press or key release will
1857 cause an event to be sent to our program (if it regsitered
1858 for these event types...).
1860 <li class="subsubtitle"><a name="keypress">Keyboard press and release events</a>
1862 If a window controlled by our program currently holds the
1863 keyboard focus, it can receive key press and key release
1864 events. So, we should add one (or more) of the following
1865 masks when we create our window:
1868 <li><span class="code">KeyPressMask</span>: notify us when
1869 a key was pressed while any of our controlled windows had
1871 <li><span class="code">KeyReleaseMask</span>: notify us
1872 when a key was released while any of our controlled
1873 windows had the keyboard focus.
1876 The structure to be checked for in our events loop is the
1877 same for these two events, and is the following:
1881 BYTE response_type; /* The type of the event */
1884 XCBTIMESTAMP time; /* Time, in milliseconds the event took place in */
1896 typedef XCBKeyPressEvent XCBKeyReleaseEvent;
1899 The <span class="code">detail</span> field refer to the
1900 physical key on the keyboard.
1903 <b>TODO:</b> Talk about getting the ASCII code from the key code.
1906 <li class="subtitle"><a name="eventex">X events: a complete example</a>
1908 As an example for handling events, we show a program that
1909 creates a window, enter an events loop and check for all the
1910 events described above, and write on the terminal the relevant
1911 characteristics of the event. With this code, it should be
1912 easy to add drawing operations, like those which have been
1916 #include <malloc.h>
1917 #include <stdio.h>
1919 #include <X11/XCB/xcb.h>
1922 main (int argc, char *argv[])
1931 /* Open the connection to the X server */
1932 c = XCBConnect (NULL, NULL);
1934 /* Get the first screen */
1935 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
1937 /* Ask for our window's Id */
1938 win.window = XCBWINDOWNew(c);
1940 /* Create the window */
1941 mask = XCBCWBackPixel | XCBCWEventMask;
1942 values[0] = screen->white_pixel;
1943 values[1] = ExposureMask | ButtonPressMask | ButtonReleaseMask |
1944 PointerMotionMask | EnterWindowMask | LeaveWindowMask |
1945 KeyPressMask | KeyReleaseMask;
1946 XCBCreateWindow (c, /* Connection */
1948 win.window, /* window Id */
1949 screen->root, /* parent window */
1951 150, 150, /* width, height */
1952 10, /* border_width */
1953 InputOutput, /* class */
1954 screen->root_visual, /* visual */
1955 mask, values); /* masks */
1957 /* Map the window on the screen */
1958 XCBMapWindow (c, win.window);
1961 while ((e = XCBWaitEvent (c)))
1963 switch (e->response_type)
1967 XCBExposeEvent *ev = (XCBExposeEvent *)e;
1969 printf ("Window %ld exposed. Region to be redrawn at location (%d,%d), with dimension (%d,%d)\n",
1970 ev->window.xid, ev->x, ev->y, ev->width, ev->height);
1973 case XCBButtonPress:
1975 XCBButtonPressEvent *ev = (XCBButtonPressEvent *)e;
1978 if ((ev->state | Button1Mask) == Button1Mask)
1980 if ((ev->state | Button2Mask) == Button2Mask)
1982 if ((ev->state | Button3Mask) == Button3Mask)
1984 if ((ev->state | Button4Mask) == Button4Mask)
1986 if ((ev->state | Button5Mask) == Button5Mask)
1989 switch (ev->detail.id)
1993 printf ("Wheel Button up in window %ld, at coordinates (%d,%d)\n",
1994 ev->event.xid, ev->event_x, ev->event_y);
1999 printf ("Wheel Button down in window %ld, at coordinates (%d,%d)\n",
2000 ev->event.xid, ev->event_x, ev->event_y);
2004 printf ("Button %d pressed in window %ld, at coordinates (%d,%d)\n",
2005 ev->detail.id, ev->event.xid, ev->event_x, ev->event_y);
2009 case XCBButtonRelease:
2011 XCBButtonReleaseEvent *ev = (XCBButtonReleaseEvent *)e;
2014 if ((ev->state | Button1Mask) == Button1Mask)
2016 if ((ev->state | Button2Mask) == Button2Mask)
2018 if ((ev->state | Button3Mask) == Button3Mask)
2020 if ((ev->state | Button4Mask) == Button4Mask)
2022 if ((ev->state | Button5Mask) == Button5Mask)
2025 printf ("Button %d released in window %ld, at coordinates (%d,%d)\n",
2026 ev->detail.id, ev->event.xid, ev->event_x, ev->event_y);
2029 case XCBMotionNotify:
2031 XCBMotionNotifyEvent *ev = (XCBMotionNotifyEvent *)e;
2033 printf ("Mouse moved in window %ld, at coordinates (%d,%d)\n",
2034 ev->event.xid, ev->event_x, ev->event_y);
2037 case XCBEnterNotify:
2039 XCBEnterNotifyEvent *ev = (XCBEnterNotifyEvent *)e;
2041 printf ("Mouse entered window %ld, at coordinates (%d,%d)\n",
2042 ev->event.xid, ev->event_x, ev->event_y);
2045 case XCBLeaveNotify:
2047 XCBLeaveNotifyEvent *ev = (XCBLeaveNotifyEvent *)e;
2049 printf ("Mouse leaved window %ld, at coordinates (%d,%d)\n",
2050 ev->event.xid, ev->event_x, ev->event_y);
2055 XCBKeyPressEvent *ev = (XCBKeyPressEvent *)e;
2057 printf ("Key pressed in window %ld\n",
2063 XCBKeyReleaseEvent *ev = (XCBKeyReleaseEvent *)e;
2065 printf ("Key releaseed in window %ld\n",
2071 /* Unknown event type, ignore it */
2075 /* Free the Generic Event */
2083 <li class="title"><a name="font">Handling text and fonts</a>
2085 Besides drawing graphics on a window, we often want to draw
2086 text. Text strings have two major properties: the characters to
2087 be drawn and the font with which they are drawn. In order to
2088 draw text, we need to first request the X server to load a
2089 font. We then assign a font to a Graphic Context, and finally, we
2090 draw the text in a window, using the Graphic Context.
2093 <li class="subtitle"><a name="fontstruct">The Font structure</a>
2095 In order to support flexible fonts, a font structure is
2096 defined. You know what ? Its an Id:
2104 It is used to contain information about a font, and is passed
2105 to several functions that handle fonts selection and text drawing.
2108 <li class="title"><a name="wm">Interacting with the window manager</a>
2110 After we have seen how to create windows and draw on them, we
2111 take one step back, and look at how our windows are interacting
2112 with their environment (the full screen and the other
2113 windows). First of all, our application needs to interact with
2114 the window manager. The window manager is responsible to
2115 decorating drawn windows (i.e. adding a frame, an iconify
2116 button, a system menu, a title bar, etc), as well as handling
2117 icons shown when windows are being iconified. It also handles
2118 ordering of windows on the screen, and other administrative
2119 tasks. We need to give it various hints as to how we want it to
2120 treat our application's windows.
2123 <li class="subtitle"><a name="wmprop">Window properties</a>
2125 Many of the parameters communicated to the window manager are
2126 passed using data called "properties". These properties are
2127 attached by the X server to different windows, and are stores
2128 in a format that makes it possible to read them from different
2129 machines that may use different architectures (remember that
2130 an X client program may run on a remote machine).
2133 The property and its type (a string, an integer, etc) are
2134 Id. Their type are <span class="code">XCBATOM</span>:
2142 To change the property of a window, we use the following
2146 XCBVoidCookie XCBChangeProperty (XCBConnection *c, /* Connection to the X server */
2147 CARD8 mode, /* Property mode */
2148 XCBWINDOW window, /* Window */
2149 XCBATOM property, /* Property to change */
2150 XCBATOM type, /* Type of the property */
2151 CARD8 format, /* Format of the property (8, 16, 32) */
2152 CARD32 data_len, /* Length of the data parameter */
2153 const void *data); /* Data */
2156 The <span class="code">mode</span> parameter coud be one of
2157 the following value (defined in the X.h header file):
2165 <li class="subtitle"><a name="wmname">Setting the window name and icon name</a>
2167 The firt thing we want to do would be to set the name for our
2168 window. This is done using the
2169 <span class="code">XCBChangeProperty()</span> function. This
2170 name may be used by the window manager as the title of the
2171 window (in the title bar), in a task list, etc. The property
2172 atom to use to set the name of a window is
2173 <span class="code">WM_NAME</span> (and
2174 <span class="code">WM_ICON_NAME</span> for the iconified
2175 window) and its type is <span class="code">STRING</span>. Here
2176 is an example of utilization:
2179 #include <string.h>
2181 #include <X11/XCB/xcb.h>
2182 #include <X11/XCB/xcb_atom.h>
2185 main (int argc, char *argv[])
2190 char *title = "Hello World !";
2191 char *title_icon = "Hello World ! (iconified)";
2195 /* Open the connection to the X server */
2196 c = XCBConnect (NULL, NULL);
2198 /* Get the first screen */
2199 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2201 /* Ask for our window's Id */
2202 win.window = XCBWINDOWNew(c);
2204 /* Create the window */
2205 XCBCreateWindow (c, /* Connection */
2207 win.window, /* window Id */
2208 screen->root, /* parent window */
2210 250, 150, /* width, height */
2211 10, /* border_width */
2212 InputOutput, /* class */
2213 screen->root_visual, /* visual */
2214 0, NULL); /* masks, not used */
2216 /* Set the title of the window */
2217 XCBChangeProperty(c, PropModeReplace, win.window,
2219 strlen(title), title);
2221 /* Set the title of the window icon */
2222 XCBChangeProperty(c, PropModeReplace, win.window,
2223 WM_ICON_NAME, STRING, 8,
2224 strlen(title_icon), title_icon);
2226 /* Map the window on the screen */
2227 XCBMapWindow (c, win.window);
2237 <p>Note: the use of the atoms needs our program to be compiled
2238 and linked against xcb_atom, so that we have to use
2242 gcc prog.c -o prog `pkg-config --cflags --libs xcb_atom`
2246 for the program to compile fine.
2250 <li class="title"><a name="winop">Simple window operations</a>
2252 One more thing we can do to our window is manipulate them on the
2253 screen (resize them, move them, raise or lower them, iconify
2254 them, and so on). Some window operations functions are supplied
2255 by XCB for this purpose.
2258 <li class="subtitle"><a name="winmap">Mapping and un-mapping a window</a>
2260 The first pair of operations we can apply on a window is
2261 mapping it, or un-mapping it. Mapping a window causes the
2262 window to appear on the screen, as we have seen in our simple
2263 window program example. Un-mapping it causes it to be removed
2264 from the screen (although the window as a logical entity still
2265 exists). This gives the effect of making a window hidden
2266 (unmapped) and shown again (mapped). For example, if we have a
2267 dialog box window in our program, instead of creating it every
2268 time the user asks to open it, we can create the window once,
2269 in an un-mapped mode, and when the user asks to open it, we
2270 simply map the window on the screen. When the user clicked the
2271 'OK' or 'Cancel' button, we simply un-map the window. This is
2272 much faster than creating and destroying the window, however,
2273 the cost is wasted resources, both on the client side, and on
2277 To map a window, you use the following function:
2280 XCBVoidCookie XCBMapWindow(XCBConnection *c, XCBWINDOW window);
2283 To have a simple example, see the <a href="#helloworld">example</a>
2284 above. The mapping operation will cause an
2285 <span class="code">Expose</span> event to be sent to our
2286 application, unless the window is completely covered by other
2290 Un-mapping a window is also simple. You use the function
2293 XCBVoidCookie XCBUnmapWindow(XCBConnection *c, XCBWINDOW window);
2296 The utilization of this function is the same as
2297 <span class="code">XCBMapWindow()</span>.
2299 <li class="subtitle"><a name="winconf">Configuring a window</a>
2301 As we have seen when we have created our first window, in the
2302 X Events subsection, we can set some attributes to the window
2303 (that is, the position, the size, the events the window will
2304 receive, etc). If we want to modify them, but the window is
2305 already created, we can change them by using the following
2309 XCBVoidCookie XCBConfigureWindow (XCBConnection *c, /* The connection to the X server*/
2310 XCBWINDOW window, /* The window to configure */
2311 CARD16 value_mask, /* The mask */
2312 const CARD32 *value_list); /* The values to set */
2315 We set the <span class="code">value_mask</span> to one or
2316 several mask values that are in the X.h header:
2319 <li><span class="code">CWX</span>: new x coordinate of the window's top left corner
2320 <li><span class="code">CWY</span>: new y coordinate of the window's top left corner
2321 <li><span class="code">CWWidth</span>: new width of the window
2322 <li><span class="code">CWHeight</span>: new height of the window
2323 <li><span class="code">CWBorderWidth</span>: new width of the border of the window
2324 <li><span class="code">CWSibling</span>
2325 <li><span class="code">CWStackMode</span>: the new stacking order
2328 We then give to <span class="code">value_mask</span> the new
2329 value. We now describe how to use
2330 <span class="code">XCBConfigureWindow</span> in some useful
2333 <li class="subtitle"><a name="winmove">Moving a window around the screen</a>
2335 An operation we might want to do with windows is to move them
2336 to a different location. This can be done like this:
2339 const static CARD32 values[] = { 10, 20 };
2341 /* The connection c and the window win are supposed to be defined */
2343 /* Move the window to coordinates x = 10 and y = 20 */
2344 XCBConfigureWindow (c, win, CWX | CWY, values);
2347 Note that when the window is moved, it might get partially
2348 exposed or partially hidden by other windows, and thus we
2349 might get <span class="code">Expose</span> events due to this
2352 <li class="subtitle"><a name="winsize">Resizing a window</a>
2354 Yet another operation we can do is to change the size of a
2355 window. This is done using the following code:
2358 const static CARD32 values[] = { 200, 300 };
2360 /* The connection c and the window win are supposed to be defined */
2362 /* Resize the window to width = 10 and height = 20 */
2363 XCBConfigureWindow (c, win, CWWidth | CWHeight, values);
2366 We can also combine the move and resize operations using one
2367 single call to <span class="code">XCBConfigureWindow</span>:
2370 const static CARD32 values[] = { 10, 20, 200, 300 };
2372 /* The connection c and the window win are supposed to be defined */
2374 /* Move the window to coordinates x = 10 and y = 20 */
2375 /* and resize the window to width = 10 and height = 20 */
2376 XCBConfigureWindow (c, win, CWX | CWY | CWWidth | CWHeight, values);
2378 <li class="subtitle"><a name="winstack">Changing windows stacking order: raise and lower</a>
2380 Until now, we changed properties of a single window. We'll see
2381 that there are properties that relate to the window and other
2382 windows. One of hem is the stacking order. That is, the order
2383 in which the windows are layered on top of each other. The
2384 front-most window is said to be on the top of the stack, while
2385 the back-most window is at the bottom of the stack. Here is
2386 how to manipulate our windows stack order:
2389 const static CARD32 values[] = { Above };
2391 /* The connection c and the window win are supposed to be defined */
2393 /* Move the window on the top of the stack */
2394 XCBConfigureWindow (c, win, CWStackMode, values);
2397 const static CARD32 values[] = { Below };
2399 /* The connection c and the window win are supposed to be defined */
2401 /* Move the window on the bottom of the stack */
2402 XCBConfigureWindow (c, win, CWStackMode, values);
2404 <li class="subtitle"><a name="wingetinfo">Getting information about a window</a>
2406 Just like we can set various attributes of our windows, we can
2407 also ask the X server supply the current values of these
2408 attributes. For example, we can check where a window is
2409 located on the screen, what is its current size, whether it is
2410 mapped or not, etc. The structure that contains some of this
2416 CARD8 depth; /* depth of the window */
2419 XCBWINDOW root; /* Id of the root window *>
2420 INT16 x; /* X coordinate of the window's location */
2421 INT16 y; /* Y coordinate of the window's location */
2422 CARD16 width; /* Width of the window */
2423 CARD16 height; /* Height of the window */
2424 CARD16 border_width; /* Width of the window's border */
2425 } XCBGetGeometryRep;
2428 XCB fill this structure with two functions:
2431 XCBGetGeometryCookie XCBGetGeometry (XCBConnection *c,
2432 XCBDRAWABLE drawable);
2433 XCBGetGeometryRep *XCBGetGeometryReply (XCBConnection *c,
2434 XCBGetGeometryCookie cookie,
2435 XCBGenericError **e);
2438 You use them as follows:
2443 XCBGetGeometryRep *geom;
2445 /* You initialize c and win */
2447 geom = XCBGetGeometryReply (c, XCBGetGeometry (c, win), 0);
2449 /* Do something with the fields of geom */
2454 Remark that you have to free the structure, as
2455 <span class="code">XCBGetGeometryReply</span> allocates a
2459 One problem is that the returned location of the window is
2460 relative to its parent window. This makes these coordinates
2461 rather useless for any window manipulation functions, like
2462 moving it on the screen. In order to overcome this problem, we
2463 need to take a two-step operation. First, we find out the Id
2464 of the parent window of our window. We then translate the
2465 above relative coordinates to the screen coordinates.
2468 To get the Id of the parent window, we need this structure:
2477 XCBWINDOW parent; /* Id of the parent window */
2478 CARD16 children_len;
2483 To fill this structure, we use these two functions:
2486 XCBQueryTreeCookie XCBQueryTree (XCBConnection *c,
2488 XCBQueryTreeRep *XCBQueryTreeReply (XCBConnection *c,
2489 XCBQueryTreeCookie cookie,
2490 XCBGenericError **e);
2493 The translated coordinates will be found in this structure:
2502 CARD16 dst_x; /* Translated x coordinate */
2503 CARD16 dst_y; /* Translated y coordinate */
2504 } XCBTranslateCoordinatesRep;
2507 As usual, we need two functions to fill this structure:
2510 XCBTranslateCoordinatesCookie XCBTranslateCoordinates (XCBConnection *c,
2511 XCBWINDOW src_window,
2512 XCBWINDOW dst_window,
2515 XCBTranslateCoordinatesRep *XCBTranslateCoordinatesReply (XCBConnection *c,
2516 XCBTranslateCoordinatesCookie cookie,
2517 XCBGenericError **e);
2520 We use them as follows:
2525 XCBGetGeometryRep *geom;
2526 XCBQueryTreeRep *tree;
2527 XCBTranslateCoordinatesRep *trans;
2529 /* You initialize c and win */
2531 geom = XCBGetGeometryReply (c, XCBGetGeometry (c, win), 0);
2535 tree = XCBQueryTreeReply (c, XCBQueryTree (c, win), 0);
2539 trans = XCBTranslateCoordinatesReply (c,
2540 XCBTranslateCoordinates (c,
2543 geom->x, geom->y),
2548 /* the translated coordinates are in trans->dst_x and trans->dst_y */
2555 Of course, as for <span class="code">geom</span>,
2556 <span class="code">tree</span> and
2557 <span class="code">trans</span> have to be freed.
2560 The work is a bit hard, but XCB is a very low-level library.
2563 <b>TODO:</b> the utilization of these functions should be a
2564 prog, which displays the coordinates of the window.
2567 There is another structure that gives informations about our window:
2572 CARD8 backing_store;
2575 XCBVISUALID visual; /* Visual of the window */
2579 CARD32 backing_planes;
2580 CARD32 backing_pixel;
2582 BOOL map_is_installed;
2583 CARD8 map_state; /* Map state of the window */
2584 BOOL override_redirect;
2585 XCBCOLORMAP colormap; /* Colormap of the window */
2586 CARD32 all_event_masks;
2587 CARD32 your_event_mask;
2588 CARD16 do_not_propagate_mask;
2589 } XCBGetWindowAttributesRep;
2592 XCB supplies these two functions to fill it:
2595 XCBGetWindowAttributesCookie XCBGetWindowAttributes (XCBConnection *c,
2597 XCBGetWindowAttributesRep *XCBGetWindowAttributesReply (XCBConnection *c,
2598 XCBGetWindowAttributesCookie cookie,
2599 XCBGenericError **e);
2602 You use them as follows:
2607 XCBGetWindowAttributesRep *attr;
2609 /* You initialize c and win */
2611 attr = XCBGetWindowAttributesReply (c, XCBGetWindowAttributes (c, win), 0);
2616 /* Do something with the fields of attr */
2621 As for <span class="code">geom</span>,
2622 <span class="code">attr</span> has to be freed.
2625 <li class="title"><a name="usecolor">Using colors to paint the rainbow</a>
2627 Up until now, all our painting operation were done using black
2628 and white. We will (finally) see now how to draw using colors.
2631 <li class="subtitle"><a name="colormap">Color maps</a>
2633 In the beginning, there were not enough colors. Screen
2634 controllers could only support a limited number of colors
2635 simultaneously (initially 2, then 4, 16 and 256). Because of
2636 this, an application could not just ask to draw in a "light
2637 purple-red" color, and expect that color to be available. Each
2638 application allocated the colors it needed, and when all the
2639 color entries (4, 16, 256 colors) were in use, the next color
2640 allocation would fail.
2643 Thus, the notion of "a color map" was introduced. A color map
2644 is a table whose size is the same as the number of
2645 simultaneous colors a given screen controller. Each entry
2646 contained the RGB (Red, Green and Blue) values of a different
2647 color (all colors can be drawn using some combination of red,
2648 green and blue). When an application wants to draw on the
2649 screen, it does not specify which color to use. Rather, it
2650 specifies which color entry of some color map to be used
2651 during this drawing. Change the value in this color map entry
2652 and the drawing will use a different color.
2655 In order to be able to draw using colors that got something to
2656 do with what the programmer intended, color map allocation
2657 functions are supplied. You could ask to allocate entry for a
2658 color with a set of RGB values. If one already existed, you
2659 would get its index in the table. If none existed, and the
2660 table was not full, a new cell would be allocated to contain
2661 the given RGB values, and its index returned. If the table was
2662 full, the procedure would fail. You could then ask to get a
2663 color map entry with a color that is closest to the one you
2664 were asking for. This would mean that the actual drawing on
2665 the screen would be done using colors similar to what you
2666 wanted, but not the same.
2669 On today's more modern screens where one runs an X server with
2670 support for 16 million colors, this limitation looks a little
2671 silly, but remember that there are still older computers with
2672 older graphics cards out there. Using color map, support for
2673 these screen becomes transparent to you. On a display
2674 supporting 16 million colors, any color entry allocation
2675 request would succeed. On a display supporting a limited
2676 number of colors, some color allocation requests would return
2677 similar colors. It won't look as good, but your application
2680 <li class="subtitle"><a name="colormapalloc">Allocating and freeing Color Maps</a>
2682 When you draw using XCB, you can choose to use the standard
2683 color map of the screen your window is displayed on, or you
2684 can allocate a new color map and apply it to a window. In the
2685 latter case, each time the mouse moves onto your window, the
2686 screen color map will be replaced by your window's color map,
2687 and you'll see all the other windows on screen change their
2688 colors into something quite bizzare. In fact, this is the
2689 effect you get with X applications that use the "-install"
2690 command line option.
2693 In XCB, a color map is (as often in X) an Id:
2701 In order to access the screen's default color map, you just
2702 have to retrieve the <span class="code">default_colormap</span>
2703 field of the <span class="code">XCBSCREEN</span> structure
2705 <a href="#screen">Checking basic information about a connection</a>):
2708 #include <stdio.h>
2710 #include <X11/XCB/xcb.h>
2713 main (int argc, char *argv[])
2717 XCBCOLORMAP colormap;
2719 /* Open the connection to the X server and get the first screen */
2720 c = XCBConnect (NULL, NULL);
2721 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2723 colormap = screen->default_colormap;
2729 This will return the color map used by default on the first
2730 screen (again, remember that an X server may support several
2731 different screens, each of which might have its own resources).
2734 The other option, that of allocating a new colormap, works as
2735 follows. We first ask the X server to give an Id to our color
2736 map, with this function:
2739 XCBCOLORMAP XCBCOLORMAPNew (XCBConnection *c);
2742 Then, we create the color map with
2745 XCBVoidCookie XCBCreateColormap (XCBConnection *c, /* Pointer to the XCBConnection structure */
2746 BYTE alloc, /* Colormap entries to be allocated (AllocNone or AllocAll) */
2747 XCBCOLORMAP mid, /* Id of the color map */
2748 XCBWINDOW window, /* Window on whose screen the colormap will be created */
2749 XCBVISUALID visual); /* Id of the visual supported by the screen */
2752 Here is an example of creation of a new color map:
2755 #include <X11/XCB/xcb.h>
2758 main (int argc, char *argv[])
2765 /* Open the connection to the X server and get the first screen */
2766 c = XCBConnect (NULL, NULL);
2767 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2769 /* We create the window win here*/
2771 cmap = XCBCOLORMAPNew (c);
2772 XCBCreateColormap (c, AllocNone, cmap, win, screen->root_visual);
2778 Note that the window parameter is only used to allow the X
2779 server to create the color map for the given screen. We can
2780 then use this color map for any window drawn on the same screen.
2783 To free a color map, it suffices to use this function:
2786 XCBVoidCookie XCBFreeColormap (XCBConnection *c, /* The connection */
2787 XCBCOLORMAP cmap); /* The color map */
2795 <li>XCreateColormap ()
2800 <li>XCBCOLORMAPNew ()
2801 <li>XCBCreateColormap ()
2806 <li>XFreeColormap ()
2811 <li>XCBFreeColormap ()
2816 <li class="subtitle"><a name="alloccolor">Allocating and freeing a color entry</a>
2818 Once we got access to some color map, we can start allocating
2819 colors. The informations related to a color are stored in the
2820 following structure:
2828 CARD16 red; /* The red component */
2829 CARD16 green; /* The green component */
2830 CARD16 blue; /* The blue component */
2832 CARD32 pixel; /* The entry in the color map, supplied by the X server */
2836 XCB supplies these two functions to fill it:
2839 XCBAllocColorCookie XCBAllocColor (XCBConnection *c,
2844 XCBAllocColorRep *XCBAllocColorReply (XCBConnection *c,
2845 XCBAllocColorCookie cookie,
2846 XCBGenericError **e);
2849 The fuction <span class="code">XCBAllocColor()</span> takes the
2850 3 RGB components as parameters (red, green and blue). Here is an
2851 example of using these functions:
2854 #include <malloc.h>
2856 #include <X11/XCB/xcb.h>
2859 main (int argc, char *argv[])
2865 XCBAllocColorRep *rep;
2867 /* Open the connection to the X server and get the first screen */
2868 c = XCBConnect (NULL, NULL);
2869 screen = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).data;
2871 /* We create the window win here*/
2873 cmap = XCBCOLORMAPNew (c);
2874 XCBCreateColormap (c, AllocNone, cmap, win, screen->root_visual);
2876 rep = XCBAllocColorReply (c, XCBAllocColor (c, cmap, 65535, 0, 0), 0);
2881 /* Do something with r->pixel or the components */
2889 As <span class="code">XCBAllocColorReply()</span> allocates
2890 memory, you have to free <span class="code">rep</span>.
2893 <b>TODO</b>: Talk about freeing colors.
2896 <li class="title"><a name="pixmaps">X Bitmaps and Pixmaps</a>
2898 One thing many so-called "Multi-Media" applications need to do,
2899 is display images. In the X world, this is done using bitmaps
2900 and pixmaps. We have already seen some usage of them when
2901 setting an icon for our application. Lets study them further,
2902 and see how to draw these images inside a window, along side the
2903 simple graphics and text we have seen so far.
2906 One thing to note before delving further, is that XCB (nor Xlib)
2907 supplies no means of manipulating popular image formats, such as
2908 gif, png, jpeg or tiff. It is up to the programmer (or to higher
2909 level graphics libraries) to translate these image formats into
2910 formats that the X server is familiar with (x bitmaps and x
2914 <li class="subtitle"><a name="pixmapswhat">What is a X Bitmap? An X Pixmap?</a>
2916 An X bitmap is a two-color image stored in a format specific
2917 to the X window system. When stored in a file, the bitmap data
2918 looks like a C source file. It contains variables defining the
2919 width and the height of the bitmap, an array containing the
2920 bit values of the bitmap (the size of the array is
2921 weight*height), and an optional hot-spot location (that will
2922 be explained later, when discussing mouse cursors).
2925 An X pixmap is a format used to stored images in the memory of
2926 an X server. This format can store both black and white images
2927 (such as x bitmaps) as well as color images. It is the only
2928 image format supported by the X protocol, and any image to be
2929 drawn on screen, should be first translated into this format.
2932 In actuality, an X pixmap can be thought of as a window that
2933 does not appear on the screen. Many graphics operations that
2934 work on windows, will also work on pixmaps. Indeed, the type
2935 of X pixmap in XCB is an Id like a window:
2943 In order to make the difference between a window and a pixmap,
2944 XCB introduces a drawable type, which is a <b>union</b>
2953 in order to avoid confusion between a window and a pixmap. The
2954 operations that will work indifferently on a window or a pixmap
2955 will require a <span class="code">XCBDRAWABLE</span>
2959 Remark: In Xlib, there is no specific difference between a
2960 <span class="code">Drawable</span>, a
2961 <span class="code">Pixmap</span> or a
2962 <span class="code">Window</span>: all are 32 bit long
2966 <li class="subtitle"><a name="pixmapscreate">Creating a pixmap</a>
2968 Sometimes we want to create an un-initialized pixmap, so we
2969 can later draw into it. This is useful for image drawing
2970 programs (creating a new empty canvas will cause the creation
2971 of a new pixmap on which the drawing can be stored). It is
2972 also useful when reading various image formats: we load the
2973 image data into memory, create a pixmap on the server, and
2974 then draw the decoded image data onto that pixmap.
2977 To create a new pixmap, we first ask the X server to give an
2978 Id to our pixmap, with this function:
2981 XCBPIXMAP XCBPIXMAPNew (XCBConnection *c);
2984 Then, XCB supplies the following function to create new pixmaps:
2987 XCBVoidCookie XCBCreatePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
2988 CARD8 depth, /* Depth of the screen */
2989 XCBPIXMAP pid, /* Id of the pixmap */
2990 XCBDRAWABLE drawable,
2991 CARD16 width, /* Width of the window (in pixels) */
2992 CARD16 height); /* Height of the window (in pixels) */
2995 <b>TODO</b>: Explain the drawable parameter, and give an
2996 example (like xpoints.c)
2998 <li class="subtitle"><a name="pixmapsdraw"></a>Drawing a pixmap in a window
3000 Once we got a handle to a pixmap, we can draw it on some
3001 window, using the following function:
3004 XCBVoidCookie XCBCopyArea (XCBConnection *c, /* Pointer to the XCBConnection structure */
3005 XCBDRAWABLE src_drawable, /* The Drawable we want to paste */
3006 XCBDRAWABLE dst_drawable, /* The Drawable on which we copy the previous Drawable */
3007 XCBGCONTEXT gc, /* A Graphic Context */
3008 INT16 src_x, /* Top left x coordinate of the region we want to copy */
3009 INT16 src_y, /* Top left y coordinate of the region we want to copy */
3010 INT16 dst_x, /* Top left x coordinate of the region where we want to copy */
3011 INT16 dst_y, /* Top left y coordinate of the region where we want to copy */
3012 CARD16 width, /* Width of the region we want to copy */
3013 CARD16 height); /* Height of the region we want to copy */
3016 As you can see, we could copy the whole pixmap, as well as
3017 only a given rectangle of the pixmap. This is useful to
3018 optimize the drawing speed: we could copy only what we have
3019 modified in the pixmap.
3022 <b>One important note should be made</b>: it is possible to
3023 create pixmaps with different depths on the same screen. When
3024 we perform copy operations (a pixmap onto a window, etc), we
3025 should make sure that both source and target have the same
3026 depth. If they have a different depth, the operation would
3027 fail. The exception to this is if we copy a specific bit plane
3028 of the source pixmap using the
3029 <span class="code">XCBCopyPlane</span> function. In such an
3030 event, we can copy a specific plain to the target window (in
3031 actuality, setting a specific bit in the color of each pixel
3032 copied). This can be used to generate strange graphic effects
3033 in widow, but that is beyond the scope of this tutorial.
3035 <li class="subtitle"><a name="pixmapsfree"></a>Freeing a pixmap
3037 Finally, when we are done using a given pixmap, we should free
3038 it, in order to free resources of the X server. This is done
3039 using this function:
3042 XCBVoidCookie XCBFreePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
3043 XCBPIXMAP pixmap); /* A given pixmap */
3046 Of course, after having freed it, we must not try accessing
3050 <b>TODO</b>: Give an example, or a link to xpoints.c
3053 <li class="title"><a name="translation">Translation of basic Xlib functions and macros</a>
3055 The problem when you want to port an Xlib program to XCB is that
3056 you don't know if the Xlib function that you want to "translate"
3057 is a X Window one or an Xlib macro. In that section, we describe
3058 a way to translate the usual functions or macros that Xlib
3059 provides. It's usually just a member of a structure.
3062 <li class="subtitle"><a name="displaystructure">Members of the Display structure</a>
3063 In this section, we look at how to translate the macros that
3064 return some members of the <span class="code">Display</span>
3065 structure. They are obtained by using a function that requires a
3066 <span class="code">XCBConnection *</span> or a member of the
3067 <span class="code">XCBConnSetupSuccessRep</span> structure
3068 (via the function <span class="code">XCBGetSetup</span>), or
3069 a function that requires that structure.
3071 <li class="subtitle"><a name="ConnectionNumber">ConnectionNumber</a>
3073 This number is the file descriptor that connects the client
3074 to the server. You just have to use that function:
3077 int XCBGetFileDescriptor(XCBConnection *c);
3079 <li class="subtitle"><a name="DefaultScreen"></a>DefaultScreen
3081 That number is not stored by XCB. It is returned in the
3082 second parameter of the function <span class="code"><a href="#openconn">XCBConnect</a></span>.
3083 Hence, you have to store it yourself if you want to use
3084 it. Then, to get the <span class="code">XCBSCREEN</span>
3085 structure, you have to iterate on the screens.
3086 The equivalent function of the Xlib's
3087 <span class="code">ScreenOfDisplay</span> function can be
3088 found <a href="#ScreenOfDisplay">below</a>. OK, here is the
3089 small piece of code to get that number:
3093 int screen_default_nbr;
3095 /* you pass the name of the display you want to XCBConnect */
3097 c = XCBConnect (display_name, &screen_default_nbr);
3099 /* screen_default_nbr contains now the number of the default screen */
3101 <li class="subtitle"><a name="QLength"></a>QLength
3105 <li class="subtitle"><a name="ScreenCount"></a>ScreenCount
3107 You get the count of screens with the functions
3108 <span class="code">XCBGetSetup</span>
3110 <span class="code">XCBConnSetupSuccessRepRootsIter</span>
3111 (if you need to iterate):
3117 /* you init the connection */
3119 screen_count = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c)).rem;
3121 /* screen_count contains now the count of screens */
3124 If you don't want to iterate over the screens, a better way
3125 to get that number is to use
3126 <span class="code">XCBConnSetupSuccessRepRootsLength</span>:
3132 /* you init the connection */
3134 screen_count = XCBConnSetupSuccessRepRootsLength (XCBGetSetup (c));
3136 /* screen_count contains now the count of screens */
3138 <li class="subtitle"><a name="ServerVendor"></a>ServerVendor
3140 You get the name of the vendor of the server hardware with
3141 the functions <span class="code">XCBGetSetup</span>
3144 class="code">XCBConnSetupSuccessRepVendor</span>. Beware
3145 that, unlike Xlib, the string returned by XCB is not
3146 necessarily null-terminaled:
3150 char *vendor = NULL;
3153 /* you init the connection */
3154 length = XCBConnSetupSuccessRepVendorLength (XCBGetSetup (c));
3155 vendor = (char *)malloc (length + 1);
3157 memcpy (vendor, XCBConnSetupSuccessRepVendor (XCBGetSetup (c)), length);
3158 vendor[length] = '\0';
3160 /* vendor contains now the name of the vendor. Must be freed when not used anymore */
3162 <li class="subtitle"><a name="ProtocolVersion"></a>ProtocolVersion
3164 You get the major version of the protocol in the
3165 <span class="code">XCBConnSetupSuccessRep</span>
3166 structure, with the function <span class="code">XCBGetSetup</span>:
3170 CARD16 protocol_major_version;
3172 /* you init the connection */
3174 protocol_major_version = XCBGetSetup (c)->protocol_major_version;
3176 /* protocol_major_version contains now the major version of the protocol */
3178 <li class="subtitle"><a name="ProtocolRevision"></a>ProtocolRevision
3180 You get the minor version of the protocol in the
3181 <span class="code">XCBConnSetupSuccessRep</span>
3182 structure, with the function <span class="code">XCBGetSetup</span>:
3186 CARD16 protocol_minor_version;
3188 /* you init the connection */
3190 protocol_minor_version = XCBGetSetup (c)->protocol_minor_version;
3192 /* protocol_minor_version contains now the minor version of the protocol */
3194 <li class="subtitle"><a name="VendorRelease"></a>VendorRelease
3196 You get the number of the release of the server hardware in the
3197 <span class="code">XCBConnSetupSuccessRep</span>
3198 structure, with the function <span class="code">XCBGetSetup</span>:
3202 CARD32 release_number;
3204 /* you init the connection */
3206 release_number = XCBGetSetup (c)->release_number;
3208 /* release_number contains now the number of the release of the server hardware */
3210 <li class="subtitle"><a name="DisplayString"></a>DisplayString
3212 The name of the display is not stored in XCB. You have to
3213 store it by yourself.
3215 <li class="subtitle"><a name="BitmapUnit"></a>BitmapUnit
3217 You get the bitmap scanline unit in the
3218 <span class="code">XCBConnSetupSuccessRep</span>
3219 structure, with the function <span class="code">XCBGetSetup</span>:
3223 CARD8 bitmap_format_scanline_unit;
3225 /* you init the connection */
3227 bitmap_format_scanline_unit = XCBGetSetup (c)->bitmap_format_scanline_unit;
3229 /* bitmap_format_scanline_unit contains now the bitmap scanline unit */
3231 <li class="subtitle"><a name="BitmapBitOrder"></a>BitmapBitOrder
3233 You get the bitmap bit order in the
3234 <span class="code">XCBConnSetupSuccessRep</span>
3235 structure, with the function <span class="code">XCBGetSetup</span>:
3239 CARD8 bitmap_format_bit_order;
3241 /* you init the connection */
3243 bitmap_format_bit_order = XCBGetSetup (c)->bitmap_format_bit_order;
3245 /* bitmap_format_bit_order contains now the bitmap bit order */
3247 <li class="subtitle"><a name="BitmapPad"></a>BitmapPad
3249 You get the bitmap scanline pad in the
3250 <span class="code">XCBConnSetupSuccessRep</span>
3251 structure, with the function <span class="code">XCBGetSetup</span>:
3255 CARD8 bitmap_format_scanline_pad;
3257 /* you init the connection */
3259 bitmap_format_scanline_pad = XCBGetSetup (c)->bitmap_format_scanline_pad;
3261 /* bitmap_format_scanline_pad contains now the bitmap scanline pad */
3263 <li class="subtitle"><a name="ImageByteOrder"></a>ImageByteOrder
3265 You get the image byte order in the
3266 <span class="code">XCBConnSetupSuccessRep</span>
3267 structure, with the function <span class="code">XCBGetSetup</span>:
3271 CARD8 image_byte_order;
3273 /* you init the connection */
3275 image_byte_order = XCBGetSetup (c)->image_byte_order;
3277 /* image_byte_order contains now the image byte order */
3280 <li class="subtitle"><a name="screenofdisplay">ScreenOfDisplay related functions</a>
3282 in Xlib, <span class="code">ScreenOfDisplay</span> returns a
3283 <span class="code">Screen</span> structure that contains
3284 several characteristics of your screen. XCB has a similar
3285 structure (<span class="code">XCBSCREEN</span>),
3286 but the way to obtain it is a bit different. With
3287 Xlib, you just provide the number of the screen and you grab it
3288 from an array. With XCB, you iterate over all the screens to
3289 obtain the one you want. The complexity of this operation is
3290 O(n). So the best is to store this structure if you use
3291 it often. See <a href="#ScreenOfDisplay">ScreenOfDisplay</a> just below.
3294 Xlib provides generally two functions to obtain the characteristics
3295 related to the screen. One with the display and the number of
3296 the screen, which calls <span class="code">ScreenOfDisplay</span>,
3297 and the other that uses the <span class="code">Screen</span> structure.
3298 This might be a bit confusing. As mentioned above, with XCB, it
3299 is better to store the <span class="code">XCBSCREEN</span>
3300 structure. Then, you have to read the members of this
3301 structure. That's why the Xlib functions are put by pairs (or
3302 more) as, with XCB, you will use the same code.
3305 <li class="subtitle"><a name="ScreenOfDisplay">ScreenOfDisplay</a>
3307 This function returns the Xlib <span class="code">Screen</span>
3308 structure. With XCB, you iterate over all the screens and
3309 once you get the one you want, you return it:
3311 <pre class="code"><a name="ScreenOfDisplay"></a>
3312 XCBSCREEN *ScreenOfDisplay (XCBConnection *c,
3317 iter = XCBConnSetupSuccessRepRootsIter (XCBGetSetup (c));
3318 for (; iter.rem; --screen, XCBSCREENNext (&iter))
3326 As mentioned above, you might want to store the value
3327 returned by this function.
3330 All the functions below will use the result of that
3331 function, as they just grab a specific member of the
3332 <span class="code">XCBSCREEN</span> structure.
3334 <li class="subtitle"><a name="DefaultScreenOfDisplay"></a>DefaultScreenOfDisplay
3336 It is the default screen that you obtain when you connect to
3337 the X server. It suffices to call the <a href="#ScreenOfDisplay">ScreenOfDisplay</a>
3338 function above with the connection and the number of the
3343 int screen_default_nbr;
3344 XCBSCREEN *default_screen; /* the returned default screen */
3346 /* you pass the name of the display you want to XCBConnect */
3348 c = XCBConnect (display_name, &screen_default_nbr);
3349 default_screen = ScreenOfDisplay (c, screen_default_nbr);
3351 /* default_screen contains now the default root window, or a NULL window if no screen is found */
3353 <li class="subtitle"><a name="RootWindow">RootWindow / RootWindowOfScreen</a>
3360 XCBWINDOW root_window = { 0 }; /* the returned window */
3362 /* you init the connection and screen_nbr */
3364 screen = ScreenOfDisplay (c, screen_nbr);
3366 root_window = screen->root;
3368 /* root_window contains now the root window, or a NULL window if no screen is found */
3370 <li class="subtitle"><a name="DefaultRootWindow">DefaultRootWindow</a>
3372 It is the root window of the default screen. So, you call
3373 <a name="ScreenOfDisplay">ScreenOfDisplay</a> with the
3374 default screen number and you get the
3375 <a href="#RootWindow">root window</a> as above:
3380 int screen_default_nbr;
3381 XCBWINDOW root_window = { 0 }; /* the returned root window */
3383 /* you pass the name of the display you want to XCBConnect */
3385 c = XCBConnect (display_name, &screen_default_nbr);
3386 screen = ScreenOfDisplay (c, screen_default_nbr);
3388 root_window = screen->root;
3390 /* root_window contains now the default root window, or a NULL window if no screen is found */
3392 <li class="subtitle"><a name="DefaultVisual">DefaultVisual / DefaultVisualOfScreen</a>
3394 While a Visual is, in Xlib, a structure, in XCB, there are
3395 two types: <span class="code">XCBVISUALID</span>, which is
3396 the Id of the visual, and <span class="code">XCBVISUALTYPE</span>,
3397 which corresponds to the Xlib Visual. To get the Id of the
3398 visual of a screen, just get the
3399 <span class="code">root_visual</span>
3400 member of a <span class="code">XCBSCREEN</span>:
3406 XCBVISUALID root_visual = { 0 }; /* the returned visual Id */
3408 /* you init the connection and screen_nbr */
3410 screen = ScreenOfDisplay (c, screen_nbr);
3412 root_visual = screen->root_visual;
3414 /* root_visual contains now the value of the Id of the visual, or a NULL visual if no screen is found */
3417 To get the <span class="code">XCBVISUALTYPE</span>
3418 structure, it's a bit less easy. You have to get the
3419 <span class="code">XCBSCREEN</span> structure that you want,
3420 get its <span class="code">root_visual</span> member,
3421 then iterate over the <span class="code">XCBDEPTH</span>s
3422 and the <span class="code">XCBVISUALTYPE</span>s, and compare
3423 the <span class="code">XCBVISUALID</span> of these <span class="code">XCBVISUALTYPE</span>s:
3424 with <span class="code">root_visual</span>:
3430 XCBVISUALID root_visual = { 0 };
3431 XCBVISUATYPE *visual_type = NULL; /* the returned visual type */
3433 /* you init the connection and screen_nbr */
3435 screen = ScreenOfDisplay (c, screen_nbr);
3438 XCBDEPTHIter depth_iter;
3440 depth_iter = XCBSCREENAllowedDepthsIter (screen);
3441 for (; depth_iter.rem; XCBDEPTHNext (&depth_iter))
3443 XCBVISUALTYPEIter visual_iter;
3445 visual_iter = XCBDEPTHVisualsIter (depth_iter.data);
3446 for (; visual_iter.rem; XCBVISUALTYPENext (&visual_iter))
3448 if (screen->root_visual.id == visual_iter.data->visual_id.id)
3450 visual_type = visual_iter.data;
3457 /* visual_type contains now the visual structure, or a NULL visual structure if no screen is found */
3459 <li class="subtitle"><a name="DefaultGC">DefaultGC / DefaultGCOfScreen</a>
3461 This default Graphic Context is just a newly created Graphic
3462 Context, associated to the root window of a
3463 <span class="code">XCBSCREEN</span>,
3464 using the black white pixels of that screen:
3470 XCBGCONTEXT gc = { 0 }; /* the returned default graphic context */
3472 /* you init the connection and screen_nbr */
3474 screen = ScreenOfDisplay (c, screen_nbr);
3481 gc = XCBGCONTEXTNew (c);
3482 draw.window = screen->root;
3483 mask = GCForeground | GCBackground;
3484 values[0] = screen->black_pixel;
3485 values[1] = screen->white_pixel;
3486 XCBCreateGC (c, gc, draw, mask, values);
3489 /* gc contains now the default graphic context */
3491 <li class="subtitle"><a name="BlackPixel">BlackPixel / BlackPixelOfScreen</a>
3493 It is the Id of the black pixel, which is in the structure
3494 of an <span class="code">XCBSCREEN</span>.
3500 CARD32 black_pixel = 0; /* the returned black pixel */
3502 /* you init the connection and screen_nbr */
3504 screen = ScreenOfDisplay (c, screen_nbr);
3506 black_pixel = screen->black_pixel;
3508 /* black_pixel contains now the value of the black pixel, or 0 if no screen is found */
3510 <li class="subtitle"><a name="WhitePixel">WhitePixel / WhitePixelOfScreen</a>
3512 It is the Id of the white pixel, which is in the structure
3513 of an <span class="code">XCBSCREEN</span>.
3519 CARD32 white_pixel = 0; /* the returned white pixel */
3521 /* you init the connection and screen_nbr */
3523 screen = ScreenOfDisplay (c, screen_nbr);
3525 white_pixel = screen->white_pixel;
3527 /* white_pixel contains now the value of the white pixel, or 0 if no screen is found */
3529 <li class="subtitle"><a name="DisplayWidth">DisplayWidth / WidthOfScreen</a>
3531 It is the width in pixels of the screen that you want, and
3532 which is in the structure of the corresponding
3533 <span class="code">XCBSCREEN</span>.
3539 CARD32 width_in_pixels = 0; /* the returned width in pixels */
3541 /* you init the connection and screen_nbr */
3543 screen = ScreenOfDisplay (c, screen_nbr);
3545 width_in_pixels = screen->width_in_pixels;
3547 /* width_in_pixels contains now the width in pixels, or 0 if no screen is found */
3549 <li class="subtitle"><a name="DisplayHeight">DisplayHeight / HeightOfScreen</a>
3551 It is the height in pixels of the screen that you want, and
3552 which is in the structure of the corresponding
3553 <span class="code">XCBSCREEN</span>.
3559 CARD32 height_in_pixels = 0; /* the returned height in pixels */
3561 /* you init the connection and screen_nbr */
3563 screen = ScreenOfDisplay (c, screen_nbr);
3565 height_in_pixels = screen->height_in_pixels;
3567 /* height_in_pixels contains now the height in pixels, or 0 if no screen is found */
3569 <li class="subtitle"><a name="DisplayWidthMM">DisplayWidthMM / WidthMMOfScreen</a>
3571 It is the width in millimeters of the screen that you want, and
3572 which is in the structure of the corresponding
3573 <span class="code">XCBSCREEN</span>.
3579 CARD32 width_in_millimeters = 0; /* the returned width in millimeters */
3581 /* you init the connection and screen_nbr */
3583 screen = ScreenOfDisplay (c, screen_nbr);
3585 width_in_millimeters = screen->width_in_millimeters;
3587 /* width_in_millimeters contains now the width in millimeters, or 0 if no screen is found */
3589 <li class="subtitle"><a name="DisplayHeightMM">DisplayHeightMM / HeightMMOfScreen</a>
3591 It is the height in millimeters of the screen that you want, and
3592 which is in the structure of the corresponding
3593 <span class="code">XCBSCREEN</span>.
3599 CARD32 height_in_millimeters = 0; /* the returned height in millimeters */
3601 /* you init the connection and screen_nbr */
3603 screen = ScreenOfDisplay (c, screen_nbr);
3605 height_in_millimeters = screen->height_in_millimeters;
3607 /* height_in_millimeters contains now the height in millimeters, or 0 if no screen is found */
3609 <li class="subtitle"><a name="DisplayPlanes">DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen</a>
3611 It is the depth (in bits) of the root window of the
3612 screen. You get it from the <span class="code">XCBSCREEN</span> structure.
3618 CARD8 root_depth = 0; /* the returned depth of the root window */
3620 /* you init the connection and screen_nbr */
3622 screen = ScreenOfDisplay (c, screen_nbr);
3624 root_depth = screen->root_depth;
3626 /* root_depth contains now the depth of the root window, or 0 if no screen is found */
3628 <li class="subtitle"><a name="DefaultColormap">DefaultColormap / DefaultColormapOfScreen</a>
3630 This is the default colormap of the screen (and not the
3631 (default) colormap of the default screen !). As usual, you
3632 get it from the <span class="code">XCBSCREEN</span> structure:
3638 XCBCOLORMAP default_colormap = { 0 }; /* the returned default colormap */
3640 /* you init the connection and screen_nbr */
3642 screen = ScreenOfDisplay (c, screen_nbr);
3644 default_colormap = screen->default_colormap;
3646 /* default_colormap contains now the default colormap, or a NULL colormap if no screen is found */
3648 <li class="subtitle"><a name="MinCmapsOfScreen"></a>MinCmapsOfScreen
3650 You get the minimum installed colormaps in the <span class="code">XCBSCREEN</span> structure:
3656 CARD16 min_installed_maps = 0; /* the returned minimum installed colormaps */
3658 /* you init the connection and screen_nbr */
3660 screen = ScreenOfDisplay (c, screen_nbr);
3662 min_installed_maps = screen->min_installed_maps;
3664 /* min_installed_maps contains now the minimum installed colormaps, or 0 if no screen is found */
3666 <li class="subtitle"><a name="MaxCmapsOfScreen"></a>MaxCmapsOfScreen
3668 You get the maximum installed colormaps in the <span class="code">XCBSCREEN</span> structure:
3674 CARD16 max_installed_maps = 0; /* the returned maximum installed colormaps */
3676 /* you init the connection and screen_nbr */
3678 screen = ScreenOfDisplay (c, screen_nbr);
3680 max_installed_maps = screen->max_installed_maps;
3682 /* max_installed_maps contains now the maximum installed colormaps, or 0 if no screen is found */
3684 <li class="subtitle"><a name="DoesSaveUnders"></a>DoesSaveUnders
3686 You know if <span class="code">save_unders</span> is set,
3687 by looking in the <span class="code">XCBSCREEN</span> structure:
3693 BOOL save_unders = 0; /* the returned value of save_unders */
3695 /* you init the connection and screen_nbr */
3697 screen = ScreenOfDisplay (c, screen_nbr);
3699 save_unders = screen->save_unders;
3701 /* save_unders contains now the value of save_unders, or FALSE if no screen is found */
3703 <li class="subtitle"><a name="DoesBackingStore"></a>DoesBackingStore
3705 You know the value of <span class="code">backing_stores</span>,
3706 by looking in the <span class="code">XCBSCREEN</span> structure:
3712 BYTE backing_stores = 0; /* the returned value of backing_stores */
3714 /* you init the connection and screen_nbr */
3716 screen = ScreenOfDisplay (c, screen_nbr);
3718 backing_stores = screen->backing_stores;
3720 /* backing_stores contains now the value of backing_stores, or FALSE if no screen is found */
3722 <li class="subtitle"><a name="EventMaskOfScreen"></a>EventMaskOfScreen
3724 To get the current input masks,
3725 you look in the <span class="code">XCBSCREEN</span> structure:
3731 CARD32 current_input_masks = 0; /* the returned value of current input masks */
3733 /* you init the connection and screen_nbr */
3735 screen = ScreenOfDisplay (c, screen_nbr);
3737 current_input_masks = screen->current_input_masks;
3739 /* current_input_masks contains now the value of the current input masks, or FALSE if no screen is found */
3742 <li class="subtitle"><a name="misc">Miscellaneous macros</a>
3744 <li class="subtitle"><a name="DisplayOfScreen"></a>DisplayOfScreen
3746 in Xlib, the <span class="code">Screen</span> structure
3747 stores its associated <span class="code">Display</span>
3748 structure. This is not the case in the X Window protocol,
3749 hence, it's also not the case in XCB. So you have to store
3752 <li class="subtitle"><a name="DisplayCells"></a>DisplayCells / CellsOfScreen
3754 To get the colormap entries,
3755 you look in the <span class="code">XCBVISUALTYPE</span>
3756 structure, that you grab like <a class="subsection" href="#DefaultVisual">here</a>:
3760 XCBVISUALTYPE *visual_type;
3761 CARD16 colormap_entries = 0; /* the returned value of the colormap entries */
3763 /* you init the connection and visual_type */
3766 colormap_entries = visual_type->colormap_entries;
3768 /* colormap_entries contains now the value of the colormap entries, or FALSE if no screen is found */