From 3744281b9ae8aa0ab86ceaee1afe8a603e3aeb2c Mon Sep 17 00:00:00 2001 From: marha Date: Mon, 19 Nov 2012 10:16:38 +0100 Subject: dos -> unix --- libxcb/doc/.gitignore | 2 +- libxcb/doc/tutorial/index.html | 9042 ++++++++++++++++++++-------------------- libxcb/doc/tutorial/xcb.css | 246 +- libxcb/doc/xcb.doxygen.in | 2506 +++++------ 4 files changed, 5898 insertions(+), 5898 deletions(-) (limited to 'libxcb/doc') diff --git a/libxcb/doc/.gitignore b/libxcb/doc/.gitignore index 55caf95c6..94ce3a9b9 100644 --- a/libxcb/doc/.gitignore +++ b/libxcb/doc/.gitignore @@ -1,2 +1,2 @@ -manual +manual xcb.doxygen \ No newline at end of file diff --git a/libxcb/doc/tutorial/index.html b/libxcb/doc/tutorial/index.html index bb3338869..adec0acd3 100644 --- a/libxcb/doc/tutorial/index.html +++ b/libxcb/doc/tutorial/index.html @@ -1,4521 +1,4521 @@ - - - - - - Basic Graphics Programming With The XCB Library - - - - - -
- Basic Graphics Programming With The XCB Library -
-
-
    -
  1. Introduction -
  2. The client and server model of the X window system -
  3. GUI programming: the asynchronous model -
  4. Basic XCB notions -
      -
    1. The X Connection -
    2. Requests and replies: the Xlib killers -
    3. The Graphics Context -
    4. Object handles -
    5. Memory allocation for XCB structures -
    6. Events -
    -
  5. Using XCB-based programs -
      -
    1. Installation of XCB -
    2. Compiling XCB-based programs -
    -
  6. Opening and closing the connection to an X server -
  7. Checking basic information about a connection -
  8. Creating a basic window - the "hello world" program -
  9. Drawing in a window -
      -
    1. Allocating a Graphics Context -
    2. Changing the attributes of a Graphics Context -
    3. Drawing primitives: point, line, box, circle,... -
    -
  10. X Events -
      -
    1. Registering for event types using event masks -
    2. Receiving events: writing the events loop -
    3. Expose events -
    4. Getting user input -
        -
      1. Mouse button press and release events -
      2. Mouse movement events -
      3. Mouse pointer enter and leave events -
      4. The keyboard focus -
      5. Keyboard press and release events -
      -
    5. X events: a complete example -
    -
  11. Handling text and fonts -
      -
    1. The Font structure -
    2. Opening a Font -
    3. Assigning a Font to a Graphic Context -
    4. Drawing text in a drawable -
    5. Complete example -
    -
  12. Windows hierarchy -
      -
    1. Root, parent and child windows -
    2. Events propagation -
    -
  13. Interacting with the window manager -
      -
    1. Window properties -
    2. Setting the window name and icon name -
    3. Setting preferred window size(s) -
    4. Setting miscellaneous window manager hints -
    5. Setting an application's icon -
    6. Obeying the delete-window protocol -
    -
  14. Simple window operations -
      -
    1. Mapping and unmapping a window -
    2. Configuring a window -
    3. Moving a window around the screen -
    4. Resizing a window -
    5. Changing windows stacking order: raise and lower -
    6. Iconifying and de-iconifying a window -
    7. Getting informations about a window -
    -
  15. Using colors to paint the rainbow -
      -
    1. Color maps -
    2. Allocating and freeing Color Maps -
    3. Allocating and freeing a color entry -
    4. Drawing with a color -
    -
  16. X Bitmaps and Pixmaps -
      -
    1. What is a X Bitmap ? An X Pixmap ? -
    2. Loading a bitmap from a file -
    3. Drawing a bitmap in a window -
    4. Creating a pixmap -
    5. Drawing a pixmap in a window -
    6. Freeing a pixmap -
    -
  17. Messing with the mouse cursor -
      -
    1. Creating and destroying a mouse cursor -
    2. Setting a window's mouse cursor -
    3. Complete example -
    -
  18. Translation of basic Xlib functions and macros -
      -
    1. Members of the Display structure -
        -
      1. ConnectionNumber -
      2. DefaultScreen -
      3. QLength -
      4. ScreenCount -
      5. ServerVendor -
      6. ProtocolVersion -
      7. ProtocolRevision -
      8. VendorRelease -
      9. DisplayString -
      10. BitmapUnit -
      11. BitmapBitOrder -
      12. BitmapPad -
      13. ImageByteOrder -
      -
    2. ScreenOfDisplay related functions -
        -
      1. ScreenOfDisplay -
      2. DefaultScreenOfDisplay -
      3. RootWindow / RootWindowOfScreen -
      4. DefaultRootWindow -
      5. DefaultVisual / DefaultVisualOfScreen -
      6. DefaultGC / DefaultGCOfScreen -
      7. BlackPixel / BlackPixelOfScreen -
      8. WhitePixel / WhitePixelOfScreen -
      9. DisplayWidth / WidthOfScreen -
      10. DisplayHeight / HeightOfScreen -
      11. DisplayWidthMM / WidthMMOfScreen -
      12. DisplayHeightMM / HeightMMOfScreen -
      13. DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen -
      14. DefaultColormap / DefaultColormapOfScreen -
      15. MinCmapsOfScreen -
      16. MaxCmapsOfScreen -
      17. DoesSaveUnders -
      18. DoesBackingStore -
      19. EventMaskOfScreen -
      -
    3. Miscellaneaous macros -
        -
      1. DisplayOfScreen -
      2. DisplayCells / CellsOfScreen -
      -
    -
-
-
-
    -
  1. Introduction -

    - This tutorial is based on the - Xlib Tutorial - written by Guy Keren. The - author allowed me to take some parts of his text, mainly the text which - deals with the X Windows generality. -

    -

    - This tutorial is intended for people who want to start to program - with the XCB - library. keep in mind that XCB, like the - Xlib - library, isn't what most programmers wanting to write X - applications are looking for. They should use a much higher - level GUI toolkit like Motif, - LessTiff, - GTK, - QT, - EWL, - ETK, or use - Cairo. - However, - we need to start somewhere. More than this, knowing how things - work down below is never a bad idea. -

    -

    - After reading this tutorial, one should be able to write very - simple graphical programs, but not programs with decent user - interfaces. For such programs, one of the previously mentioned - libraries should be used. -

    -

    - But what is XCB? Xlib has been - the standard C binding for the X - Window System protocol for many years now. It is an - excellent piece of work, but there are applications for which it - is not ideal, for example: -

    -
      -
    • Small platforms: Xlib is a large piece of code, and - it's difficult to make it smaller -
    • Latency hiding: Xlib requests requiring a reply are - effectively synchronous: they block until the reply appears, - whether the result is needed immediately or not. -
    • Direct access to the protocol: Xlib does quite a - bit of caching, layering, and similar optimizations. While this - is normally a feature, it makes it difficult to simply emit - specified X protocol requests and process specific - responses. -
    • Threaded applications: While Xlib does attempt to - support multithreading, the API makes this difficult and - error-prone. -
    • New extensions: The Xlib infrastructure provides - limited support for the new creation of X extension client side - code. -
    -

    - For these reasons, among others, XCB, an X C binding, has been - designed to solve the above problems and thus provide a base for -

    -
      -
    • Toolkit implementation. -
    • Direct protocol-level programming. -
    • Lightweight emulation of commonly used portions of the - Xlib API. -
    -
    -
  2. The client and server model of the X window system -

    - The X Window System was developed with one major goal: - flexibility. The idea was that the way things look is one thing, - but the way things work is another matter. Thus, the lower - levels provide the tools required to draw windows, handle user - input, allow drawing graphics using colors (or black and white - screens), etc. To this point, a decision was made to separate - the system into two parts. A client that decides what to do, and - a server that actually draws on the screen and reads user input - in order to send it to the client for processing. -

    -

    - This model is the complete opposite of what is used to when - dealing with clients and servers. In our case, the user sits - near the machine controlled by the server, while the client - might be running on a remote machine. The server controls the - screens, mouse and keyboard. A client may connect to the server, - request that it draws a window (or several windows), and ask the - server to send it any input the user sends to these - windows. Thus, several clients may connect to a single X server - (one might be running mail software, one running a WWW - browser, etc). When input is sent by the user to some window, - the server sends a message to the client controlling this window - for processing. The client decides what to do with this input, - and sends the server requests for drawing in the window. -

    -

    - The whole session is carried out using the X message - protocol. This protocol was originally carried over the TCP/IP - protocol suite, allowing the client to run on any machine - connected to the same network that the server is. Later on, the - X servers were extended to allow clients running on the local - machine with more optimized access to the server (note that an X - protocol message may be several hundreds of KB in size), such as - using shared memory, or using Unix domain sockets (a method for - creating a logical channel on a Unix system between two processes). -

    -
  3. GUI programming: the asynchronous model -

    - Unlike conventional computer programs, that carry some serial - nature, a GUI program usually uses an asynchronous programming - model, also known as "event-driven programming". This means that - that program mostly sits idle, waiting for events sent by the X - server, and then acts upon these events. An event may say "The - user pressed the 1st button mouse in spot (x,y)", or "The window - you control needs to be redrawn". In order for the program to be - responsive to the user input, as well as to refresh requests, it - needs to handle each event in a rather short period of time - (e.g. less that 200 milliseconds, as a rule of thumb). -

    -

    - This also implies that the program may not perform operations - that might take a long time while handling an event (such as - opening a network connection to some remote server, or - connecting to a database server, or even performing a long file - copy operation). Instead, it needs to perform all these - operations in an asynchronous manner. This may be done by using - various asynchronous models to perform the longish operations, - or by performing them in a different process or thread. -

    -

    - So the way a GUI program looks is something like that: -

    -
      -
    1. Perform initialization routines. -
    2. Connect to the X server. -
    3. Perform X-related initialization. -
    4. While not finished: -
        -
      1. Receive the next event from the X server. -
      2. Handle the event, possibly sending various drawing - requests to the X server. -
      3. If the event was a quit message, exit the loop. -
      -
    5. Close down the connection to the X server. -
    6. Perform cleanup operations. -
    -
    -
  4. Basic XCB notions -

    - XCB has been created to eliminate the need for - programs to actually implement the X protocol layer. This - library gives a program a very low-level access to any X - server. Since the protocol is standardized, a client using any - implementation of XCB may talk with any X server (the same - occurs for Xlib, of course). We now give a brief description of - the basic XCB notions. They will be detailed later. -

    -
      -
    1. The X Connection -

      - The major notion of using XCB is the X Connection. This is a - structure representing the connection we have open with a - given X server. It hides a queue of messages coming from the - server, and a queue of pending requests that our client - intends to send to the server. In XCB, this structure is named - 'xcb_connection_t'. It is analogous to the Xlib Display. - When we open a connection to an X server, the - library returns a pointer to such a structure. Later, we - supply this pointer to any XCB function that should send - messages to the X server or receive messages from this server. -

      -
    2. Requests and - replies: the Xlib killers -

      - To ask for information from the X server, we have to make a request - and ask for a reply. With Xlib, these two tasks are - automatically done: Xlib locks the system, sends a request, - waits for a reply from the X server and unlocks. This is - annoying, especially if one makes a lot of requests to the X - server. Indeed, Xlib has to wait for the end of a reply - before asking for the next request (because of the locks that - Xlib sends). For example, here is a time-line of N=4 - requests/replies with Xlib, with a round-trip latency - T_round_trip that is 5 times long as the time required - to write or read a request/reply (T_write/T_read): -

      -
      -  W-----RW-----RW-----RW-----R
      -
      -
        -
      • W: Writing request -
      • -: Stalled, waiting for data -
      • R: Reading reply -
      -

      - The total time is N * (T_write + T_round_trip + T_read). -

      -

      - With XCB, we can suppress most of the round-trips as the - requests and the replies are not locked. We usually send a - request, then XCB returns to us a cookie, which is an - identifier. Then, later, we ask for a reply using this - cookie and XCB returns a - pointer to that reply. Hence, with XCB, we can send a lot of - requests, and later in the program, ask for all the replies - when we need them. Here is the time-line for 4 - requests/replies when we use this property of XCB: -

      -
      -  WWWW--RRRR
      -
      -

      - The total time is N * T_write + max (0, T_round_trip - (N-1) * - T_write) + N * T_read. Which can be considerably faster than - all those Xlib round-trips. -

      -

      - Here is a program that computes the time to create 500 atoms - with Xlib and XCB. It shows the Xlib way, the bad XCB way - (which is similar to Xlib) and the good XCB way. On my - computer, XCB is 25 times faster than Xlib. -

      -
      -#include <stdlib.h>
      -#include <stdio.h>
      -#include <string.h>
      -#include <sys/time.h>
      -
      -#include <xcb/xcb.h>
      -
      -#include <X11/Xlib.h>
      -
      -double
      -get_time(void)
      -{
      -  struct timeval timev;
      -
      -  gettimeofday(&timev, NULL);
      -
      -  return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
      -}
      -
      -int
      -main ()
      -{
      -  xcb_connection_t         *c;
      -  xcb_atom_t               *atoms;
      -  xcb_intern_atom_cookie_t *cs;
      -  char                    **names;
      -  int                       count;
      -  int                       i;
      -  double                    start;
      -  double                    end;
      -  double                    diff;
      -
      -  /* Xlib */
      -  Display *disp;
      -  Atom    *atoms_x;
      -  double   diff_x;
      -
      -  c = xcb_connect (NULL, NULL);
      -
      -  count = 500;
      -  atoms = (xcb_atom_t *)malloc (count * sizeof (atoms));
      -  names = (char **)malloc (count * sizeof (char *));
      -
      -  /* init names */
      -  for (i = 0; i < count; ++i) {
      -    char buf[100];
      -
      -    sprintf (buf, "NAME%d", i);
      -    names[i] = strdup (buf);
      -  }
      -
      -  /* bad use */
      -  start = get_time ();
      -
      -  for (i = 0; i < count; ++i)
      -    atoms[i] = xcb_intern_atom_reply (c,
      -                                      xcb_intern_atom (c,
      -                                                       0,
      -                                                       strlen(names[i]),
      -                                                       names[i]),
      -                                      NULL)->atom;
      -
      -  end = get_time ();
      -  diff = end - start;
      -  printf ("bad use time  : %f\n", diff);
      -
      -  /* good use */
      -  start = get_time ();
      -
      -  cs = (xcb_intern_atom_cookie_t *) malloc (count * sizeof(xcb_intern_atom_cookie_t));
      -  for(i = 0; i < count; ++i)
      -    cs[i] = xcb_intern_atom (c, 0, strlen(names[i]), names[i]);
      -
      -  for(i = 0; i < count; ++i) {
      -    xcb_intern_atom_reply_t *r;
      -
      -    r = xcb_intern_atom_reply(c, cs[i], 0);
      -    if(r)
      -      atoms[i] = r->atom;
      -    free(r);
      -  }
      -
      -  end = get_time ();
      -  printf ("good use time : %f\n", end - start);
      -  printf ("ratio         : %f\n", diff / (end - start));
      -  diff = end - start;
      -
      -  /* free var */
      -  free (atoms);
      -  free (cs);
      -
      -  xcb_disconnect (c);
      -
      -  /* Xlib */
      -  disp = XOpenDisplay (getenv("DISPLAY"));
      -
      -  atoms_x = (Atom *)malloc (count * sizeof (atoms_x));
      -
      -  start = get_time ();
      -
      -  for (i = 0; i < count; ++i)
      -    atoms_x[i] = XInternAtom(disp, names[i], 0);
      -
      -  end = get_time ();
      -  diff_x = end - start;
      -  printf ("Xlib use time : %f\n", diff_x);
      -  printf ("ratio         : %f\n", diff_x / diff);
      -
      -  free (atoms_x);
      -  for (i = 0; i < count; ++i)
      -    free (names[i]);
      -  free (names);
      -
      -  XCloseDisplay (disp);
      -
      -  return 0;
      -}
      -
      -
    3. The Graphic Context -

      - When we perform various drawing operations (graphics, text, - etc), we may specify various options for controlling how the - data will be drawn (what foreground and background colors to - use, how line edges will be connected, what font to use when - drawing some text, etc). In order to avoid the need to supply - hundreds of parameters to each drawing function, a graphical - context structure is used. We set the various drawing options - in this structure, and then we pass a pointer to this - structure to any drawing routines. This is rather handy, as we - often need to perform several drawing requests with the same - options. Thus, we would initialize a graphical context, set - the desired options, and pass this structure to all drawing - functions. -

      -

      - Note that graphic contexts have no client-side structure in - XCB, they're just XIDs. Xlib has a client-side structure - because it caches the GC contents so it can avoid making - redundant requests, but of course XCB doesn't do that. -

      -
    4. Events -

      - A structure is used to pass events received from the X - server. XCB supports exactly the events specified in the - protocol (33 events). This structure contains the type - of event received (including a bit for whether it came - from the server or another client), as well as the data associated with the - event (e.g. position on the screen where the event was - generated, mouse button associated with the event, region of - the screen associated with a "redraw" event, etc). The way to - read the event's data depends on the event type. -

      -
    -
    -
  5. Using XCB-based programs -
    -
      -
    1. Installation of XCB -

      - TODO: These instructions are out of date. - Just reference the main XCB page - so we don't have to maintain these instructions in more than - one place. -

      -

      - To build XCB from source, you need to have installed at - least: -

      - -

      - You have to checkout in the git repository the following modules: -

      -
        -
      • Xau from xlibs -
      • xcb-proto -
      • xcb -
      -

      - Note that xcb-proto exists only to install header - files, so typing 'make' or 'make all' will produce the message - "Nothing to be done for 'all'". That's normal. -

      -
    2. Compiling XCB-based programs -

      - Compiling XCB-based programs requires linking them with the XCB - library. This is easily done thanks to pkgconfig: -

      -
      -gcc -Wall prog.c -o prog `pkg-config --cflags --libs xcb`
      -
      -
    -
  6. Opening and closing the connection to an X server -

    - An X program first needs to open the connection to the X - server. There is a function that opens a connection. It requires - the display name, or NULL. In the latter case, the display name - will be the one in the environment variable DISPLAY. -

    -
    -xcb_connection_t *xcb_connect (const char *displayname,
    -                               int        *screenp);
    -
    -

    - The second parameter returns the screen number used for the - connection. The returned structure describes an XCB connection - and is opaque. Here is how the connection can be opened: -

    -
    -#include <xcb/xcb.h>
    -
    -int
    -main ()
    -{
    -  xcb_connection_t *c;
    -
    -  /* Open the connection to the X server. Use the DISPLAY environment variable as the default display name */
    -  c = xcb_connect (NULL, NULL);
    -
    -  return 0;
    -}
    -
    -

    - To close a connection, it suffices to use: -

    -
    -void xcb_disconnect (xcb_connection_t *c);
    -
    -
    -
    - Comparison Xlib/XCB -
    -
    -
      -
    • XOpenDisplay () -
    -
    -
    -
      -
    • xcb_connect () -
    -
    -
    -
      -
    • XCloseDisplay () -
    -
    -
    -
      -
    • xcb_disconnect () -
    -
    -
    -
    -
  7. Checking basic information about a connection -

    - Once we have opened a connection to an X server, we should check some - basic information about it: what screens it has, what is the - size (width and height) of the screen, how many colors it - supports (black and white ? grey scale ?, 256 colors ? more ?), - and so on. We get such information from the xcb_screen_t - structure: -

    -
    -typedef struct {
    -    xcb_window_t   root;
    -    xcb_colormap_t default_colormap;
    -    uint32_t       white_pixel;
    -    uint32_t       black_pixel;
    -    uint32_t       current_input_masks;
    -    uint16_t       width_in_pixels;
    -    uint16_t       height_in_pixels;
    -    uint16_t       width_in_millimeters;
    -    uint16_t       height_in_millimeters;
    -    uint16_t       min_installed_maps;
    -    uint16_t       max_installed_maps;
    -    xcb_visualid_t root_visual;
    -    uint8_t        backing_stores;
    -    uint8_t        save_unders;
    -    uint8_t        root_depth;
    -    uint8_t        allowed_depths_len;
    -} xcb_screen_t;
    -
    -

    - We could retrieve the first screen of the connection by using the - following function: -

    -
    -xcb_screen_iterator_t xcb_setup_roots_iterator (xcb_setup_t *R);
    -
    -

    - Here is a small program that shows how to use this function: -

    -
    -#include <stdio.h>
    -
    -#include <xcb/xcb.h>
    -
    -int
    -main ()
    -{
    -  xcb_connection_t     *c;
    -  xcb_screen_t         *screen;
    -  int                   screen_nbr;
    -  xcb_screen_iterator_t iter;
    -
    -  /* Open the connection to the X server. Use the DISPLAY environment variable */
    -  c = xcb_connect (NULL, &screen_nbr);
    -
    -  /* Get the screen #screen_nbr */
    -  iter = xcb_setup_roots_iterator (xcb_get_setup (c));
    -  for (; iter.rem; --screen_nbr, xcb_screen_next (&iter))
    -    if (screen_nbr == 0) {
    -      screen = iter.data;
    -      break;
    -    }
    -
    -  printf ("\n");
    -  printf ("Informations of screen %ld:\n", screen->root);
    -  printf ("  width.........: %d\n", screen->width_in_pixels);
    -  printf ("  height........: %d\n", screen->height_in_pixels);
    -  printf ("  white pixel...: %ld\n", screen->white_pixel);
    -  printf ("  black pixel...: %ld\n", screen->black_pixel);
    -  printf ("\n");
    -
    -  return 0;
    -}
    -
    -
  8. Creating a basic window - the "hello world" program -

    - After we got some basic information about our screen, we can - create our first window. In the X Window System, a window is - characterized by an Id. So, in XCB, a window is of type: -

    -
    -typedef uint32_t xcb_window_t;
    -
    -

    - We first ask for a new Id for our window, with this function: -

    -
    -xcb_window_t xcb_generate_id(xcb_connection_t *c);
    -
    -

    - Then, XCB supplies the following function to create new windows: -

    -
    -xcb_void_cookie_t xcb_create_window (xcb_connection_t *c,             /* Pointer to the xcb_connection_t structure */
    -                                     uint8_t           depth,         /* Depth of the screen */
    -                                     xcb_window_t      wid,           /* Id of the window */
    -                                     xcb_window_t      parent,        /* Id of an existing window that should be the parent of the new window */
    -                                     int16_t           x,             /* X position of the top-left corner of the window (in pixels) */
    -                                     int16_t           y,             /* Y position of the top-left corner of the window (in pixels) */
    -                                     uint16_t          width,         /* Width of the window (in pixels) */
    -                                     uint16_t          height,        /* Height of the window (in pixels) */
    -                                     uint16_t          border_width,  /* Width of the window's border (in pixels) */
    -                                     uint16_t          _class,
    -                                     xcb_visualid_t    visual,
    -                                     uint32_t          value_mask,
    -                                     const uint32_t   *value_list);
    -
    -

    - The fact that we created the window does not mean that it will - be drawn on screen. By default, newly created windows are not - mapped on the screen (they are invisible). In order to make our - window visible, we use the function xcb_map_window(), whose - prototype is -

    -
    -xcb_void_cookie_t xcb_map_window (xcb_connection_t *c,
    -                                  xcb_window_t      window);
    -
    -

    - Finally, here is a small program to create a window of size - 150x150 pixels, positioned at the top-left corner of the screen: -

    -
    -#include <unistd.h>      /* pause() */
    -
    -#include <xcb/xcb.h>
    -
    -int
    -main ()
    -{
    -  xcb_connection_t *c;
    -  xcb_screen_t     *screen;
    -  xcb_window_t      win;
    -
    -  /* Open the connection to the X server */
    -  c = xcb_connect (NULL, NULL);
    -
    -  /* Get the first screen */
    -  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
    -
    -  /* Ask for our window's Id */
    -  win = xcb_generate_id(c);
    -
    -  /* Create the window */
    -  xcb_create_window (c,                             /* Connection          */
    -                     XCB_COPY_FROM_PARENT,          /* depth (same as root)*/
    -                     win,                           /* window Id           */
    -                     screen->root,                  /* parent window       */
    -                     0, 0,                          /* x, y                */
    -                     150, 150,                      /* width, height       */
    -                     10,                            /* border_width        */
    -                     XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
    -                     screen->root_visual,           /* visual              */
    -                     0, NULL);                      /* masks, not used yet */
    -
    -  /* Map the window on the screen */
    -  xcb_map_window (c, win);
    -
    -  /* Make sure commands are sent before we pause, so window is shown */
    -  xcb_flush (c);
    -
    -  pause ();    /* hold client until Ctrl-C */
    -
    -  return 0;
    -}
    -
    -

    - In this code, you see one more function - xcb_flush(), not explained - yet. It is used to flush all the pending requests. More - precisely, there are 2 functions that do such things. The first - one is xcb_flush(): -

    -
    -int xcb_flush (xcb_connection_t *c);
    -
    -

    - This function flushes all pending requests to the X server (much - like the fflush() function is used to - flush standard output). The second function is - xcb_aux_sync(): -

    -
    -int xcb_aux_sync (xcb_connection_t *c);
    -
    -

    - This functions also flushes all pending requests to the X - server, and then waits until the X server finishing processing - these requests. In a normal program, this will not be necessary - (we'll see why when we get to write a normal X program), but for - now, we put it there. -

    -

    - The window that is created by the above code has a non defined - background. This one can be set to a specific color, - thanks to the two last parameters of - xcb_create_window(), which are not - described yet. See the subsections - Configuring a window or - Registering for event types using event masks - for examples on how to use these parameters. In addition, as no - events are handled, you have to make a Ctrl-C to interrupt the - program. -

    -

    - TODO: one should tell what these functions return and - about the generic error -

    -
    -
    - Comparison Xlib/XCB -
    -
    -
      -
    • XCreateWindow () -
    -
    -
    -
      -
    • xcb_generate_id () -
    • xcb_create_window () -
    -
    -
    -
    -
  9. Drawing in a window -

    - Drawing in a window can be done using various graphical - functions (drawing pixels, lines, rectangles, etc). In order to - draw in a window, we first need to define various general - drawing parameters (what line width to use, which color to draw - with, etc). This is done using a graphical context. -

    -
      -
    1. Allocating a Graphics Context -

      - As we said, a graphical context defines several attributes to - be used with the various drawing functions. For this, we - define a graphical context. We can use more than one graphical - context with a single window, in order to draw in multiple - styles (different colors, different line widths, etc). In XCB, - a Graphics Context is, as a window, characterized by an Id: -

      -
      -typedef uint32_t xcb_gcontext_t;
      -
      -

      - We first ask the X server to attribute an Id to our graphic - context with this function: -

      -
      -xcb_gcontext_t xcb_generate_id (xcb_connection_t *c);
      -
      -

      - Then, we set the attributes of the graphic context with this function: -

      -
      -xcb_void_cookie_t xcb_create_gc (xcb_connection_t *c,
      -                                 xcb_gcontext_t    cid,
      -                                 xcb_drawable_t    drawable,
      -                                 uint32_t          value_mask,
      -                                 const uint32_t   *value_list);
      -
      -

      - We give now an example on how to allocate a graphic context - that specifies that each drawing function that uses it will - draw in foreground with a black color. -

      -
      -#include <xcb/xcb.h>
      -
      -int
      -main ()
      -{
      -  xcb_connection_t *c;
      -  xcb_screen_t     *screen;
      -  xcb_drawable_t    win;
      -  xcb_gcontext_t    black;
      -  uint32_t          mask;
      -  uint32_t          value[1];
      -
      -  /* Open the connection to the X server and get the first screen */
      -  c = xcb_connect (NULL, NULL);
      -  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      -
      -  /* Create a black graphic context for drawing in the foreground */
      -  win = screen->root;
      -  black = xcb_generate_id (c);
      -  mask = XCB_GC_FOREGROUND;
      -  value[0] = screen->black_pixel;
      -  xcb_create_gc (c, black, win, mask, value);
      -
      -  return 0;
      -}
      -
      -

      - Note should be taken regarding the role of "value_mask" and - "value_list" in the prototype of xcb_create_gc(). Since a - graphic context has many attributes, and since we often just - want to define a few of them, we need to be able to tell the - xcb_create_gc() which attributes we - want to set. This is what the "value_mask" parameter is - for. We then use the "value_list" parameter to specify actual - values for the attribute we defined in "value_mask". Thus, for - each constant used in "value_list", we will use the matching - constant in "value_mask". In this case, we define a graphic - context with one attribute: when drawing (a point, a line, - etc), the foreground color will be black. The rest of the - attributes of this graphic context will be set to their - default values. -

      -

      - See the next Subsection for more details. -

      -
      -
      - Comparison Xlib/XCB -
      -
      -
        -
      • XCreateGC () -
      -
      -
      -
        -
      • xcb_generate_id () -
      • xcb_create_gc () -
      -
      -
      -
      -
    2. Changing the attributes of a Graphics Context -

      - Once we have allocated a Graphic Context, we may need to - change its attributes (for example, changing the foreground - color we use to draw a line, or changing the attributes of the - font we use to display strings. See Subsections Drawing with a - color and - Assigning a Font to a Graphic Context). - This is done by using this function: -

      -
      -xcb_void_cookie_t xcb_change_gc (xcb_connection_t *c,           /* The XCB Connection */
      -                                 xcb_gcontext_t    gc,          /* The Graphic Context */
      -                                 uint32_t          value_mask,  /* Components of the Graphic Context that have to be set */
      -                                 const uint32_t   *value_list); /* Value as specified by value_mask */
      -
      -

      - The value_mask parameter could take - any combination of these masks from the xcb_gc_t enumeration: -

      -
        -
      • XCB_GC_FUNCTION -
      • XCB_GC_PLANE_MASK -
      • XCB_GC_FOREGROUND -
      • XCB_GC_BACKGROUND -
      • XCB_GC_LINE_WIDTH -
      • XCB_GC_LINE_STYLE -
      • XCB_GC_CAP_STYLE -
      • XCB_GC_JOIN_STYLE -
      • XCB_GC_FILL_STYLE -
      • XCB_GC_FILL_RULE -
      • XCB_GC_TILE -
      • XCB_GC_STIPPLE -
      • XCB_GC_TILE_STIPPLE_ORIGIN_X -
      • XCB_GC_TILE_STIPPLE_ORIGIN_Y -
      • XCB_GC_FONT -
      • XCB_GC_SUBWINDOW_MODE -
      • XCB_GC_GRAPHICS_EXPOSURES -
      • XCB_GC_CLIP_ORIGIN_X -
      • XCB_GC_CLIP_ORIGIN_Y -
      • XCB_GC_CLIP_MASK -
      • XCB_GC_DASH_OFFSET -
      • XCB_GC_DASH_LIST -
      • XCB_GC_ARC_MODE -
      -

      - It is possible to set several attributes at the same - time (for example setting the attributes of a font and the - color which will be used to display a string), by OR'ing these - values in value_mask. Then - value_list has to be an array which - lists the value for the respective attributes. These values - must be in the same order as masks listed above. See Subsection - Drawing with a color to have an example. -

      -

      - TODO: set the links of the 3 subsections, once they will - be written :) -

      -

      - TODO: give an example which sets several attributes. -

      -
    3. Drawing primitives: point, line, box, circle,... -

      - After we have created a Graphic Context, we can draw on a - window using this Graphic Context, with a set of XCB - functions, collectively called "drawing primitives". Let see - how they are used. -

      -

      - To draw a point, or several points, we use -

      -
      -xcb_void_cookie_t xcb_poly_point (xcb_connection_t  *c,               /* The connection to the X server */
      -                                  uint8_t            coordinate_mode, /* Coordinate mode, usually set to XCB_COORD_MODE_ORIGIN */
      -                                  xcb_drawable_t     drawable,        /* The drawable on which we want to draw the point(s) */
      -                                  xcb_gcontext_t     gc,              /* The Graphic Context we use to draw the point(s) */
      -                                  uint32_t           points_len,      /* The number of points */
      -                                  const xcb_point_t *points);         /* An array of points */
      -
      -

      - The coordinate_mode parameter - specifies the coordinate mode. Available values are -

      -
        -
      • XCB_COORD_MODE_ORIGIN -
      • XCB_COORD_MODE_PREVIOUS -
      -

      - If XCB_COORD_MODE_PREVIOUS is used, then all points but the first one - are relative to the immediately previous point. -

      -

      - The xcb_point_t type is just a - structure with two fields (the coordinates of the point): -

      -
      -typedef struct {
      -    int16_t x;
      -    int16_t y;
      -} xcb_point_t;
      -
      -

      - You could see an example in xpoints.c. TODO Set the link. -

      -

      - To draw a line, or a polygonal line, we use -

      -
      -xcb_void_cookie_t xcb_poly_line (xcb_connection_t  *c,               /* The connection to the X server */
      -                                 uint8_t            coordinate_mode, /* Coordinate mode, usually set to XCB_COORD_MODE_ORIGIN */
      -                                 xcb_drawable_t     drawable,        /* The drawable on which we want to draw the line(s) */
      -                                 xcb_gcontext_t     gc,              /* The Graphic Context we use to draw the line(s) */
      -                                 uint32_t           points_len,      /* The number of points in the polygonal line */
      -                                 const xcb_point_t *points);         /* An array of points */
      -
      -

      - This function will draw the line between the first and the - second points, then the line between the second and the third - points, and so on. -

      -

      - To draw a segment, or several segments, we use -

      -
      -xcb_void_cookie_t xcb_poly_segment (xcb_connection_t    *c,              /* The connection to the X server */
      -                                    xcb_drawable_t       drawable,       /* The drawable on which we want to draw the segment(s) */
      -                                    xcb_gcontext_t       gc,             /* The Graphic Context we use to draw the segment(s) */
      -                                    uint32_t             segments_len,   /* The number of segments */
      -                                    const xcb_segment_t *segments);      /* An array of segments */
      -
      -

      - The xcb_segment_t type is just a - structure with four fields (the coordinates of the two points - that define the segment): -

      -
      -typedef struct {
      -    int16_t x1;
      -    int16_t y1;
      -    int16_t x2;
      -    int16_t y2;
      -} xcb_segment_t;
      -
      -

      - To draw a rectangle, or several rectangles, we use -

      -
      -xcb_void_cookie_t xcb_poly_rectangle (xcb_connection_t      *c,              /* The connection to the X server */
      -                                      xcb_drawable_t         drawable,       /* The drawable on which we want to draw the rectangle(s) */
      -                                      xcb_gcontext_t         gc,             /* The Graphic Context we use to draw the rectangle(s) */
      -                                      uint32_t               rectangles_len, /* The number of rectangles */
      -                                      const xcb_rectangle_t *rectangles);    /* An array of rectangles */
      -
      -

      - The xcb_rectangle_t type is just a - structure with four fields (the coordinates of the top-left - corner of the rectangle, and its width and height): -

      -
      -typedef struct {
      -    int16_t  x;
      -    int16_t  y;
      -    uint16_t width;
      -    uint16_t height;
      -} xcb_rectangle_t;
      -
      - - -

      - To draw an elliptical arc, or several elliptical arcs, we use -

      -
      -xcb_void_cookie_t xcb_poly_arc (xcb_connection_t *c,          /* The connection to the X server */
      -                                xcb_drawable_t    drawable,   /* The drawable on which we want to draw the arc(s) */
      -                                xcb_gcontext_t    gc,         /* The Graphic Context we use to draw the arc(s) */
      -                                uint32_t          arcs_len,   /* The number of arcs */
      -                                const xcb_arc_t  *arcs);      /* An array of arcs */
      -
      -

      - The xcb_arc_t type is a structure with - six fields: -

      -
      -typedef struct {
      -    int16_t  x;       /* Top left x coordinate of the rectangle surrounding the ellipse */
      -    int16_t  y;       /* Top left y coordinate of the rectangle surrounding the ellipse */
      -    uint16_t width;   /* Width of the rectangle surrounding the ellipse */
      -    uint16_t height;  /* Height of the rectangle surrounding the ellipse */
      -    int16_t  angle1;  /* Angle at which the arc begins */
      -    int16_t  angle2;  /* Angle at which the arc ends */
      -} xcb_arc_t;
      -
      -
      -

      - Note: the angles are expressed in units of 1/64 of a degree, - so to have an angle of 90 degrees, starting at 0, - angle1 = 0 and - angle2 = 90 << 6. Positive angles - indicate counterclockwise motion, while negative angles - indicate clockwise motion. -

      -
      - - -

      - The corresponding function which fill inside the geometrical - object are listed below, without further explanation, as they - are used as the above functions. -

      -

      - To Fill a polygon defined by the points given as arguments , - we use -

      -
      -xcb_void_cookie_t xcb_fill_poly (xcb_connection_t  *c,
      -                                 xcb_drawable_t     drawable,
      -                                 xcb_gcontext_t     gc,
      -                                 uint8_t            shape,
      -                                 uint8_t            coordinate_mode,
      -                                 uint32_t           points_len,
      -                                 const xcb_point_t *points);
      -
      -

      - The shape parameter specifies a - shape that helps the server to improve performance. Available - values are -

      -
        -
      • XCB_POLY_SHAPE_COMPLEX -
      • XCB_POLY_SHAPE_NONCONVEX -
      • XCB_POLY_SHAPE_CONVEX -
      -

      - To fill one or several rectangles, we use -

      -
      -xcb_void_cookie_t xcb_poly_fill_rectangle (xcb_connection_t      *c,
      -                                           xcb_drawable_t         drawable,
      -                                           xcb_gcontext_t         gc,
      -                                           uint32_t               rectangles_len,
      -                                           const xcb_rectangle_t *rectangles);
      -
      -

      - To fill one or several arcs, we use -

      -
      -xcb_void_cookie_t xcb_poly_fill_arc (xcb_connection_t *c,
      -                                     xcb_drawable_t    drawable,
      -                                     xcb_gcontext_t    gc,
      -                                     uint32_t          arcs_len,
      -                                     const xcb_arc_t  *arcs);
      -
      -
      - -

      - To illustrate these functions, here is an example that draws - four points, a polygonal line, two segments, two rectangles - and two arcs. Remark that we use events for the first time, as - an introduction to the next section. -

      -

      - TODO: Use screen->root_depth for depth parameter. -

      -
      -#include <stdlib.h>
      -#include <stdio.h>
      -
      -#include <xcb/xcb.h>
      -
      -int
      -main ()
      -{
      -  xcb_connection_t    *c;
      -  xcb_screen_t        *screen;
      -  xcb_drawable_t       win;
      -  xcb_gcontext_t       foreground;
      -  xcb_generic_event_t *e;
      -  uint32_t             mask = 0;
      -  uint32_t             values[2];
      -
      -  /* geometric objects */
      -  xcb_point_t          points[] = {
      -    {10, 10},
      -    {10, 20},
      -    {20, 10},
      -    {20, 20}};
      -
      -  xcb_point_t          polyline[] = {
      -    {50, 10},
      -    { 5, 20},     /* rest of points are relative */
      -    {25,-20},
      -    {10, 10}};
      -
      -  xcb_segment_t        segments[] = {
      -    {100, 10, 140, 30},
      -    {110, 25, 130, 60}};
      -
      -  xcb_rectangle_t      rectangles[] = {
      -    { 10, 50, 40, 20},
      -    { 80, 50, 10, 40}};
      -
      -  xcb_arc_t            arcs[] = {
      -    {10, 100, 60, 40, 0, 90 << 6},
      -    {90, 100, 55, 40, 0, 270 << 6}};
      -
      -  /* Open the connection to the X server */
      -  c = xcb_connect (NULL, NULL);
      -
      -  /* Get the first screen */
      -  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      -
      -  /* Create black (foreground) graphic context */
      -  win = screen->root;
      -
      -  foreground = xcb_generate_id (c);
      -  mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
      -  values[0] = screen->black_pixel;
      -  values[1] = 0;
      -  xcb_create_gc (c, foreground, win, mask, values);
      -
      -  /* Ask for our window's Id */
      -  win = xcb_generate_id(c);
      -
      -  /* Create the window */
      -  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
      -  values[0] = screen->white_pixel;
      -  values[1] = XCB_EVENT_MASK_EXPOSURE;
      -  xcb_create_window (c,                             /* Connection          */
      -                     XCB_COPY_FROM_PARENT,          /* depth               */
      -                     win,                           /* window Id           */
      -                     screen->root,                  /* parent window       */
      -                     0, 0,                          /* x, y                */
      -                     150, 150,                      /* width, height       */
      -                     10,                            /* border_width        */
      -                     XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
      -                     screen->root_visual,           /* visual              */
      -                     mask, values);                 /* masks */
      -
      -  /* Map the window on the screen */
      -  xcb_map_window (c, win);
      -
      -
      -  /* We flush the request */
      -  xcb_flush (c);
      -
      -  while ((e = xcb_wait_for_event (c))) {
      -    switch (e->response_type & ~0x80) {
      -    case XCB_EXPOSE: {
      -      /* We draw the points */
      -      xcb_poly_point (c, XCB_COORD_MODE_ORIGIN, win, foreground, 4, points);
      -
      -      /* We draw the polygonal line */
      -      xcb_poly_line (c, XCB_COORD_MODE_PREVIOUS, win, foreground, 4, polyline);
      -
      -      /* We draw the segements */
      -      xcb_poly_segment (c, win, foreground, 2, segments);
      -
      -      /* We draw the rectangles */
      -      xcb_poly_rectangle (c, win, foreground, 2, rectangles);
      -
      -      /* We draw the arcs */
      -      xcb_poly_arc (c, win, foreground, 2, arcs);
      -
      -      /* We flush the request */
      -      xcb_flush (c);
      -
      -      break;
      -    }
      -    default: {
      -      /* Unknown event type, ignore it */
      -      break;
      -    }
      -    }
      -    /* Free the Generic Event */
      -    free (e);
      -  }
      -
      -  return 0;
      -}
      -
      -
    -
  10. X Events -

    - In an X program, everything is driven by events. Event painting - on the screen is sometimes done as a response to an event (an - Expose event). If part of a program's - window that was hidden, gets exposed (e.g. the window was raised - above other widows), the X server will send an "expose" event to - let the program know it should repaint that part of the - window. User input (key presses, mouse movement, etc) is also - received as a set of events. -

    -
      -
    1. Registering for event types using event masks -

      - During the creation of a window, you should give it what kind - of events it wishes to receive. Thus, you may register for - various mouse (also called pointer) events, keyboard events, - expose events, and so on. This is done for optimizing the - server-to-client connection (i.e. why send a program (that - might even be running at the other side of the globe) an event - it is not interested in ?) -

      -

      - In XCB, you use the "value_mask" and "value_list" data in the - xcb_create_window() function to - register for events. Here is how we register for - Expose event when creating a window: -

      -
      -  mask = XCB_CW_EVENT_MASK;
      -  valwin[0] = XCB_EVENT_MASK_EXPOSURE;
      -  win = xcb_generate_id (c);
      -  xcb_create_window (c, depth, win, root->root,
      -                     0, 0, 150, 150, 10,
      -                     XCB_WINDOW_CLASS_INPUT_OUTPUT, root->root_visual,
      -                     mask, valwin);
      -
      -

      - XCB_EVENT_MASK_EXPOSURE is a constant defined - in the xcb_event_mask_t enumeration in the "xproto.h" header file. If we wanted to register for several - event types, we can logically "or" them, as follows: -

      -
      -  mask = XCB_CW_EVENT_MASK;
      -  valwin[0] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS;
      -  win = xcb_generate_id (c);
      -  xcb_create_window (c, depth, win, root->root,
      -                     0, 0, 150, 150, 10,
      -                     XCB_WINDOW_CLASS_INPUT_OUTPUT, root->root_visual,
      -                     mask, valwin);
      -
      -

      - This registers for Expose events as - well as for mouse button presses inside the created - window. You should note that a mask may represent several - event sub-types. -

      -

      - The values that a mask could take are given - by the xcb_cw_t enumeration: -

      -
      -typedef enum {
      -    XCB_CW_BACK_PIXMAP       = 1L<<0,
      -    XCB_CW_BACK_PIXEL        = 1L<<1,
      -    XCB_CW_BORDER_PIXMAP     = 1L<<2,
      -    XCB_CW_BORDER_PIXEL      = 1L<<3,
      -    XCB_CW_BIT_GRAVITY       = 1L<<4,
      -    XCB_CW_WIN_GRAVITY       = 1L<<5,
      -    XCB_CW_BACKING_STORE     = 1L<<6,
      -    XCB_CW_BACKING_PLANES    = 1L<<7,
      -    XCB_CW_BACKING_PIXEL     = 1L<<8,
      -    XCB_CW_OVERRIDE_REDIRECT = 1L<<9,
      -    XCB_CW_SAVE_UNDER        = 1L<<10,
      -    XCB_CW_EVENT_MASK        = 1L<<11,
      -    XCB_CW_DONT_PROPAGATE    = 1L<<12,
      -    XCB_CW_COLORMAP          = 1L<<13,
      -    XCB_CW_CURSOR            = 1L<<14
      -} xcb_cw_t;
      -
      -
      -

      Note: we must be careful when setting the values of the valwin - parameter, as they have to follow the order the - xcb_cw_t enumeration. Here is an - example: -

      -
      -
      -  mask = XCB_CW_EVENT_MASK | XCB_CW_BACK_PIXMAP;
      -  valwin[0] = XCB_NONE;                                              /* for XCB_CW_BACK_PIXMAP (whose value is 1)     */
      -  valwin[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS; /* for XCB_CW_EVENT_MASK, whose value (2048)     */
      -                                                                     /* is greater than the one of XCB_CW_BACK_PIXMAP */
      -
      -

      - If the window has already been created, we can use the - xcb_change_window_attributes() function to set - the events that the window will receive. The subsection - Configuring a window shows its - prototype. As an example, here is a piece of code that - configures the window to receive the - Expose and - ButtonPress events: -

      -
      -const static uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS };
      -
      -/* The connection c and the window win are supposed to be defined */
      -
      -xcb_change_window_attributes (c, win, XCB_CW_EVENT_MASK, values);
      -
      -
      -

      - Note: A common bug programmers do is adding code to handle new - event types in their program, while forgetting to add the - masks for these events in the creation of the window. Such a - programmer then should sit down for hours debugging his - program, wondering "Why doesn't my program notice that I - released the button?", only to find that they registered for - button press events but not for button release events. -

      -
      -
    2. Receiving events: writing the events loop -

      - After we have registered for the event types we are interested - in, we need to enter a loop of receiving events and handling - them. There are two ways to receive events: a blocking way and - a non-blocking way: -

      -
        -
      • - xcb_wait_for_event (xcb_connection_t *c) - is the blocking way. It waits (so blocks...) until an event is - queued in the X server. Then it retrieves it into a newly - allocated structure (it dequeues it from the queue) and returns - it. This structure has to be freed. The function returns - NULL if an error occurs. - -
        -
      • - xcb_poll_for_event (xcb_connection_t *c, int - *error) is the non-blocking way. It looks at the event - queue and returns (and dequeues too) an existing event into - a newly allocated structure. This structure has to be - freed. It returns NULL if there is - no event. If an error occurs, the parameter error will be filled with the error - status. -
      -

      - There are various ways to write such a loop. We present two - ways to write such a loop, with the two functions above. The - first one uses xcb_wait_for_event_t, which - is similar to an event Xlib loop using only XNextEvent: -

      -
      -  xcb_generic_event_t *e;
      -
      -  while ((e = xcb_wait_for_event (c))) {
      -    switch (e->response_type & ~0x80) {
      -    case XCB_EXPOSE: {
      -      /* Handle the Expose event type */
      -      xcb_expose_event_t *ev = (xcb_expose_event_t *)e;
      -
      -      /* ... */
      -
      -      break;
      -    }
      -    case XCB_BUTTON_PRESS: {
      -      /* Handle the ButtonPress event type */
      -      xcb_button_press_event_t *ev = (xcb_button_press_event_t *)e;
      -
      -      /* ... */
      -
      -      break;
      -    }
      -    default: {
      -      /* Unknown event type, ignore it */
      -      break;
      -    }
      -    }
      -    /* Free the Generic Event */
      -    free (e);
      -  }
      -
      -

      - You will certainly want to use xcb_poll_for_event(xcb_connection_t *c, int - *error) if, in Xlib, you use XPending or - XCheckMaskEvent: -

      -
      -  while (XPending (display)) {
      -    XEvent ev;
      -
      -    XNextEvent(d, &ev);
      -
      -    /* Manage your event */
      -  }
      -
      -

      - Such a loop in XCB looks like: -

      -
      -  xcb_generic_event_t *ev;
      -
      -  while ((ev = xcb_poll_for_event (conn, 0))) {
      -    /* Manage your event */
      -  }
      -
      -

      - The events are managed in the same way as with xcb_wait_for_event_t. - Obviously, we will need to give the user some way of - terminating the program. This is usually done by handling a - special "quit" event, as we will soon see. -

      -
      -
      - Comparison Xlib/XCB -
      -
      -
        -
      • XNextEvent () -
      -
      -
      -
        -
      • xcb_wait_for_event () -
      -
      -
      -
        -
      • XPending () -
      • XCheckMaskEvent () -
      -
      -
      -
        -
      • xcb_poll_for_event () -
      -
      -
      -
      -
    3. Expose events -

      - The Expose event is one of the most - basic (and most used) events an application may receive. It - will be sent to us in one of several cases: -

      -
        -
      • A window that covered part of our window has moved - away, exposing part (or all) of our window. -
      • Our window was raised above other windows. -
      • Our window mapped for the first time. -
      • Our window was de-iconified. -
      -

      - You should note the implicit assumption hidden here: the - contents of our window is lost when it is being obscured - (covered) by either windows. One may wonder why the X server - does not save this contents. The answer is: to save - memory. After all, the number of windows on a display at a - given time may be very large, and storing the contents of all - of them might require a lot of memory. Actually, there is a - way to tell the X server to store the contents of a window in - special cases, as we will see later. -

      -

      - When we get an Expose event, we - should take the event's data from the members of the following - structure: -

      -
      -typedef struct {
      -    uint8_t      response_type; /* The type of the event, here it is XCB_EXPOSE */
      -    uint8_t      pad0;
      -    uint16_t     sequence;
      -    xcb_window_t window;        /* The Id of the window that receives the event (in case */
      -                                /* our application registered for events on several windows */
      -    uint16_t     x;             /* The x coordinate of the top-left part of the window that needs to be redrawn */
      -    uint16_t     y;             /* The y coordinate of the top-left part of the window that needs to be redrawn */
      -    uint16_t     width;         /* The width of the part of the window that needs to be redrawn */
      -    uint16_t     height;        /* The height of the part of the window that needs to be redrawn */
      -    uint16_t     count;
      -} xcb_expose_event_t;
      -
      -
    4. Getting user input -

      - User input traditionally comes from two sources: the mouse - and the keyboard. Various event types exist to notify us of - user input (a key being presses on the keyboard, a key being - released on the keyboard, the mouse moving over our window, - the mouse entering (or leaving) our window, and so on. -

      -
        -
      1. Mouse button press and release events -

        - The first event type we will deal with is a mouse - button-press (or button-release) event in our window. In - order to register to such an event type, we should add one - (or more) of the following masks when we create our window: -

        -
          -
        • XCB_EVENT_MASK_BUTTON_PRESS: notify us - of any button that was pressed in one of our windows. -
        • XCB_EVENT_MASK_BUTTON_RELEASE: notify us - of any button that was released in one of our windows. -
        -

        - The structure to be checked for in our events loop is the - same for these two events, and is the following: -

        -
        -typedef struct {
        -    uint8_t         response_type; /* The type of the event, here it is xcb_button_press_event_t or xcb_button_release_event_t */
        -    xcb_button_t    detail;
        -    uint16_t        sequence;
        -    xcb_timestamp_t time;          /* Time, in milliseconds the event took place in */
        -    xcb_window_t    root;
        -    xcb_window_t    event;
        -    xcb_window_t    child;
        -    int16_t         root_x;
        -    int16_t         root_y;
        -    int16_t         event_x;       /* The x coordinate where the mouse has been pressed in the window */
        -    int16_t         event_y;       /* The y coordinate where the mouse has been pressed in the window */
        -    uint16_t        state;         /* A mask of the buttons (or keys) during the event */
        -    uint8_t         same_screen;
        -} xcb_button_press_event_t;
        -
        -typedef xcb_button_press_event_t xcb_button_release_event_t;
        -
        -

        - The time field may be used to calculate "double-click" - situations by an application (e.g. if the mouse button was - clicked two times in a duration shorter than a given amount - of time, assume this was a double click). -

        -

        - The state field is a mask of the buttons held down during - the event. It is a bitwise OR of any of the following (from the xcb_button_mask_t and - xcb_mod_mask_t enumerations): -

        -
          -
        • XCB_BUTTON_MASK_1 -
        • XCB_BUTTON_MASK_2 -
        • XCB_BUTTON_MASK_3 -
        • XCB_BUTTON_MASK_4 -
        • XCB_BUTTON_MASK_5 -
        • XCB_MOD_MASK_SHIFT -
        • XCB_MOD_MASK_LOCK -
        • XCB_MOD_MASK_CONTROL -
        • XCB_MOD_MASK_1 -
        • XCB_MOD_MASK_2 -
        • XCB_MOD_MASK_3 -
        • XCB_MOD_MASK_4 -
        • XCB_MOD_MASK_5 -
        -

        - Their names are self explanatory, where the first 5 refer to - the mouse buttons that are being pressed, while the rest - refer to various "special keys" that are being pressed (Mod1 - is usually the 'Alt' key or the 'Meta' key). -

        -

        - TODO: Problem: it seems that the state does not - change when clicking with various buttons. -

        -
      2. Mouse movement events -

        - Similar to mouse button press and release events, we also - can be notified of various mouse movement events. These can - be split into two families. One is of mouse pointer - movement while no buttons are pressed, and the second is a - mouse pointer motion while one (or more) of the buttons are - pressed (this is sometimes called "a mouse drag operation", - or just "dragging"). The following event masks may be added - during the creation of our window: -

        -
          -
        • XCB_EVENT_MASK_POINTER_MOTION: events of - the pointer moving in one of the windows controlled by our - application, while no mouse button is held pressed. -
        • XCB_EVENT_MASK_BUTTON_MOTION: Events of - the pointer moving while one or more of the mouse buttons - is held pressed. -
        • XCB_EVENT_MASK_BUTTON_1_MOTION: same as - XCB_EVENT_MASK_BUTTON_MOTION, but only when - the 1st mouse button is held pressed. -
        • XCB_EVENT_MASK_BUTTON_2_MOTION, - XCB_EVENT_MASK_BUTTON_3_MOTION, - XCB_EVENT_MASK_BUTTON_4_MOTION, - XCB_EVENT_MASK_BUTTON_5_MOTION: same as - XCB_EVENT_MASK_BUTTON_1_MOTION, but - respectively for 2nd, 3rd, 4th and 5th mouse button. -
        -

        - The structure to be checked for in our events loop is the - same for these events, and is the following: -

        -
        -typedef struct {
        -    uint8_t         response_type; /* The type of the event */
        -    uint8_t         detail;
        -    uint16_t        sequence;
        -    xcb_timestamp_t time;          /* Time, in milliseconds the event took place in */
        -    xcb_window_t    root;
        -    xcb_window_t    event;
        -    xcb_window_t    child;
        -    int16_t         root_x;
        -    int16_t         root_y;
        -    int16_t         event_x;       /* The x coordinate of the mouse when the  event was generated */
        -    int16_t         event_y;       /* The y coordinate of the mouse when the  event was generated */
        -    uint16_t        state;         /* A mask of the buttons (or keys) during the event */
        -    uint8_t         same_screen;
        -} xcb_motion_notify_event_t;
        -
        -
      3. Mouse pointer enter and leave events -

        - Another type of event that applications might be interested - in, is a mouse pointer entering a window the program - controls, or leaving such a window. Some programs use these - events to show the user that the application is now in - focus. In order to register for such an event type, we - should add one (or more) of the following masks when we - create our window: -

        -
          -
        • xcb_event_enter_window_t: notify us - when the mouse pointer enters any of our controlled - windows. -
        • xcb_event_leave_window_t: notify us - when the mouse pointer leaves any of our controlled - windows. -
        -

        - The structure to be checked for in our events loop is the - same for these two events, and is the following: -

        -
        -typedef struct {
        -    uint8_t         response_type; /* The type of the event */
        -    uint8_t         detail;
        -    uint16_t        sequence;
        -    xcb_timestamp_t time;          /* Time, in milliseconds the event took place in */
        -    xcb_window_t    root;
        -    xcb_window_t    event;
        -    xcb_window_t    child;
        -    int16_t         root_x;
        -    int16_t         root_y;
        -    int16_t         event_x;       /* The x coordinate of the mouse when the  event was generated */
        -    int16_t         event_y;       /* The y coordinate of the mouse when the  event was generated */
        -    uint16_t        state;         /* A mask of the buttons (or keys) during the event */
        -    uint8_t         mode;          /* The number of mouse button that was clicked */
        -    uint8_t         same_screen_focus;
        -} xcb_enter_notify_event_t;
        -
        -typedef xcb_enter_notify_event_t xcb_leave_notify_event_t;
        -
        -
      4. The keyboard focus -

        - There may be many windows on a screen, but only a single - keyboard attached to them. How does the X server then know - which window should be sent a given keyboard input ? This is - done using the keyboard focus. Only a single window on the - screen may have the keyboard focus at a given time. There - is a XCB function that allows a program to set the keyboard - focus to a given window. The user can usually set the - keyboard focus using the window manager (often by clicking - on the title bar of the desired window). Once our window - has the keyboard focus, every key press or key release will - cause an event to be sent to our program (if it regsitered - for these event types...). -

        -
      5. Keyboard press and release events -

        - If a window controlled by our program currently holds the - keyboard focus, it can receive key press and key release - events. So, we should add one (or more) of the following - masks when we create our window: -

        -
          -
        • XCB_EVENT_MASK_KEY_PRESS: notify us when - a key was pressed while any of our controlled windows had - the keyboard focus. -
        • XCB_EVENT_MASK_KEY_RELEASE: notify us - when a key was released while any of our controlled - windows had the keyboard focus. -
        -

        - The structure to be checked for in our events loop is the - same for these two events, and is the following: -

        -
        -typedef struct {
        -    uint8_t         response_type; /* The type of the event */
        -    xcb_keycode_t   detail;
        -    uint16_t        sequence;
        -    xcb_timestamp_t time;          /* Time, in milliseconds the event took place in */
        -    xcb_window_t    root;
        -    xcb_window_t    event;
        -    xcb_window_t    child;
        -    int16_t         root_x;
        -    int16_t         root_y;
        -    int16_t         event_x;
        -    int16_t         event_y;
        -    uint16_t        state;
        -    uint8_t         same_screen;
        -} xcb_key_press_event_t;
        -
        -typedef xcb_key_press_event_t xcb_key_release_event_t;
        -
        -

        - The detail field refers to the - physical key on the keyboard. -

        -

        - TODO: Talk about getting the ASCII code from the key code. -

        -
      -
    5. X events: a complete example -

      - As an example for handling events, we show a program that - creates a window, enters an events loop and checks for all the - events described above, and writes on the terminal the relevant - characteristics of the event. With this code, it should be - easy to add drawing operations, like those which have been - described above. -

      -
      -#include <stdlib.h>
      -#include <stdio.h>
      -
      -#include <xcb/xcb.h>
      -
      -void
      -print_modifiers (uint32_t mask)
      -{
      -  const char **mod, *mods[] = {
      -    "Shift", "Lock", "Ctrl", "Alt",
      -    "Mod2", "Mod3", "Mod4", "Mod5",
      -    "Button1", "Button2", "Button3", "Button4", "Button5"
      -  };
      -  printf ("Modifier mask: ");
      -  for (mod = mods ; mask; mask >>= 1, mod++)
      -    if (mask & 1)
      -      printf(*mod);
      -  putchar ('\n');
      -}
      -
      -int
      -main ()
      -{
      -  xcb_connection_t    *c;
      -  xcb_screen_t        *screen;
      -  xcb_window_t         win;
      -  xcb_generic_event_t *e;
      -  uint32_t             mask = 0;
      -  uint32_t             values[2];
      -
      -  /* Open the connection to the X server */
      -  c = xcb_connect (NULL, NULL);
      -
      -  /* Get the first screen */
      -  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      -
      -  /* Ask for our window's Id */
      -  win = xcb_generate_id (c);
      -
      -  /* Create the window */
      -  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
      -  values[0] = screen->white_pixel;
      -  values[1] = XCB_EVENT_MASK_EXPOSURE       | XCB_EVENT_MASK_BUTTON_PRESS   |
      -              XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION |
      -              XCB_EVENT_MASK_ENTER_WINDOW   | XCB_EVENT_MASK_LEAVE_WINDOW   |
      -              XCB_EVENT_MASK_KEY_PRESS      | XCB_EVENT_MASK_KEY_RELEASE;
      -  xcb_create_window (c,                             /* Connection          */
      -                     0,                             /* depth               */
      -                     win,                           /* window Id           */
      -                     screen->root,                  /* parent window       */
      -                     0, 0,                          /* x, y                */
      -                     150, 150,                      /* width, height       */
      -                     10,                            /* border_width        */
      -                     XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
      -                     screen->root_visual,           /* visual              */
      -                     mask, values);                 /* masks */
      -
      -  /* Map the window on the screen */
      -  xcb_map_window (c, win);
      -
      -  xcb_flush (c);
      -
      -  while ((e = xcb_wait_for_event (c))) {
      -    switch (e->response_type & ~0x80) {
      -    case XCB_EXPOSE: {
      -      xcb_expose_event_t *ev = (xcb_expose_event_t *)e;
      -
      -      printf ("Window %ld exposed. Region to be redrawn at location (%d,%d), with dimension (%d,%d)\n",
      -              ev->window, ev->x, ev->y, ev->width, ev->height);
      -      break;
      -    }
      -    case XCB_BUTTON_PRESS: {
      -      xcb_button_press_event_t *ev = (xcb_button_press_event_t *)e;
      -      print_modifiers(ev->state);
      -
      -      switch (ev->detail) {
      -      case 4:
      -        printf ("Wheel Button up in window %ld, at coordinates (%d,%d)\n",
      -                ev->event, ev->event_x, ev->event_y);
      -        break;
      -      case 5:
      -        printf ("Wheel Button down in window %ld, at coordinates (%d,%d)\n",
      -                ev->event, ev->event_x, ev->event_y);
      -        break;
      -      default:
      -        printf ("Button %d pressed in window %ld, at coordinates (%d,%d)\n",
      -                ev->detail, ev->event, ev->event_x, ev->event_y);
      -      }
      -      break;
      -    }
      -    case XCB_BUTTON_RELEASE: {
      -      xcb_button_release_event_t *ev = (xcb_button_release_event_t *)e;
      -      print_modifiers(ev->state);
      -
      -      printf ("Button %d released in window %ld, at coordinates (%d,%d)\n",
      -              ev->detail, ev->event, ev->event_x, ev->event_y);
      -      break;
      -    }
      -    case XCB_MOTION_NOTIFY: {
      -      xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)e;
      -
      -      printf ("Mouse moved in window %ld, at coordinates (%d,%d)\n",
      -              ev->event, ev->event_x, ev->event_y);
      -      break;
      -    }
      -    case XCB_ENTER_NOTIFY: {
      -      xcb_enter_notify_event_t *ev = (xcb_enter_notify_event_t *)e;
      -
      -      printf ("Mouse entered window %ld, at coordinates (%d,%d)\n",
      -              ev->event, ev->event_x, ev->event_y);
      -      break;
      -    }
      -    case XCB_LEAVE_NOTIFY: {
      -      xcb_leave_notify_event_t *ev = (xcb_leave_notify_event_t *)e;
      -
      -      printf ("Mouse left window %ld, at coordinates (%d,%d)\n",
      -              ev->event, ev->event_x, ev->event_y);
      -      break;
      -    }
      -    case XCB_KEY_PRESS: {
      -      xcb_key_press_event_t *ev = (xcb_key_press_event_t *)e;
      -      print_modifiers(ev->state);
      -
      -      printf ("Key pressed in window %ld\n",
      -              ev->event);
      -      break;
      -    }
      -    case XCB_KEY_RELEASE: {
      -      xcb_key_release_event_t *ev = (xcb_key_release_event_t *)e;
      -      print_modifiers(ev->state);
      -
      -      printf ("Key released in window %ld\n",
      -              ev->event);
      -      break;
      -    }
      -    default:
      -      /* Unknown event type, ignore it */
      -      printf("Unknown event: %d\n", e->response_type);
      -      break;
      -    }
      -    /* Free the Generic Event */
      -    free (e);
      -  }
      -
      -  return 0;
      -}
      -
      -
    -
  11. Handling text and fonts -

    - Besides drawing graphics on a window, we often want to draw - text. Text strings have two major properties: the characters to - be drawn and the font with which they are drawn. In order to - draw text, we need to first request the X server to load a - font. We then assign a font to a Graphic Context, and finally, we - draw the text in a window, using the Graphic Context. -

    -
      -
    1. The Font structure -

      - In order to support flexible fonts, a font type is - defined. You know what ? It's an Id: -

      -
      -typedef uint32_t xcb_font_t;
      -
      -

      - It is used to contain information about a font, and is passed - to several functions that handle fonts selection and text drawing. - We ask the X server to attribute an Id to our font with the - function: -

      -
      -xcb_font_t xcb_generate_id (xcb_connection_t *c);
      -
      -
      -
    2. Opening a Font -

      - To open a font, we use the following function: -

      -
      -xcb_void_cookie_t xcb_open_font (xcb_connection_t *c,
      -                                 xcb_font_t        fid,
      -                                 uint16_t          name_len,
      -                                 const char       *name);
      -
      -

      - The fid parameter is the font Id - defined by xcb_generate_id() (see - above). The name parameter is the - name of the font you want to open. Use the command - xlsfonts in a terminal to know which - are the fonts available on your computer. The parameter - name_len is the length of the name - of the font (given by strlen()). -

      -
    3. Assigning a Font to a Graphic Context -

      - Once a font is opened, you have to create a Graphic Context - that will contain the informations about the color of the - foreground and the background used when you draw a text in a - Drawable. Here is an exemple of a Graphic Context that will - allow us to draw an opened font with a black foreground and a - white background: -

      -
      -  /*
      -   * c is the connection
      -   * screen is the screen where the window is displayed
      -   * window is the window in which we will draw the text
      -   * font is the opened font
      -   */
      -
      -  uint32_t             value_list[3];
      -  xcb_gcontext_t       gc;
      -  uint32_t             mask;
      -
      -  gc = xcb_generate_id (c);
      -  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
      -  value_list[0] = screen->black_pixel;
      -  value_list[1] = screen->white_pixel;
      -  value_list[2] = font;
      -  xcb_create_gc (c, gc, window, mask, value_list);
      -
      -  /* The font is not needed anymore, so we close it */
      -  xcb_close_font (c, font);
      -
      -
    4. Drawing text in a drawable -

      - To draw a text in a drawable, we use the following function: -

      -
      -xcb_void_cookie_t xcb_image_text_8 (xcb_connection_t *c,
      -                                    uint8_t           string_len,
      -                                    xcb_drawable_t    drawable,
      -                                    xcb_gcontext_t    gc,
      -                                    int16_t           x,
      -                                    int16_t           y,
      -                                    const char       *string);
      -
      -

      - The string parameter is the text to - draw. The location of the drawing is given by the parameters - x and y. - The base line of the text is exactly the parameter - y. -

      -
    5. Complete example -

      - This example draw a text at 10 pixels (for the base line) of - the bottom of a window. Pressing the Esc key exits the program. -

      -
      -#include <stdlib.h>
      -#include <stdio.h>
      -#include <string.h>
      -
      -#include <xcb/xcb.h>
      -
      -#define WIDTH 300
      -#define HEIGHT 100
      -
      -
      -
      -static xcb_gc_t gc_font_get (xcb_connection_t *c,
      -                             xcb_screen_t     *screen,
      -                             xcb_window_t      window,
      -                             const char       *font_name);
      -
      -static void text_draw (xcb_connection_t *c,
      -                       xcb_screen_t     *screen,
      -                       xcb_window_t      window,
      -                       int16_t           x1,
      -                       int16_t           y1,
      -                       const char       *label);
      -
      -static void
      -text_draw (xcb_connection_t *c,
      -           xcb_screen_t     *screen,
      -           xcb_window_t      window,
      -           int16_t           x1,
      -           int16_t           y1,
      -           const char       *label)
      -{
      -  xcb_void_cookie_t    cookie_gc;
      -  xcb_void_cookie_t    cookie_text;
      -  xcb_generic_error_t *error;
      -  xcb_gcontext_t       gc;
      -  uint8_t              length;
      -
      -  length = strlen (label);
      -
      -  gc = gc_font_get(c, screen, window, "7x13");
      -
      -  cookie_text = xcb_image_text_8_checked (c, length, window, gc,
      -                                          x1,
      -                                          y1, label);
      -  error = xcb_request_check (c, cookie_text);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't paste text : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  cookie_gc = xcb_free_gc (c, gc);
      -  error = xcb_request_check (c, cookie_gc);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't free gc : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -}
      -
      -static xcb_gc_t
      -gc_font_get (xcb_connection_t *c,
      -             xcb_screen_t     *screen,
      -             xcb_window_t      window,
      -             const char       *font_name)
      -{
      -  uint32_t             value_list[3];
      -  xcb_void_cookie_t    cookie_font;
      -  xcb_void_cookie_t    cookie_gc;
      -  xcb_generic_error_t *error;
      -  xcb_font_t           font;
      -  xcb_gcontext_t       gc;
      -  uint32_t             mask;
      -
      -  font = xcb_generate_id (c);
      -  cookie_font = xcb_open_font_checked (c, font,
      -                                       strlen (font_name),
      -                                       font_name);
      -
      -  error = xcb_request_check (c, cookie_font);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't open font : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    return -1;
      -  }
      -
      -  gc = xcb_generate_id (c);
      -  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
      -  value_list[0] = screen->black_pixel;
      -  value_list[1] = screen->white_pixel;
      -  value_list[2] = font;
      -  cookie_gc = xcb_create_gc_checked (c, gc, window, mask, value_list);
      -  error = xcb_request_check (c, cookie_gc);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't create gc : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  cookie_font = xcb_close_font_checked (c, font);
      -  error = xcb_request_check (c, cookie_font);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't close font : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  return gc;
      -}
      -
      -int main ()
      -{
      -  xcb_screen_iterator_t screen_iter;
      -  xcb_connection_t     *c;
      -  const xcb_setup_t    *setup;
      -  xcb_screen_t         *screen;
      -  xcb_generic_event_t  *e;
      -  xcb_generic_error_t  *error;
      -  xcb_void_cookie_t     cookie_window;
      -  xcb_void_cookie_t     cookie_map;
      -  xcb_window_t          window;
      -  uint32_t              mask;
      -  uint32_t              values[2];
      -  int                   screen_number;
      -
      -  /* getting the connection */
      -  c = xcb_connect (NULL, &screen_number);
      -  if (!c) {
      -    fprintf (stderr, "ERROR: can't connect to an X server\n");
      -    return -1;
      -  }
      -
      -  /* getting the current screen */
      -  setup = xcb_get_setup (c);
      -
      -  screen = NULL;
      -  screen_iter = xcb_setup_roots_iterator (setup);
      -  for (; screen_iter.rem != 0; --screen_number, xcb_screen_next (&screen_iter))
      -    if (screen_number == 0)
      -      {
      -        screen = screen_iter.data;
      -        break;
      -      }
      -  if (!screen) {
      -    fprintf (stderr, "ERROR: can't get the current screen\n");
      -    xcb_disconnect (c);
      -    return -1;
      -  }
      -
      -  /* creating the window */
      -  window = xcb_generate_id (c);
      -  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
      -  values[0] = screen->white_pixel;
      -  values[1] =
      -    XCB_EVENT_MASK_KEY_RELEASE |
      -    XCB_EVENT_MASK_BUTTON_PRESS |
      -    XCB_EVENT_MASK_EXPOSURE |
      -    XCB_EVENT_MASK_POINTER_MOTION;
      -  cookie_window = xcb_create_window_checked (c,
      -                                             screen->root_depth,
      -                                             window, screen->root,
      -                                             20, 200, WIDTH, HEIGHT,
      -                                             0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
      -                                             screen->root_visual,
      -                                             mask, values);
      -  cookie_map = xcb_map_window_checked (c, window);
      -
      -  /* error managing */
      -  error = xcb_request_check (c, cookie_window);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't create window : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    return -1;
      -  }
      -  error = xcb_request_check (c, cookie_map);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't map window : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    return -1;
      -  }
      -
      -  xcb_flush(c);
      -
      -  while (1) {
      -    e = xcb_poll_for_event(c);
      -    if (e) {
      -      switch (e->response_type & ~0x80) {
      -      case XCB_EXPOSE: {
      -        char *text;
      -
      -        text = "Press ESC key to exit...";
      -        text_draw (c, screen, window, 10, HEIGHT - 10, text);
      -        break;
      -      }
      -      case XCB_KEY_RELEASE: {
      -        xcb_key_release_event_t *ev;
      -
      -        ev = (xcb_key_release_event_t *)e;
      -
      -        switch (ev->detail) {
      -          /* ESC */
      -        case 9:
      -          free (e);
      -          xcb_disconnect (c);
      -          return 0;
      -        }
      -      }
      -      }
      -      free (e);
      -    }
      -  }
      -
      -  return 0;
      -}
      -
      -
    -
  12. Interacting with the window manager -

    - After we have seen how to create windows and draw on them, we - take one step back, and look at how our windows are interacting - with their environment (the full screen and the other - windows). First of all, our application needs to interact with - the window manager. The window manager is responsible to - decorating drawn windows (i.e. adding a frame, an iconify - button, a system menu, a title bar, etc), as well as handling - icons shown when windows are being iconified. It also handles - ordering of windows on the screen, and other administrative - tasks. We need to give it various hints as to how we want it to - treat our application's windows. -

    -
      -
    1. Window properties -

      - Many of the parameters communicated to the window manager are - passed using data called "properties". These properties are - attached by the X server to different windows, and are stored - in a format that makes it possible to read them from different - machines that may use different architectures (remember that - an X client program may run on a remote machine). -

      -

      - The property and its type (a string, an integer, etc) are - Id. Their type are xcb_atom_t: -

      -
      -typedef uint32_t xcb_atom_t;
      -
      -

      - To change the property of a window, we use the following - function: -

      -
      -xcb_void_cookie_t xcb_change_property (xcb_connection_t *c,       /* Connection to the X server */
      -                                       uint8_t          mode,     /* Property mode */
      -                                       xcb_window_t     window,   /* Window */
      -                                       xcb_atom_t       property, /* Property to change */
      -                                       xcb_atom_t       type,     /* Type of the property */
      -                                       uint8_t          format,   /* Format of the property (8, 16, 32) */
      -                                       uint32_t         data_len, /* Length of the data parameter */
      -                                       const void      *data);    /* Data */
      -
      -

      - The mode parameter coud be one of - the following values (defined in enumeration xcb_prop_mode_t in - the xproto.h header file): -

      -
        -
      • XCB_PROP_MODE_REPLACE -
      • XCB_PROP_MODE_PREPEND -
      • XCB_PROP_MODE_APPEND -
      -
      -
    2. Setting the window name and icon name -

      - The first thing we want to do would be to set the name for our - window. This is done using the - xcb_change_property() function. This - name may be used by the window manager as the title of the - window (in the title bar), in a task list, etc. The property - atom to use to set the name of a window is - WM_NAME (and - WM_ICON_NAME for the iconified - window) and its type is STRING. Here - is an example of utilization: -

      -
      -#include <string.h>
      -
      -#include <xcb/xcb.h>
      -#include <xcb/xcb_atom.h>
      -
      -int
      -main ()
      -{
      -  xcb_connection_t *c;
      -  xcb_screen_t     *screen;
      -  xcb_window_t      win;
      -  char             *title = "Hello World !";
      -  char             *title_icon = "Hello World ! (iconified)";
      -
      -
      -
      -  /* Open the connection to the X server */
      -  c = xcb_connect (NULL, NULL);
      -
      -  /* Get the first screen */
      -  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      -
      -  /* Ask for our window's Id */
      -  win = xcb_generate_id (c);
      -
      -  /* Create the window */
      -  xcb_create_window (c,                             /* Connection          */
      -                     0,                             /* depth               */
      -                     win,                           /* window Id           */
      -                     screen->root,                  /* parent window       */
      -                     0, 0,                          /* x, y                */
      -                     250, 150,                      /* width, height       */
      -                     10,                            /* border_width        */
      -                     XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
      -                     screen->root_visual,           /* visual              */
      -                     0, NULL);                      /* masks, not used     */
      -
      -  /* Set the title of the window */
      -  xcb_change_property (c, XCB_PROP_MODE_REPLACE, win,
      -                       WM_NAME, STRING, 8,
      -                       strlen (title), title);
      -
      -  /* Set the title of the window icon */
      -  xcb_change_property (c, XCB_PROP_MODE_REPLACE, win,
      -                       WM_ICON_NAME, STRING, 8,
      -                       strlen(title_icon), title_icon);
      -
      -  /* Map the window on the screen */
      -  xcb_map_window (c, win);
      -
      -  xcb_flush (c);
      -
      -  while (1) {}
      -
      -  return 0;
      -}
      -
      -
      -

      Note: the use of the atoms needs our program to be compiled - and linked against xcb_atom, so that we have to use -

      -
      -
      -gcc prog.c -o prog `pkg-config --cflags --libs xcb_atom`
      -
      -
      -

      - for the program to compile fine. -

      -
      -
    -
  13. Simple window operations -

    - One more thing we can do to our window is manipulate them on the - screen (resize them, move them, raise or lower them, iconify - them, and so on). Some window operations functions are supplied - by XCB for this purpose. -

    -
      -
    1. Mapping and un-mapping a window -

      - The first pair of operations we can apply on a window is - mapping it, or un-mapping it. Mapping a window causes the - window to appear on the screen, as we have seen in our simple - window program example. Un-mapping it causes it to be removed - from the screen (although the window as a logical entity still - exists). This gives the effect of making a window hidden - (unmapped) and shown again (mapped). For example, if we have a - dialog box window in our program, instead of creating it every - time the user asks to open it, we can create the window once, - in an un-mapped mode, and when the user asks to open it, we - simply map the window on the screen. When the user clicked the - 'OK' or 'Cancel' button, we simply un-map the window. This is - much faster than creating and destroying the window, however, - the cost is wasted resources, both on the client side, and on - the X server side. -

      -

      - To map a window, you use the following function: -

      -
      -xcb_void_cookie_t xcb_map_window (xcb_connection_t *c,
      -                                  xcb_window_t      window);
      -
      -

      - To have a simple example, see the example - above. The mapping operation will cause an - Expose event to be sent to our - application, unless the window is completely covered by other - windows. -

      -

      - Un-mapping a window is also simple. You use the function -

      -
      -xcb_void_cookie_t xcb_unmap_window (xcb_connection_t *c,
      -                                    xcb_window_t      window);
      -
      -

      - The utilization of this function is the same as - xcb_map_window(). -

      -
    2. Configuring a window -

      - As we have seen when we have created our first window, in the - X Events subsection, we can set some attributes for the window - (that is, the position, the size, the events the window will - receive, etc). If we want to modify them, but the window is - already created, we can change them by using the following - function: -

      -
      -xcb_void_cookie_t xcb_configure_window (xcb_connection_t *c,            /* The connection to the X server*/
      -                                        xcb_window_t      window,       /* The window to configure */
      -                                        uint16_t          value_mask,   /* The mask */
      -                                        const uint32_t   *value_list);  /* The values to set */
      -
      -

      - We set the value_mask to one or - several mask values that are in the xcb_config_window_t enumeration in the xproto.h header: -

      -
        -
      • XCB_CONFIG_WINDOW_X: new x coordinate of the window's top left corner -
      • XCB_CONFIG_WINDOW_Y: new y coordinate of the window's top left corner -
      • XCB_CONFIG_WINDOW_WIDTH: new width of the window -
      • XCB_CONFIG_WINDOW_HEIGHT: new height of the window -
      • XCB_CONFIG_WINDOW_BORDER_WIDTH: new width of the border of the window -
      • XCB_CONFIG_WINDOW_SIBLING -
      • XCB_CONFIG_WINDOW_STACK_MODE: the new stacking order -
      -

      - We then give to value_mask the new - value. We now describe how to use - xcb_configure_window_t in some useful - situations. -

      -
    3. Moving a window around the screen -

      - An operation we might want to do with windows is to move them - to a different location. This can be done like this: -

      -
      -const static uint32_t values[] = { 10, 20 };
      -
      -/* The connection c and the window win are supposed to be defined */
      -
      -/* Move the window to coordinates x = 10 and y = 20 */
      -xcb_configure_window (c, win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values);
      -
      -

      - Note that when the window is moved, it might get partially - exposed or partially hidden by other windows, and thus we - might get Expose events due to this - operation. -

      -
    4. Resizing a window -

      - Yet another operation we can do is to change the size of a - window. This is done using the following code: -

      -
      -const static uint32_t values[] = { 200, 300 };
      -
      -/* The connection c and the window win are supposed to be defined */
      -
      -/* Resize the window to width = 10 and height = 20 */
      -xcb_configure_window (c, win, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
      -
      -

      - We can also combine the move and resize operations using one - single call to xcb_configure_window_t: -

      -
      -const static uint32_t values[] = { 10, 20, 200, 300 };
      -
      -/* The connection c and the window win are supposed to be defined */
      -
      -/* Move the window to coordinates x = 10 and y = 20 */
      -/* and resize the window to width = 10 and height = 20 */
      -xcb_configure_window (c, win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
      -
      -
    5. Changing windows stacking order: raise and lower -

      - Until now, we changed properties of a single window. We'll see - that there are properties that relate to the window and other - windows. One of them is the stacking order. That is, the order - in which the windows are layered on top of each other. The - front-most window is said to be on the top of the stack, while - the back-most window is at the bottom of the stack. Here is - how to manipulate our windows stack order: -

      -
      -const static uint32_t values[] = { XCB_STACK_MODE_ABOVE };
      -
      -/* The connection c and the window win are supposed to be defined */
      -
      -/* Move the window on the top of the stack */
      -xcb_configure_window (c, win, XCB_CONFIG_WINDOW_STACK_MODE, values);
      -
      -
      -const static uint32_t values[] = { XCB_STACK_MODE_BELOW };
      -
      -/* The connection c and the window win are supposed to be defined */
      -
      -/* Move the window on the bottom of the stack */
      -xcb_configure_window (c, win, XCB_CONFIG_WINDOW_STACK_MODE, values);
      -
      -
    6. Getting information about a window -

      - Just like we can set various attributes of our windows, we can - also ask the X server supply the current values of these - attributes. For example, we can check where a window is - located on the screen, what is its current size, whether it is - mapped or not, etc. The structure that contains some of this - information is -

      -
      -typedef struct {
      -    uint8_t      response_type;
      -    uint8_t      depth;         /* depth of the window */
      -    uint16_t     sequence;
      -    uint32_t     length;
      -    xcb_window_t root;          /* Id of the root window *>
      -    int16_t      x;             /* X coordinate of the window's location */
      -    int16_t      y;             /* Y coordinate of the window's location */
      -    uint16_t     width;         /* Width of the window */
      -    uint16_t     height;        /* Height of the window */
      -    uint16_t     border_width;  /* Width of the window's border */
      -} xcb_get_geometry_reply_t;
      -
      -

      - XCB fill this structure with two functions: -

      -
      -xcb_get_geometry_cookie_t  xcb_get_geometry       (xcb_connection_t         *c,
      -                                                   xcb_drawable_t            drawable);
      -xcb_get_geometry_reply_t  *xcb_get_geometry_reply (xcb_connection_t         *c,
      -                                                   xcb_get_geometry_cookie_t cookie,
      -                                                   xcb_generic_error_t     **e);
      -
      -

      - You use them as follows: -

      -
      -  xcb_connection_t         *c;
      -  xcb_drawable_t            win;
      -  xcb_get_geometry_reply_t *geom;
      -
      -  /* You initialize c and win */
      -
      -  geom = xcb_get_geometry_reply (c, xcb_get_geometry (c, win), NULL);
      -
      -  /* Do something with the fields of geom */
      -
      -  free (geom);
      -
      -

      - Remark that you have to free the structure, as - xcb_get_geometry_reply_t allocates a - newly one. -

      -

      - One problem is that the returned location of the window is - relative to its parent window. This makes these coordinates - rather useless for any window manipulation functions, like - moving it on the screen. In order to overcome this problem, we - need to take a two-step operation. First, we find out the Id - of the parent window of our window. We then translate the - above relative coordinates to the screen coordinates. -

      -

      - To get the Id of the parent window, we need this structure: -

      -
      -typedef struct {
      -    uint8_t      response_type;
      -    uint8_t      pad0;
      -    uint16_t     sequence;
      -    uint32_t     length;
      -    xcb_window_t root;
      -    xcb_window_t parent;       /* Id of the parent window */
      -    uint16_t     children_len;
      -    uint8_t      pad1[14];
      -} xcb_query_tree_reply_t;
      -
      -

      - To fill this structure, we use these two functions: -

      -
      -xcb_query_tree_cookie_t xcb_query_tree       (xcb_connection_t        *c,
      -                                              xcb_window_t             window);
      -xcb_query_tree_reply_t *xcb_query_tree_reply (xcb_connection_t        *c,
      -                                              xcb_query_tree_cookie_t  cookie,
      -                                              xcb_generic_error_t    **e);
      -
      -

      - The translated coordinates will be found in this structure: -

      -
      -typedef struct {
      -    uint8_t      response_type;
      -    uint8_t      same_screen;
      -    uint16_t     sequence;
      -    uint32_t     length;
      -    xcb_window_t child;
      -    uint16_t     dst_x;        /* Translated x coordinate */
      -    uint16_t     dst_y;        /* Translated y coordinate */
      -} xcb_translate_coordinates_reply_t;
      -
      -

      - As usual, we need two functions to fill this structure: -

      -
      -xcb_translate_coordinates_cookie_t xcb_translate_coordinates       (xcb_connection_t                  *c,
      -                                                                    xcb_window_t                       src_window,
      -                                                                    xcb_window_t                       dst_window,
      -                                                                    int16_t                            src_x,
      -                                                                    int16_t                            src_y);
      -xcb_translate_coordinates_reply_t *xcb_translate_coordinates_reply (xcb_connection_t                  *c,
      -                                                                    xcb_translate_coordinates_cookie_t cookie,
      -                                                                    xcb_generic_error_t              **e);
      -
      -

      - We use them as follows: -

      -
      -  xcb_connection_t                  *c;
      -  xcb_drawable_t                     win;
      -  xcb_get_geometry_reply_t          *geom;
      -  xcb_query_tree_reply_t            *tree;
      -  xcb_translate_coordinates_reply_t *trans;
      -
      -  /* You initialize c and win */
      -
      -  geom  = xcb_get_geometry_reply (c, xcb_get_geometry (c, win), NULL);
      -  if (!geom)
      -    return 0;
      -
      -  tree  = xcb_query_tree_reply (c, xcb_query_tree (c, win), NULL);
      -  if (!tree)
      -    return 0;
      -
      -  trans = xcb_translate_coordinates_reply (c,
      -                                           xcb_translate_coordinates (c,
      -                                                                      win,
      -                                                                      tree->parent,
      -                                                                      geom->x, geom->y),
      -                                           NULL);
      -  if (!trans)
      -    return 0;
      -
      -  /* the translated coordinates are in trans->dst_x and trans->dst_y */
      -
      -  free (trans);
      -  free (tree);
      -  free (geom);
      -
      -

      - Of course, as for geom, - tree and - trans have to be freed. -

      -

      - The work is a bit hard, but XCB is a very low-level library. -

      -

      - TODO: the utilization of these functions should be a - prog, which displays the coordinates of the window. -

      -

      - There is another structure that gives informations about our window: -

      -
      -typedef struct {
      -    uint8_t        response_type;
      -    uint8_t        backing_store;
      -    uint16_t       sequence;
      -    uint32_t       length;
      -    xcb_visualid_t visual;                /* Visual of the window */
      -    uint16_t       _class;
      -    uint8_t        bit_gravity;
      -    uint8_t        win_gravity;
      -    uint32_t       backing_planes;
      -    uint32_t       backing_pixel;
      -    uint8_t        save_under;
      -    uint8_t        map_is_installed;
      -    uint8_t        map_state;             /* Map state of the window */
      -    uint8_t        override_redirect;
      -    xcb_colormap_t colormap;              /* Colormap of the window */
      -    uint32_t       all_event_masks;
      -    uint32_t       your_event_mask;
      -    uint16_t       do_not_propagate_mask;
      -} xcb_get_window_attributes_reply_t;
      -
      -

      - XCB supplies these two functions to fill it: -

      -
      -xcb_get_window_attributes_cookie_t xcb_get_window_attributes       (xcb_connection_t                  *c,
      -                                                                    xcb_window_t                       window);
      -xcb_get_window_attributes_reply_t *xcb_get_window_attributes_reply (xcb_connection_t                  *c,
      -                                                                    xcb_get_window_attributes_cookie_t cookie,
      -                                                                    xcb_generic_error_t              **e);
      -
      -

      - You use them as follows: -

      -
      -  xcb_connection_t                  *c;
      -  xcb_drawable_t                     win;
      -  xcb_get_window_attributes_reply_t *attr;
      -
      -  /* You initialize c and win */
      -
      -  attr = xcb_get_window_attributes_reply (c, xcb_get_window_attributes (c, win), NULL);
      -
      -  if (!attr)
      -    return 0;
      -
      -  /* Do something with the fields of attr */
      -
      -  free (attr);
      -
      -

      - As for geom, - attr has to be freed. -

      -
    -
  14. Using colors to paint the rainbow -

    - Up until now, all our painting operation were done using black - and white. We will (finally) see now how to draw using colors. -

    -
      -
    1. Color maps -

      - In the beginning, there were not enough colors. Screen - controllers could only support a limited number of colors - simultaneously (initially 2, then 4, 16 and 256). Because of - this, an application could not just ask to draw in a "light - purple-red" color, and expect that color to be available. Each - application allocated the colors it needed, and when all the - color entries (4, 16, 256 colors) were in use, the next color - allocation would fail. -

      -

      - Thus, the notion of "a color map" was introduced. A color map - is a table whose size is the same as the number of - simultaneous colors a given screen controller. Each entry - contained the RGB (Red, Green and Blue) values of a different - color (all colors can be drawn using some combination of red, - green and blue). When an application wants to draw on the - screen, it does not specify which color to use. Rather, it - specifies which color entry of some color map to be used - during this drawing. Change the value in this color map entry - and the drawing will use a different color. -

      -

      - In order to be able to draw using colors that got something to - do with what the programmer intended, color map allocation - functions are supplied. You could ask to allocate entry for a - color with a set of RGB values. If one already existed, you - would get its index in the table. If none existed, and the - table was not full, a new cell would be allocated to contain - the given RGB values, and its index returned. If the table was - full, the procedure would fail. You could then ask to get a - color map entry with a color that is closest to the one you - were asking for. This would mean that the actual drawing on - the screen would be done using colors similar to what you - wanted, but not the same. -

      -

      - On today's more modern screens where one runs an X server with - support for 16 million colors, this limitation looks a little - silly, but remember that there are still older computers with - older graphics cards out there. Using color map, support for - these screen becomes transparent to you. On a display - supporting 16 million colors, any color entry allocation - request would succeed. On a display supporting a limited - number of colors, some color allocation requests would return - similar colors. It won't look as good, but your application - would still work. -

      -
    2. Allocating and freeing Color Maps -

      - When you draw using XCB, you can choose to use the standard - color map of the screen your window is displayed on, or you - can allocate a new color map and apply it to a window. In the - latter case, each time the mouse moves onto your window, the - screen color map will be replaced by your window's color map, - and you'll see all the other windows on screen change their - colors into something quite bizzare. In fact, this is the - effect you get with X applications that use the "-install" - command line option. -

      -

      - In XCB, a color map is (as often in X) an Id: -

      -
      -typedef uint32_t xcb_colormap_t;
      -
      -

      - In order to access the screen's default color map, you just - have to retrieve the default_colormap - field of the xcb_screen_t structure - (see Section - Checking basic information about a connection): -

      -
      -#include <stdio.h>
      -
      -#include <xcb/xcb.h>
      -
      -int
      -main ()
      -{
      -  xcb_connection_t *c;
      -  xcb_screen_t     *screen;
      -  xcb_colormap_t    colormap;
      -
      -  /* Open the connection to the X server and get the first screen */
      -  c = xcb_connect (NULL, NULL);
      -  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      -
      -  colormap = screen->default_colormap;
      -
      -  return 0;
      -}
      -
      -

      - This will return the color map used by default on the first - screen (again, remember that an X server may support several - different screens, each of which might have its own resources). -

      -

      - The other option, that of allocating a new colormap, works as - follows. We first ask the X server to give an Id to our color - map, with this function: -

      -
      -xcb_colormap_t xcb_generate_id (xcb_connection_t *c);
      -
      -

      - Then, we create the color map with -

      -
      -xcb_void_cookie_t xcb_create_colormap (xcb_connection_t *c,       /* Pointer to the xcb_connection_t structure */
      -                                       uint8_t           alloc,   /* Colormap entries to be allocated (AllocNone or AllocAll) */
      -                                       xcb_colormap_t    mid,     /* Id of the color map */
      -                                       xcb_window_t      window,  /* Window on whose screen the colormap will be created */
      -                                       xcb_visualid_t    visual); /* Id of the visual supported by the screen */
      -
      -

      - Here is an example of creation of a new color map: -

      -
      -#include <xcb/xcb.h>
      -
      -int
      -main ()
      -{
      -  xcb_connection_t *c;
      -  xcb_screen_t     *screen;
      -  xcb_window_t      win;
      -  xcb_colormap_t    cmap
      -
      -  /* Open the connection to the X server and get the first screen */
      -  c = xcb_connect (NULL, NULL);
      -  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      -
      -  /* We create the window win here*/
      -
      -  cmap = xcb_generate_id (c);
      -  xcb_create_colormap (c, XCB_COLORMAP_ALLOC_NONE, cmap, win, screen->root_visual);
      -
      -  return 0;
      -}
      -
      -

      - Note that the window parameter is only used to allow the X - server to create the color map for the given screen. We can - then use this color map for any window drawn on the same screen. -

      -

      - To free a color map, it suffices to use this function: -

      -
      -xcb_void_cookie_t xcb_free_colormap (xcb_connection_t *c,   /* The connection */
      -                                     xcb_colormap_t cmap);  /* The color map */
      -
      -
      -
      - Comparison Xlib/XCB -
      -
      -
        -
      • XCreateColormap () -
      -
      -
      -
        -
      • xcb_generate_id () -
      • xcb_create_colormap () -
      -
      -
      -
        -
      • XFreeColormap () -
      -
      -
      -
        -
      • xcb_free_colormap () -
      -
      -
      -
      -
    3. Allocating and freeing a color entry -

      - Once we got access to some color map, we can start allocating - colors. The informations related to a color are stored in the - following structure: -

      -
      -typedef struct {
      -    uint8_t  response_type;
      -    uint8_t  pad0;
      -    uint16_t sequence;
      -    uint32_t length;
      -    uint16_t red;          /* The red component   */
      -    uint16_t green;        /* The green component */
      -    uint16_t blue;         /* The blue component  */
      -    uint8_t  pad1[2];
      -    uint32_t pixel;        /* The entry in the color map, supplied by the X server */
      -} xcb_alloc_color_reply_t;
      -
      -

      - XCB supplies these two functions to fill it: -

      -
      -xcb_alloc_color_cookie_t xcb_alloc_color       (xcb_connection_t        *c,
      -                                                xcb_colormap_t           cmap,
      -                                                uint16_t                 red,
      -                                                uint16_t                 green,
      -                                                uint16_t                 blue);
      -xcb_alloc_color_reply_t *xcb_alloc_color_reply (xcb_connection_t        *c,
      -                                                xcb_alloc_color_cookie_t cookie,
      -                                                xcb_generic_error_t    **e);
      -
      -

      - The fuction xcb_alloc_color() takes the - 3 RGB components as parameters (red, green and blue). Here is an - example of using these functions: -

      -
      -#include <malloc.h>
      -
      -#include <xcb/xcb.h>
      -
      -int
      -main ()
      -{
      -  xcb_connection_t        *c;
      -  xcb_screen_t            *screen;
      -  xcb_window_t             win;
      -  xcb_colormap_t           cmap;
      -  xcb_alloc_color_reply_t *rep;
      -
      -  /* Open the connection to the X server and get the first screen */
      -  c = xcb_connect (NULL, NULL);
      -  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      -
      -  /* We create the window win here*/
      -
      -  cmap = xcb_generate_id (c);
      -  xcb_create_colormap (c, XCB_COLORMAP_ALLOC_NONE, cmap, win, screen->root_visual);
      -
      -  rep = xcb_alloc_color_reply (c, xcb_alloc_color (c, cmap, 65535, 0, 0), NULL);
      -
      -  if (!rep)
      -    return 0;
      -
      -  /* Do something with r->pixel or the components */
      -
      -  free (rep);
      -
      -  return 0;
      -}
      -
      -

      - As xcb_alloc_color_reply() allocates - memory, you have to free rep. -

      -

      - TODO: Talk about freeing colors. -

      -
    -
  15. X Bitmaps and Pixmaps -

    - One thing many so-called "Multi-Media" applications need to do, - is display images. In the X world, this is done using bitmaps - and pixmaps. We have already seen some usage of them when - setting an icon for our application. Lets study them further, - and see how to draw these images inside a window, along side the - simple graphics and text we have seen so far. -

    -

    - One thing to note before delving further, is that XCB (nor Xlib) - supplies no means of manipulating popular image formats, such as - gif, png, jpeg or tiff. It is up to the programmer (or to higher - level graphics libraries) to translate these image formats into - formats that the X server is familiar with (x bitmaps and x - pixmaps). -

    -
      -
    1. What is a X Bitmap? An X Pixmap? -

      - An X bitmap is a two-color image stored in a format specific - to the X window system. When stored in a file, the bitmap data - looks like a C source file. It contains variables defining the - width and the height of the bitmap, an array containing the - bit values of the bitmap (the size of the array is - (width+7)/8*height and the bit and byte order are LSB), and - an optional hot-spot location (that will - be explained later, when discussing mouse cursors). -

      -

      - An X pixmap is a format used to stored images in the memory of - an X server. This format can store both black and white images - (such as x bitmaps) as well as color images. It is the only - image format supported by the X protocol, and any image to be - drawn on screen, should be first translated into this format. -

      -

      - In actuality, an X pixmap can be thought of as a window that - does not appear on the screen. Many graphics operations that - work on windows, will also work on pixmaps. Indeed, the type - of X pixmap in XCB is an Id like a window: -

      -
      -typedef uint32_t xcb_pixmap_t;
      -
      -

      - Like Xlib, there is no difference between a Drawable, a Window - or a Pixmap: -

      -
      -typedef uint32_t xcb_drawable_t;
      -
      -

      - in order to avoid confusion between a window and a pixmap. The - operations that will work the same on a window or a pixmap - will require a xcb_drawable_t -

      -
      -

      - Remark: In Xlib, there is no specific difference between a - Drawable, a - Pixmap or a - Window: all are 32 bit long - integer. XCB wraps all these different IDs in structures to - provide some measure of type-safety. -

      -
      -
    2. Creating a pixmap -

      - Sometimes we want to create an un-initialized pixmap, so we - can later draw into it. This is useful for image drawing - programs (creating a new empty canvas will cause the creation - of a new pixmap on which the drawing can be stored). It is - also useful when reading various image formats: we load the - image data into memory, create a pixmap on the server, and - then draw the decoded image data onto that pixmap. -

      -

      - To create a new pixmap, we first ask the X server to give an - Id to our pixmap, with this function: -

      -
      -xcb_pixmap_t xcb_generate_id (xcb_connection_t *c);
      -
      -

      - Then, XCB supplies the following function to create new pixmaps: -

      -
      -xcb_void_cookie_t xcb_create_pixmap (xcb_connection_t *c,         /* Pointer to the xcb_connection_t structure */
      -                                     uint8_t           depth,     /* Depth of the screen */
      -                                     xcb_pixmap_t      pid,       /* Id of the pixmap */
      -                                     xcb_drawable_t    drawable,
      -                                     uint16_t          width,     /* Width of the window (in pixels) */
      -                                     uint16_t          height);   /* Height of the window (in pixels) */
      -
      -

      - TODO: Explain the drawable parameter, and give an - example (like xpoints.c) -

      -
    3. Drawing a pixmap in a window -

      - Once we got a handle to a pixmap, we can draw it on some - window, using the following function: -

      -
      -xcb_void_cookie_t xcb_copy_area (xcb_connection_t *c,             /* Pointer to the xcb_connection_t structure */
      -                                 xcb_drawable_t    src_drawable,  /* The Drawable we want to paste */
      -                                 xcb_drawable_t    dst_drawable,  /* The Drawable on which we copy the previous Drawable */
      -                                 xcb_gcontext_t    gc,            /* A Graphic Context */
      -                                 int16_t           src_x,         /* Top left x coordinate of the region we want to copy */
      -                                 int16_t           src_y,         /* Top left y coordinate of the region we want to copy */
      -                                 int16_t           dst_x,         /* Top left x coordinate of the region where we want to copy */
      -                                 int16_t           dst_y,         /* Top left y coordinate of the region where we want to copy */
      -                                 uint16_t          width,         /* Width of the region we want to copy */
      -                                 uint16_t          height);       /* Height of the region we want to copy */
      -
      -

      - As you can see, we could copy the whole pixmap, as well as - only a given rectangle of the pixmap. This is useful to - optimize the drawing speed: we could copy only what we have - modified in the pixmap. -

      -

      - One important note should be made: it is possible to - create pixmaps with different depths on the same screen. When - we perform copy operations (a pixmap onto a window, etc), we - should make sure that both source and target have the same - depth. If they have a different depth, the operation would - fail. The exception to this is if we copy a specific bit plane - of the source pixmap using the - xcb_copy_plane_t function. In such an - event, we can copy a specific plane to the target window (in - actuality, setting a specific bit in the color of each pixel - copied). This can be used to generate strange graphic effects - in a window, but that is beyond the scope of this tutorial. -

      -
    4. Freeing a pixmap -

      - Finally, when we are done using a given pixmap, we should free - it, in order to free resources of the X server. This is done - using this function: -

      -
      -xcb_void_cookie_t xcb_free_pixmap (xcb_connection_t *c,        /* Pointer to the xcb_connection_t structure */
      -                                   xcb_pixmap_t      pixmap);  /* A given pixmap */
      -
      -

      - Of course, after having freed it, we must not try accessing - the pixmap again. -

      -

      - TODO: Give an example, or a link to xpoints.c -

      -
    -
  16. Messing with the mouse cursor -

    - It it possible to modify the shape of the mouse pointer (also - called the X pointer) when in certain states, as we otfen see in - programs. For example, a busy application would often display - the sand clock over its main window, to give the user a visual - hint that he should wait. Let's see how we can change the mouse - cursor of our windows. -

    -
      -
    1. Creating and destroying a mouse cursor -

      - There are two methods for creating cursors. One of them is by - using a set of predefined cursors, that are supplied by the X - server, the other is by using a user-supplied bitmap. -

      -

      - In the first method, we use a special font named "cursor", and - the function xcb_create_glyph_cursor: -

      -
      -xcb_void_cookie_t xcb_create_glyph_cursor (xcb_connection_t *c,
      -                                           xcb_cursor_t      cid,
      -                                           xcb_font_t        source_font, /* font for the source glyph */
      -                                           xcb_font_t        mask_font,   /* font for the mask glyph or XCB_NONE */
      -                                           uint16_t          source_char, /* character glyph for the source */
      -                                           uint16_t          mask_char,   /* character glyph for the mask */
      -                                           uint16_t          fore_red,    /* red value for the foreground of the source */
      -                                           uint16_t          fore_green,  /* green value for the foreground of the source */
      -                                           uint16_t          fore_blue,   /* blue value for the foreground of the source */
      -                                           uint16_t          back_red,    /* red value for the background of the source */
      -                                           uint16_t          back_green,  /* green value for the background of the source */
      -                                           uint16_t          back_blue)   /* blue value for the background of the source */
      -
      -

      - TODO: Describe source_char - and mask_char, for example by giving - an example on how to get the values. There is a list there: - X Font Cursors -

      -

      - So we first open that font (see Loading a Font) - and create the new cursor. As for every X ressource, we have to - ask for an X id with xcb_generate_id - first: -

      -
      -xcb_font_t           font;
      -xcb_cursor_t         cursor;
      -
      -/* The connection is set */
      -
      -font = xcb_generate_id (conn);
      -xcb_open_font (conn, font, strlen ("cursor"), "cursor");
      -
      -cursor = xcb_generate_id (conn);
      -xcb_create_glyph_cursor (conn, cursor, font, font,
      -                         58, 58 + 1,
      -                         0, 0, 0,
      -                         0, 0, 0);
      -
      -

      - We have created the cursor "right hand" by specifying 58 to - the source_font argument and 58 + 1 - to the mask_font. -

      -

      - The cursor is destroyed by using the function -

      -
      -xcb_void_cookie_t xcb_free_cursor (xcb_connection_t *c,
      -                                   xcb_cursor_t      cursor);
      -
      -

      - In the second method, we create a new cursor by using a pair - of pixmaps, with depth of one (that is, two colors - pixmaps). One pixmap defines the shape of the cursor, while - the other works as a mask, specifying which pixels of the - cursor will be actually drawn. The rest of the pixels will be - transparent. -

      -

      - TODO: give an example. -

      -
    2. Setting a window's mouse cursor -

      - Once the cursor is created, we can modify the cursor of our - window by using xcb_change_window_attributes - and using the XCB_CWCURSOR attribute: -

      -
      -uint32_t mask;
      -uint32_t value_list;
      -
      -/* The connection and window are set */
      -/* The cursor is already created */
      -
      -mask = XCB_CWCURSOR;
      -value_list = cursor;
      -xcb_change_window_attributes (conn, window, mask, &value_list);
      -
      -

      - Of course, the cursor and the font must be freed. -

      -
    3. Complete example -

      - The following example displays a window with a - button. When entering the window, the window cursor is changed - to an arrow. When clicking once on the button, the cursor is - changed to a hand. When clicking again on the button, the - cursor window gets back to the arrow. The Esc key exits the - application. -

      -
      -#include <stdlib.h>
      -#include <stdio.h>
      -#include <string.h>
      -
      -#include <xcb/xcb.h>
      -
      -#define WIDTH 300
      -#define HEIGHT 150
      -
      -
      -
      -static xcb_gc_t gc_font_get (xcb_connection_t *c,
      -                             xcb_screen_t     *screen,
      -                             xcb_window_t      window,
      -                             const char       *font_name);
      -
      -static void button_draw (xcb_connection_t *c,
      -                         xcb_screen_t     *screen,
      -                         xcb_window_t      window,
      -                         int16_t           x1,
      -                         int16_t           y1,
      -                         const char       *label);
      -
      -static void text_draw (xcb_connection_t *c,
      -                       xcb_screen_t     *screen,
      -                       xcb_window_t      window,
      -                       int16_t           x1,
      -                       int16_t           y1,
      -                       const char       *label);
      -
      -static void cursor_set (xcb_connection_t *c,
      -                        xcb_screen_t     *screen,
      -                        xcb_window_t      window,
      -                        int               cursor_id);
      -
      -
      -static void
      -button_draw (xcb_connection_t *c,
      -             xcb_screen_t     *screen,
      -             xcb_window_t      window,
      -             int16_t           x1,
      -             int16_t           y1,
      -             const char       *label)
      -{
      -  xcb_point_t          points[5];
      -  xcb_void_cookie_t    cookie_gc;
      -  xcb_void_cookie_t    cookie_line;
      -  xcb_void_cookie_t    cookie_text;
      -  xcb_generic_error_t *error;
      -  xcb_gcontext_t       gc;
      -  int16_t              width;
      -  int16_t              height;
      -  uint8_t              length;
      -  int16_t              inset;
      -
      -  length = strlen (label);
      -  inset = 2;
      -
      -  gc = gc_font_get(c, screen, window, "7x13");
      -
      -  width = 7 * length + 2 * (inset + 1);
      -  height = 13 + 2 * (inset + 1);
      -  points[0].x = x1;
      -  points[0].y = y1;
      -  points[1].x = x1 + width;
      -  points[1].y = y1;
      -  points[2].x = x1 + width;
      -  points[2].y = y1 - height;
      -  points[3].x = x1;
      -  points[3].y = y1 - height;
      -  points[4].x = x1;
      -  points[4].y = y1;
      -  cookie_line = xcb_poly_line_checked (c, XCB_COORD_MODE_ORIGIN,
      -                                       window, gc, 5, points);
      -
      -  error = xcb_request_check (c, cookie_line);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't draw lines : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  cookie_text = xcb_image_text_8_checked (c, length, window, gc,
      -                                          x1 + inset + 1,
      -                                          y1 - inset - 1, label);
      -  error = xcb_request_check (c, cookie_text);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't paste text : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  cookie_gc = xcb_free_gc (c, gc);
      -  error = xcb_request_check (c, cookie_gc);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't free gc : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -}
      -
      -static void
      -text_draw (xcb_connection_t *c,
      -           xcb_screen_t     *screen,
      -           xcb_window_t      window,
      -           int16_t           x1,
      -           int16_t           y1,
      -           const char       *label)
      -{
      -  xcb_void_cookie_t    cookie_gc;
      -  xcb_void_cookie_t    cookie_text;
      -  xcb_generic_error_t *error;
      -  xcb_gcontext_t       gc;
      -  uint8_t              length;
      -
      -  length = strlen (label);
      -
      -  gc = gc_font_get(c, screen, window, "7x13");
      -
      -  cookie_text = xcb_image_text_8_checked (c, length, window, gc,
      -                                          x1,
      -                                          y1, label);
      -  error = xcb_request_check (c, cookie_text);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't paste text : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  cookie_gc = xcb_free_gc (c, gc);
      -  error = xcb_request_check (c, cookie_gc);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't free gc : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -}
      -
      -static xcb_gc_t
      -gc_font_get (xcb_connection_t *c,
      -             xcb_screen_t     *screen,
      -             xcb_window_t      window,
      -             const char       *font_name)
      -{
      -  uint32_t             value_list[3];
      -  xcb_void_cookie_t    cookie_font;
      -  xcb_void_cookie_t    cookie_gc;
      -  xcb_generic_error_t *error;
      -  xcb_font_t           font;
      -  xcb_gcontext_t       gc;
      -  uint32_t             mask;
      -
      -  font = xcb_generate_id (c);
      -  cookie_font = xcb_open_font_checked (c, font,
      -                                       strlen (font_name),
      -                                       font_name);
      -
      -  error = xcb_request_check (c, cookie_font);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't open font : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    return -1;
      -  }
      -
      -  gc = xcb_generate_id (c);
      -  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
      -  value_list[0] = screen->black_pixel;
      -  value_list[1] = screen->white_pixel;
      -  value_list[2] = font;
      -  cookie_gc = xcb_create_gc_checked (c, gc, window, mask, value_list);
      -  error = xcb_request_check (c, cookie_gc);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't create gc : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  cookie_font = xcb_close_font_checked (c, font);
      -  error = xcb_request_check (c, cookie_font);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't close font : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  return gc;
      -}
      -
      -static void
      -cursor_set (xcb_connection_t *c,
      -            xcb_screen_t     *screen,
      -            xcb_window_t      window,
      -            int               cursor_id)
      -{
      -  uint32_t             values_list[3];
      -  xcb_void_cookie_t    cookie_font;
      -  xcb_void_cookie_t    cookie_gc;
      -  xcb_generic_error_t *error;
      -  xcb_font_t           font;
      -  xcb_cursor_t         cursor;
      -  xcb_gcontext_t       gc;
      -  uint32_t             mask;
      -  uint32_t             value_list;
      -
      -  font = xcb_generate_id (c);
      -  cookie_font = xcb_open_font_checked (c, font,
      -                                       strlen ("cursor"),
      -                                       "cursor");
      -  error = xcb_request_check (c, cookie_font);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't open font : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  cursor = xcb_generate_id (c);
      -  xcb_create_glyph_cursor (c, cursor, font, font,
      -                           cursor_id, cursor_id + 1,
      -                           0, 0, 0,
      -                           0, 0, 0);
      -
      -  gc = xcb_generate_id (c);
      -  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
      -  values_list[0] = screen->black_pixel;
      -  values_list[1] = screen->white_pixel;
      -  values_list[2] = font;
      -  cookie_gc = xcb_create_gc_checked (c, gc, window, mask, values_list);
      -  error = xcb_request_check (c, cookie_gc);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't create gc : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -
      -  mask = XCB_CW_CURSOR;
      -  value_list = cursor;
      -  xcb_change_window_attributes (c, window, mask, &value_list);
      -
      -  xcb_free_cursor (c, cursor);
      -
      -  cookie_font = xcb_close_font_checked (c, font);
      -  error = xcb_request_check (c, cookie_font);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't close font : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    exit (-1);
      -  }
      -}
      -
      -int main ()
      -{
      -  xcb_screen_iterator_t screen_iter;
      -  xcb_connection_t     *c;
      -  const xcb_setup_t    *setup;
      -  xcb_screen_t         *screen;
      -  xcb_generic_event_t  *e;
      -  xcb_generic_error_t  *error;
      -  xcb_void_cookie_t     cookie_window;
      -  xcb_void_cookie_t     cookie_map;
      -  xcb_window_t          window;
      -  uint32_t              mask;
      -  uint32_t              values[2];
      -  int                   screen_number;
      -  uint8_t               is_hand = 0;
      -
      -  /* getting the connection */
      -  c = xcb_connect (NULL, &screen_number);
      -  if (!c) {
      -    fprintf (stderr, "ERROR: can't connect to an X server\n");
      -    return -1;
      -  }
      -
      -  /* getting the current screen */
      -  setup = xcb_get_setup (c);
      -
      -  screen = NULL;
      -  screen_iter = xcb_setup_roots_iterator (setup);
      -  for (; screen_iter.rem != 0; --screen_number, xcb_screen_next (&screen_iter))
      -    if (screen_number == 0)
      -      {
      -        screen = screen_iter.data;
      -        break;
      -      }
      -  if (!screen) {
      -    fprintf (stderr, "ERROR: can't get the current screen\n");
      -    xcb_disconnect (c);
      -    return -1;
      -  }
      -
      -  /* creating the window */
      -  window = xcb_generate_id (c);
      -  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
      -  values[0] = screen->white_pixel;
      -  values[1] =
      -    XCB_EVENT_MASK_KEY_RELEASE |
      -    XCB_EVENT_MASK_BUTTON_PRESS |
      -    XCB_EVENT_MASK_EXPOSURE |
      -    XCB_EVENT_MASK_POINTER_MOTION;
      -  cookie_window = xcb_create_window_checked (c,
      -                                             screen->root_depth,
      -                                             window, screen->root,
      -                                             20, 200, WIDTH, HEIGHT,
      -                                             0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
      -                                             screen->root_visual,
      -                                             mask, values);
      -  cookie_map = xcb_map_window_checked (c, window);
      -
      -  /* error managing */
      -  error = xcb_request_check (c, cookie_window);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't create window : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    return -1;
      -  }
      -  error = xcb_request_check (c, cookie_map);
      -  if (error) {
      -    fprintf (stderr, "ERROR: can't map window : %d\n", error->error_code);
      -    xcb_disconnect (c);
      -    return -1;
      -  }
      -
      -  cursor_set (c, screen, window, 68);
      -
      -  xcb_flush(c);
      -
      -  while (1) {
      -    e = xcb_poll_for_event(c);
      -    if (e) {
      -      switch (e->response_type & ~0x80) {
      -      case XCB_EXPOSE: {
      -        char *text;
      -
      -        text = "click here to change cursor";
      -        button_draw (c, screen, window,
      -                     (WIDTH - 7 * strlen(text)) / 2,
      -                     (HEIGHT - 16) / 2, text);
      -
      -        text = "Press ESC key to exit...";
      -        text_draw (c, screen, window, 10, HEIGHT - 10, text);
      -        break;
      -      }
      -      case XCB_BUTTON_PRESS: {
      -        xcb_button_press_event_t *ev;
      -        int                       length;
      -
      -        ev = (xcb_button_press_event_t *)e;
      -        length = strlen ("click here to change cursor");
      -
      -        if ((ev->event_x >= (WIDTH - 7 * length) / 2) &&
      -            (ev->event_x <= ((WIDTH - 7 * length) / 2 + 7 * length + 6)) &&
      -            (ev->event_y >= (HEIGHT - 16) / 2 - 19) &&
      -            (ev->event_y <= ((HEIGHT - 16) / 2)))
      -          is_hand = 1 - is_hand;
      -
      -        is_hand ? cursor_set (c, screen, window, 58) : cursor_set (c, screen, window, 68);
      -      }
      -      case XCB_KEY_RELEASE: {
      -        xcb_key_release_event_t *ev;
      -
      -        ev = (xcb_key_release_event_t *)e;
      -
      -        switch (ev->detail) {
      -          /* ESC */
      -        case 9:
      -          free (e);
      -          xcb_disconnect (c);
      -          return 0;
      -        }
      -      }
      -      }
      -      free (e);
      -    }
      -  }
      -
      -  return 0;
      -}
      -
      -
    -
  17. Translation of basic Xlib functions and macros -

    - The problem when you want to port an Xlib program to XCB is that - you don't know if the Xlib function that you want to "translate" - is a X Window one or an Xlib macro. In that section, we describe - a way to translate the usual functions or macros that Xlib - provides. It's usually just a member of a structure. -

    -
      -
    1. Members of the Display structure -

      - In this section, we look at how to translate the macros that - return some members of the Display - structure. They are obtained by using a function that requires a - xcb_connection_t * or a member of the - xcb_setup_t structure - (via the function xcb_get_setup), or - a function that requires that structure. -

      -
        -
      1. ConnectionNumber -

        - This number is the file descriptor that connects the client - to the server. You just have to use that function: -

        -
        -int xcb_get_file_descriptor (xcb_connection_t *c);
        -
        -
      2. DefaultScreen -

        - That number is not stored by XCB. It is returned in the - second parameter of the function xcb_connect. - Hence, you have to store it yourself if you want to use - it. Then, to get the xcb_screen_t - structure, you have to iterate on the screens. - The equivalent function of the Xlib's - ScreenOfDisplay function can be - found below. This is also provided in the - xcb_aux_t library as xcb_aux_get_screen(). OK, here is the - small piece of code to get that number: -

        -
        -xcb_connection_t *c;
        -int               screen_default_nbr;
        -
        -/* you pass the name of the display you want to xcb_connect_t */
        -
        -c = xcb_connect (display_name, &screen_default_nbr);
        -
        -/* screen_default_nbr contains now the number of the default screen */
        -
        -
      3. QLength -

        - Not documented yet. -

        -

        - However, this points out a basic difference in philosophy between - Xlib and XCB. Xlib has several functions for filtering and - manipulating the incoming and outgoing X message queues. XCB - wishes to hide this as much as possible from the user, which - allows for more freedom in implementation strategies. -

        -
      4. ScreenCount -

        - You get the count of screens with the functions - xcb_get_setup - and - xcb_setup_roots_iterator - (if you need to iterate): -

        -
        -xcb_connection_t *c;
        -int               screen_count;
        -
        -/* you init the connection */
        -
        -screen_count = xcb_setup_roots_iterator (xcb_get_setup (c)).rem;
        -
        -/* screen_count contains now the count of screens */
        -
        -

        - If you don't want to iterate over the screens, a better way - to get that number is to use - xcb_setup_roots_length_t: -

        -
        -xcb_connection_t *c;
        -int               screen_count;
        -
        -/* you init the connection */
        -
        -screen_count = xcb_setup_roots_length (xcb_get_setup (c));
        -
        -/* screen_count contains now the count of screens */
        -
        -
      5. ServerVendor -

        - You get the name of the vendor of the server hardware with - the functions xcb_get_setup - and - xcb_setup_vendor. Beware - that, unlike Xlib, the string returned by XCB is not - necessarily null-terminaled: -

        -
        -xcb_connection_t *c;
        -char             *vendor = NULL;
        -int               length;
        -
        -/* you init the connection */
        -length = xcb_setup_vendor_length (xcb_get_setup (c));
        -vendor = (char *)malloc (length + 1);
        -if (vendor)
        -memcpy (vendor, xcb_setup_vendor (xcb_get_setup (c)), length);
        -vendor[length] = '\0';
        -
        -/* vendor contains now the name of the vendor. Must be freed when not used anymore */
        -
        -
      6. ProtocolVersion -

        - You get the major version of the protocol in the - xcb_setup_t - structure, with the function xcb_get_setup: -

        -
        -xcb_connection_t *c;
        -uint16_t          protocol_major_version;
        -
        -/* you init the connection */
        -
        -protocol_major_version = xcb_get_setup (c)->protocol_major_version;
        -
        -/* protocol_major_version contains now the major version of the protocol */
        -
        -
      7. ProtocolRevision -

        - You get the minor version of the protocol in the - xcb_setup_t - structure, with the function xcb_get_setup: -

        -
        -xcb_connection_t *c;
        -uint16_t          protocol_minor_version;
        -
        -/* you init the connection */
        -
        -protocol_minor_version = xcb_get_setup (c)->protocol_minor_version;
        -
        -/* protocol_minor_version contains now the minor version of the protocol */
        -
        -
      8. VendorRelease -

        - You get the number of the release of the server hardware in the - xcb_setup_t - structure, with the function xcb_get_setup: -

        -
        -xcb_connection_t *c;
        -uint32_t          release_number;
        -
        -/* you init the connection */
        -
        -release_number = xcb_get_setup (c)->release_number;
        -
        -/* release_number contains now the number of the release of the server hardware */
        -
        -
      9. DisplayString -

        - The name of the display is not stored in XCB. You have to - store it by yourself. -

        -
      10. BitmapUnit -

        - You get the bitmap scanline unit in the - xcb_setup_t - structure, with the function xcb_get_setup: -

        -
        -xcb_connection_t *c;
        -uint8_t           bitmap_format_scanline_unit;
        -
        -/* you init the connection */
        -
        -bitmap_format_scanline_unit = xcb_get_setup (c)->bitmap_format_scanline_unit;
        -
        -/* bitmap_format_scanline_unit contains now the bitmap scanline unit */
        -
        -
      11. BitmapBitOrder -

        - You get the bitmap bit order in the - xcb_setup_t - structure, with the function xcb_get_setup: -

        -
        -xcb_connection_t *c;
        -uint8_t           bitmap_format_bit_order;
        -
        -/* you init the connection */
        -
        -bitmap_format_bit_order = xcb_get_setup (c)->bitmap_format_bit_order;
        -
        -/* bitmap_format_bit_order contains now the bitmap bit order */
        -
        -
      12. BitmapPad -

        - You get the bitmap scanline pad in the - xcb_setup_t - structure, with the function xcb_get_setup: -

        -
        -xcb_connection_t *c;
        -uint8_t           bitmap_format_scanline_pad;
        -
        -/* you init the connection */
        -
        -bitmap_format_scanline_pad = xcb_get_setup (c)->bitmap_format_scanline_pad;
        -
        -/* bitmap_format_scanline_pad contains now the bitmap scanline pad */
        -
        -
      13. ImageByteOrder -

        - You get the image byte order in the - xcb_setup_t - structure, with the function xcb_get_setup: -

        -
        -xcb_connection_t *c;
        -uint8_t           image_byte_order;
        -
        -/* you init the connection */
        -
        -image_byte_order = xcb_get_setup (c)->image_byte_order;
        -
        -/* image_byte_order contains now the image byte order */
        -
        -
      -
    2. ScreenOfDisplay related functions -

      - in Xlib, ScreenOfDisplay returns a - Screen structure that contains - several characteristics of your screen. XCB has a similar - structure (xcb_screen_t), - but the way to obtain it is a bit different. With - Xlib, you just provide the number of the screen and you grab it - from an array. With XCB, you iterate over all the screens to - obtain the one you want. The complexity of this operation is - O(n). So the best is to store this structure if you use - it often. See screen_of_display just below. -

      -

      - Xlib provides generally two functions to obtain the characteristics - related to the screen. One with the display and the number of - the screen, which calls ScreenOfDisplay, - and the other that uses the Screen structure. - This might be a bit confusing. As mentioned above, with XCB, it - is better to store the xcb_screen_t - structure. Then, you have to read the members of this - structure. That's why the Xlib functions are put by pairs (or - more) as, with XCB, you will use the same code. -

      -
        -
      1. ScreenOfDisplay -

        - This function returns the Xlib Screen - structure. With XCB, you iterate over all the screens and - once you get the one you want, you return it: -

        -
        
        -xcb_screen_t *screen_of_display (xcb_connection_t *c,
        -                                 int               screen)
        -{
        -  xcb_screen_iterator_t iter;
        -
        -  iter = xcb_setup_roots_iterator (xcb_get_setup (c));
        -  for (; iter.rem; --screen, xcb_screen_next (&iter))
        -    if (screen == 0)
        -      return iter.data;
        -
        -  return NULL;
        -}
        -
        -

        - As mentioned above, you might want to store the value - returned by this function. -

        -

        - All the functions below will use the result of that - function, as they just grab a specific member of the - xcb_screen_t structure. -

        -
      2. DefaultScreenOfDisplay -

        - It is the default screen that you obtain when you connect to - the X server. It suffices to call the screen_of_display - function above with the connection and the number of the - default screen. -

        -
        -xcb_connection_t *c;
        -int               screen_default_nbr;
        -xcb_screen_t     *default_screen;  /* the returned default screen */
        -
        -/* you pass the name of the display you want to xcb_connect_t */
        -
        -c = xcb_connect (display_name, &screen_default_nbr);
        -default_screen = screen_of_display (c, screen_default_nbr);
        -
        -/* default_screen contains now the default root window, or a NULL window if no screen is found */
        -
        -
      3. RootWindow / RootWindowOfScreen -
        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -xcb_window_t      root_window = { 0 };  /* the returned window */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  root_window = screen->root;
        -
        -/* root_window contains now the root window, or a NULL window if no screen is found */
        -
        -
      4. DefaultRootWindow -

        - It is the root window of the default screen. So, you call - ScreenOfDisplay with the - default screen number and you get the - root window as above: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_default_nbr;
        -xcb_window_t      root_window = { 0 };  /* the returned root window */
        -
        -/* you pass the name of the display you want to xcb_connect_t */
        -
        -c = xcb_connect (display_name, &screen_default_nbr);
        -screen = screen_of_display (c, screen_default_nbr);
        -if (screen)
        -  root_window = screen->root;
        -
        -/* root_window contains now the default root window, or a NULL window if no screen is found */
        -
        -
      5. DefaultVisual / DefaultVisualOfScreen -

        - While a Visual is, in Xlib, a structure, in XCB, there are - two types: xcb_visualid_t, which is - the Id of the visual, and xcb_visualtype_t, - which corresponds to the Xlib Visual. To get the Id of the - visual of a screen, just get the - root_visual - member of a xcb_screen_t: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -xcb_visualid_t    root_visual = { 0 };    /* the returned visual Id */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  root_visual = screen->root_visual;
        -
        -/* root_visual contains now the value of the Id of the visual, or a NULL visual if no screen is found */
        -
        -

        - To get the xcb_visualtype_t - structure, it's a bit less easy. You have to get the - xcb_screen_t structure that you want, - get its root_visual member, - then iterate over the xcb_depth_ts - and the xcb_visualtype_ts, and compare - the xcb_visualid_t of these xcb_visualtype_ts: - with root_visual: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -xcb_visualid_t    root_visual = { 0 };
        -xcb_visualtype_t  *visual_type = NULL;    /* the returned visual type */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen) {
        -  xcb_depth_iterator_t depth_iter;
        -
        -  depth_iter = xcb_screen_allowed_depths_iterator (screen);
        -  for (; depth_iter.rem; xcb_depth_next (&depth_iter)) {
        -    xcb_visualtype_iterator_t visual_iter;
        -
        -    visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
        -    for (; visual_iter.rem; xcb_visualtype_next (&visual_iter)) {
        -      if (screen->root_visual == visual_iter.data->visual_id) {
        -        visual_type = visual_iter.data;
        -        break;
        -      }
        -    }
        -  }
        -}
        -
        -/* visual_type contains now the visual structure, or a NULL visual structure if no screen is found */
        -
        -
      6. DefaultGC / DefaultGCOfScreen -

        - This default Graphic Context is just a newly created Graphic - Context, associated to the root window of a - xcb_screen_t, - using the black white pixels of that screen: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -xcb_gcontext_t    gc = { 0 };    /* the returned default graphic context */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen) {
        -  xcb_drawable_t draw;
        -  uint32_t       mask;
        -  uint32_t       values[2];
        -
        -  gc = xcb_generate_id (c);
        -  draw = screen->root;
        -  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
        -  values[0] = screen->black_pixel;
        -  values[1] = screen->white_pixel;
        -  xcb_create_gc (c, gc, draw, mask, values);
        -}
        -
        -/* gc contains now the default graphic context */
        -
        -
      7. BlackPixel / BlackPixelOfScreen -

        - It is the Id of the black pixel, which is in the structure - of an xcb_screen_t. -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint32_t          black_pixel = 0;    /* the returned black pixel */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  black_pixel = screen->black_pixel;
        -
        -/* black_pixel contains now the value of the black pixel, or 0 if no screen is found */
        -
        -
      8. WhitePixel / WhitePixelOfScreen -

        - It is the Id of the white pixel, which is in the structure - of an xcb_screen_t. -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint32_t          white_pixel = 0;    /* the returned white pixel */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  white_pixel = screen->white_pixel;
        -
        -/* white_pixel contains now the value of the white pixel, or 0 if no screen is found */
        -
        -
      9. DisplayWidth / WidthOfScreen -

        - It is the width in pixels of the screen that you want, and - which is in the structure of the corresponding - xcb_screen_t. -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint32_t          width_in_pixels = 0;    /* the returned width in pixels */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  width_in_pixels = screen->width_in_pixels;
        -
        -/* width_in_pixels contains now the width in pixels, or 0 if no screen is found */
        -
        -
      10. DisplayHeight / HeightOfScreen -

        - It is the height in pixels of the screen that you want, and - which is in the structure of the corresponding - xcb_screen_t. -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint32_t          height_in_pixels = 0;    /* the returned height in pixels */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  height_in_pixels = screen->height_in_pixels;
        -
        -/* height_in_pixels contains now the height in pixels, or 0 if no screen is found */
        -
        -
      11. DisplayWidthMM / WidthMMOfScreen -

        - It is the width in millimeters of the screen that you want, and - which is in the structure of the corresponding - xcb_screen_t. -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint32_t          width_in_millimeters = 0;    /* the returned width in millimeters */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  width_in_millimeters = screen->width_in_millimeters;
        -
        -/* width_in_millimeters contains now the width in millimeters, or 0 if no screen is found */
        -
        -
      12. DisplayHeightMM / HeightMMOfScreen -

        - It is the height in millimeters of the screen that you want, and - which is in the structure of the corresponding - xcb_screen_t. -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint32_t          height_in_millimeters = 0;    /* the returned height in millimeters */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  height_in_millimeters = screen->height_in_millimeters;
        -
        -/* height_in_millimeters contains now the height in millimeters, or 0 if no screen is found */
        -
        -
      13. DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen -

        - It is the depth (in bits) of the root window of the - screen. You get it from the xcb_screen_t structure. -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint8_t           root_depth = 0;  /* the returned depth of the root window */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  root_depth = screen->root_depth;
        -
        -/* root_depth contains now the depth of the root window, or 0 if no screen is found */
        -
        -
      14. DefaultColormap / DefaultColormapOfScreen -

        - This is the default colormap of the screen (and not the - (default) colormap of the default screen !). As usual, you - get it from the xcb_screen_t structure: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -xcb_colormap_t    default_colormap = { 0 };  /* the returned default colormap */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  default_colormap = screen->default_colormap;
        -
        -/* default_colormap contains now the default colormap, or a NULL colormap if no screen is found */
        -
        -
      15. MinCmapsOfScreen -

        - You get the minimum installed colormaps in the xcb_screen_t structure: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint16_t          min_installed_maps = 0;  /* the returned minimum installed colormaps */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  min_installed_maps = screen->min_installed_maps;
        -
        -/* min_installed_maps contains now the minimum installed colormaps, or 0 if no screen is found */
        -
        -
      16. MaxCmapsOfScreen -

        - You get the maximum installed colormaps in the xcb_screen_t structure: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint16_t          max_installed_maps = 0;  /* the returned maximum installed colormaps */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  max_installed_maps = screen->max_installed_maps;
        -
        -/* max_installed_maps contains now the maximum installed colormaps, or 0 if no screen is found */
        -
        -
      17. DoesSaveUnders -

        - You know if save_unders is set, - by looking in the xcb_screen_t structure: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint8_t           save_unders = 0;  /* the returned value of save_unders */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  save_unders = screen->save_unders;
        -
        -/* save_unders contains now the value of save_unders, or FALSE if no screen is found */
        -
        -
      18. DoesBackingStore -

        - You know the value of backing_stores, - by looking in the xcb_screen_t structure: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint8_t           backing_stores = 0;  /* the returned value of backing_stores */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  backing_stores = screen->backing_stores;
        -
        -/* backing_stores contains now the value of backing_stores, or FALSE if no screen is found */
        -
        -
      19. EventMaskOfScreen -

        - To get the current input masks, - you look in the xcb_screen_t structure: -

        -
        -xcb_connection_t *c;
        -xcb_screen_t     *screen;
        -int               screen_nbr;
        -uint32_t          current_input_masks = 0;  /* the returned value of current input masks */
        -
        -/* you init the connection and screen_nbr */
        -
        -screen = screen_of_display (c, screen_nbr);
        -if (screen)
        -  current_input_masks = screen->current_input_masks;
        -
        -/* current_input_masks contains now the value of the current input masks, or FALSE if no screen is found */
        -
        -
      -
    3. Miscellaneous macros -
        -
      1. DisplayOfScreen -

        - in Xlib, the Screen structure - stores its associated Display - structure. This is not the case in the X Window protocol, - hence, it's also not the case in XCB. So you have to store - it by yourself. -

        -
      2. DisplayCells / CellsOfScreen -

        - To get the colormap entries, - you look in the xcb_visualtype_t - structure, that you grab like here: -

        -
        -xcb_connection_t *c;
        -xcb_visualtype_t *visual_type;
        -uint16_t          colormap_entries = 0;  /* the returned value of the colormap entries */
        -
        -/* you init the connection and visual_type */
        -
        -if (visual_type)
        -  colormap_entries = visual_type->colormap_entries;
        -
        -/* colormap_entries contains now the value of the colormap entries, or FALSE if no screen is found */
        -
        -
      -
    -
-
- - - + + + + + + Basic Graphics Programming With The XCB Library + + + + + +
+ Basic Graphics Programming With The XCB Library +
+
+
    +
  1. Introduction +
  2. The client and server model of the X window system +
  3. GUI programming: the asynchronous model +
  4. Basic XCB notions +
      +
    1. The X Connection +
    2. Requests and replies: the Xlib killers +
    3. The Graphics Context +
    4. Object handles +
    5. Memory allocation for XCB structures +
    6. Events +
    +
  5. Using XCB-based programs +
      +
    1. Installation of XCB +
    2. Compiling XCB-based programs +
    +
  6. Opening and closing the connection to an X server +
  7. Checking basic information about a connection +
  8. Creating a basic window - the "hello world" program +
  9. Drawing in a window +
      +
    1. Allocating a Graphics Context +
    2. Changing the attributes of a Graphics Context +
    3. Drawing primitives: point, line, box, circle,... +
    +
  10. X Events +
      +
    1. Registering for event types using event masks +
    2. Receiving events: writing the events loop +
    3. Expose events +
    4. Getting user input +
        +
      1. Mouse button press and release events +
      2. Mouse movement events +
      3. Mouse pointer enter and leave events +
      4. The keyboard focus +
      5. Keyboard press and release events +
      +
    5. X events: a complete example +
    +
  11. Handling text and fonts +
      +
    1. The Font structure +
    2. Opening a Font +
    3. Assigning a Font to a Graphic Context +
    4. Drawing text in a drawable +
    5. Complete example +
    +
  12. Windows hierarchy +
      +
    1. Root, parent and child windows +
    2. Events propagation +
    +
  13. Interacting with the window manager +
      +
    1. Window properties +
    2. Setting the window name and icon name +
    3. Setting preferred window size(s) +
    4. Setting miscellaneous window manager hints +
    5. Setting an application's icon +
    6. Obeying the delete-window protocol +
    +
  14. Simple window operations +
      +
    1. Mapping and unmapping a window +
    2. Configuring a window +
    3. Moving a window around the screen +
    4. Resizing a window +
    5. Changing windows stacking order: raise and lower +
    6. Iconifying and de-iconifying a window +
    7. Getting informations about a window +
    +
  15. Using colors to paint the rainbow +
      +
    1. Color maps +
    2. Allocating and freeing Color Maps +
    3. Allocating and freeing a color entry +
    4. Drawing with a color +
    +
  16. X Bitmaps and Pixmaps +
      +
    1. What is a X Bitmap ? An X Pixmap ? +
    2. Loading a bitmap from a file +
    3. Drawing a bitmap in a window +
    4. Creating a pixmap +
    5. Drawing a pixmap in a window +
    6. Freeing a pixmap +
    +
  17. Messing with the mouse cursor +
      +
    1. Creating and destroying a mouse cursor +
    2. Setting a window's mouse cursor +
    3. Complete example +
    +
  18. Translation of basic Xlib functions and macros +
      +
    1. Members of the Display structure +
        +
      1. ConnectionNumber +
      2. DefaultScreen +
      3. QLength +
      4. ScreenCount +
      5. ServerVendor +
      6. ProtocolVersion +
      7. ProtocolRevision +
      8. VendorRelease +
      9. DisplayString +
      10. BitmapUnit +
      11. BitmapBitOrder +
      12. BitmapPad +
      13. ImageByteOrder +
      +
    2. ScreenOfDisplay related functions +
        +
      1. ScreenOfDisplay +
      2. DefaultScreenOfDisplay +
      3. RootWindow / RootWindowOfScreen +
      4. DefaultRootWindow +
      5. DefaultVisual / DefaultVisualOfScreen +
      6. DefaultGC / DefaultGCOfScreen +
      7. BlackPixel / BlackPixelOfScreen +
      8. WhitePixel / WhitePixelOfScreen +
      9. DisplayWidth / WidthOfScreen +
      10. DisplayHeight / HeightOfScreen +
      11. DisplayWidthMM / WidthMMOfScreen +
      12. DisplayHeightMM / HeightMMOfScreen +
      13. DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen +
      14. DefaultColormap / DefaultColormapOfScreen +
      15. MinCmapsOfScreen +
      16. MaxCmapsOfScreen +
      17. DoesSaveUnders +
      18. DoesBackingStore +
      19. EventMaskOfScreen +
      +
    3. Miscellaneaous macros +
        +
      1. DisplayOfScreen +
      2. DisplayCells / CellsOfScreen +
      +
    +
+
+
+
    +
  1. Introduction +

    + This tutorial is based on the + Xlib Tutorial + written by Guy Keren. The + author allowed me to take some parts of his text, mainly the text which + deals with the X Windows generality. +

    +

    + This tutorial is intended for people who want to start to program + with the XCB + library. keep in mind that XCB, like the + Xlib + library, isn't what most programmers wanting to write X + applications are looking for. They should use a much higher + level GUI toolkit like Motif, + LessTiff, + GTK, + QT, + EWL, + ETK, or use + Cairo. + However, + we need to start somewhere. More than this, knowing how things + work down below is never a bad idea. +

    +

    + After reading this tutorial, one should be able to write very + simple graphical programs, but not programs with decent user + interfaces. For such programs, one of the previously mentioned + libraries should be used. +

    +

    + But what is XCB? Xlib has been + the standard C binding for the X + Window System protocol for many years now. It is an + excellent piece of work, but there are applications for which it + is not ideal, for example: +

    +
      +
    • Small platforms: Xlib is a large piece of code, and + it's difficult to make it smaller +
    • Latency hiding: Xlib requests requiring a reply are + effectively synchronous: they block until the reply appears, + whether the result is needed immediately or not. +
    • Direct access to the protocol: Xlib does quite a + bit of caching, layering, and similar optimizations. While this + is normally a feature, it makes it difficult to simply emit + specified X protocol requests and process specific + responses. +
    • Threaded applications: While Xlib does attempt to + support multithreading, the API makes this difficult and + error-prone. +
    • New extensions: The Xlib infrastructure provides + limited support for the new creation of X extension client side + code. +
    +

    + For these reasons, among others, XCB, an X C binding, has been + designed to solve the above problems and thus provide a base for +

    +
      +
    • Toolkit implementation. +
    • Direct protocol-level programming. +
    • Lightweight emulation of commonly used portions of the + Xlib API. +
    +
    +
  2. The client and server model of the X window system +

    + The X Window System was developed with one major goal: + flexibility. The idea was that the way things look is one thing, + but the way things work is another matter. Thus, the lower + levels provide the tools required to draw windows, handle user + input, allow drawing graphics using colors (or black and white + screens), etc. To this point, a decision was made to separate + the system into two parts. A client that decides what to do, and + a server that actually draws on the screen and reads user input + in order to send it to the client for processing. +

    +

    + This model is the complete opposite of what is used to when + dealing with clients and servers. In our case, the user sits + near the machine controlled by the server, while the client + might be running on a remote machine. The server controls the + screens, mouse and keyboard. A client may connect to the server, + request that it draws a window (or several windows), and ask the + server to send it any input the user sends to these + windows. Thus, several clients may connect to a single X server + (one might be running mail software, one running a WWW + browser, etc). When input is sent by the user to some window, + the server sends a message to the client controlling this window + for processing. The client decides what to do with this input, + and sends the server requests for drawing in the window. +

    +

    + The whole session is carried out using the X message + protocol. This protocol was originally carried over the TCP/IP + protocol suite, allowing the client to run on any machine + connected to the same network that the server is. Later on, the + X servers were extended to allow clients running on the local + machine with more optimized access to the server (note that an X + protocol message may be several hundreds of KB in size), such as + using shared memory, or using Unix domain sockets (a method for + creating a logical channel on a Unix system between two processes). +

    +
  3. GUI programming: the asynchronous model +

    + Unlike conventional computer programs, that carry some serial + nature, a GUI program usually uses an asynchronous programming + model, also known as "event-driven programming". This means that + that program mostly sits idle, waiting for events sent by the X + server, and then acts upon these events. An event may say "The + user pressed the 1st button mouse in spot (x,y)", or "The window + you control needs to be redrawn". In order for the program to be + responsive to the user input, as well as to refresh requests, it + needs to handle each event in a rather short period of time + (e.g. less that 200 milliseconds, as a rule of thumb). +

    +

    + This also implies that the program may not perform operations + that might take a long time while handling an event (such as + opening a network connection to some remote server, or + connecting to a database server, or even performing a long file + copy operation). Instead, it needs to perform all these + operations in an asynchronous manner. This may be done by using + various asynchronous models to perform the longish operations, + or by performing them in a different process or thread. +

    +

    + So the way a GUI program looks is something like that: +

    +
      +
    1. Perform initialization routines. +
    2. Connect to the X server. +
    3. Perform X-related initialization. +
    4. While not finished: +
        +
      1. Receive the next event from the X server. +
      2. Handle the event, possibly sending various drawing + requests to the X server. +
      3. If the event was a quit message, exit the loop. +
      +
    5. Close down the connection to the X server. +
    6. Perform cleanup operations. +
    +
    +
  4. Basic XCB notions +

    + XCB has been created to eliminate the need for + programs to actually implement the X protocol layer. This + library gives a program a very low-level access to any X + server. Since the protocol is standardized, a client using any + implementation of XCB may talk with any X server (the same + occurs for Xlib, of course). We now give a brief description of + the basic XCB notions. They will be detailed later. +

    +
      +
    1. The X Connection +

      + The major notion of using XCB is the X Connection. This is a + structure representing the connection we have open with a + given X server. It hides a queue of messages coming from the + server, and a queue of pending requests that our client + intends to send to the server. In XCB, this structure is named + 'xcb_connection_t'. It is analogous to the Xlib Display. + When we open a connection to an X server, the + library returns a pointer to such a structure. Later, we + supply this pointer to any XCB function that should send + messages to the X server or receive messages from this server. +

      +
    2. Requests and + replies: the Xlib killers +

      + To ask for information from the X server, we have to make a request + and ask for a reply. With Xlib, these two tasks are + automatically done: Xlib locks the system, sends a request, + waits for a reply from the X server and unlocks. This is + annoying, especially if one makes a lot of requests to the X + server. Indeed, Xlib has to wait for the end of a reply + before asking for the next request (because of the locks that + Xlib sends). For example, here is a time-line of N=4 + requests/replies with Xlib, with a round-trip latency + T_round_trip that is 5 times long as the time required + to write or read a request/reply (T_write/T_read): +

      +
      +  W-----RW-----RW-----RW-----R
      +
      +
        +
      • W: Writing request +
      • -: Stalled, waiting for data +
      • R: Reading reply +
      +

      + The total time is N * (T_write + T_round_trip + T_read). +

      +

      + With XCB, we can suppress most of the round-trips as the + requests and the replies are not locked. We usually send a + request, then XCB returns to us a cookie, which is an + identifier. Then, later, we ask for a reply using this + cookie and XCB returns a + pointer to that reply. Hence, with XCB, we can send a lot of + requests, and later in the program, ask for all the replies + when we need them. Here is the time-line for 4 + requests/replies when we use this property of XCB: +

      +
      +  WWWW--RRRR
      +
      +

      + The total time is N * T_write + max (0, T_round_trip - (N-1) * + T_write) + N * T_read. Which can be considerably faster than + all those Xlib round-trips. +

      +

      + Here is a program that computes the time to create 500 atoms + with Xlib and XCB. It shows the Xlib way, the bad XCB way + (which is similar to Xlib) and the good XCB way. On my + computer, XCB is 25 times faster than Xlib. +

      +
      +#include <stdlib.h>
      +#include <stdio.h>
      +#include <string.h>
      +#include <sys/time.h>
      +
      +#include <xcb/xcb.h>
      +
      +#include <X11/Xlib.h>
      +
      +double
      +get_time(void)
      +{
      +  struct timeval timev;
      +
      +  gettimeofday(&timev, NULL);
      +
      +  return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
      +}
      +
      +int
      +main ()
      +{
      +  xcb_connection_t         *c;
      +  xcb_atom_t               *atoms;
      +  xcb_intern_atom_cookie_t *cs;
      +  char                    **names;
      +  int                       count;
      +  int                       i;
      +  double                    start;
      +  double                    end;
      +  double                    diff;
      +
      +  /* Xlib */
      +  Display *disp;
      +  Atom    *atoms_x;
      +  double   diff_x;
      +
      +  c = xcb_connect (NULL, NULL);
      +
      +  count = 500;
      +  atoms = (xcb_atom_t *)malloc (count * sizeof (atoms));
      +  names = (char **)malloc (count * sizeof (char *));
      +
      +  /* init names */
      +  for (i = 0; i < count; ++i) {
      +    char buf[100];
      +
      +    sprintf (buf, "NAME%d", i);
      +    names[i] = strdup (buf);
      +  }
      +
      +  /* bad use */
      +  start = get_time ();
      +
      +  for (i = 0; i < count; ++i)
      +    atoms[i] = xcb_intern_atom_reply (c,
      +                                      xcb_intern_atom (c,
      +                                                       0,
      +                                                       strlen(names[i]),
      +                                                       names[i]),
      +                                      NULL)->atom;
      +
      +  end = get_time ();
      +  diff = end - start;
      +  printf ("bad use time  : %f\n", diff);
      +
      +  /* good use */
      +  start = get_time ();
      +
      +  cs = (xcb_intern_atom_cookie_t *) malloc (count * sizeof(xcb_intern_atom_cookie_t));
      +  for(i = 0; i < count; ++i)
      +    cs[i] = xcb_intern_atom (c, 0, strlen(names[i]), names[i]);
      +
      +  for(i = 0; i < count; ++i) {
      +    xcb_intern_atom_reply_t *r;
      +
      +    r = xcb_intern_atom_reply(c, cs[i], 0);
      +    if(r)
      +      atoms[i] = r->atom;
      +    free(r);
      +  }
      +
      +  end = get_time ();
      +  printf ("good use time : %f\n", end - start);
      +  printf ("ratio         : %f\n", diff / (end - start));
      +  diff = end - start;
      +
      +  /* free var */
      +  free (atoms);
      +  free (cs);
      +
      +  xcb_disconnect (c);
      +
      +  /* Xlib */
      +  disp = XOpenDisplay (getenv("DISPLAY"));
      +
      +  atoms_x = (Atom *)malloc (count * sizeof (atoms_x));
      +
      +  start = get_time ();
      +
      +  for (i = 0; i < count; ++i)
      +    atoms_x[i] = XInternAtom(disp, names[i], 0);
      +
      +  end = get_time ();
      +  diff_x = end - start;
      +  printf ("Xlib use time : %f\n", diff_x);
      +  printf ("ratio         : %f\n", diff_x / diff);
      +
      +  free (atoms_x);
      +  for (i = 0; i < count; ++i)
      +    free (names[i]);
      +  free (names);
      +
      +  XCloseDisplay (disp);
      +
      +  return 0;
      +}
      +
      +
    3. The Graphic Context +

      + When we perform various drawing operations (graphics, text, + etc), we may specify various options for controlling how the + data will be drawn (what foreground and background colors to + use, how line edges will be connected, what font to use when + drawing some text, etc). In order to avoid the need to supply + hundreds of parameters to each drawing function, a graphical + context structure is used. We set the various drawing options + in this structure, and then we pass a pointer to this + structure to any drawing routines. This is rather handy, as we + often need to perform several drawing requests with the same + options. Thus, we would initialize a graphical context, set + the desired options, and pass this structure to all drawing + functions. +

      +

      + Note that graphic contexts have no client-side structure in + XCB, they're just XIDs. Xlib has a client-side structure + because it caches the GC contents so it can avoid making + redundant requests, but of course XCB doesn't do that. +

      +
    4. Events +

      + A structure is used to pass events received from the X + server. XCB supports exactly the events specified in the + protocol (33 events). This structure contains the type + of event received (including a bit for whether it came + from the server or another client), as well as the data associated with the + event (e.g. position on the screen where the event was + generated, mouse button associated with the event, region of + the screen associated with a "redraw" event, etc). The way to + read the event's data depends on the event type. +

      +
    +
    +
  5. Using XCB-based programs +
    +
      +
    1. Installation of XCB +

      + TODO: These instructions are out of date. + Just reference the main XCB page + so we don't have to maintain these instructions in more than + one place. +

      +

      + To build XCB from source, you need to have installed at + least: +

      + +

      + You have to checkout in the git repository the following modules: +

      +
        +
      • Xau from xlibs +
      • xcb-proto +
      • xcb +
      +

      + Note that xcb-proto exists only to install header + files, so typing 'make' or 'make all' will produce the message + "Nothing to be done for 'all'". That's normal. +

      +
    2. Compiling XCB-based programs +

      + Compiling XCB-based programs requires linking them with the XCB + library. This is easily done thanks to pkgconfig: +

      +
      +gcc -Wall prog.c -o prog `pkg-config --cflags --libs xcb`
      +
      +
    +
  6. Opening and closing the connection to an X server +

    + An X program first needs to open the connection to the X + server. There is a function that opens a connection. It requires + the display name, or NULL. In the latter case, the display name + will be the one in the environment variable DISPLAY. +

    +
    +xcb_connection_t *xcb_connect (const char *displayname,
    +                               int        *screenp);
    +
    +

    + The second parameter returns the screen number used for the + connection. The returned structure describes an XCB connection + and is opaque. Here is how the connection can be opened: +

    +
    +#include <xcb/xcb.h>
    +
    +int
    +main ()
    +{
    +  xcb_connection_t *c;
    +
    +  /* Open the connection to the X server. Use the DISPLAY environment variable as the default display name */
    +  c = xcb_connect (NULL, NULL);
    +
    +  return 0;
    +}
    +
    +

    + To close a connection, it suffices to use: +

    +
    +void xcb_disconnect (xcb_connection_t *c);
    +
    +
    +
    + Comparison Xlib/XCB +
    +
    +
      +
    • XOpenDisplay () +
    +
    +
    +
      +
    • xcb_connect () +
    +
    +
    +
      +
    • XCloseDisplay () +
    +
    +
    +
      +
    • xcb_disconnect () +
    +
    +
    +
    +
  7. Checking basic information about a connection +

    + Once we have opened a connection to an X server, we should check some + basic information about it: what screens it has, what is the + size (width and height) of the screen, how many colors it + supports (black and white ? grey scale ?, 256 colors ? more ?), + and so on. We get such information from the xcb_screen_t + structure: +

    +
    +typedef struct {
    +    xcb_window_t   root;
    +    xcb_colormap_t default_colormap;
    +    uint32_t       white_pixel;
    +    uint32_t       black_pixel;
    +    uint32_t       current_input_masks;
    +    uint16_t       width_in_pixels;
    +    uint16_t       height_in_pixels;
    +    uint16_t       width_in_millimeters;
    +    uint16_t       height_in_millimeters;
    +    uint16_t       min_installed_maps;
    +    uint16_t       max_installed_maps;
    +    xcb_visualid_t root_visual;
    +    uint8_t        backing_stores;
    +    uint8_t        save_unders;
    +    uint8_t        root_depth;
    +    uint8_t        allowed_depths_len;
    +} xcb_screen_t;
    +
    +

    + We could retrieve the first screen of the connection by using the + following function: +

    +
    +xcb_screen_iterator_t xcb_setup_roots_iterator (xcb_setup_t *R);
    +
    +

    + Here is a small program that shows how to use this function: +

    +
    +#include <stdio.h>
    +
    +#include <xcb/xcb.h>
    +
    +int
    +main ()
    +{
    +  xcb_connection_t     *c;
    +  xcb_screen_t         *screen;
    +  int                   screen_nbr;
    +  xcb_screen_iterator_t iter;
    +
    +  /* Open the connection to the X server. Use the DISPLAY environment variable */
    +  c = xcb_connect (NULL, &screen_nbr);
    +
    +  /* Get the screen #screen_nbr */
    +  iter = xcb_setup_roots_iterator (xcb_get_setup (c));
    +  for (; iter.rem; --screen_nbr, xcb_screen_next (&iter))
    +    if (screen_nbr == 0) {
    +      screen = iter.data;
    +      break;
    +    }
    +
    +  printf ("\n");
    +  printf ("Informations of screen %ld:\n", screen->root);
    +  printf ("  width.........: %d\n", screen->width_in_pixels);
    +  printf ("  height........: %d\n", screen->height_in_pixels);
    +  printf ("  white pixel...: %ld\n", screen->white_pixel);
    +  printf ("  black pixel...: %ld\n", screen->black_pixel);
    +  printf ("\n");
    +
    +  return 0;
    +}
    +
    +
  8. Creating a basic window - the "hello world" program +

    + After we got some basic information about our screen, we can + create our first window. In the X Window System, a window is + characterized by an Id. So, in XCB, a window is of type: +

    +
    +typedef uint32_t xcb_window_t;
    +
    +

    + We first ask for a new Id for our window, with this function: +

    +
    +xcb_window_t xcb_generate_id(xcb_connection_t *c);
    +
    +

    + Then, XCB supplies the following function to create new windows: +

    +
    +xcb_void_cookie_t xcb_create_window (xcb_connection_t *c,             /* Pointer to the xcb_connection_t structure */
    +                                     uint8_t           depth,         /* Depth of the screen */
    +                                     xcb_window_t      wid,           /* Id of the window */
    +                                     xcb_window_t      parent,        /* Id of an existing window that should be the parent of the new window */
    +                                     int16_t           x,             /* X position of the top-left corner of the window (in pixels) */
    +                                     int16_t           y,             /* Y position of the top-left corner of the window (in pixels) */
    +                                     uint16_t          width,         /* Width of the window (in pixels) */
    +                                     uint16_t          height,        /* Height of the window (in pixels) */
    +                                     uint16_t          border_width,  /* Width of the window's border (in pixels) */
    +                                     uint16_t          _class,
    +                                     xcb_visualid_t    visual,
    +                                     uint32_t          value_mask,
    +                                     const uint32_t   *value_list);
    +
    +

    + The fact that we created the window does not mean that it will + be drawn on screen. By default, newly created windows are not + mapped on the screen (they are invisible). In order to make our + window visible, we use the function xcb_map_window(), whose + prototype is +

    +
    +xcb_void_cookie_t xcb_map_window (xcb_connection_t *c,
    +                                  xcb_window_t      window);
    +
    +

    + Finally, here is a small program to create a window of size + 150x150 pixels, positioned at the top-left corner of the screen: +

    +
    +#include <unistd.h>      /* pause() */
    +
    +#include <xcb/xcb.h>
    +
    +int
    +main ()
    +{
    +  xcb_connection_t *c;
    +  xcb_screen_t     *screen;
    +  xcb_window_t      win;
    +
    +  /* Open the connection to the X server */
    +  c = xcb_connect (NULL, NULL);
    +
    +  /* Get the first screen */
    +  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
    +
    +  /* Ask for our window's Id */
    +  win = xcb_generate_id(c);
    +
    +  /* Create the window */
    +  xcb_create_window (c,                             /* Connection          */
    +                     XCB_COPY_FROM_PARENT,          /* depth (same as root)*/
    +                     win,                           /* window Id           */
    +                     screen->root,                  /* parent window       */
    +                     0, 0,                          /* x, y                */
    +                     150, 150,                      /* width, height       */
    +                     10,                            /* border_width        */
    +                     XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
    +                     screen->root_visual,           /* visual              */
    +                     0, NULL);                      /* masks, not used yet */
    +
    +  /* Map the window on the screen */
    +  xcb_map_window (c, win);
    +
    +  /* Make sure commands are sent before we pause, so window is shown */
    +  xcb_flush (c);
    +
    +  pause ();    /* hold client until Ctrl-C */
    +
    +  return 0;
    +}
    +
    +

    + In this code, you see one more function - xcb_flush(), not explained + yet. It is used to flush all the pending requests. More + precisely, there are 2 functions that do such things. The first + one is xcb_flush(): +

    +
    +int xcb_flush (xcb_connection_t *c);
    +
    +

    + This function flushes all pending requests to the X server (much + like the fflush() function is used to + flush standard output). The second function is + xcb_aux_sync(): +

    +
    +int xcb_aux_sync (xcb_connection_t *c);
    +
    +

    + This functions also flushes all pending requests to the X + server, and then waits until the X server finishing processing + these requests. In a normal program, this will not be necessary + (we'll see why when we get to write a normal X program), but for + now, we put it there. +

    +

    + The window that is created by the above code has a non defined + background. This one can be set to a specific color, + thanks to the two last parameters of + xcb_create_window(), which are not + described yet. See the subsections + Configuring a window or + Registering for event types using event masks + for examples on how to use these parameters. In addition, as no + events are handled, you have to make a Ctrl-C to interrupt the + program. +

    +

    + TODO: one should tell what these functions return and + about the generic error +

    +
    +
    + Comparison Xlib/XCB +
    +
    +
      +
    • XCreateWindow () +
    +
    +
    +
      +
    • xcb_generate_id () +
    • xcb_create_window () +
    +
    +
    +
    +
  9. Drawing in a window +

    + Drawing in a window can be done using various graphical + functions (drawing pixels, lines, rectangles, etc). In order to + draw in a window, we first need to define various general + drawing parameters (what line width to use, which color to draw + with, etc). This is done using a graphical context. +

    +
      +
    1. Allocating a Graphics Context +

      + As we said, a graphical context defines several attributes to + be used with the various drawing functions. For this, we + define a graphical context. We can use more than one graphical + context with a single window, in order to draw in multiple + styles (different colors, different line widths, etc). In XCB, + a Graphics Context is, as a window, characterized by an Id: +

      +
      +typedef uint32_t xcb_gcontext_t;
      +
      +

      + We first ask the X server to attribute an Id to our graphic + context with this function: +

      +
      +xcb_gcontext_t xcb_generate_id (xcb_connection_t *c);
      +
      +

      + Then, we set the attributes of the graphic context with this function: +

      +
      +xcb_void_cookie_t xcb_create_gc (xcb_connection_t *c,
      +                                 xcb_gcontext_t    cid,
      +                                 xcb_drawable_t    drawable,
      +                                 uint32_t          value_mask,
      +                                 const uint32_t   *value_list);
      +
      +

      + We give now an example on how to allocate a graphic context + that specifies that each drawing function that uses it will + draw in foreground with a black color. +

      +
      +#include <xcb/xcb.h>
      +
      +int
      +main ()
      +{
      +  xcb_connection_t *c;
      +  xcb_screen_t     *screen;
      +  xcb_drawable_t    win;
      +  xcb_gcontext_t    black;
      +  uint32_t          mask;
      +  uint32_t          value[1];
      +
      +  /* Open the connection to the X server and get the first screen */
      +  c = xcb_connect (NULL, NULL);
      +  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      +
      +  /* Create a black graphic context for drawing in the foreground */
      +  win = screen->root;
      +  black = xcb_generate_id (c);
      +  mask = XCB_GC_FOREGROUND;
      +  value[0] = screen->black_pixel;
      +  xcb_create_gc (c, black, win, mask, value);
      +
      +  return 0;
      +}
      +
      +

      + Note should be taken regarding the role of "value_mask" and + "value_list" in the prototype of xcb_create_gc(). Since a + graphic context has many attributes, and since we often just + want to define a few of them, we need to be able to tell the + xcb_create_gc() which attributes we + want to set. This is what the "value_mask" parameter is + for. We then use the "value_list" parameter to specify actual + values for the attribute we defined in "value_mask". Thus, for + each constant used in "value_list", we will use the matching + constant in "value_mask". In this case, we define a graphic + context with one attribute: when drawing (a point, a line, + etc), the foreground color will be black. The rest of the + attributes of this graphic context will be set to their + default values. +

      +

      + See the next Subsection for more details. +

      +
      +
      + Comparison Xlib/XCB +
      +
      +
        +
      • XCreateGC () +
      +
      +
      +
        +
      • xcb_generate_id () +
      • xcb_create_gc () +
      +
      +
      +
      +
    2. Changing the attributes of a Graphics Context +

      + Once we have allocated a Graphic Context, we may need to + change its attributes (for example, changing the foreground + color we use to draw a line, or changing the attributes of the + font we use to display strings. See Subsections Drawing with a + color and + Assigning a Font to a Graphic Context). + This is done by using this function: +

      +
      +xcb_void_cookie_t xcb_change_gc (xcb_connection_t *c,           /* The XCB Connection */
      +                                 xcb_gcontext_t    gc,          /* The Graphic Context */
      +                                 uint32_t          value_mask,  /* Components of the Graphic Context that have to be set */
      +                                 const uint32_t   *value_list); /* Value as specified by value_mask */
      +
      +

      + The value_mask parameter could take + any combination of these masks from the xcb_gc_t enumeration: +

      +
        +
      • XCB_GC_FUNCTION +
      • XCB_GC_PLANE_MASK +
      • XCB_GC_FOREGROUND +
      • XCB_GC_BACKGROUND +
      • XCB_GC_LINE_WIDTH +
      • XCB_GC_LINE_STYLE +
      • XCB_GC_CAP_STYLE +
      • XCB_GC_JOIN_STYLE +
      • XCB_GC_FILL_STYLE +
      • XCB_GC_FILL_RULE +
      • XCB_GC_TILE +
      • XCB_GC_STIPPLE +
      • XCB_GC_TILE_STIPPLE_ORIGIN_X +
      • XCB_GC_TILE_STIPPLE_ORIGIN_Y +
      • XCB_GC_FONT +
      • XCB_GC_SUBWINDOW_MODE +
      • XCB_GC_GRAPHICS_EXPOSURES +
      • XCB_GC_CLIP_ORIGIN_X +
      • XCB_GC_CLIP_ORIGIN_Y +
      • XCB_GC_CLIP_MASK +
      • XCB_GC_DASH_OFFSET +
      • XCB_GC_DASH_LIST +
      • XCB_GC_ARC_MODE +
      +

      + It is possible to set several attributes at the same + time (for example setting the attributes of a font and the + color which will be used to display a string), by OR'ing these + values in value_mask. Then + value_list has to be an array which + lists the value for the respective attributes. These values + must be in the same order as masks listed above. See Subsection + Drawing with a color to have an example. +

      +

      + TODO: set the links of the 3 subsections, once they will + be written :) +

      +

      + TODO: give an example which sets several attributes. +

      +
    3. Drawing primitives: point, line, box, circle,... +

      + After we have created a Graphic Context, we can draw on a + window using this Graphic Context, with a set of XCB + functions, collectively called "drawing primitives". Let see + how they are used. +

      +

      + To draw a point, or several points, we use +

      +
      +xcb_void_cookie_t xcb_poly_point (xcb_connection_t  *c,               /* The connection to the X server */
      +                                  uint8_t            coordinate_mode, /* Coordinate mode, usually set to XCB_COORD_MODE_ORIGIN */
      +                                  xcb_drawable_t     drawable,        /* The drawable on which we want to draw the point(s) */
      +                                  xcb_gcontext_t     gc,              /* The Graphic Context we use to draw the point(s) */
      +                                  uint32_t           points_len,      /* The number of points */
      +                                  const xcb_point_t *points);         /* An array of points */
      +
      +

      + The coordinate_mode parameter + specifies the coordinate mode. Available values are +

      +
        +
      • XCB_COORD_MODE_ORIGIN +
      • XCB_COORD_MODE_PREVIOUS +
      +

      + If XCB_COORD_MODE_PREVIOUS is used, then all points but the first one + are relative to the immediately previous point. +

      +

      + The xcb_point_t type is just a + structure with two fields (the coordinates of the point): +

      +
      +typedef struct {
      +    int16_t x;
      +    int16_t y;
      +} xcb_point_t;
      +
      +

      + You could see an example in xpoints.c. TODO Set the link. +

      +

      + To draw a line, or a polygonal line, we use +

      +
      +xcb_void_cookie_t xcb_poly_line (xcb_connection_t  *c,               /* The connection to the X server */
      +                                 uint8_t            coordinate_mode, /* Coordinate mode, usually set to XCB_COORD_MODE_ORIGIN */
      +                                 xcb_drawable_t     drawable,        /* The drawable on which we want to draw the line(s) */
      +                                 xcb_gcontext_t     gc,              /* The Graphic Context we use to draw the line(s) */
      +                                 uint32_t           points_len,      /* The number of points in the polygonal line */
      +                                 const xcb_point_t *points);         /* An array of points */
      +
      +

      + This function will draw the line between the first and the + second points, then the line between the second and the third + points, and so on. +

      +

      + To draw a segment, or several segments, we use +

      +
      +xcb_void_cookie_t xcb_poly_segment (xcb_connection_t    *c,              /* The connection to the X server */
      +                                    xcb_drawable_t       drawable,       /* The drawable on which we want to draw the segment(s) */
      +                                    xcb_gcontext_t       gc,             /* The Graphic Context we use to draw the segment(s) */
      +                                    uint32_t             segments_len,   /* The number of segments */
      +                                    const xcb_segment_t *segments);      /* An array of segments */
      +
      +

      + The xcb_segment_t type is just a + structure with four fields (the coordinates of the two points + that define the segment): +

      +
      +typedef struct {
      +    int16_t x1;
      +    int16_t y1;
      +    int16_t x2;
      +    int16_t y2;
      +} xcb_segment_t;
      +
      +

      + To draw a rectangle, or several rectangles, we use +

      +
      +xcb_void_cookie_t xcb_poly_rectangle (xcb_connection_t      *c,              /* The connection to the X server */
      +                                      xcb_drawable_t         drawable,       /* The drawable on which we want to draw the rectangle(s) */
      +                                      xcb_gcontext_t         gc,             /* The Graphic Context we use to draw the rectangle(s) */
      +                                      uint32_t               rectangles_len, /* The number of rectangles */
      +                                      const xcb_rectangle_t *rectangles);    /* An array of rectangles */
      +
      +

      + The xcb_rectangle_t type is just a + structure with four fields (the coordinates of the top-left + corner of the rectangle, and its width and height): +

      +
      +typedef struct {
      +    int16_t  x;
      +    int16_t  y;
      +    uint16_t width;
      +    uint16_t height;
      +} xcb_rectangle_t;
      +
      + + +

      + To draw an elliptical arc, or several elliptical arcs, we use +

      +
      +xcb_void_cookie_t xcb_poly_arc (xcb_connection_t *c,          /* The connection to the X server */
      +                                xcb_drawable_t    drawable,   /* The drawable on which we want to draw the arc(s) */
      +                                xcb_gcontext_t    gc,         /* The Graphic Context we use to draw the arc(s) */
      +                                uint32_t          arcs_len,   /* The number of arcs */
      +                                const xcb_arc_t  *arcs);      /* An array of arcs */
      +
      +

      + The xcb_arc_t type is a structure with + six fields: +

      +
      +typedef struct {
      +    int16_t  x;       /* Top left x coordinate of the rectangle surrounding the ellipse */
      +    int16_t  y;       /* Top left y coordinate of the rectangle surrounding the ellipse */
      +    uint16_t width;   /* Width of the rectangle surrounding the ellipse */
      +    uint16_t height;  /* Height of the rectangle surrounding the ellipse */
      +    int16_t  angle1;  /* Angle at which the arc begins */
      +    int16_t  angle2;  /* Angle at which the arc ends */
      +} xcb_arc_t;
      +
      +
      +

      + Note: the angles are expressed in units of 1/64 of a degree, + so to have an angle of 90 degrees, starting at 0, + angle1 = 0 and + angle2 = 90 << 6. Positive angles + indicate counterclockwise motion, while negative angles + indicate clockwise motion. +

      +
      + + +

      + The corresponding function which fill inside the geometrical + object are listed below, without further explanation, as they + are used as the above functions. +

      +

      + To Fill a polygon defined by the points given as arguments , + we use +

      +
      +xcb_void_cookie_t xcb_fill_poly (xcb_connection_t  *c,
      +                                 xcb_drawable_t     drawable,
      +                                 xcb_gcontext_t     gc,
      +                                 uint8_t            shape,
      +                                 uint8_t            coordinate_mode,
      +                                 uint32_t           points_len,
      +                                 const xcb_point_t *points);
      +
      +

      + The shape parameter specifies a + shape that helps the server to improve performance. Available + values are +

      +
        +
      • XCB_POLY_SHAPE_COMPLEX +
      • XCB_POLY_SHAPE_NONCONVEX +
      • XCB_POLY_SHAPE_CONVEX +
      +

      + To fill one or several rectangles, we use +

      +
      +xcb_void_cookie_t xcb_poly_fill_rectangle (xcb_connection_t      *c,
      +                                           xcb_drawable_t         drawable,
      +                                           xcb_gcontext_t         gc,
      +                                           uint32_t               rectangles_len,
      +                                           const xcb_rectangle_t *rectangles);
      +
      +

      + To fill one or several arcs, we use +

      +
      +xcb_void_cookie_t xcb_poly_fill_arc (xcb_connection_t *c,
      +                                     xcb_drawable_t    drawable,
      +                                     xcb_gcontext_t    gc,
      +                                     uint32_t          arcs_len,
      +                                     const xcb_arc_t  *arcs);
      +
      +
      + +

      + To illustrate these functions, here is an example that draws + four points, a polygonal line, two segments, two rectangles + and two arcs. Remark that we use events for the first time, as + an introduction to the next section. +

      +

      + TODO: Use screen->root_depth for depth parameter. +

      +
      +#include <stdlib.h>
      +#include <stdio.h>
      +
      +#include <xcb/xcb.h>
      +
      +int
      +main ()
      +{
      +  xcb_connection_t    *c;
      +  xcb_screen_t        *screen;
      +  xcb_drawable_t       win;
      +  xcb_gcontext_t       foreground;
      +  xcb_generic_event_t *e;
      +  uint32_t             mask = 0;
      +  uint32_t             values[2];
      +
      +  /* geometric objects */
      +  xcb_point_t          points[] = {
      +    {10, 10},
      +    {10, 20},
      +    {20, 10},
      +    {20, 20}};
      +
      +  xcb_point_t          polyline[] = {
      +    {50, 10},
      +    { 5, 20},     /* rest of points are relative */
      +    {25,-20},
      +    {10, 10}};
      +
      +  xcb_segment_t        segments[] = {
      +    {100, 10, 140, 30},
      +    {110, 25, 130, 60}};
      +
      +  xcb_rectangle_t      rectangles[] = {
      +    { 10, 50, 40, 20},
      +    { 80, 50, 10, 40}};
      +
      +  xcb_arc_t            arcs[] = {
      +    {10, 100, 60, 40, 0, 90 << 6},
      +    {90, 100, 55, 40, 0, 270 << 6}};
      +
      +  /* Open the connection to the X server */
      +  c = xcb_connect (NULL, NULL);
      +
      +  /* Get the first screen */
      +  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      +
      +  /* Create black (foreground) graphic context */
      +  win = screen->root;
      +
      +  foreground = xcb_generate_id (c);
      +  mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
      +  values[0] = screen->black_pixel;
      +  values[1] = 0;
      +  xcb_create_gc (c, foreground, win, mask, values);
      +
      +  /* Ask for our window's Id */
      +  win = xcb_generate_id(c);
      +
      +  /* Create the window */
      +  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
      +  values[0] = screen->white_pixel;
      +  values[1] = XCB_EVENT_MASK_EXPOSURE;
      +  xcb_create_window (c,                             /* Connection          */
      +                     XCB_COPY_FROM_PARENT,          /* depth               */
      +                     win,                           /* window Id           */
      +                     screen->root,                  /* parent window       */
      +                     0, 0,                          /* x, y                */
      +                     150, 150,                      /* width, height       */
      +                     10,                            /* border_width        */
      +                     XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
      +                     screen->root_visual,           /* visual              */
      +                     mask, values);                 /* masks */
      +
      +  /* Map the window on the screen */
      +  xcb_map_window (c, win);
      +
      +
      +  /* We flush the request */
      +  xcb_flush (c);
      +
      +  while ((e = xcb_wait_for_event (c))) {
      +    switch (e->response_type & ~0x80) {
      +    case XCB_EXPOSE: {
      +      /* We draw the points */
      +      xcb_poly_point (c, XCB_COORD_MODE_ORIGIN, win, foreground, 4, points);
      +
      +      /* We draw the polygonal line */
      +      xcb_poly_line (c, XCB_COORD_MODE_PREVIOUS, win, foreground, 4, polyline);
      +
      +      /* We draw the segements */
      +      xcb_poly_segment (c, win, foreground, 2, segments);
      +
      +      /* We draw the rectangles */
      +      xcb_poly_rectangle (c, win, foreground, 2, rectangles);
      +
      +      /* We draw the arcs */
      +      xcb_poly_arc (c, win, foreground, 2, arcs);
      +
      +      /* We flush the request */
      +      xcb_flush (c);
      +
      +      break;
      +    }
      +    default: {
      +      /* Unknown event type, ignore it */
      +      break;
      +    }
      +    }
      +    /* Free the Generic Event */
      +    free (e);
      +  }
      +
      +  return 0;
      +}
      +
      +
    +
  10. X Events +

    + In an X program, everything is driven by events. Event painting + on the screen is sometimes done as a response to an event (an + Expose event). If part of a program's + window that was hidden, gets exposed (e.g. the window was raised + above other widows), the X server will send an "expose" event to + let the program know it should repaint that part of the + window. User input (key presses, mouse movement, etc) is also + received as a set of events. +

    +
      +
    1. Registering for event types using event masks +

      + During the creation of a window, you should give it what kind + of events it wishes to receive. Thus, you may register for + various mouse (also called pointer) events, keyboard events, + expose events, and so on. This is done for optimizing the + server-to-client connection (i.e. why send a program (that + might even be running at the other side of the globe) an event + it is not interested in ?) +

      +

      + In XCB, you use the "value_mask" and "value_list" data in the + xcb_create_window() function to + register for events. Here is how we register for + Expose event when creating a window: +

      +
      +  mask = XCB_CW_EVENT_MASK;
      +  valwin[0] = XCB_EVENT_MASK_EXPOSURE;
      +  win = xcb_generate_id (c);
      +  xcb_create_window (c, depth, win, root->root,
      +                     0, 0, 150, 150, 10,
      +                     XCB_WINDOW_CLASS_INPUT_OUTPUT, root->root_visual,
      +                     mask, valwin);
      +
      +

      + XCB_EVENT_MASK_EXPOSURE is a constant defined + in the xcb_event_mask_t enumeration in the "xproto.h" header file. If we wanted to register for several + event types, we can logically "or" them, as follows: +

      +
      +  mask = XCB_CW_EVENT_MASK;
      +  valwin[0] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS;
      +  win = xcb_generate_id (c);
      +  xcb_create_window (c, depth, win, root->root,
      +                     0, 0, 150, 150, 10,
      +                     XCB_WINDOW_CLASS_INPUT_OUTPUT, root->root_visual,
      +                     mask, valwin);
      +
      +

      + This registers for Expose events as + well as for mouse button presses inside the created + window. You should note that a mask may represent several + event sub-types. +

      +

      + The values that a mask could take are given + by the xcb_cw_t enumeration: +

      +
      +typedef enum {
      +    XCB_CW_BACK_PIXMAP       = 1L<<0,
      +    XCB_CW_BACK_PIXEL        = 1L<<1,
      +    XCB_CW_BORDER_PIXMAP     = 1L<<2,
      +    XCB_CW_BORDER_PIXEL      = 1L<<3,
      +    XCB_CW_BIT_GRAVITY       = 1L<<4,
      +    XCB_CW_WIN_GRAVITY       = 1L<<5,
      +    XCB_CW_BACKING_STORE     = 1L<<6,
      +    XCB_CW_BACKING_PLANES    = 1L<<7,
      +    XCB_CW_BACKING_PIXEL     = 1L<<8,
      +    XCB_CW_OVERRIDE_REDIRECT = 1L<<9,
      +    XCB_CW_SAVE_UNDER        = 1L<<10,
      +    XCB_CW_EVENT_MASK        = 1L<<11,
      +    XCB_CW_DONT_PROPAGATE    = 1L<<12,
      +    XCB_CW_COLORMAP          = 1L<<13,
      +    XCB_CW_CURSOR            = 1L<<14
      +} xcb_cw_t;
      +
      +
      +

      Note: we must be careful when setting the values of the valwin + parameter, as they have to follow the order the + xcb_cw_t enumeration. Here is an + example: +

      +
      +
      +  mask = XCB_CW_EVENT_MASK | XCB_CW_BACK_PIXMAP;
      +  valwin[0] = XCB_NONE;                                              /* for XCB_CW_BACK_PIXMAP (whose value is 1)     */
      +  valwin[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS; /* for XCB_CW_EVENT_MASK, whose value (2048)     */
      +                                                                     /* is greater than the one of XCB_CW_BACK_PIXMAP */
      +
      +

      + If the window has already been created, we can use the + xcb_change_window_attributes() function to set + the events that the window will receive. The subsection + Configuring a window shows its + prototype. As an example, here is a piece of code that + configures the window to receive the + Expose and + ButtonPress events: +

      +
      +const static uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTTON_PRESS };
      +
      +/* The connection c and the window win are supposed to be defined */
      +
      +xcb_change_window_attributes (c, win, XCB_CW_EVENT_MASK, values);
      +
      +
      +

      + Note: A common bug programmers do is adding code to handle new + event types in their program, while forgetting to add the + masks for these events in the creation of the window. Such a + programmer then should sit down for hours debugging his + program, wondering "Why doesn't my program notice that I + released the button?", only to find that they registered for + button press events but not for button release events. +

      +
      +
    2. Receiving events: writing the events loop +

      + After we have registered for the event types we are interested + in, we need to enter a loop of receiving events and handling + them. There are two ways to receive events: a blocking way and + a non-blocking way: +

      +
        +
      • + xcb_wait_for_event (xcb_connection_t *c) + is the blocking way. It waits (so blocks...) until an event is + queued in the X server. Then it retrieves it into a newly + allocated structure (it dequeues it from the queue) and returns + it. This structure has to be freed. The function returns + NULL if an error occurs. + +
        +
      • + xcb_poll_for_event (xcb_connection_t *c, int + *error) is the non-blocking way. It looks at the event + queue and returns (and dequeues too) an existing event into + a newly allocated structure. This structure has to be + freed. It returns NULL if there is + no event. If an error occurs, the parameter error will be filled with the error + status. +
      +

      + There are various ways to write such a loop. We present two + ways to write such a loop, with the two functions above. The + first one uses xcb_wait_for_event_t, which + is similar to an event Xlib loop using only XNextEvent: +

      +
      +  xcb_generic_event_t *e;
      +
      +  while ((e = xcb_wait_for_event (c))) {
      +    switch (e->response_type & ~0x80) {
      +    case XCB_EXPOSE: {
      +      /* Handle the Expose event type */
      +      xcb_expose_event_t *ev = (xcb_expose_event_t *)e;
      +
      +      /* ... */
      +
      +      break;
      +    }
      +    case XCB_BUTTON_PRESS: {
      +      /* Handle the ButtonPress event type */
      +      xcb_button_press_event_t *ev = (xcb_button_press_event_t *)e;
      +
      +      /* ... */
      +
      +      break;
      +    }
      +    default: {
      +      /* Unknown event type, ignore it */
      +      break;
      +    }
      +    }
      +    /* Free the Generic Event */
      +    free (e);
      +  }
      +
      +

      + You will certainly want to use xcb_poll_for_event(xcb_connection_t *c, int + *error) if, in Xlib, you use XPending or + XCheckMaskEvent: +

      +
      +  while (XPending (display)) {
      +    XEvent ev;
      +
      +    XNextEvent(d, &ev);
      +
      +    /* Manage your event */
      +  }
      +
      +

      + Such a loop in XCB looks like: +

      +
      +  xcb_generic_event_t *ev;
      +
      +  while ((ev = xcb_poll_for_event (conn, 0))) {
      +    /* Manage your event */
      +  }
      +
      +

      + The events are managed in the same way as with xcb_wait_for_event_t. + Obviously, we will need to give the user some way of + terminating the program. This is usually done by handling a + special "quit" event, as we will soon see. +

      +
      +
      + Comparison Xlib/XCB +
      +
      +
        +
      • XNextEvent () +
      +
      +
      +
        +
      • xcb_wait_for_event () +
      +
      +
      +
        +
      • XPending () +
      • XCheckMaskEvent () +
      +
      +
      +
        +
      • xcb_poll_for_event () +
      +
      +
      +
      +
    3. Expose events +

      + The Expose event is one of the most + basic (and most used) events an application may receive. It + will be sent to us in one of several cases: +

      +
        +
      • A window that covered part of our window has moved + away, exposing part (or all) of our window. +
      • Our window was raised above other windows. +
      • Our window mapped for the first time. +
      • Our window was de-iconified. +
      +

      + You should note the implicit assumption hidden here: the + contents of our window is lost when it is being obscured + (covered) by either windows. One may wonder why the X server + does not save this contents. The answer is: to save + memory. After all, the number of windows on a display at a + given time may be very large, and storing the contents of all + of them might require a lot of memory. Actually, there is a + way to tell the X server to store the contents of a window in + special cases, as we will see later. +

      +

      + When we get an Expose event, we + should take the event's data from the members of the following + structure: +

      +
      +typedef struct {
      +    uint8_t      response_type; /* The type of the event, here it is XCB_EXPOSE */
      +    uint8_t      pad0;
      +    uint16_t     sequence;
      +    xcb_window_t window;        /* The Id of the window that receives the event (in case */
      +                                /* our application registered for events on several windows */
      +    uint16_t     x;             /* The x coordinate of the top-left part of the window that needs to be redrawn */
      +    uint16_t     y;             /* The y coordinate of the top-left part of the window that needs to be redrawn */
      +    uint16_t     width;         /* The width of the part of the window that needs to be redrawn */
      +    uint16_t     height;        /* The height of the part of the window that needs to be redrawn */
      +    uint16_t     count;
      +} xcb_expose_event_t;
      +
      +
    4. Getting user input +

      + User input traditionally comes from two sources: the mouse + and the keyboard. Various event types exist to notify us of + user input (a key being presses on the keyboard, a key being + released on the keyboard, the mouse moving over our window, + the mouse entering (or leaving) our window, and so on. +

      +
        +
      1. Mouse button press and release events +

        + The first event type we will deal with is a mouse + button-press (or button-release) event in our window. In + order to register to such an event type, we should add one + (or more) of the following masks when we create our window: +

        +
          +
        • XCB_EVENT_MASK_BUTTON_PRESS: notify us + of any button that was pressed in one of our windows. +
        • XCB_EVENT_MASK_BUTTON_RELEASE: notify us + of any button that was released in one of our windows. +
        +

        + The structure to be checked for in our events loop is the + same for these two events, and is the following: +

        +
        +typedef struct {
        +    uint8_t         response_type; /* The type of the event, here it is xcb_button_press_event_t or xcb_button_release_event_t */
        +    xcb_button_t    detail;
        +    uint16_t        sequence;
        +    xcb_timestamp_t time;          /* Time, in milliseconds the event took place in */
        +    xcb_window_t    root;
        +    xcb_window_t    event;
        +    xcb_window_t    child;
        +    int16_t         root_x;
        +    int16_t         root_y;
        +    int16_t         event_x;       /* The x coordinate where the mouse has been pressed in the window */
        +    int16_t         event_y;       /* The y coordinate where the mouse has been pressed in the window */
        +    uint16_t        state;         /* A mask of the buttons (or keys) during the event */
        +    uint8_t         same_screen;
        +} xcb_button_press_event_t;
        +
        +typedef xcb_button_press_event_t xcb_button_release_event_t;
        +
        +

        + The time field may be used to calculate "double-click" + situations by an application (e.g. if the mouse button was + clicked two times in a duration shorter than a given amount + of time, assume this was a double click). +

        +

        + The state field is a mask of the buttons held down during + the event. It is a bitwise OR of any of the following (from the xcb_button_mask_t and + xcb_mod_mask_t enumerations): +

        +
          +
        • XCB_BUTTON_MASK_1 +
        • XCB_BUTTON_MASK_2 +
        • XCB_BUTTON_MASK_3 +
        • XCB_BUTTON_MASK_4 +
        • XCB_BUTTON_MASK_5 +
        • XCB_MOD_MASK_SHIFT +
        • XCB_MOD_MASK_LOCK +
        • XCB_MOD_MASK_CONTROL +
        • XCB_MOD_MASK_1 +
        • XCB_MOD_MASK_2 +
        • XCB_MOD_MASK_3 +
        • XCB_MOD_MASK_4 +
        • XCB_MOD_MASK_5 +
        +

        + Their names are self explanatory, where the first 5 refer to + the mouse buttons that are being pressed, while the rest + refer to various "special keys" that are being pressed (Mod1 + is usually the 'Alt' key or the 'Meta' key). +

        +

        + TODO: Problem: it seems that the state does not + change when clicking with various buttons. +

        +
      2. Mouse movement events +

        + Similar to mouse button press and release events, we also + can be notified of various mouse movement events. These can + be split into two families. One is of mouse pointer + movement while no buttons are pressed, and the second is a + mouse pointer motion while one (or more) of the buttons are + pressed (this is sometimes called "a mouse drag operation", + or just "dragging"). The following event masks may be added + during the creation of our window: +

        +
          +
        • XCB_EVENT_MASK_POINTER_MOTION: events of + the pointer moving in one of the windows controlled by our + application, while no mouse button is held pressed. +
        • XCB_EVENT_MASK_BUTTON_MOTION: Events of + the pointer moving while one or more of the mouse buttons + is held pressed. +
        • XCB_EVENT_MASK_BUTTON_1_MOTION: same as + XCB_EVENT_MASK_BUTTON_MOTION, but only when + the 1st mouse button is held pressed. +
        • XCB_EVENT_MASK_BUTTON_2_MOTION, + XCB_EVENT_MASK_BUTTON_3_MOTION, + XCB_EVENT_MASK_BUTTON_4_MOTION, + XCB_EVENT_MASK_BUTTON_5_MOTION: same as + XCB_EVENT_MASK_BUTTON_1_MOTION, but + respectively for 2nd, 3rd, 4th and 5th mouse button. +
        +

        + The structure to be checked for in our events loop is the + same for these events, and is the following: +

        +
        +typedef struct {
        +    uint8_t         response_type; /* The type of the event */
        +    uint8_t         detail;
        +    uint16_t        sequence;
        +    xcb_timestamp_t time;          /* Time, in milliseconds the event took place in */
        +    xcb_window_t    root;
        +    xcb_window_t    event;
        +    xcb_window_t    child;
        +    int16_t         root_x;
        +    int16_t         root_y;
        +    int16_t         event_x;       /* The x coordinate of the mouse when the  event was generated */
        +    int16_t         event_y;       /* The y coordinate of the mouse when the  event was generated */
        +    uint16_t        state;         /* A mask of the buttons (or keys) during the event */
        +    uint8_t         same_screen;
        +} xcb_motion_notify_event_t;
        +
        +
      3. Mouse pointer enter and leave events +

        + Another type of event that applications might be interested + in, is a mouse pointer entering a window the program + controls, or leaving such a window. Some programs use these + events to show the user that the application is now in + focus. In order to register for such an event type, we + should add one (or more) of the following masks when we + create our window: +

        +
          +
        • xcb_event_enter_window_t: notify us + when the mouse pointer enters any of our controlled + windows. +
        • xcb_event_leave_window_t: notify us + when the mouse pointer leaves any of our controlled + windows. +
        +

        + The structure to be checked for in our events loop is the + same for these two events, and is the following: +

        +
        +typedef struct {
        +    uint8_t         response_type; /* The type of the event */
        +    uint8_t         detail;
        +    uint16_t        sequence;
        +    xcb_timestamp_t time;          /* Time, in milliseconds the event took place in */
        +    xcb_window_t    root;
        +    xcb_window_t    event;
        +    xcb_window_t    child;
        +    int16_t         root_x;
        +    int16_t         root_y;
        +    int16_t         event_x;       /* The x coordinate of the mouse when the  event was generated */
        +    int16_t         event_y;       /* The y coordinate of the mouse when the  event was generated */
        +    uint16_t        state;         /* A mask of the buttons (or keys) during the event */
        +    uint8_t         mode;          /* The number of mouse button that was clicked */
        +    uint8_t         same_screen_focus;
        +} xcb_enter_notify_event_t;
        +
        +typedef xcb_enter_notify_event_t xcb_leave_notify_event_t;
        +
        +
      4. The keyboard focus +

        + There may be many windows on a screen, but only a single + keyboard attached to them. How does the X server then know + which window should be sent a given keyboard input ? This is + done using the keyboard focus. Only a single window on the + screen may have the keyboard focus at a given time. There + is a XCB function that allows a program to set the keyboard + focus to a given window. The user can usually set the + keyboard focus using the window manager (often by clicking + on the title bar of the desired window). Once our window + has the keyboard focus, every key press or key release will + cause an event to be sent to our program (if it regsitered + for these event types...). +

        +
      5. Keyboard press and release events +

        + If a window controlled by our program currently holds the + keyboard focus, it can receive key press and key release + events. So, we should add one (or more) of the following + masks when we create our window: +

        +
          +
        • XCB_EVENT_MASK_KEY_PRESS: notify us when + a key was pressed while any of our controlled windows had + the keyboard focus. +
        • XCB_EVENT_MASK_KEY_RELEASE: notify us + when a key was released while any of our controlled + windows had the keyboard focus. +
        +

        + The structure to be checked for in our events loop is the + same for these two events, and is the following: +

        +
        +typedef struct {
        +    uint8_t         response_type; /* The type of the event */
        +    xcb_keycode_t   detail;
        +    uint16_t        sequence;
        +    xcb_timestamp_t time;          /* Time, in milliseconds the event took place in */
        +    xcb_window_t    root;
        +    xcb_window_t    event;
        +    xcb_window_t    child;
        +    int16_t         root_x;
        +    int16_t         root_y;
        +    int16_t         event_x;
        +    int16_t         event_y;
        +    uint16_t        state;
        +    uint8_t         same_screen;
        +} xcb_key_press_event_t;
        +
        +typedef xcb_key_press_event_t xcb_key_release_event_t;
        +
        +

        + The detail field refers to the + physical key on the keyboard. +

        +

        + TODO: Talk about getting the ASCII code from the key code. +

        +
      +
    5. X events: a complete example +

      + As an example for handling events, we show a program that + creates a window, enters an events loop and checks for all the + events described above, and writes on the terminal the relevant + characteristics of the event. With this code, it should be + easy to add drawing operations, like those which have been + described above. +

      +
      +#include <stdlib.h>
      +#include <stdio.h>
      +
      +#include <xcb/xcb.h>
      +
      +void
      +print_modifiers (uint32_t mask)
      +{
      +  const char **mod, *mods[] = {
      +    "Shift", "Lock", "Ctrl", "Alt",
      +    "Mod2", "Mod3", "Mod4", "Mod5",
      +    "Button1", "Button2", "Button3", "Button4", "Button5"
      +  };
      +  printf ("Modifier mask: ");
      +  for (mod = mods ; mask; mask >>= 1, mod++)
      +    if (mask & 1)
      +      printf(*mod);
      +  putchar ('\n');
      +}
      +
      +int
      +main ()
      +{
      +  xcb_connection_t    *c;
      +  xcb_screen_t        *screen;
      +  xcb_window_t         win;
      +  xcb_generic_event_t *e;
      +  uint32_t             mask = 0;
      +  uint32_t             values[2];
      +
      +  /* Open the connection to the X server */
      +  c = xcb_connect (NULL, NULL);
      +
      +  /* Get the first screen */
      +  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      +
      +  /* Ask for our window's Id */
      +  win = xcb_generate_id (c);
      +
      +  /* Create the window */
      +  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
      +  values[0] = screen->white_pixel;
      +  values[1] = XCB_EVENT_MASK_EXPOSURE       | XCB_EVENT_MASK_BUTTON_PRESS   |
      +              XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_POINTER_MOTION |
      +              XCB_EVENT_MASK_ENTER_WINDOW   | XCB_EVENT_MASK_LEAVE_WINDOW   |
      +              XCB_EVENT_MASK_KEY_PRESS      | XCB_EVENT_MASK_KEY_RELEASE;
      +  xcb_create_window (c,                             /* Connection          */
      +                     0,                             /* depth               */
      +                     win,                           /* window Id           */
      +                     screen->root,                  /* parent window       */
      +                     0, 0,                          /* x, y                */
      +                     150, 150,                      /* width, height       */
      +                     10,                            /* border_width        */
      +                     XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
      +                     screen->root_visual,           /* visual              */
      +                     mask, values);                 /* masks */
      +
      +  /* Map the window on the screen */
      +  xcb_map_window (c, win);
      +
      +  xcb_flush (c);
      +
      +  while ((e = xcb_wait_for_event (c))) {
      +    switch (e->response_type & ~0x80) {
      +    case XCB_EXPOSE: {
      +      xcb_expose_event_t *ev = (xcb_expose_event_t *)e;
      +
      +      printf ("Window %ld exposed. Region to be redrawn at location (%d,%d), with dimension (%d,%d)\n",
      +              ev->window, ev->x, ev->y, ev->width, ev->height);
      +      break;
      +    }
      +    case XCB_BUTTON_PRESS: {
      +      xcb_button_press_event_t *ev = (xcb_button_press_event_t *)e;
      +      print_modifiers(ev->state);
      +
      +      switch (ev->detail) {
      +      case 4:
      +        printf ("Wheel Button up in window %ld, at coordinates (%d,%d)\n",
      +                ev->event, ev->event_x, ev->event_y);
      +        break;
      +      case 5:
      +        printf ("Wheel Button down in window %ld, at coordinates (%d,%d)\n",
      +                ev->event, ev->event_x, ev->event_y);
      +        break;
      +      default:
      +        printf ("Button %d pressed in window %ld, at coordinates (%d,%d)\n",
      +                ev->detail, ev->event, ev->event_x, ev->event_y);
      +      }
      +      break;
      +    }
      +    case XCB_BUTTON_RELEASE: {
      +      xcb_button_release_event_t *ev = (xcb_button_release_event_t *)e;
      +      print_modifiers(ev->state);
      +
      +      printf ("Button %d released in window %ld, at coordinates (%d,%d)\n",
      +              ev->detail, ev->event, ev->event_x, ev->event_y);
      +      break;
      +    }
      +    case XCB_MOTION_NOTIFY: {
      +      xcb_motion_notify_event_t *ev = (xcb_motion_notify_event_t *)e;
      +
      +      printf ("Mouse moved in window %ld, at coordinates (%d,%d)\n",
      +              ev->event, ev->event_x, ev->event_y);
      +      break;
      +    }
      +    case XCB_ENTER_NOTIFY: {
      +      xcb_enter_notify_event_t *ev = (xcb_enter_notify_event_t *)e;
      +
      +      printf ("Mouse entered window %ld, at coordinates (%d,%d)\n",
      +              ev->event, ev->event_x, ev->event_y);
      +      break;
      +    }
      +    case XCB_LEAVE_NOTIFY: {
      +      xcb_leave_notify_event_t *ev = (xcb_leave_notify_event_t *)e;
      +
      +      printf ("Mouse left window %ld, at coordinates (%d,%d)\n",
      +              ev->event, ev->event_x, ev->event_y);
      +      break;
      +    }
      +    case XCB_KEY_PRESS: {
      +      xcb_key_press_event_t *ev = (xcb_key_press_event_t *)e;
      +      print_modifiers(ev->state);
      +
      +      printf ("Key pressed in window %ld\n",
      +              ev->event);
      +      break;
      +    }
      +    case XCB_KEY_RELEASE: {
      +      xcb_key_release_event_t *ev = (xcb_key_release_event_t *)e;
      +      print_modifiers(ev->state);
      +
      +      printf ("Key released in window %ld\n",
      +              ev->event);
      +      break;
      +    }
      +    default:
      +      /* Unknown event type, ignore it */
      +      printf("Unknown event: %d\n", e->response_type);
      +      break;
      +    }
      +    /* Free the Generic Event */
      +    free (e);
      +  }
      +
      +  return 0;
      +}
      +
      +
    +
  11. Handling text and fonts +

    + Besides drawing graphics on a window, we often want to draw + text. Text strings have two major properties: the characters to + be drawn and the font with which they are drawn. In order to + draw text, we need to first request the X server to load a + font. We then assign a font to a Graphic Context, and finally, we + draw the text in a window, using the Graphic Context. +

    +
      +
    1. The Font structure +

      + In order to support flexible fonts, a font type is + defined. You know what ? It's an Id: +

      +
      +typedef uint32_t xcb_font_t;
      +
      +

      + It is used to contain information about a font, and is passed + to several functions that handle fonts selection and text drawing. + We ask the X server to attribute an Id to our font with the + function: +

      +
      +xcb_font_t xcb_generate_id (xcb_connection_t *c);
      +
      +
      +
    2. Opening a Font +

      + To open a font, we use the following function: +

      +
      +xcb_void_cookie_t xcb_open_font (xcb_connection_t *c,
      +                                 xcb_font_t        fid,
      +                                 uint16_t          name_len,
      +                                 const char       *name);
      +
      +

      + The fid parameter is the font Id + defined by xcb_generate_id() (see + above). The name parameter is the + name of the font you want to open. Use the command + xlsfonts in a terminal to know which + are the fonts available on your computer. The parameter + name_len is the length of the name + of the font (given by strlen()). +

      +
    3. Assigning a Font to a Graphic Context +

      + Once a font is opened, you have to create a Graphic Context + that will contain the informations about the color of the + foreground and the background used when you draw a text in a + Drawable. Here is an exemple of a Graphic Context that will + allow us to draw an opened font with a black foreground and a + white background: +

      +
      +  /*
      +   * c is the connection
      +   * screen is the screen where the window is displayed
      +   * window is the window in which we will draw the text
      +   * font is the opened font
      +   */
      +
      +  uint32_t             value_list[3];
      +  xcb_gcontext_t       gc;
      +  uint32_t             mask;
      +
      +  gc = xcb_generate_id (c);
      +  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
      +  value_list[0] = screen->black_pixel;
      +  value_list[1] = screen->white_pixel;
      +  value_list[2] = font;
      +  xcb_create_gc (c, gc, window, mask, value_list);
      +
      +  /* The font is not needed anymore, so we close it */
      +  xcb_close_font (c, font);
      +
      +
    4. Drawing text in a drawable +

      + To draw a text in a drawable, we use the following function: +

      +
      +xcb_void_cookie_t xcb_image_text_8 (xcb_connection_t *c,
      +                                    uint8_t           string_len,
      +                                    xcb_drawable_t    drawable,
      +                                    xcb_gcontext_t    gc,
      +                                    int16_t           x,
      +                                    int16_t           y,
      +                                    const char       *string);
      +
      +

      + The string parameter is the text to + draw. The location of the drawing is given by the parameters + x and y. + The base line of the text is exactly the parameter + y. +

      +
    5. Complete example +

      + This example draw a text at 10 pixels (for the base line) of + the bottom of a window. Pressing the Esc key exits the program. +

      +
      +#include <stdlib.h>
      +#include <stdio.h>
      +#include <string.h>
      +
      +#include <xcb/xcb.h>
      +
      +#define WIDTH 300
      +#define HEIGHT 100
      +
      +
      +
      +static xcb_gc_t gc_font_get (xcb_connection_t *c,
      +                             xcb_screen_t     *screen,
      +                             xcb_window_t      window,
      +                             const char       *font_name);
      +
      +static void text_draw (xcb_connection_t *c,
      +                       xcb_screen_t     *screen,
      +                       xcb_window_t      window,
      +                       int16_t           x1,
      +                       int16_t           y1,
      +                       const char       *label);
      +
      +static void
      +text_draw (xcb_connection_t *c,
      +           xcb_screen_t     *screen,
      +           xcb_window_t      window,
      +           int16_t           x1,
      +           int16_t           y1,
      +           const char       *label)
      +{
      +  xcb_void_cookie_t    cookie_gc;
      +  xcb_void_cookie_t    cookie_text;
      +  xcb_generic_error_t *error;
      +  xcb_gcontext_t       gc;
      +  uint8_t              length;
      +
      +  length = strlen (label);
      +
      +  gc = gc_font_get(c, screen, window, "7x13");
      +
      +  cookie_text = xcb_image_text_8_checked (c, length, window, gc,
      +                                          x1,
      +                                          y1, label);
      +  error = xcb_request_check (c, cookie_text);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't paste text : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  cookie_gc = xcb_free_gc (c, gc);
      +  error = xcb_request_check (c, cookie_gc);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't free gc : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +}
      +
      +static xcb_gc_t
      +gc_font_get (xcb_connection_t *c,
      +             xcb_screen_t     *screen,
      +             xcb_window_t      window,
      +             const char       *font_name)
      +{
      +  uint32_t             value_list[3];
      +  xcb_void_cookie_t    cookie_font;
      +  xcb_void_cookie_t    cookie_gc;
      +  xcb_generic_error_t *error;
      +  xcb_font_t           font;
      +  xcb_gcontext_t       gc;
      +  uint32_t             mask;
      +
      +  font = xcb_generate_id (c);
      +  cookie_font = xcb_open_font_checked (c, font,
      +                                       strlen (font_name),
      +                                       font_name);
      +
      +  error = xcb_request_check (c, cookie_font);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't open font : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    return -1;
      +  }
      +
      +  gc = xcb_generate_id (c);
      +  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
      +  value_list[0] = screen->black_pixel;
      +  value_list[1] = screen->white_pixel;
      +  value_list[2] = font;
      +  cookie_gc = xcb_create_gc_checked (c, gc, window, mask, value_list);
      +  error = xcb_request_check (c, cookie_gc);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't create gc : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  cookie_font = xcb_close_font_checked (c, font);
      +  error = xcb_request_check (c, cookie_font);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't close font : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  return gc;
      +}
      +
      +int main ()
      +{
      +  xcb_screen_iterator_t screen_iter;
      +  xcb_connection_t     *c;
      +  const xcb_setup_t    *setup;
      +  xcb_screen_t         *screen;
      +  xcb_generic_event_t  *e;
      +  xcb_generic_error_t  *error;
      +  xcb_void_cookie_t     cookie_window;
      +  xcb_void_cookie_t     cookie_map;
      +  xcb_window_t          window;
      +  uint32_t              mask;
      +  uint32_t              values[2];
      +  int                   screen_number;
      +
      +  /* getting the connection */
      +  c = xcb_connect (NULL, &screen_number);
      +  if (!c) {
      +    fprintf (stderr, "ERROR: can't connect to an X server\n");
      +    return -1;
      +  }
      +
      +  /* getting the current screen */
      +  setup = xcb_get_setup (c);
      +
      +  screen = NULL;
      +  screen_iter = xcb_setup_roots_iterator (setup);
      +  for (; screen_iter.rem != 0; --screen_number, xcb_screen_next (&screen_iter))
      +    if (screen_number == 0)
      +      {
      +        screen = screen_iter.data;
      +        break;
      +      }
      +  if (!screen) {
      +    fprintf (stderr, "ERROR: can't get the current screen\n");
      +    xcb_disconnect (c);
      +    return -1;
      +  }
      +
      +  /* creating the window */
      +  window = xcb_generate_id (c);
      +  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
      +  values[0] = screen->white_pixel;
      +  values[1] =
      +    XCB_EVENT_MASK_KEY_RELEASE |
      +    XCB_EVENT_MASK_BUTTON_PRESS |
      +    XCB_EVENT_MASK_EXPOSURE |
      +    XCB_EVENT_MASK_POINTER_MOTION;
      +  cookie_window = xcb_create_window_checked (c,
      +                                             screen->root_depth,
      +                                             window, screen->root,
      +                                             20, 200, WIDTH, HEIGHT,
      +                                             0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
      +                                             screen->root_visual,
      +                                             mask, values);
      +  cookie_map = xcb_map_window_checked (c, window);
      +
      +  /* error managing */
      +  error = xcb_request_check (c, cookie_window);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't create window : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    return -1;
      +  }
      +  error = xcb_request_check (c, cookie_map);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't map window : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    return -1;
      +  }
      +
      +  xcb_flush(c);
      +
      +  while (1) {
      +    e = xcb_poll_for_event(c);
      +    if (e) {
      +      switch (e->response_type & ~0x80) {
      +      case XCB_EXPOSE: {
      +        char *text;
      +
      +        text = "Press ESC key to exit...";
      +        text_draw (c, screen, window, 10, HEIGHT - 10, text);
      +        break;
      +      }
      +      case XCB_KEY_RELEASE: {
      +        xcb_key_release_event_t *ev;
      +
      +        ev = (xcb_key_release_event_t *)e;
      +
      +        switch (ev->detail) {
      +          /* ESC */
      +        case 9:
      +          free (e);
      +          xcb_disconnect (c);
      +          return 0;
      +        }
      +      }
      +      }
      +      free (e);
      +    }
      +  }
      +
      +  return 0;
      +}
      +
      +
    +
  12. Interacting with the window manager +

    + After we have seen how to create windows and draw on them, we + take one step back, and look at how our windows are interacting + with their environment (the full screen and the other + windows). First of all, our application needs to interact with + the window manager. The window manager is responsible to + decorating drawn windows (i.e. adding a frame, an iconify + button, a system menu, a title bar, etc), as well as handling + icons shown when windows are being iconified. It also handles + ordering of windows on the screen, and other administrative + tasks. We need to give it various hints as to how we want it to + treat our application's windows. +

    +
      +
    1. Window properties +

      + Many of the parameters communicated to the window manager are + passed using data called "properties". These properties are + attached by the X server to different windows, and are stored + in a format that makes it possible to read them from different + machines that may use different architectures (remember that + an X client program may run on a remote machine). +

      +

      + The property and its type (a string, an integer, etc) are + Id. Their type are xcb_atom_t: +

      +
      +typedef uint32_t xcb_atom_t;
      +
      +

      + To change the property of a window, we use the following + function: +

      +
      +xcb_void_cookie_t xcb_change_property (xcb_connection_t *c,       /* Connection to the X server */
      +                                       uint8_t          mode,     /* Property mode */
      +                                       xcb_window_t     window,   /* Window */
      +                                       xcb_atom_t       property, /* Property to change */
      +                                       xcb_atom_t       type,     /* Type of the property */
      +                                       uint8_t          format,   /* Format of the property (8, 16, 32) */
      +                                       uint32_t         data_len, /* Length of the data parameter */
      +                                       const void      *data);    /* Data */
      +
      +

      + The mode parameter coud be one of + the following values (defined in enumeration xcb_prop_mode_t in + the xproto.h header file): +

      +
        +
      • XCB_PROP_MODE_REPLACE +
      • XCB_PROP_MODE_PREPEND +
      • XCB_PROP_MODE_APPEND +
      +
      +
    2. Setting the window name and icon name +

      + The first thing we want to do would be to set the name for our + window. This is done using the + xcb_change_property() function. This + name may be used by the window manager as the title of the + window (in the title bar), in a task list, etc. The property + atom to use to set the name of a window is + WM_NAME (and + WM_ICON_NAME for the iconified + window) and its type is STRING. Here + is an example of utilization: +

      +
      +#include <string.h>
      +
      +#include <xcb/xcb.h>
      +#include <xcb/xcb_atom.h>
      +
      +int
      +main ()
      +{
      +  xcb_connection_t *c;
      +  xcb_screen_t     *screen;
      +  xcb_window_t      win;
      +  char             *title = "Hello World !";
      +  char             *title_icon = "Hello World ! (iconified)";
      +
      +
      +
      +  /* Open the connection to the X server */
      +  c = xcb_connect (NULL, NULL);
      +
      +  /* Get the first screen */
      +  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      +
      +  /* Ask for our window's Id */
      +  win = xcb_generate_id (c);
      +
      +  /* Create the window */
      +  xcb_create_window (c,                             /* Connection          */
      +                     0,                             /* depth               */
      +                     win,                           /* window Id           */
      +                     screen->root,                  /* parent window       */
      +                     0, 0,                          /* x, y                */
      +                     250, 150,                      /* width, height       */
      +                     10,                            /* border_width        */
      +                     XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class               */
      +                     screen->root_visual,           /* visual              */
      +                     0, NULL);                      /* masks, not used     */
      +
      +  /* Set the title of the window */
      +  xcb_change_property (c, XCB_PROP_MODE_REPLACE, win,
      +                       WM_NAME, STRING, 8,
      +                       strlen (title), title);
      +
      +  /* Set the title of the window icon */
      +  xcb_change_property (c, XCB_PROP_MODE_REPLACE, win,
      +                       WM_ICON_NAME, STRING, 8,
      +                       strlen(title_icon), title_icon);
      +
      +  /* Map the window on the screen */
      +  xcb_map_window (c, win);
      +
      +  xcb_flush (c);
      +
      +  while (1) {}
      +
      +  return 0;
      +}
      +
      +
      +

      Note: the use of the atoms needs our program to be compiled + and linked against xcb_atom, so that we have to use +

      +
      +
      +gcc prog.c -o prog `pkg-config --cflags --libs xcb_atom`
      +
      +
      +

      + for the program to compile fine. +

      +
      +
    +
  13. Simple window operations +

    + One more thing we can do to our window is manipulate them on the + screen (resize them, move them, raise or lower them, iconify + them, and so on). Some window operations functions are supplied + by XCB for this purpose. +

    +
      +
    1. Mapping and un-mapping a window +

      + The first pair of operations we can apply on a window is + mapping it, or un-mapping it. Mapping a window causes the + window to appear on the screen, as we have seen in our simple + window program example. Un-mapping it causes it to be removed + from the screen (although the window as a logical entity still + exists). This gives the effect of making a window hidden + (unmapped) and shown again (mapped). For example, if we have a + dialog box window in our program, instead of creating it every + time the user asks to open it, we can create the window once, + in an un-mapped mode, and when the user asks to open it, we + simply map the window on the screen. When the user clicked the + 'OK' or 'Cancel' button, we simply un-map the window. This is + much faster than creating and destroying the window, however, + the cost is wasted resources, both on the client side, and on + the X server side. +

      +

      + To map a window, you use the following function: +

      +
      +xcb_void_cookie_t xcb_map_window (xcb_connection_t *c,
      +                                  xcb_window_t      window);
      +
      +

      + To have a simple example, see the example + above. The mapping operation will cause an + Expose event to be sent to our + application, unless the window is completely covered by other + windows. +

      +

      + Un-mapping a window is also simple. You use the function +

      +
      +xcb_void_cookie_t xcb_unmap_window (xcb_connection_t *c,
      +                                    xcb_window_t      window);
      +
      +

      + The utilization of this function is the same as + xcb_map_window(). +

      +
    2. Configuring a window +

      + As we have seen when we have created our first window, in the + X Events subsection, we can set some attributes for the window + (that is, the position, the size, the events the window will + receive, etc). If we want to modify them, but the window is + already created, we can change them by using the following + function: +

      +
      +xcb_void_cookie_t xcb_configure_window (xcb_connection_t *c,            /* The connection to the X server*/
      +                                        xcb_window_t      window,       /* The window to configure */
      +                                        uint16_t          value_mask,   /* The mask */
      +                                        const uint32_t   *value_list);  /* The values to set */
      +
      +

      + We set the value_mask to one or + several mask values that are in the xcb_config_window_t enumeration in the xproto.h header: +

      +
        +
      • XCB_CONFIG_WINDOW_X: new x coordinate of the window's top left corner +
      • XCB_CONFIG_WINDOW_Y: new y coordinate of the window's top left corner +
      • XCB_CONFIG_WINDOW_WIDTH: new width of the window +
      • XCB_CONFIG_WINDOW_HEIGHT: new height of the window +
      • XCB_CONFIG_WINDOW_BORDER_WIDTH: new width of the border of the window +
      • XCB_CONFIG_WINDOW_SIBLING +
      • XCB_CONFIG_WINDOW_STACK_MODE: the new stacking order +
      +

      + We then give to value_mask the new + value. We now describe how to use + xcb_configure_window_t in some useful + situations. +

      +
    3. Moving a window around the screen +

      + An operation we might want to do with windows is to move them + to a different location. This can be done like this: +

      +
      +const static uint32_t values[] = { 10, 20 };
      +
      +/* The connection c and the window win are supposed to be defined */
      +
      +/* Move the window to coordinates x = 10 and y = 20 */
      +xcb_configure_window (c, win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y, values);
      +
      +

      + Note that when the window is moved, it might get partially + exposed or partially hidden by other windows, and thus we + might get Expose events due to this + operation. +

      +
    4. Resizing a window +

      + Yet another operation we can do is to change the size of a + window. This is done using the following code: +

      +
      +const static uint32_t values[] = { 200, 300 };
      +
      +/* The connection c and the window win are supposed to be defined */
      +
      +/* Resize the window to width = 10 and height = 20 */
      +xcb_configure_window (c, win, XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
      +
      +

      + We can also combine the move and resize operations using one + single call to xcb_configure_window_t: +

      +
      +const static uint32_t values[] = { 10, 20, 200, 300 };
      +
      +/* The connection c and the window win are supposed to be defined */
      +
      +/* Move the window to coordinates x = 10 and y = 20 */
      +/* and resize the window to width = 10 and height = 20 */
      +xcb_configure_window (c, win, XCB_CONFIG_WINDOW_X | XCB_CONFIG_WINDOW_Y | XCB_CONFIG_WINDOW_WIDTH | XCB_CONFIG_WINDOW_HEIGHT, values);
      +
      +
    5. Changing windows stacking order: raise and lower +

      + Until now, we changed properties of a single window. We'll see + that there are properties that relate to the window and other + windows. One of them is the stacking order. That is, the order + in which the windows are layered on top of each other. The + front-most window is said to be on the top of the stack, while + the back-most window is at the bottom of the stack. Here is + how to manipulate our windows stack order: +

      +
      +const static uint32_t values[] = { XCB_STACK_MODE_ABOVE };
      +
      +/* The connection c and the window win are supposed to be defined */
      +
      +/* Move the window on the top of the stack */
      +xcb_configure_window (c, win, XCB_CONFIG_WINDOW_STACK_MODE, values);
      +
      +
      +const static uint32_t values[] = { XCB_STACK_MODE_BELOW };
      +
      +/* The connection c and the window win are supposed to be defined */
      +
      +/* Move the window on the bottom of the stack */
      +xcb_configure_window (c, win, XCB_CONFIG_WINDOW_STACK_MODE, values);
      +
      +
    6. Getting information about a window +

      + Just like we can set various attributes of our windows, we can + also ask the X server supply the current values of these + attributes. For example, we can check where a window is + located on the screen, what is its current size, whether it is + mapped or not, etc. The structure that contains some of this + information is +

      +
      +typedef struct {
      +    uint8_t      response_type;
      +    uint8_t      depth;         /* depth of the window */
      +    uint16_t     sequence;
      +    uint32_t     length;
      +    xcb_window_t root;          /* Id of the root window *>
      +    int16_t      x;             /* X coordinate of the window's location */
      +    int16_t      y;             /* Y coordinate of the window's location */
      +    uint16_t     width;         /* Width of the window */
      +    uint16_t     height;        /* Height of the window */
      +    uint16_t     border_width;  /* Width of the window's border */
      +} xcb_get_geometry_reply_t;
      +
      +

      + XCB fill this structure with two functions: +

      +
      +xcb_get_geometry_cookie_t  xcb_get_geometry       (xcb_connection_t         *c,
      +                                                   xcb_drawable_t            drawable);
      +xcb_get_geometry_reply_t  *xcb_get_geometry_reply (xcb_connection_t         *c,
      +                                                   xcb_get_geometry_cookie_t cookie,
      +                                                   xcb_generic_error_t     **e);
      +
      +

      + You use them as follows: +

      +
      +  xcb_connection_t         *c;
      +  xcb_drawable_t            win;
      +  xcb_get_geometry_reply_t *geom;
      +
      +  /* You initialize c and win */
      +
      +  geom = xcb_get_geometry_reply (c, xcb_get_geometry (c, win), NULL);
      +
      +  /* Do something with the fields of geom */
      +
      +  free (geom);
      +
      +

      + Remark that you have to free the structure, as + xcb_get_geometry_reply_t allocates a + newly one. +

      +

      + One problem is that the returned location of the window is + relative to its parent window. This makes these coordinates + rather useless for any window manipulation functions, like + moving it on the screen. In order to overcome this problem, we + need to take a two-step operation. First, we find out the Id + of the parent window of our window. We then translate the + above relative coordinates to the screen coordinates. +

      +

      + To get the Id of the parent window, we need this structure: +

      +
      +typedef struct {
      +    uint8_t      response_type;
      +    uint8_t      pad0;
      +    uint16_t     sequence;
      +    uint32_t     length;
      +    xcb_window_t root;
      +    xcb_window_t parent;       /* Id of the parent window */
      +    uint16_t     children_len;
      +    uint8_t      pad1[14];
      +} xcb_query_tree_reply_t;
      +
      +

      + To fill this structure, we use these two functions: +

      +
      +xcb_query_tree_cookie_t xcb_query_tree       (xcb_connection_t        *c,
      +                                              xcb_window_t             window);
      +xcb_query_tree_reply_t *xcb_query_tree_reply (xcb_connection_t        *c,
      +                                              xcb_query_tree_cookie_t  cookie,
      +                                              xcb_generic_error_t    **e);
      +
      +

      + The translated coordinates will be found in this structure: +

      +
      +typedef struct {
      +    uint8_t      response_type;
      +    uint8_t      same_screen;
      +    uint16_t     sequence;
      +    uint32_t     length;
      +    xcb_window_t child;
      +    uint16_t     dst_x;        /* Translated x coordinate */
      +    uint16_t     dst_y;        /* Translated y coordinate */
      +} xcb_translate_coordinates_reply_t;
      +
      +

      + As usual, we need two functions to fill this structure: +

      +
      +xcb_translate_coordinates_cookie_t xcb_translate_coordinates       (xcb_connection_t                  *c,
      +                                                                    xcb_window_t                       src_window,
      +                                                                    xcb_window_t                       dst_window,
      +                                                                    int16_t                            src_x,
      +                                                                    int16_t                            src_y);
      +xcb_translate_coordinates_reply_t *xcb_translate_coordinates_reply (xcb_connection_t                  *c,
      +                                                                    xcb_translate_coordinates_cookie_t cookie,
      +                                                                    xcb_generic_error_t              **e);
      +
      +

      + We use them as follows: +

      +
      +  xcb_connection_t                  *c;
      +  xcb_drawable_t                     win;
      +  xcb_get_geometry_reply_t          *geom;
      +  xcb_query_tree_reply_t            *tree;
      +  xcb_translate_coordinates_reply_t *trans;
      +
      +  /* You initialize c and win */
      +
      +  geom  = xcb_get_geometry_reply (c, xcb_get_geometry (c, win), NULL);
      +  if (!geom)
      +    return 0;
      +
      +  tree  = xcb_query_tree_reply (c, xcb_query_tree (c, win), NULL);
      +  if (!tree)
      +    return 0;
      +
      +  trans = xcb_translate_coordinates_reply (c,
      +                                           xcb_translate_coordinates (c,
      +                                                                      win,
      +                                                                      tree->parent,
      +                                                                      geom->x, geom->y),
      +                                           NULL);
      +  if (!trans)
      +    return 0;
      +
      +  /* the translated coordinates are in trans->dst_x and trans->dst_y */
      +
      +  free (trans);
      +  free (tree);
      +  free (geom);
      +
      +

      + Of course, as for geom, + tree and + trans have to be freed. +

      +

      + The work is a bit hard, but XCB is a very low-level library. +

      +

      + TODO: the utilization of these functions should be a + prog, which displays the coordinates of the window. +

      +

      + There is another structure that gives informations about our window: +

      +
      +typedef struct {
      +    uint8_t        response_type;
      +    uint8_t        backing_store;
      +    uint16_t       sequence;
      +    uint32_t       length;
      +    xcb_visualid_t visual;                /* Visual of the window */
      +    uint16_t       _class;
      +    uint8_t        bit_gravity;
      +    uint8_t        win_gravity;
      +    uint32_t       backing_planes;
      +    uint32_t       backing_pixel;
      +    uint8_t        save_under;
      +    uint8_t        map_is_installed;
      +    uint8_t        map_state;             /* Map state of the window */
      +    uint8_t        override_redirect;
      +    xcb_colormap_t colormap;              /* Colormap of the window */
      +    uint32_t       all_event_masks;
      +    uint32_t       your_event_mask;
      +    uint16_t       do_not_propagate_mask;
      +} xcb_get_window_attributes_reply_t;
      +
      +

      + XCB supplies these two functions to fill it: +

      +
      +xcb_get_window_attributes_cookie_t xcb_get_window_attributes       (xcb_connection_t                  *c,
      +                                                                    xcb_window_t                       window);
      +xcb_get_window_attributes_reply_t *xcb_get_window_attributes_reply (xcb_connection_t                  *c,
      +                                                                    xcb_get_window_attributes_cookie_t cookie,
      +                                                                    xcb_generic_error_t              **e);
      +
      +

      + You use them as follows: +

      +
      +  xcb_connection_t                  *c;
      +  xcb_drawable_t                     win;
      +  xcb_get_window_attributes_reply_t *attr;
      +
      +  /* You initialize c and win */
      +
      +  attr = xcb_get_window_attributes_reply (c, xcb_get_window_attributes (c, win), NULL);
      +
      +  if (!attr)
      +    return 0;
      +
      +  /* Do something with the fields of attr */
      +
      +  free (attr);
      +
      +

      + As for geom, + attr has to be freed. +

      +
    +
  14. Using colors to paint the rainbow +

    + Up until now, all our painting operation were done using black + and white. We will (finally) see now how to draw using colors. +

    +
      +
    1. Color maps +

      + In the beginning, there were not enough colors. Screen + controllers could only support a limited number of colors + simultaneously (initially 2, then 4, 16 and 256). Because of + this, an application could not just ask to draw in a "light + purple-red" color, and expect that color to be available. Each + application allocated the colors it needed, and when all the + color entries (4, 16, 256 colors) were in use, the next color + allocation would fail. +

      +

      + Thus, the notion of "a color map" was introduced. A color map + is a table whose size is the same as the number of + simultaneous colors a given screen controller. Each entry + contained the RGB (Red, Green and Blue) values of a different + color (all colors can be drawn using some combination of red, + green and blue). When an application wants to draw on the + screen, it does not specify which color to use. Rather, it + specifies which color entry of some color map to be used + during this drawing. Change the value in this color map entry + and the drawing will use a different color. +

      +

      + In order to be able to draw using colors that got something to + do with what the programmer intended, color map allocation + functions are supplied. You could ask to allocate entry for a + color with a set of RGB values. If one already existed, you + would get its index in the table. If none existed, and the + table was not full, a new cell would be allocated to contain + the given RGB values, and its index returned. If the table was + full, the procedure would fail. You could then ask to get a + color map entry with a color that is closest to the one you + were asking for. This would mean that the actual drawing on + the screen would be done using colors similar to what you + wanted, but not the same. +

      +

      + On today's more modern screens where one runs an X server with + support for 16 million colors, this limitation looks a little + silly, but remember that there are still older computers with + older graphics cards out there. Using color map, support for + these screen becomes transparent to you. On a display + supporting 16 million colors, any color entry allocation + request would succeed. On a display supporting a limited + number of colors, some color allocation requests would return + similar colors. It won't look as good, but your application + would still work. +

      +
    2. Allocating and freeing Color Maps +

      + When you draw using XCB, you can choose to use the standard + color map of the screen your window is displayed on, or you + can allocate a new color map and apply it to a window. In the + latter case, each time the mouse moves onto your window, the + screen color map will be replaced by your window's color map, + and you'll see all the other windows on screen change their + colors into something quite bizzare. In fact, this is the + effect you get with X applications that use the "-install" + command line option. +

      +

      + In XCB, a color map is (as often in X) an Id: +

      +
      +typedef uint32_t xcb_colormap_t;
      +
      +

      + In order to access the screen's default color map, you just + have to retrieve the default_colormap + field of the xcb_screen_t structure + (see Section + Checking basic information about a connection): +

      +
      +#include <stdio.h>
      +
      +#include <xcb/xcb.h>
      +
      +int
      +main ()
      +{
      +  xcb_connection_t *c;
      +  xcb_screen_t     *screen;
      +  xcb_colormap_t    colormap;
      +
      +  /* Open the connection to the X server and get the first screen */
      +  c = xcb_connect (NULL, NULL);
      +  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      +
      +  colormap = screen->default_colormap;
      +
      +  return 0;
      +}
      +
      +

      + This will return the color map used by default on the first + screen (again, remember that an X server may support several + different screens, each of which might have its own resources). +

      +

      + The other option, that of allocating a new colormap, works as + follows. We first ask the X server to give an Id to our color + map, with this function: +

      +
      +xcb_colormap_t xcb_generate_id (xcb_connection_t *c);
      +
      +

      + Then, we create the color map with +

      +
      +xcb_void_cookie_t xcb_create_colormap (xcb_connection_t *c,       /* Pointer to the xcb_connection_t structure */
      +                                       uint8_t           alloc,   /* Colormap entries to be allocated (AllocNone or AllocAll) */
      +                                       xcb_colormap_t    mid,     /* Id of the color map */
      +                                       xcb_window_t      window,  /* Window on whose screen the colormap will be created */
      +                                       xcb_visualid_t    visual); /* Id of the visual supported by the screen */
      +
      +

      + Here is an example of creation of a new color map: +

      +
      +#include <xcb/xcb.h>
      +
      +int
      +main ()
      +{
      +  xcb_connection_t *c;
      +  xcb_screen_t     *screen;
      +  xcb_window_t      win;
      +  xcb_colormap_t    cmap
      +
      +  /* Open the connection to the X server and get the first screen */
      +  c = xcb_connect (NULL, NULL);
      +  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      +
      +  /* We create the window win here*/
      +
      +  cmap = xcb_generate_id (c);
      +  xcb_create_colormap (c, XCB_COLORMAP_ALLOC_NONE, cmap, win, screen->root_visual);
      +
      +  return 0;
      +}
      +
      +

      + Note that the window parameter is only used to allow the X + server to create the color map for the given screen. We can + then use this color map for any window drawn on the same screen. +

      +

      + To free a color map, it suffices to use this function: +

      +
      +xcb_void_cookie_t xcb_free_colormap (xcb_connection_t *c,   /* The connection */
      +                                     xcb_colormap_t cmap);  /* The color map */
      +
      +
      +
      + Comparison Xlib/XCB +
      +
      +
        +
      • XCreateColormap () +
      +
      +
      +
        +
      • xcb_generate_id () +
      • xcb_create_colormap () +
      +
      +
      +
        +
      • XFreeColormap () +
      +
      +
      +
        +
      • xcb_free_colormap () +
      +
      +
      +
      +
    3. Allocating and freeing a color entry +

      + Once we got access to some color map, we can start allocating + colors. The informations related to a color are stored in the + following structure: +

      +
      +typedef struct {
      +    uint8_t  response_type;
      +    uint8_t  pad0;
      +    uint16_t sequence;
      +    uint32_t length;
      +    uint16_t red;          /* The red component   */
      +    uint16_t green;        /* The green component */
      +    uint16_t blue;         /* The blue component  */
      +    uint8_t  pad1[2];
      +    uint32_t pixel;        /* The entry in the color map, supplied by the X server */
      +} xcb_alloc_color_reply_t;
      +
      +

      + XCB supplies these two functions to fill it: +

      +
      +xcb_alloc_color_cookie_t xcb_alloc_color       (xcb_connection_t        *c,
      +                                                xcb_colormap_t           cmap,
      +                                                uint16_t                 red,
      +                                                uint16_t                 green,
      +                                                uint16_t                 blue);
      +xcb_alloc_color_reply_t *xcb_alloc_color_reply (xcb_connection_t        *c,
      +                                                xcb_alloc_color_cookie_t cookie,
      +                                                xcb_generic_error_t    **e);
      +
      +

      + The fuction xcb_alloc_color() takes the + 3 RGB components as parameters (red, green and blue). Here is an + example of using these functions: +

      +
      +#include <malloc.h>
      +
      +#include <xcb/xcb.h>
      +
      +int
      +main ()
      +{
      +  xcb_connection_t        *c;
      +  xcb_screen_t            *screen;
      +  xcb_window_t             win;
      +  xcb_colormap_t           cmap;
      +  xcb_alloc_color_reply_t *rep;
      +
      +  /* Open the connection to the X server and get the first screen */
      +  c = xcb_connect (NULL, NULL);
      +  screen = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
      +
      +  /* We create the window win here*/
      +
      +  cmap = xcb_generate_id (c);
      +  xcb_create_colormap (c, XCB_COLORMAP_ALLOC_NONE, cmap, win, screen->root_visual);
      +
      +  rep = xcb_alloc_color_reply (c, xcb_alloc_color (c, cmap, 65535, 0, 0), NULL);
      +
      +  if (!rep)
      +    return 0;
      +
      +  /* Do something with r->pixel or the components */
      +
      +  free (rep);
      +
      +  return 0;
      +}
      +
      +

      + As xcb_alloc_color_reply() allocates + memory, you have to free rep. +

      +

      + TODO: Talk about freeing colors. +

      +
    +
  15. X Bitmaps and Pixmaps +

    + One thing many so-called "Multi-Media" applications need to do, + is display images. In the X world, this is done using bitmaps + and pixmaps. We have already seen some usage of them when + setting an icon for our application. Lets study them further, + and see how to draw these images inside a window, along side the + simple graphics and text we have seen so far. +

    +

    + One thing to note before delving further, is that XCB (nor Xlib) + supplies no means of manipulating popular image formats, such as + gif, png, jpeg or tiff. It is up to the programmer (or to higher + level graphics libraries) to translate these image formats into + formats that the X server is familiar with (x bitmaps and x + pixmaps). +

    +
      +
    1. What is a X Bitmap? An X Pixmap? +

      + An X bitmap is a two-color image stored in a format specific + to the X window system. When stored in a file, the bitmap data + looks like a C source file. It contains variables defining the + width and the height of the bitmap, an array containing the + bit values of the bitmap (the size of the array is + (width+7)/8*height and the bit and byte order are LSB), and + an optional hot-spot location (that will + be explained later, when discussing mouse cursors). +

      +

      + An X pixmap is a format used to stored images in the memory of + an X server. This format can store both black and white images + (such as x bitmaps) as well as color images. It is the only + image format supported by the X protocol, and any image to be + drawn on screen, should be first translated into this format. +

      +

      + In actuality, an X pixmap can be thought of as a window that + does not appear on the screen. Many graphics operations that + work on windows, will also work on pixmaps. Indeed, the type + of X pixmap in XCB is an Id like a window: +

      +
      +typedef uint32_t xcb_pixmap_t;
      +
      +

      + Like Xlib, there is no difference between a Drawable, a Window + or a Pixmap: +

      +
      +typedef uint32_t xcb_drawable_t;
      +
      +

      + in order to avoid confusion between a window and a pixmap. The + operations that will work the same on a window or a pixmap + will require a xcb_drawable_t +

      +
      +

      + Remark: In Xlib, there is no specific difference between a + Drawable, a + Pixmap or a + Window: all are 32 bit long + integer. XCB wraps all these different IDs in structures to + provide some measure of type-safety. +

      +
      +
    2. Creating a pixmap +

      + Sometimes we want to create an un-initialized pixmap, so we + can later draw into it. This is useful for image drawing + programs (creating a new empty canvas will cause the creation + of a new pixmap on which the drawing can be stored). It is + also useful when reading various image formats: we load the + image data into memory, create a pixmap on the server, and + then draw the decoded image data onto that pixmap. +

      +

      + To create a new pixmap, we first ask the X server to give an + Id to our pixmap, with this function: +

      +
      +xcb_pixmap_t xcb_generate_id (xcb_connection_t *c);
      +
      +

      + Then, XCB supplies the following function to create new pixmaps: +

      +
      +xcb_void_cookie_t xcb_create_pixmap (xcb_connection_t *c,         /* Pointer to the xcb_connection_t structure */
      +                                     uint8_t           depth,     /* Depth of the screen */
      +                                     xcb_pixmap_t      pid,       /* Id of the pixmap */
      +                                     xcb_drawable_t    drawable,
      +                                     uint16_t          width,     /* Width of the window (in pixels) */
      +                                     uint16_t          height);   /* Height of the window (in pixels) */
      +
      +

      + TODO: Explain the drawable parameter, and give an + example (like xpoints.c) +

      +
    3. Drawing a pixmap in a window +

      + Once we got a handle to a pixmap, we can draw it on some + window, using the following function: +

      +
      +xcb_void_cookie_t xcb_copy_area (xcb_connection_t *c,             /* Pointer to the xcb_connection_t structure */
      +                                 xcb_drawable_t    src_drawable,  /* The Drawable we want to paste */
      +                                 xcb_drawable_t    dst_drawable,  /* The Drawable on which we copy the previous Drawable */
      +                                 xcb_gcontext_t    gc,            /* A Graphic Context */
      +                                 int16_t           src_x,         /* Top left x coordinate of the region we want to copy */
      +                                 int16_t           src_y,         /* Top left y coordinate of the region we want to copy */
      +                                 int16_t           dst_x,         /* Top left x coordinate of the region where we want to copy */
      +                                 int16_t           dst_y,         /* Top left y coordinate of the region where we want to copy */
      +                                 uint16_t          width,         /* Width of the region we want to copy */
      +                                 uint16_t          height);       /* Height of the region we want to copy */
      +
      +

      + As you can see, we could copy the whole pixmap, as well as + only a given rectangle of the pixmap. This is useful to + optimize the drawing speed: we could copy only what we have + modified in the pixmap. +

      +

      + One important note should be made: it is possible to + create pixmaps with different depths on the same screen. When + we perform copy operations (a pixmap onto a window, etc), we + should make sure that both source and target have the same + depth. If they have a different depth, the operation would + fail. The exception to this is if we copy a specific bit plane + of the source pixmap using the + xcb_copy_plane_t function. In such an + event, we can copy a specific plane to the target window (in + actuality, setting a specific bit in the color of each pixel + copied). This can be used to generate strange graphic effects + in a window, but that is beyond the scope of this tutorial. +

      +
    4. Freeing a pixmap +

      + Finally, when we are done using a given pixmap, we should free + it, in order to free resources of the X server. This is done + using this function: +

      +
      +xcb_void_cookie_t xcb_free_pixmap (xcb_connection_t *c,        /* Pointer to the xcb_connection_t structure */
      +                                   xcb_pixmap_t      pixmap);  /* A given pixmap */
      +
      +

      + Of course, after having freed it, we must not try accessing + the pixmap again. +

      +

      + TODO: Give an example, or a link to xpoints.c +

      +
    +
  16. Messing with the mouse cursor +

    + It it possible to modify the shape of the mouse pointer (also + called the X pointer) when in certain states, as we otfen see in + programs. For example, a busy application would often display + the sand clock over its main window, to give the user a visual + hint that he should wait. Let's see how we can change the mouse + cursor of our windows. +

    +
      +
    1. Creating and destroying a mouse cursor +

      + There are two methods for creating cursors. One of them is by + using a set of predefined cursors, that are supplied by the X + server, the other is by using a user-supplied bitmap. +

      +

      + In the first method, we use a special font named "cursor", and + the function xcb_create_glyph_cursor: +

      +
      +xcb_void_cookie_t xcb_create_glyph_cursor (xcb_connection_t *c,
      +                                           xcb_cursor_t      cid,
      +                                           xcb_font_t        source_font, /* font for the source glyph */
      +                                           xcb_font_t        mask_font,   /* font for the mask glyph or XCB_NONE */
      +                                           uint16_t          source_char, /* character glyph for the source */
      +                                           uint16_t          mask_char,   /* character glyph for the mask */
      +                                           uint16_t          fore_red,    /* red value for the foreground of the source */
      +                                           uint16_t          fore_green,  /* green value for the foreground of the source */
      +                                           uint16_t          fore_blue,   /* blue value for the foreground of the source */
      +                                           uint16_t          back_red,    /* red value for the background of the source */
      +                                           uint16_t          back_green,  /* green value for the background of the source */
      +                                           uint16_t          back_blue)   /* blue value for the background of the source */
      +
      +

      + TODO: Describe source_char + and mask_char, for example by giving + an example on how to get the values. There is a list there: + X Font Cursors +

      +

      + So we first open that font (see Loading a Font) + and create the new cursor. As for every X ressource, we have to + ask for an X id with xcb_generate_id + first: +

      +
      +xcb_font_t           font;
      +xcb_cursor_t         cursor;
      +
      +/* The connection is set */
      +
      +font = xcb_generate_id (conn);
      +xcb_open_font (conn, font, strlen ("cursor"), "cursor");
      +
      +cursor = xcb_generate_id (conn);
      +xcb_create_glyph_cursor (conn, cursor, font, font,
      +                         58, 58 + 1,
      +                         0, 0, 0,
      +                         0, 0, 0);
      +
      +

      + We have created the cursor "right hand" by specifying 58 to + the source_font argument and 58 + 1 + to the mask_font. +

      +

      + The cursor is destroyed by using the function +

      +
      +xcb_void_cookie_t xcb_free_cursor (xcb_connection_t *c,
      +                                   xcb_cursor_t      cursor);
      +
      +

      + In the second method, we create a new cursor by using a pair + of pixmaps, with depth of one (that is, two colors + pixmaps). One pixmap defines the shape of the cursor, while + the other works as a mask, specifying which pixels of the + cursor will be actually drawn. The rest of the pixels will be + transparent. +

      +

      + TODO: give an example. +

      +
    2. Setting a window's mouse cursor +

      + Once the cursor is created, we can modify the cursor of our + window by using xcb_change_window_attributes + and using the XCB_CWCURSOR attribute: +

      +
      +uint32_t mask;
      +uint32_t value_list;
      +
      +/* The connection and window are set */
      +/* The cursor is already created */
      +
      +mask = XCB_CWCURSOR;
      +value_list = cursor;
      +xcb_change_window_attributes (conn, window, mask, &value_list);
      +
      +

      + Of course, the cursor and the font must be freed. +

      +
    3. Complete example +

      + The following example displays a window with a + button. When entering the window, the window cursor is changed + to an arrow. When clicking once on the button, the cursor is + changed to a hand. When clicking again on the button, the + cursor window gets back to the arrow. The Esc key exits the + application. +

      +
      +#include <stdlib.h>
      +#include <stdio.h>
      +#include <string.h>
      +
      +#include <xcb/xcb.h>
      +
      +#define WIDTH 300
      +#define HEIGHT 150
      +
      +
      +
      +static xcb_gc_t gc_font_get (xcb_connection_t *c,
      +                             xcb_screen_t     *screen,
      +                             xcb_window_t      window,
      +                             const char       *font_name);
      +
      +static void button_draw (xcb_connection_t *c,
      +                         xcb_screen_t     *screen,
      +                         xcb_window_t      window,
      +                         int16_t           x1,
      +                         int16_t           y1,
      +                         const char       *label);
      +
      +static void text_draw (xcb_connection_t *c,
      +                       xcb_screen_t     *screen,
      +                       xcb_window_t      window,
      +                       int16_t           x1,
      +                       int16_t           y1,
      +                       const char       *label);
      +
      +static void cursor_set (xcb_connection_t *c,
      +                        xcb_screen_t     *screen,
      +                        xcb_window_t      window,
      +                        int               cursor_id);
      +
      +
      +static void
      +button_draw (xcb_connection_t *c,
      +             xcb_screen_t     *screen,
      +             xcb_window_t      window,
      +             int16_t           x1,
      +             int16_t           y1,
      +             const char       *label)
      +{
      +  xcb_point_t          points[5];
      +  xcb_void_cookie_t    cookie_gc;
      +  xcb_void_cookie_t    cookie_line;
      +  xcb_void_cookie_t    cookie_text;
      +  xcb_generic_error_t *error;
      +  xcb_gcontext_t       gc;
      +  int16_t              width;
      +  int16_t              height;
      +  uint8_t              length;
      +  int16_t              inset;
      +
      +  length = strlen (label);
      +  inset = 2;
      +
      +  gc = gc_font_get(c, screen, window, "7x13");
      +
      +  width = 7 * length + 2 * (inset + 1);
      +  height = 13 + 2 * (inset + 1);
      +  points[0].x = x1;
      +  points[0].y = y1;
      +  points[1].x = x1 + width;
      +  points[1].y = y1;
      +  points[2].x = x1 + width;
      +  points[2].y = y1 - height;
      +  points[3].x = x1;
      +  points[3].y = y1 - height;
      +  points[4].x = x1;
      +  points[4].y = y1;
      +  cookie_line = xcb_poly_line_checked (c, XCB_COORD_MODE_ORIGIN,
      +                                       window, gc, 5, points);
      +
      +  error = xcb_request_check (c, cookie_line);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't draw lines : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  cookie_text = xcb_image_text_8_checked (c, length, window, gc,
      +                                          x1 + inset + 1,
      +                                          y1 - inset - 1, label);
      +  error = xcb_request_check (c, cookie_text);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't paste text : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  cookie_gc = xcb_free_gc (c, gc);
      +  error = xcb_request_check (c, cookie_gc);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't free gc : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +}
      +
      +static void
      +text_draw (xcb_connection_t *c,
      +           xcb_screen_t     *screen,
      +           xcb_window_t      window,
      +           int16_t           x1,
      +           int16_t           y1,
      +           const char       *label)
      +{
      +  xcb_void_cookie_t    cookie_gc;
      +  xcb_void_cookie_t    cookie_text;
      +  xcb_generic_error_t *error;
      +  xcb_gcontext_t       gc;
      +  uint8_t              length;
      +
      +  length = strlen (label);
      +
      +  gc = gc_font_get(c, screen, window, "7x13");
      +
      +  cookie_text = xcb_image_text_8_checked (c, length, window, gc,
      +                                          x1,
      +                                          y1, label);
      +  error = xcb_request_check (c, cookie_text);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't paste text : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  cookie_gc = xcb_free_gc (c, gc);
      +  error = xcb_request_check (c, cookie_gc);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't free gc : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +}
      +
      +static xcb_gc_t
      +gc_font_get (xcb_connection_t *c,
      +             xcb_screen_t     *screen,
      +             xcb_window_t      window,
      +             const char       *font_name)
      +{
      +  uint32_t             value_list[3];
      +  xcb_void_cookie_t    cookie_font;
      +  xcb_void_cookie_t    cookie_gc;
      +  xcb_generic_error_t *error;
      +  xcb_font_t           font;
      +  xcb_gcontext_t       gc;
      +  uint32_t             mask;
      +
      +  font = xcb_generate_id (c);
      +  cookie_font = xcb_open_font_checked (c, font,
      +                                       strlen (font_name),
      +                                       font_name);
      +
      +  error = xcb_request_check (c, cookie_font);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't open font : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    return -1;
      +  }
      +
      +  gc = xcb_generate_id (c);
      +  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
      +  value_list[0] = screen->black_pixel;
      +  value_list[1] = screen->white_pixel;
      +  value_list[2] = font;
      +  cookie_gc = xcb_create_gc_checked (c, gc, window, mask, value_list);
      +  error = xcb_request_check (c, cookie_gc);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't create gc : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  cookie_font = xcb_close_font_checked (c, font);
      +  error = xcb_request_check (c, cookie_font);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't close font : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  return gc;
      +}
      +
      +static void
      +cursor_set (xcb_connection_t *c,
      +            xcb_screen_t     *screen,
      +            xcb_window_t      window,
      +            int               cursor_id)
      +{
      +  uint32_t             values_list[3];
      +  xcb_void_cookie_t    cookie_font;
      +  xcb_void_cookie_t    cookie_gc;
      +  xcb_generic_error_t *error;
      +  xcb_font_t           font;
      +  xcb_cursor_t         cursor;
      +  xcb_gcontext_t       gc;
      +  uint32_t             mask;
      +  uint32_t             value_list;
      +
      +  font = xcb_generate_id (c);
      +  cookie_font = xcb_open_font_checked (c, font,
      +                                       strlen ("cursor"),
      +                                       "cursor");
      +  error = xcb_request_check (c, cookie_font);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't open font : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  cursor = xcb_generate_id (c);
      +  xcb_create_glyph_cursor (c, cursor, font, font,
      +                           cursor_id, cursor_id + 1,
      +                           0, 0, 0,
      +                           0, 0, 0);
      +
      +  gc = xcb_generate_id (c);
      +  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
      +  values_list[0] = screen->black_pixel;
      +  values_list[1] = screen->white_pixel;
      +  values_list[2] = font;
      +  cookie_gc = xcb_create_gc_checked (c, gc, window, mask, values_list);
      +  error = xcb_request_check (c, cookie_gc);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't create gc : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +
      +  mask = XCB_CW_CURSOR;
      +  value_list = cursor;
      +  xcb_change_window_attributes (c, window, mask, &value_list);
      +
      +  xcb_free_cursor (c, cursor);
      +
      +  cookie_font = xcb_close_font_checked (c, font);
      +  error = xcb_request_check (c, cookie_font);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't close font : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    exit (-1);
      +  }
      +}
      +
      +int main ()
      +{
      +  xcb_screen_iterator_t screen_iter;
      +  xcb_connection_t     *c;
      +  const xcb_setup_t    *setup;
      +  xcb_screen_t         *screen;
      +  xcb_generic_event_t  *e;
      +  xcb_generic_error_t  *error;
      +  xcb_void_cookie_t     cookie_window;
      +  xcb_void_cookie_t     cookie_map;
      +  xcb_window_t          window;
      +  uint32_t              mask;
      +  uint32_t              values[2];
      +  int                   screen_number;
      +  uint8_t               is_hand = 0;
      +
      +  /* getting the connection */
      +  c = xcb_connect (NULL, &screen_number);
      +  if (!c) {
      +    fprintf (stderr, "ERROR: can't connect to an X server\n");
      +    return -1;
      +  }
      +
      +  /* getting the current screen */
      +  setup = xcb_get_setup (c);
      +
      +  screen = NULL;
      +  screen_iter = xcb_setup_roots_iterator (setup);
      +  for (; screen_iter.rem != 0; --screen_number, xcb_screen_next (&screen_iter))
      +    if (screen_number == 0)
      +      {
      +        screen = screen_iter.data;
      +        break;
      +      }
      +  if (!screen) {
      +    fprintf (stderr, "ERROR: can't get the current screen\n");
      +    xcb_disconnect (c);
      +    return -1;
      +  }
      +
      +  /* creating the window */
      +  window = xcb_generate_id (c);
      +  mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
      +  values[0] = screen->white_pixel;
      +  values[1] =
      +    XCB_EVENT_MASK_KEY_RELEASE |
      +    XCB_EVENT_MASK_BUTTON_PRESS |
      +    XCB_EVENT_MASK_EXPOSURE |
      +    XCB_EVENT_MASK_POINTER_MOTION;
      +  cookie_window = xcb_create_window_checked (c,
      +                                             screen->root_depth,
      +                                             window, screen->root,
      +                                             20, 200, WIDTH, HEIGHT,
      +                                             0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
      +                                             screen->root_visual,
      +                                             mask, values);
      +  cookie_map = xcb_map_window_checked (c, window);
      +
      +  /* error managing */
      +  error = xcb_request_check (c, cookie_window);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't create window : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    return -1;
      +  }
      +  error = xcb_request_check (c, cookie_map);
      +  if (error) {
      +    fprintf (stderr, "ERROR: can't map window : %d\n", error->error_code);
      +    xcb_disconnect (c);
      +    return -1;
      +  }
      +
      +  cursor_set (c, screen, window, 68);
      +
      +  xcb_flush(c);
      +
      +  while (1) {
      +    e = xcb_poll_for_event(c);
      +    if (e) {
      +      switch (e->response_type & ~0x80) {
      +      case XCB_EXPOSE: {
      +        char *text;
      +
      +        text = "click here to change cursor";
      +        button_draw (c, screen, window,
      +                     (WIDTH - 7 * strlen(text)) / 2,
      +                     (HEIGHT - 16) / 2, text);
      +
      +        text = "Press ESC key to exit...";
      +        text_draw (c, screen, window, 10, HEIGHT - 10, text);
      +        break;
      +      }
      +      case XCB_BUTTON_PRESS: {
      +        xcb_button_press_event_t *ev;
      +        int                       length;
      +
      +        ev = (xcb_button_press_event_t *)e;
      +        length = strlen ("click here to change cursor");
      +
      +        if ((ev->event_x >= (WIDTH - 7 * length) / 2) &&
      +            (ev->event_x <= ((WIDTH - 7 * length) / 2 + 7 * length + 6)) &&
      +            (ev->event_y >= (HEIGHT - 16) / 2 - 19) &&
      +            (ev->event_y <= ((HEIGHT - 16) / 2)))
      +          is_hand = 1 - is_hand;
      +
      +        is_hand ? cursor_set (c, screen, window, 58) : cursor_set (c, screen, window, 68);
      +      }
      +      case XCB_KEY_RELEASE: {
      +        xcb_key_release_event_t *ev;
      +
      +        ev = (xcb_key_release_event_t *)e;
      +
      +        switch (ev->detail) {
      +          /* ESC */
      +        case 9:
      +          free (e);
      +          xcb_disconnect (c);
      +          return 0;
      +        }
      +      }
      +      }
      +      free (e);
      +    }
      +  }
      +
      +  return 0;
      +}
      +
      +
    +
  17. Translation of basic Xlib functions and macros +

    + The problem when you want to port an Xlib program to XCB is that + you don't know if the Xlib function that you want to "translate" + is a X Window one or an Xlib macro. In that section, we describe + a way to translate the usual functions or macros that Xlib + provides. It's usually just a member of a structure. +

    +
      +
    1. Members of the Display structure +

      + In this section, we look at how to translate the macros that + return some members of the Display + structure. They are obtained by using a function that requires a + xcb_connection_t * or a member of the + xcb_setup_t structure + (via the function xcb_get_setup), or + a function that requires that structure. +

      +
        +
      1. ConnectionNumber +

        + This number is the file descriptor that connects the client + to the server. You just have to use that function: +

        +
        +int xcb_get_file_descriptor (xcb_connection_t *c);
        +
        +
      2. DefaultScreen +

        + That number is not stored by XCB. It is returned in the + second parameter of the function xcb_connect. + Hence, you have to store it yourself if you want to use + it. Then, to get the xcb_screen_t + structure, you have to iterate on the screens. + The equivalent function of the Xlib's + ScreenOfDisplay function can be + found below. This is also provided in the + xcb_aux_t library as xcb_aux_get_screen(). OK, here is the + small piece of code to get that number: +

        +
        +xcb_connection_t *c;
        +int               screen_default_nbr;
        +
        +/* you pass the name of the display you want to xcb_connect_t */
        +
        +c = xcb_connect (display_name, &screen_default_nbr);
        +
        +/* screen_default_nbr contains now the number of the default screen */
        +
        +
      3. QLength +

        + Not documented yet. +

        +

        + However, this points out a basic difference in philosophy between + Xlib and XCB. Xlib has several functions for filtering and + manipulating the incoming and outgoing X message queues. XCB + wishes to hide this as much as possible from the user, which + allows for more freedom in implementation strategies. +

        +
      4. ScreenCount +

        + You get the count of screens with the functions + xcb_get_setup + and + xcb_setup_roots_iterator + (if you need to iterate): +

        +
        +xcb_connection_t *c;
        +int               screen_count;
        +
        +/* you init the connection */
        +
        +screen_count = xcb_setup_roots_iterator (xcb_get_setup (c)).rem;
        +
        +/* screen_count contains now the count of screens */
        +
        +

        + If you don't want to iterate over the screens, a better way + to get that number is to use + xcb_setup_roots_length_t: +

        +
        +xcb_connection_t *c;
        +int               screen_count;
        +
        +/* you init the connection */
        +
        +screen_count = xcb_setup_roots_length (xcb_get_setup (c));
        +
        +/* screen_count contains now the count of screens */
        +
        +
      5. ServerVendor +

        + You get the name of the vendor of the server hardware with + the functions xcb_get_setup + and + xcb_setup_vendor. Beware + that, unlike Xlib, the string returned by XCB is not + necessarily null-terminaled: +

        +
        +xcb_connection_t *c;
        +char             *vendor = NULL;
        +int               length;
        +
        +/* you init the connection */
        +length = xcb_setup_vendor_length (xcb_get_setup (c));
        +vendor = (char *)malloc (length + 1);
        +if (vendor)
        +memcpy (vendor, xcb_setup_vendor (xcb_get_setup (c)), length);
        +vendor[length] = '\0';
        +
        +/* vendor contains now the name of the vendor. Must be freed when not used anymore */
        +
        +
      6. ProtocolVersion +

        + You get the major version of the protocol in the + xcb_setup_t + structure, with the function xcb_get_setup: +

        +
        +xcb_connection_t *c;
        +uint16_t          protocol_major_version;
        +
        +/* you init the connection */
        +
        +protocol_major_version = xcb_get_setup (c)->protocol_major_version;
        +
        +/* protocol_major_version contains now the major version of the protocol */
        +
        +
      7. ProtocolRevision +

        + You get the minor version of the protocol in the + xcb_setup_t + structure, with the function xcb_get_setup: +

        +
        +xcb_connection_t *c;
        +uint16_t          protocol_minor_version;
        +
        +/* you init the connection */
        +
        +protocol_minor_version = xcb_get_setup (c)->protocol_minor_version;
        +
        +/* protocol_minor_version contains now the minor version of the protocol */
        +
        +
      8. VendorRelease +

        + You get the number of the release of the server hardware in the + xcb_setup_t + structure, with the function xcb_get_setup: +

        +
        +xcb_connection_t *c;
        +uint32_t          release_number;
        +
        +/* you init the connection */
        +
        +release_number = xcb_get_setup (c)->release_number;
        +
        +/* release_number contains now the number of the release of the server hardware */
        +
        +
      9. DisplayString +

        + The name of the display is not stored in XCB. You have to + store it by yourself. +

        +
      10. BitmapUnit +

        + You get the bitmap scanline unit in the + xcb_setup_t + structure, with the function xcb_get_setup: +

        +
        +xcb_connection_t *c;
        +uint8_t           bitmap_format_scanline_unit;
        +
        +/* you init the connection */
        +
        +bitmap_format_scanline_unit = xcb_get_setup (c)->bitmap_format_scanline_unit;
        +
        +/* bitmap_format_scanline_unit contains now the bitmap scanline unit */
        +
        +
      11. BitmapBitOrder +

        + You get the bitmap bit order in the + xcb_setup_t + structure, with the function xcb_get_setup: +

        +
        +xcb_connection_t *c;
        +uint8_t           bitmap_format_bit_order;
        +
        +/* you init the connection */
        +
        +bitmap_format_bit_order = xcb_get_setup (c)->bitmap_format_bit_order;
        +
        +/* bitmap_format_bit_order contains now the bitmap bit order */
        +
        +
      12. BitmapPad +

        + You get the bitmap scanline pad in the + xcb_setup_t + structure, with the function xcb_get_setup: +

        +
        +xcb_connection_t *c;
        +uint8_t           bitmap_format_scanline_pad;
        +
        +/* you init the connection */
        +
        +bitmap_format_scanline_pad = xcb_get_setup (c)->bitmap_format_scanline_pad;
        +
        +/* bitmap_format_scanline_pad contains now the bitmap scanline pad */
        +
        +
      13. ImageByteOrder +

        + You get the image byte order in the + xcb_setup_t + structure, with the function xcb_get_setup: +

        +
        +xcb_connection_t *c;
        +uint8_t           image_byte_order;
        +
        +/* you init the connection */
        +
        +image_byte_order = xcb_get_setup (c)->image_byte_order;
        +
        +/* image_byte_order contains now the image byte order */
        +
        +
      +
    2. ScreenOfDisplay related functions +

      + in Xlib, ScreenOfDisplay returns a + Screen structure that contains + several characteristics of your screen. XCB has a similar + structure (xcb_screen_t), + but the way to obtain it is a bit different. With + Xlib, you just provide the number of the screen and you grab it + from an array. With XCB, you iterate over all the screens to + obtain the one you want. The complexity of this operation is + O(n). So the best is to store this structure if you use + it often. See screen_of_display just below. +

      +

      + Xlib provides generally two functions to obtain the characteristics + related to the screen. One with the display and the number of + the screen, which calls ScreenOfDisplay, + and the other that uses the Screen structure. + This might be a bit confusing. As mentioned above, with XCB, it + is better to store the xcb_screen_t + structure. Then, you have to read the members of this + structure. That's why the Xlib functions are put by pairs (or + more) as, with XCB, you will use the same code. +

      +
        +
      1. ScreenOfDisplay +

        + This function returns the Xlib Screen + structure. With XCB, you iterate over all the screens and + once you get the one you want, you return it: +

        +
        
        +xcb_screen_t *screen_of_display (xcb_connection_t *c,
        +                                 int               screen)
        +{
        +  xcb_screen_iterator_t iter;
        +
        +  iter = xcb_setup_roots_iterator (xcb_get_setup (c));
        +  for (; iter.rem; --screen, xcb_screen_next (&iter))
        +    if (screen == 0)
        +      return iter.data;
        +
        +  return NULL;
        +}
        +
        +

        + As mentioned above, you might want to store the value + returned by this function. +

        +

        + All the functions below will use the result of that + function, as they just grab a specific member of the + xcb_screen_t structure. +

        +
      2. DefaultScreenOfDisplay +

        + It is the default screen that you obtain when you connect to + the X server. It suffices to call the screen_of_display + function above with the connection and the number of the + default screen. +

        +
        +xcb_connection_t *c;
        +int               screen_default_nbr;
        +xcb_screen_t     *default_screen;  /* the returned default screen */
        +
        +/* you pass the name of the display you want to xcb_connect_t */
        +
        +c = xcb_connect (display_name, &screen_default_nbr);
        +default_screen = screen_of_display (c, screen_default_nbr);
        +
        +/* default_screen contains now the default root window, or a NULL window if no screen is found */
        +
        +
      3. RootWindow / RootWindowOfScreen +
        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +xcb_window_t      root_window = { 0 };  /* the returned window */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  root_window = screen->root;
        +
        +/* root_window contains now the root window, or a NULL window if no screen is found */
        +
        +
      4. DefaultRootWindow +

        + It is the root window of the default screen. So, you call + ScreenOfDisplay with the + default screen number and you get the + root window as above: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_default_nbr;
        +xcb_window_t      root_window = { 0 };  /* the returned root window */
        +
        +/* you pass the name of the display you want to xcb_connect_t */
        +
        +c = xcb_connect (display_name, &screen_default_nbr);
        +screen = screen_of_display (c, screen_default_nbr);
        +if (screen)
        +  root_window = screen->root;
        +
        +/* root_window contains now the default root window, or a NULL window if no screen is found */
        +
        +
      5. DefaultVisual / DefaultVisualOfScreen +

        + While a Visual is, in Xlib, a structure, in XCB, there are + two types: xcb_visualid_t, which is + the Id of the visual, and xcb_visualtype_t, + which corresponds to the Xlib Visual. To get the Id of the + visual of a screen, just get the + root_visual + member of a xcb_screen_t: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +xcb_visualid_t    root_visual = { 0 };    /* the returned visual Id */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  root_visual = screen->root_visual;
        +
        +/* root_visual contains now the value of the Id of the visual, or a NULL visual if no screen is found */
        +
        +

        + To get the xcb_visualtype_t + structure, it's a bit less easy. You have to get the + xcb_screen_t structure that you want, + get its root_visual member, + then iterate over the xcb_depth_ts + and the xcb_visualtype_ts, and compare + the xcb_visualid_t of these xcb_visualtype_ts: + with root_visual: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +xcb_visualid_t    root_visual = { 0 };
        +xcb_visualtype_t  *visual_type = NULL;    /* the returned visual type */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen) {
        +  xcb_depth_iterator_t depth_iter;
        +
        +  depth_iter = xcb_screen_allowed_depths_iterator (screen);
        +  for (; depth_iter.rem; xcb_depth_next (&depth_iter)) {
        +    xcb_visualtype_iterator_t visual_iter;
        +
        +    visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
        +    for (; visual_iter.rem; xcb_visualtype_next (&visual_iter)) {
        +      if (screen->root_visual == visual_iter.data->visual_id) {
        +        visual_type = visual_iter.data;
        +        break;
        +      }
        +    }
        +  }
        +}
        +
        +/* visual_type contains now the visual structure, or a NULL visual structure if no screen is found */
        +
        +
      6. DefaultGC / DefaultGCOfScreen +

        + This default Graphic Context is just a newly created Graphic + Context, associated to the root window of a + xcb_screen_t, + using the black white pixels of that screen: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +xcb_gcontext_t    gc = { 0 };    /* the returned default graphic context */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen) {
        +  xcb_drawable_t draw;
        +  uint32_t       mask;
        +  uint32_t       values[2];
        +
        +  gc = xcb_generate_id (c);
        +  draw = screen->root;
        +  mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
        +  values[0] = screen->black_pixel;
        +  values[1] = screen->white_pixel;
        +  xcb_create_gc (c, gc, draw, mask, values);
        +}
        +
        +/* gc contains now the default graphic context */
        +
        +
      7. BlackPixel / BlackPixelOfScreen +

        + It is the Id of the black pixel, which is in the structure + of an xcb_screen_t. +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint32_t          black_pixel = 0;    /* the returned black pixel */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  black_pixel = screen->black_pixel;
        +
        +/* black_pixel contains now the value of the black pixel, or 0 if no screen is found */
        +
        +
      8. WhitePixel / WhitePixelOfScreen +

        + It is the Id of the white pixel, which is in the structure + of an xcb_screen_t. +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint32_t          white_pixel = 0;    /* the returned white pixel */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  white_pixel = screen->white_pixel;
        +
        +/* white_pixel contains now the value of the white pixel, or 0 if no screen is found */
        +
        +
      9. DisplayWidth / WidthOfScreen +

        + It is the width in pixels of the screen that you want, and + which is in the structure of the corresponding + xcb_screen_t. +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint32_t          width_in_pixels = 0;    /* the returned width in pixels */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  width_in_pixels = screen->width_in_pixels;
        +
        +/* width_in_pixels contains now the width in pixels, or 0 if no screen is found */
        +
        +
      10. DisplayHeight / HeightOfScreen +

        + It is the height in pixels of the screen that you want, and + which is in the structure of the corresponding + xcb_screen_t. +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint32_t          height_in_pixels = 0;    /* the returned height in pixels */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  height_in_pixels = screen->height_in_pixels;
        +
        +/* height_in_pixels contains now the height in pixels, or 0 if no screen is found */
        +
        +
      11. DisplayWidthMM / WidthMMOfScreen +

        + It is the width in millimeters of the screen that you want, and + which is in the structure of the corresponding + xcb_screen_t. +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint32_t          width_in_millimeters = 0;    /* the returned width in millimeters */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  width_in_millimeters = screen->width_in_millimeters;
        +
        +/* width_in_millimeters contains now the width in millimeters, or 0 if no screen is found */
        +
        +
      12. DisplayHeightMM / HeightMMOfScreen +

        + It is the height in millimeters of the screen that you want, and + which is in the structure of the corresponding + xcb_screen_t. +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint32_t          height_in_millimeters = 0;    /* the returned height in millimeters */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  height_in_millimeters = screen->height_in_millimeters;
        +
        +/* height_in_millimeters contains now the height in millimeters, or 0 if no screen is found */
        +
        +
      13. DisplayPlanes / DefaultDepth / DefaultDepthOfScreen / PlanesOfScreen +

        + It is the depth (in bits) of the root window of the + screen. You get it from the xcb_screen_t structure. +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint8_t           root_depth = 0;  /* the returned depth of the root window */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  root_depth = screen->root_depth;
        +
        +/* root_depth contains now the depth of the root window, or 0 if no screen is found */
        +
        +
      14. DefaultColormap / DefaultColormapOfScreen +

        + This is the default colormap of the screen (and not the + (default) colormap of the default screen !). As usual, you + get it from the xcb_screen_t structure: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +xcb_colormap_t    default_colormap = { 0 };  /* the returned default colormap */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  default_colormap = screen->default_colormap;
        +
        +/* default_colormap contains now the default colormap, or a NULL colormap if no screen is found */
        +
        +
      15. MinCmapsOfScreen +

        + You get the minimum installed colormaps in the xcb_screen_t structure: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint16_t          min_installed_maps = 0;  /* the returned minimum installed colormaps */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  min_installed_maps = screen->min_installed_maps;
        +
        +/* min_installed_maps contains now the minimum installed colormaps, or 0 if no screen is found */
        +
        +
      16. MaxCmapsOfScreen +

        + You get the maximum installed colormaps in the xcb_screen_t structure: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint16_t          max_installed_maps = 0;  /* the returned maximum installed colormaps */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  max_installed_maps = screen->max_installed_maps;
        +
        +/* max_installed_maps contains now the maximum installed colormaps, or 0 if no screen is found */
        +
        +
      17. DoesSaveUnders +

        + You know if save_unders is set, + by looking in the xcb_screen_t structure: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint8_t           save_unders = 0;  /* the returned value of save_unders */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  save_unders = screen->save_unders;
        +
        +/* save_unders contains now the value of save_unders, or FALSE if no screen is found */
        +
        +
      18. DoesBackingStore +

        + You know the value of backing_stores, + by looking in the xcb_screen_t structure: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint8_t           backing_stores = 0;  /* the returned value of backing_stores */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  backing_stores = screen->backing_stores;
        +
        +/* backing_stores contains now the value of backing_stores, or FALSE if no screen is found */
        +
        +
      19. EventMaskOfScreen +

        + To get the current input masks, + you look in the xcb_screen_t structure: +

        +
        +xcb_connection_t *c;
        +xcb_screen_t     *screen;
        +int               screen_nbr;
        +uint32_t          current_input_masks = 0;  /* the returned value of current input masks */
        +
        +/* you init the connection and screen_nbr */
        +
        +screen = screen_of_display (c, screen_nbr);
        +if (screen)
        +  current_input_masks = screen->current_input_masks;
        +
        +/* current_input_masks contains now the value of the current input masks, or FALSE if no screen is found */
        +
        +
      +
    3. Miscellaneous macros +
        +
      1. DisplayOfScreen +

        + in Xlib, the Screen structure + stores its associated Display + structure. This is not the case in the X Window protocol, + hence, it's also not the case in XCB. So you have to store + it by yourself. +

        +
      2. DisplayCells / CellsOfScreen +

        + To get the colormap entries, + you look in the xcb_visualtype_t + structure, that you grab like here: +

        +
        +xcb_connection_t *c;
        +xcb_visualtype_t *visual_type;
        +uint16_t          colormap_entries = 0;  /* the returned value of the colormap entries */
        +
        +/* you init the connection and visual_type */
        +
        +if (visual_type)
        +  colormap_entries = visual_type->colormap_entries;
        +
        +/* colormap_entries contains now the value of the colormap entries, or FALSE if no screen is found */
        +
        +
      +
    +
+
+ + + diff --git a/libxcb/doc/tutorial/xcb.css b/libxcb/doc/tutorial/xcb.css index 48b0249a8..e059b3b33 100644 --- a/libxcb/doc/tutorial/xcb.css +++ b/libxcb/doc/tutorial/xcb.css @@ -1,123 +1,123 @@ -body -{ - background-color: #dddddd; - color: #000000; - padding: 8px; - margin: 0px; -} -div.title -{ - text-align: center; - font-weight: bold; - font-size: 28px; -} -div.emph -{ - text-align: left; - font-weight: bold; -} -div.section li.title -{ - font-weight: bold; - font-size: 22px; -} -div.section li.title p -{ - font-weight: normal; - font-size: 16px; -} -div.section li.title ul -{ - font-weight: normal; - font-size: 16px; -} -div.section li.title ol -{ - font-weight: normal; - font-size: 16px; -} -div.section li.subtitle -{ - font-weight: bold; - font-size: 18px; -} -div.section li.subsubtitle -{ - font-weight: bold; - font-size: 16px; -} -div.comp -{ - border: thin solid #000000; - color: #000000; - background-color: #ffffe0; - padding: 14px; -} -div.comp div.title -{ - font-weight: bold; - font-size: 16px; - text-align: center; -} -div.comp div.xlib ul li -{ - font-family: monospace; - font-size: 12px; - font-weight: bold; - position: absolute; - width: 49%; - margin-left: 0px; - margin-top: 10px; -} -div.comp div.xcb ul li -{ - font-family: monospace; - font-size: 12px; - font-weight: bold; - position: relative; - margin-left: 51%; - margin-top: 10px; -} -pre.code -{ - border: thin solid #000000; - color: #000000; - background-color: #efefef; - padding: 4px; - text-align: left; - font-size: 10px; -} -pre.text -{ - border: thin solid #000000; - color: #000000; - background-color: #efefef; - padding: 4px; - text-align: left; - font-size: 10px; -} -span.code -{ - font-family: monospace; - font-size: 12px; -} -pre.code .type -{ - color: #44bb44; -} -pre.code .function -{ - color: #449fb7; -} -pre.code .include -{ - color: #7d93ae; -} -pre.code .string -{ - color: #ef6e4b; -} -pre.code .keyword -{ - color: #00bbbb; -} +body +{ + background-color: #dddddd; + color: #000000; + padding: 8px; + margin: 0px; +} +div.title +{ + text-align: center; + font-weight: bold; + font-size: 28px; +} +div.emph +{ + text-align: left; + font-weight: bold; +} +div.section li.title +{ + font-weight: bold; + font-size: 22px; +} +div.section li.title p +{ + font-weight: normal; + font-size: 16px; +} +div.section li.title ul +{ + font-weight: normal; + font-size: 16px; +} +div.section li.title ol +{ + font-weight: normal; + font-size: 16px; +} +div.section li.subtitle +{ + font-weight: bold; + font-size: 18px; +} +div.section li.subsubtitle +{ + font-weight: bold; + font-size: 16px; +} +div.comp +{ + border: thin solid #000000; + color: #000000; + background-color: #ffffe0; + padding: 14px; +} +div.comp div.title +{ + font-weight: bold; + font-size: 16px; + text-align: center; +} +div.comp div.xlib ul li +{ + font-family: monospace; + font-size: 12px; + font-weight: bold; + position: absolute; + width: 49%; + margin-left: 0px; + margin-top: 10px; +} +div.comp div.xcb ul li +{ + font-family: monospace; + font-size: 12px; + font-weight: bold; + position: relative; + margin-left: 51%; + margin-top: 10px; +} +pre.code +{ + border: thin solid #000000; + color: #000000; + background-color: #efefef; + padding: 4px; + text-align: left; + font-size: 10px; +} +pre.text +{ + border: thin solid #000000; + color: #000000; + background-color: #efefef; + padding: 4px; + text-align: left; + font-size: 10px; +} +span.code +{ + font-family: monospace; + font-size: 12px; +} +pre.code .type +{ + color: #44bb44; +} +pre.code .function +{ + color: #449fb7; +} +pre.code .include +{ + color: #7d93ae; +} +pre.code .string +{ + color: #ef6e4b; +} +pre.code .keyword +{ + color: #00bbbb; +} diff --git a/libxcb/doc/xcb.doxygen.in b/libxcb/doc/xcb.doxygen.in index d674cbab1..58aa07630 100644 --- a/libxcb/doc/xcb.doxygen.in +++ b/libxcb/doc/xcb.doxygen.in @@ -1,1253 +1,1253 @@ -# Doxyfile 1.5.0 - -# This file describes the settings to be used by the documentation system -# doxygen (www.doxygen.org) for a project -# -# All text after a hash (#) is considered a comment and will be ignored -# The format is: -# TAG = value [value, ...] -# For lists items can also be appended using: -# TAG += value [value, ...] -# Values that contain spaces should be placed between quotes (" ") - -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- - -# The PROJECT_NAME tag is a single word (or a sequence of words surrounded -# by quotes) that should identify the project. - -PROJECT_NAME = "XCB" - -# The PROJECT_NUMBER tag can be used to enter a project or revision number. -# This could be handy for archiving the generated documentation or -# if some version control system is used. - -PROJECT_NUMBER = @VERSION@ - -# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) -# base path where the generated documentation will be put. -# If a relative path is entered, it will be relative to the location -# where doxygen was started. If left blank the current directory will be used. - -OUTPUT_DIRECTORY = @top_builddir@/doc - -# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create -# 4096 sub-directories (in 2 levels) under the output directory of each output -# format and will distribute the generated files over these directories. -# Enabling this option can be useful when feeding doxygen a huge amount of -# source files, where putting all generated files in the same directory would -# otherwise cause performance problems for the file system. - -CREATE_SUBDIRS = NO - -# The OUTPUT_LANGUAGE tag is used to specify the language in which all -# documentation generated by doxygen is written. Doxygen will use this -# information to generate all constant output in the proper language. -# The default language is English, other supported languages are: -# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, -# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, -# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, -# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, -# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. - -OUTPUT_LANGUAGE = English - -# This tag can be used to specify the encoding used in the generated output. -# The encoding is not always determined by the language that is chosen, -# but also whether or not the output is meant for Windows or non-Windows users. -# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES -# forces the Windows encoding (this is the default for the Windows binary), -# whereas setting the tag to NO uses a Unix-style encoding (the default for -# all platforms other than Windows). - -USE_WINDOWS_ENCODING = NO - -# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will -# include brief member descriptions after the members that are listed in -# the file and class documentation (similar to JavaDoc). -# Set to NO to disable this. - -BRIEF_MEMBER_DESC = YES - -# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend -# the brief description of a member or function before the detailed description. -# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the -# brief descriptions will be completely suppressed. - -REPEAT_BRIEF = YES - -# This tag implements a quasi-intelligent brief description abbreviator -# that is used to form the text in various listings. Each string -# in this list, if found as the leading text of the brief description, will be -# stripped from the text and the result after processing the whole list, is -# used as the annotated text. Otherwise, the brief description is used as-is. -# If left blank, the following values are used ("$name" is automatically -# replaced with the name of the entity): "The $name class" "The $name widget" -# "The $name file" "is" "provides" "specifies" "contains" -# "represents" "a" "an" "the" - -ABBREVIATE_BRIEF = - -# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then -# Doxygen will generate a detailed section even if there is only a brief -# description. - -ALWAYS_DETAILED_SEC = NO - -# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all -# inherited members of a class in the documentation of that class as if those -# members were ordinary class members. Constructors, destructors and assignment -# operators of the base classes will not be shown. - -INLINE_INHERITED_MEMB = NO - -# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full -# path before files name in the file list and in the header files. If set -# to NO the shortest path that makes the file name unique will be used. - -FULL_PATH_NAMES = NO - -# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag -# can be used to strip a user-defined part of the path. Stripping is -# only done if one of the specified strings matches the left-hand part of -# the path. The tag can be used to show relative paths in the file list. -# If left blank the directory from which doxygen is run is used as the -# path to strip. - -STRIP_FROM_PATH = - -# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of -# the path mentioned in the documentation of a class, which tells -# the reader which header file to include in order to use a class. -# If left blank only the name of the header file containing the class -# definition is used. Otherwise one should specify the include paths that -# are normally passed to the compiler using the -I flag. - -STRIP_FROM_INC_PATH = - -# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter -# (but less readable) file names. This can be useful is your file systems -# doesn't support long names like on DOS, Mac, or CD-ROM. - -SHORT_NAMES = NO - -# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen -# will interpret the first line (until the first dot) of a JavaDoc-style -# comment as the brief description. If set to NO, the JavaDoc -# comments will behave just like the Qt-style comments (thus requiring an -# explicit @brief command for a brief description. - -JAVADOC_AUTOBRIEF = NO - -# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen -# treat a multi-line C++ special comment block (i.e. a block of //! or /// -# comments) as a brief description. This used to be the default behaviour. -# The new default is to treat a multi-line C++ comment block as a detailed -# description. Set this tag to YES if you prefer the old behaviour instead. - -MULTILINE_CPP_IS_BRIEF = NO - -# If the DETAILS_AT_TOP tag is set to YES then Doxygen -# will output the detailed description near the top, like JavaDoc. -# If set to NO, the detailed description appears after the member -# documentation. - -DETAILS_AT_TOP = NO - -# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented -# member inherits the documentation from any documented member that it -# re-implements. - -INHERIT_DOCS = YES - -# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce -# a new page for each member. If set to NO, the documentation of a member will -# be part of the file/class/namespace that contains it. - -SEPARATE_MEMBER_PAGES = NO - -# The TAB_SIZE tag can be used to set the number of spaces in a tab. -# Doxygen uses this value to replace tabs by spaces in code fragments. - -TAB_SIZE = 8 - -# This tag can be used to specify a number of aliases that acts -# as commands in the documentation. An alias has the form "name=value". -# For example adding "sideeffect=\par Side Effects:\n" will allow you to -# put the command \sideeffect (or @sideeffect) in the documentation, which -# will result in a user-defined paragraph with heading "Side Effects:". -# You can put \n's in the value part of an alias to insert newlines. - -ALIASES = - -# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C -# sources only. Doxygen will then generate output that is more tailored for C. -# For instance, some of the names that are used will be different. The list -# of all members will be omitted, etc. - -OPTIMIZE_OUTPUT_FOR_C = YES - -# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java -# sources only. Doxygen will then generate output that is more tailored for Java. -# For instance, namespaces will be presented as packages, qualified scopes -# will look different, etc. - -OPTIMIZE_OUTPUT_JAVA = NO - -# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to -# include (a tag file for) the STL sources as input, then you should -# set this tag to YES in order to let doxygen match functions declarations and -# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. -# func(std::string) {}). This also make the inheritance and collaboration -# diagrams that involve STL classes more complete and accurate. - -BUILTIN_STL_SUPPORT = NO - -# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC -# tag is set to YES, then doxygen will reuse the documentation of the first -# member in the group (if any) for the other members of the group. By default -# all members of a group must be documented explicitly. - -DISTRIBUTE_GROUP_DOC = NO - -# Set the SUBGROUPING tag to YES (the default) to allow class member groups of -# the same type (for instance a group of public functions) to be put as a -# subgroup of that type (e.g. under the Public Functions section). Set it to -# NO to prevent subgrouping. Alternatively, this can be done per class using -# the \nosubgrouping command. - -SUBGROUPING = YES - -#--------------------------------------------------------------------------- -# Build related configuration options -#--------------------------------------------------------------------------- - -# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in -# documentation are documented, even if no documentation was available. -# Private class members and static file members will be hidden unless -# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES - -EXTRACT_ALL = NO - -# If the EXTRACT_PRIVATE tag is set to YES all private members of a class -# will be included in the documentation. - -EXTRACT_PRIVATE = NO - -# If the EXTRACT_STATIC tag is set to YES all static members of a file -# will be included in the documentation. - -EXTRACT_STATIC = NO - -# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) -# defined locally in source files will be included in the documentation. -# If set to NO only classes defined in header files are included. - -EXTRACT_LOCAL_CLASSES = YES - -# This flag is only useful for Objective-C code. When set to YES local -# methods, which are defined in the implementation section but not in -# the interface are included in the documentation. -# If set to NO (the default) only methods in the interface are included. - -EXTRACT_LOCAL_METHODS = NO - -# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all -# undocumented members of documented classes, files or namespaces. -# If set to NO (the default) these members will be included in the -# various overviews, but no documentation section is generated. -# This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_MEMBERS = NO - -# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all -# undocumented classes that are normally visible in the class hierarchy. -# If set to NO (the default) these classes will be included in the various -# overviews. This option has no effect if EXTRACT_ALL is enabled. - -HIDE_UNDOC_CLASSES = NO - -# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all -# friend (class|struct|union) declarations. -# If set to NO (the default) these declarations will be included in the -# documentation. - -HIDE_FRIEND_COMPOUNDS = NO - -# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any -# documentation blocks found inside the body of a function. -# If set to NO (the default) these blocks will be appended to the -# function's detailed documentation block. - -HIDE_IN_BODY_DOCS = NO - -# The INTERNAL_DOCS tag determines if documentation -# that is typed after a \internal command is included. If the tag is set -# to NO (the default) then the documentation will be excluded. -# Set it to YES to include the internal documentation. - -INTERNAL_DOCS = NO - -# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate -# file names in lower-case letters. If set to YES upper-case letters are also -# allowed. This is useful if you have classes or files whose names only differ -# in case and if your file system supports case sensitive file names. Windows -# and Mac users are advised to set this option to NO. - -CASE_SENSE_NAMES = YES - -# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen -# will show members with their full class and namespace scopes in the -# documentation. If set to YES the scope will be hidden. - -HIDE_SCOPE_NAMES = NO - -# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen -# will put a list of the files that are included by a file in the documentation -# of that file. - -SHOW_INCLUDE_FILES = YES - -# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] -# is inserted in the documentation for inline members. - -INLINE_INFO = YES - -# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen -# will sort the (detailed) documentation of file and class members -# alphabetically by member name. If set to NO the members will appear in -# declaration order. - -SORT_MEMBER_DOCS = YES - -# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the -# brief documentation of file, namespace and class members alphabetically -# by member name. If set to NO (the default) the members will appear in -# declaration order. - -SORT_BRIEF_DOCS = NO - -# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be -# sorted by fully-qualified names, including namespaces. If set to -# NO (the default), the class list will be sorted only by class name, -# not including the namespace part. -# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. -# Note: This option applies only to the class list, not to the -# alphabetical list. - -SORT_BY_SCOPE_NAME = NO - -# The GENERATE_TODOLIST tag can be used to enable (YES) or -# disable (NO) the todo list. This list is created by putting \todo -# commands in the documentation. - -GENERATE_TODOLIST = YES - -# The GENERATE_TESTLIST tag can be used to enable (YES) or -# disable (NO) the test list. This list is created by putting \test -# commands in the documentation. - -GENERATE_TESTLIST = YES - -# The GENERATE_BUGLIST tag can be used to enable (YES) or -# disable (NO) the bug list. This list is created by putting \bug -# commands in the documentation. - -GENERATE_BUGLIST = YES - -# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or -# disable (NO) the deprecated list. This list is created by putting -# \deprecated commands in the documentation. - -GENERATE_DEPRECATEDLIST= YES - -# The ENABLED_SECTIONS tag can be used to enable conditional -# documentation sections, marked by \if sectionname ... \endif. - -ENABLED_SECTIONS = - -# The MAX_INITIALIZER_LINES tag determines the maximum number of lines -# the initial value of a variable or define consists of for it to appear in -# the documentation. If the initializer consists of more lines than specified -# here it will be hidden. Use a value of 0 to hide initializers completely. -# The appearance of the initializer of individual variables and defines in the -# documentation can be controlled using \showinitializer or \hideinitializer -# command in the documentation regardless of this setting. - -MAX_INITIALIZER_LINES = 30 - -# Set the SHOW_USED_FILES tag to NO to disable the list of files generated -# at the bottom of the documentation of classes and structs. If set to YES the -# list will mention the files that were used to generate the documentation. - -SHOW_USED_FILES = YES - -# If the sources in your project are distributed over multiple directories -# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy -# in the documentation. The default is NO. - -SHOW_DIRECTORIES = NO - -# The FILE_VERSION_FILTER tag can be used to specify a program or script that -# doxygen should invoke to get the current version for each file (typically from the -# version control system). Doxygen will invoke the program by executing (via -# popen()) the command , where is the value of -# the FILE_VERSION_FILTER tag, and is the name of an input file -# provided by doxygen. Whatever the program writes to standard output -# is used as the file version. See the manual for examples. - -FILE_VERSION_FILTER = - -#--------------------------------------------------------------------------- -# configuration options related to warning and progress messages -#--------------------------------------------------------------------------- - -# The QUIET tag can be used to turn on/off the messages that are generated -# by doxygen. Possible values are YES and NO. If left blank NO is used. - -QUIET = YES - -# The WARNINGS tag can be used to turn on/off the warning messages that are -# generated by doxygen. Possible values are YES and NO. If left blank -# NO is used. - -WARNINGS = YES - -# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings -# for undocumented members. If EXTRACT_ALL is set to YES then this flag will -# automatically be disabled. - -# XXX: In the future this should be turned on. For now it generates too much noise. -WARN_IF_UNDOCUMENTED = NO - -# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for -# potential errors in the documentation, such as not documenting some -# parameters in a documented function, or documenting parameters that -# don't exist or using markup commands wrongly. - -WARN_IF_DOC_ERROR = YES - -# This WARN_NO_PARAMDOC option can be abled to get warnings for -# functions that are documented, but have no documentation for their parameters -# or return value. If set to NO (the default) doxygen will only warn about -# wrong or incomplete parameter documentation, but not about the absence of -# documentation. - -WARN_NO_PARAMDOC = YES - -# The WARN_FORMAT tag determines the format of the warning messages that -# doxygen can produce. The string should contain the $file, $line, and $text -# tags, which will be replaced by the file and line number from which the -# warning originated and the warning text. Optionally the format may contain -# $version, which will be replaced by the version of the file (if it could -# be obtained via FILE_VERSION_FILTER) - -WARN_FORMAT = "$file:$line: $text" - -# The WARN_LOGFILE tag can be used to specify a file to which warning -# and error messages should be written. If left blank the output is written -# to stderr. - -WARN_LOGFILE = - -#--------------------------------------------------------------------------- -# configuration options related to the input files -#--------------------------------------------------------------------------- - -# The INPUT tag can be used to specify the files and/or directories that contain -# documented source files. You may enter file names like "myfile.cpp" or -# directories like "/usr/src/myproject". Separate the files or directories -# with spaces. - -INPUT = @top_srcdir@/src @top_builddir@/src - -# If the value of the INPUT tag contains directories, you can use the -# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank the following patterns are tested: -# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx -# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py - -FILE_PATTERNS = - -# The RECURSIVE tag can be used to turn specify whether or not subdirectories -# should be searched for input files as well. Possible values are YES and NO. -# If left blank NO is used. - -RECURSIVE = NO - -# The EXCLUDE tag can be used to specify files and/or directories that should -# excluded from the INPUT source files. This way you can easily exclude a -# subdirectory from a directory tree whose root is specified with the INPUT tag. - -EXCLUDE = - -# The EXCLUDE_SYMLINKS tag can be used select whether or not files or -# directories that are symbolic links (a Unix filesystem feature) are excluded -# from the input. - -EXCLUDE_SYMLINKS = NO - -# If the value of the INPUT tag contains directories, you can use the -# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude -# certain files from those directories. Note that the wildcards are matched -# against the file with absolute path, so to exclude all test directories -# for example use the pattern */test/* - -EXCLUDE_PATTERNS = - -# The EXAMPLE_PATH tag can be used to specify one or more files or -# directories that contain example code fragments that are included (see -# the \include command). - -EXAMPLE_PATH = - -# If the value of the EXAMPLE_PATH tag contains directories, you can use the -# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp -# and *.h) to filter out the source-files in the directories. If left -# blank all files are included. - -EXAMPLE_PATTERNS = - -# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be -# searched for input files to be used with the \include or \dontinclude -# commands irrespective of the value of the RECURSIVE tag. -# Possible values are YES and NO. If left blank NO is used. - -EXAMPLE_RECURSIVE = NO - -# The IMAGE_PATH tag can be used to specify one or more files or -# directories that contain image that are included in the documentation (see -# the \image command). - -IMAGE_PATH = - -# The INPUT_FILTER tag can be used to specify a program that doxygen should -# invoke to filter for each input file. Doxygen will invoke the filter program -# by executing (via popen()) the command , where -# is the value of the INPUT_FILTER tag, and is the name of an -# input file. Doxygen will then use the output that the filter program writes -# to standard output. If FILTER_PATTERNS is specified, this tag will be -# ignored. - -INPUT_FILTER = - -# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern -# basis. Doxygen will compare the file name with each pattern and apply the -# filter if there is a match. The filters are a list of the form: -# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further -# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER -# is applied to all files. - -FILTER_PATTERNS = - -# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using -# INPUT_FILTER) will be used to filter the input files when producing source -# files to browse (i.e. when SOURCE_BROWSER is set to YES). - -FILTER_SOURCE_FILES = NO - -#--------------------------------------------------------------------------- -# configuration options related to source browsing -#--------------------------------------------------------------------------- - -# If the SOURCE_BROWSER tag is set to YES then a list of source files will -# be generated. Documented entities will be cross-referenced with these sources. -# Note: To get rid of all source code in the generated output, make sure also -# VERBATIM_HEADERS is set to NO. - -SOURCE_BROWSER = NO - -# Setting the INLINE_SOURCES tag to YES will include the body -# of functions and classes directly in the documentation. - -INLINE_SOURCES = NO - -# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct -# doxygen to hide any special comment blocks from generated source code -# fragments. Normal C and C++ comments will always remain visible. - -STRIP_CODE_COMMENTS = YES - -# If the REFERENCED_BY_RELATION tag is set to YES (the default) -# then for each documented function all documented -# functions referencing it will be listed. - -REFERENCED_BY_RELATION = YES - -# If the REFERENCES_RELATION tag is set to YES (the default) -# then for each documented function all documented entities -# called/used by that function will be listed. - -REFERENCES_RELATION = YES - -# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) -# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from -# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will -# link to the source code. Otherwise they will link to the documentstion. - -REFERENCES_LINK_SOURCE = YES - -# If the USE_HTAGS tag is set to YES then the references to source code -# will point to the HTML generated by the htags(1) tool instead of doxygen -# built-in source browser. The htags tool is part of GNU's global source -# tagging system (see http://www.gnu.org/software/global/global.html). You -# will need version 4.8.6 or higher. - -USE_HTAGS = NO - -# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen -# will generate a verbatim copy of the header file for each class for -# which an include is specified. Set to NO to disable this. - -VERBATIM_HEADERS = YES - -#--------------------------------------------------------------------------- -# configuration options related to the alphabetical class index -#--------------------------------------------------------------------------- - -# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index -# of all compounds will be generated. Enable this if the project -# contains a lot of classes, structs, unions or interfaces. - -ALPHABETICAL_INDEX = NO - -# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then -# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns -# in which this list will be split (can be a number in the range [1..20]) - -COLS_IN_ALPHA_INDEX = 5 - -# In case all classes in a project start with a common prefix, all -# classes will be put under the same header in the alphabetical index. -# The IGNORE_PREFIX tag can be used to specify one or more prefixes that -# should be ignored while generating the index headers. - -IGNORE_PREFIX = - -#--------------------------------------------------------------------------- -# configuration options related to the HTML output -#--------------------------------------------------------------------------- - -# If the GENERATE_HTML tag is set to YES (the default) Doxygen will -# generate HTML output. - -GENERATE_HTML = YES - -# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `html' will be used as the default path. - -HTML_OUTPUT = manual - -# The HTML_FILE_EXTENSION tag can be used to specify the file extension for -# each generated HTML page (for example: .htm,.php,.asp). If it is left blank -# doxygen will generate files with .html extension. - -HTML_FILE_EXTENSION = .html - -# The HTML_HEADER tag can be used to specify a personal HTML header for -# each generated HTML page. If it is left blank doxygen will generate a -# standard header. - -HTML_HEADER = - -# The HTML_FOOTER tag can be used to specify a personal HTML footer for -# each generated HTML page. If it is left blank doxygen will generate a -# standard footer. - -HTML_FOOTER = - -# The HTML_STYLESHEET tag can be used to specify a user-defined cascading -# style sheet that is used by each HTML page. It can be used to -# fine-tune the look of the HTML output. If the tag is left blank doxygen -# will generate a default style sheet. Note that doxygen will try to copy -# the style sheet file to the HTML output directory, so don't put your own -# stylesheet in the HTML output directory as well, or it will be erased! - -HTML_STYLESHEET = - -# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, -# files or namespaces will be aligned in HTML using tables. If set to -# NO a bullet list will be used. - -HTML_ALIGN_MEMBERS = YES - -# If the GENERATE_HTMLHELP tag is set to YES, additional index files -# will be generated that can be used as input for tools like the -# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) -# of the generated HTML documentation. - -GENERATE_HTMLHELP = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can -# be used to specify the file name of the resulting .chm file. You -# can add a path in front of the file if the result should not be -# written to the html output directory. - -CHM_FILE = - -# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can -# be used to specify the location (absolute path including file name) of -# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run -# the HTML help compiler on the generated index.hhp. - -HHC_LOCATION = - -# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag -# controls if a separate .chi index file is generated (YES) or that -# it should be included in the master .chm file (NO). - -GENERATE_CHI = NO - -# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag -# controls whether a binary table of contents is generated (YES) or a -# normal table of contents (NO) in the .chm file. - -BINARY_TOC = NO - -# The TOC_EXPAND flag can be set to YES to add extra items for group members -# to the contents of the HTML help documentation and to the tree view. - -TOC_EXPAND = NO - -# The DISABLE_INDEX tag can be used to turn on/off the condensed index at -# top of each HTML page. The value NO (the default) enables the index and -# the value YES disables it. - -DISABLE_INDEX = NO - -# This tag can be used to set the number of enum values (range [1..20]) -# that doxygen will group on one line in the generated HTML documentation. - -ENUM_VALUES_PER_LINE = 4 - -# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be -# generated containing a tree-like index structure (just like the one that -# is generated for HTML Help). For this to work a browser that supports -# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, -# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are -# probably better off using the HTML help feature. - -GENERATE_TREEVIEW = NO - -# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be -# used to set the initial width (in pixels) of the frame in which the tree -# is shown. - -TREEVIEW_WIDTH = 250 - -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- - -# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will -# generate Latex output. - -GENERATE_LATEX = NO - -# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `latex' will be used as the default path. - -LATEX_OUTPUT = latex - -# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be -# invoked. If left blank `latex' will be used as the default command name. - -LATEX_CMD_NAME = latex - -# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to -# generate index for LaTeX. If left blank `makeindex' will be used as the -# default command name. - -MAKEINDEX_CMD_NAME = makeindex - -# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact -# LaTeX documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_LATEX = NO - -# The PAPER_TYPE tag can be used to set the paper type that is used -# by the printer. Possible values are: a4, a4wide, letter, legal and -# executive. If left blank a4wide will be used. - -PAPER_TYPE = a4wide - -# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX -# packages that should be included in the LaTeX output. - -EXTRA_PACKAGES = - -# The LATEX_HEADER tag can be used to specify a personal LaTeX header for -# the generated latex document. The header should contain everything until -# the first chapter. If it is left blank doxygen will generate a -# standard header. Notice: only use this tag if you know what you are doing! - -LATEX_HEADER = - -# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated -# is prepared for conversion to pdf (using ps2pdf). The pdf file will -# contain links (just like the HTML output) instead of page references -# This makes the output suitable for online browsing using a pdf viewer. - -PDF_HYPERLINKS = NO - -# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of -# plain latex in the generated Makefile. Set this option to YES to get a -# higher quality PDF documentation. - -USE_PDFLATEX = NO - -# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. -# command to the generated LaTeX files. This will instruct LaTeX to keep -# running if errors occur, instead of asking the user for help. -# This option is also used when generating formulas in HTML. - -LATEX_BATCHMODE = NO - -# If LATEX_HIDE_INDICES is set to YES then doxygen will not -# include the index chapters (such as File Index, Compound Index, etc.) -# in the output. - -LATEX_HIDE_INDICES = NO - -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- - -# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output -# The RTF output is optimized for Word 97 and may not look very pretty with -# other RTF readers or editors. - -GENERATE_RTF = NO - -# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `rtf' will be used as the default path. - -RTF_OUTPUT = rtf - -# If the COMPACT_RTF tag is set to YES Doxygen generates more compact -# RTF documents. This may be useful for small projects and may help to -# save some trees in general. - -COMPACT_RTF = NO - -# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated -# will contain hyperlink fields. The RTF file will -# contain links (just like the HTML output) instead of page references. -# This makes the output suitable for online browsing using WORD or other -# programs which support those fields. -# Note: wordpad (write) and others do not support links. - -RTF_HYPERLINKS = NO - -# Load stylesheet definitions from file. Syntax is similar to doxygen's -# config file, i.e. a series of assignments. You only have to provide -# replacements, missing definitions are set to their default value. - -RTF_STYLESHEET_FILE = - -# Set optional variables used in the generation of an rtf document. -# Syntax is similar to doxygen's config file. - -RTF_EXTENSIONS_FILE = - -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- - -# If the GENERATE_MAN tag is set to YES (the default) Doxygen will -# generate man pages - -GENERATE_MAN = NO - -# The MAN_OUTPUT tag is used to specify where the man pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `man' will be used as the default path. - -MAN_OUTPUT = man - -# The MAN_EXTENSION tag determines the extension that is added to -# the generated man pages (default is the subroutine's section .3) - -MAN_EXTENSION = .3 - -# If the MAN_LINKS tag is set to YES and Doxygen generates man output, -# then it will generate one additional man file for each entity -# documented in the real man page(s). These additional files -# only source the real man page, but without them the man command -# would be unable to find the correct page. The default is NO. - -MAN_LINKS = NO - -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- - -# If the GENERATE_XML tag is set to YES Doxygen will -# generate an XML file that captures the structure of -# the code including all documentation. - -GENERATE_XML = NO - -# The XML_OUTPUT tag is used to specify where the XML pages will be put. -# If a relative path is entered the value of OUTPUT_DIRECTORY will be -# put in front of it. If left blank `xml' will be used as the default path. - -XML_OUTPUT = xml - -# The XML_SCHEMA tag can be used to specify an XML schema, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_SCHEMA = - -# The XML_DTD tag can be used to specify an XML DTD, -# which can be used by a validating XML parser to check the -# syntax of the XML files. - -XML_DTD = - -# If the XML_PROGRAMLISTING tag is set to YES Doxygen will -# dump the program listings (including syntax highlighting -# and cross-referencing information) to the XML output. Note that -# enabling this will significantly increase the size of the XML output. - -XML_PROGRAMLISTING = YES - -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- - -# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will -# generate an AutoGen Definitions (see autogen.sf.net) file -# that captures the structure of the code including all -# documentation. Note that this feature is still experimental -# and incomplete at the moment. - -GENERATE_AUTOGEN_DEF = NO - -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- - -# If the GENERATE_PERLMOD tag is set to YES Doxygen will -# generate a Perl module file that captures the structure of -# the code including all documentation. Note that this -# feature is still experimental and incomplete at the -# moment. - -GENERATE_PERLMOD = NO - -# If the PERLMOD_LATEX tag is set to YES Doxygen will generate -# the necessary Makefile rules, Perl scripts and LaTeX code to be able -# to generate PDF and DVI output from the Perl module output. - -PERLMOD_LATEX = NO - -# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be -# nicely formatted so it can be parsed by a human reader. This is useful -# if you want to understand what is going on. On the other hand, if this -# tag is set to NO the size of the Perl module output will be much smaller -# and Perl will parse it just the same. - -PERLMOD_PRETTY = YES - -# The names of the make variables in the generated doxyrules.make file -# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. -# This is useful so different doxyrules.make files included by the same -# Makefile don't overwrite each other's variables. - -PERLMOD_MAKEVAR_PREFIX = - -#--------------------------------------------------------------------------- -# Configuration options related to the preprocessor -#--------------------------------------------------------------------------- - -# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will -# evaluate all C-preprocessor directives found in the sources and include -# files. - -ENABLE_PREPROCESSING = YES - -# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro -# names in the source code. If set to NO (the default) only conditional -# compilation will be performed. Macro expansion can be done in a controlled -# way by setting EXPAND_ONLY_PREDEF to YES. - -MACRO_EXPANSION = NO - -# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES -# then the macro expansion is limited to the macros specified with the -# PREDEFINED and EXPAND_AS_DEFINED tags. - -EXPAND_ONLY_PREDEF = NO - -# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files -# in the INCLUDE_PATH (see below) will be search if a #include is found. - -SEARCH_INCLUDES = YES - -# The INCLUDE_PATH tag can be used to specify one or more directories that -# contain include files that are not input files but should be processed by -# the preprocessor. - -INCLUDE_PATH = - -# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard -# patterns (like *.h and *.hpp) to filter out the header-files in the -# directories. If left blank, the patterns specified with FILE_PATTERNS will -# be used. - -INCLUDE_FILE_PATTERNS = - -# The PREDEFINED tag can be used to specify one or more macro names that -# are defined before the preprocessor is started (similar to the -D option of -# gcc). The argument of the tag is a list of macros of the form: name -# or name=definition (no spaces). If the definition and the = are -# omitted =1 is assumed. To prevent a macro definition from being -# undefined via #undef or recursively expanded use the := operator -# instead of the = operator. - -PREDEFINED = - -# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then -# this tag can be used to specify a list of macro names that should be expanded. -# The macro definition that is found in the sources will be used. -# Use the PREDEFINED tag if you want to use a different macro definition. - -EXPAND_AS_DEFINED = - -# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then -# doxygen's preprocessor will remove all function-like macros that are alone -# on a line, have an all uppercase name, and do not end with a semicolon. Such -# function macros are typically used for boiler-plate code, and will confuse -# the parser if not removed. - -SKIP_FUNCTION_MACROS = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to external references -#--------------------------------------------------------------------------- - -# The TAGFILES option can be used to specify one or more tagfiles. -# Optionally an initial location of the external documentation -# can be added for each tagfile. The format of a tag file without -# this location is as follows: -# TAGFILES = file1 file2 ... -# Adding location for the tag files is done as follows: -# TAGFILES = file1=loc1 "file2 = loc2" ... -# where "loc1" and "loc2" can be relative or absolute paths or -# URLs. If a location is present for each tag, the installdox tool -# does not have to be run to correct the links. -# Note that each tag file must have a unique name -# (where the name does NOT include the path) -# If a tag file is not located in the directory in which doxygen -# is run, you must also specify the path to the tagfile here. - -TAGFILES = - -# When a file name is specified after GENERATE_TAGFILE, doxygen will create -# a tag file that is based on the input files it reads. - -GENERATE_TAGFILE = - -# If the ALLEXTERNALS tag is set to YES all external classes will be listed -# in the class index. If set to NO only the inherited external classes -# will be listed. - -ALLEXTERNALS = NO - -# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed -# in the modules index. If set to NO, only the current project's groups will -# be listed. - -EXTERNAL_GROUPS = YES - -# The PERL_PATH should be the absolute path and name of the perl script -# interpreter (i.e. the result of `which perl'). - -PERL_PATH = /usr/bin/perl - -#--------------------------------------------------------------------------- -# Configuration options related to the dot tool -#--------------------------------------------------------------------------- - -# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will -# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base -# or super classes. Setting the tag to NO turns the diagrams off. Note that -# this option is superseded by the HAVE_DOT option below. This is only a -# fallback. It is recommended to install and use dot, since it yields more -# powerful graphs. - -CLASS_DIAGRAMS = YES - -# If set to YES, the inheritance and collaboration graphs will hide -# inheritance and usage relations if the target is undocumented -# or is not a class. - -HIDE_UNDOC_RELATIONS = YES - -# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is -# available from the path. This tool is part of Graphviz, a graph visualization -# toolkit from AT&T and Lucent Bell Labs. The other options in this section -# have no effect if this option is set to NO (the default) - -HAVE_DOT = YES - -# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect inheritance relations. Setting this tag to YES will force the -# the CLASS_DIAGRAMS tag to NO. - -CLASS_GRAPH = YES - -# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for each documented class showing the direct and -# indirect implementation dependencies (inheritance, containment, and -# class references variables) of the class with other documented classes. - -COLLABORATION_GRAPH = YES - -# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen -# will generate a graph for groups, showing the direct groups dependencies - -GROUP_GRAPHS = YES - -# If the UML_LOOK tag is set to YES doxygen will generate inheritance and -# collaboration diagrams in a style similar to the OMG's Unified Modeling -# Language. - -UML_LOOK = NO - -# If set to YES, the inheritance and collaboration graphs will show the -# relations between templates and their instances. - -TEMPLATE_RELATIONS = NO - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT -# tags are set to YES then doxygen will generate a graph for each documented -# file showing the direct and indirect include dependencies of the file with -# other documented files. - -INCLUDE_GRAPH = YES - -# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and -# HAVE_DOT tags are set to YES then doxygen will generate a graph for each -# documented header file showing the documented files that directly or -# indirectly include this file. - -INCLUDED_BY_GRAPH = YES - -# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a call dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable call graphs for selected -# functions only using the \callgraph command. - -CALL_GRAPH = NO - -# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will -# generate a caller dependency graph for every global function or class method. -# Note that enabling this option will significantly increase the time of a run. -# So in most cases it will be better to enable caller graphs for selected -# functions only using the \callergraph command. - -CALLER_GRAPH = NO - -# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen -# will graphical hierarchy of all classes instead of a textual one. - -GRAPHICAL_HIERARCHY = YES - -# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES -# then doxygen will show the dependencies a directory has on other directories -# in a graphical way. The dependency relations are determined by the #include -# relations between the files in the directories. - -DIRECTORY_GRAPH = YES - -# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images -# generated by dot. Possible values are png, jpg, or gif -# If left blank png will be used. - -DOT_IMAGE_FORMAT = png - -# The tag DOT_PATH can be used to specify the path where the dot tool can be -# found. If left blank, it is assumed the dot tool can be found in the path. - -DOT_PATH = - -# The DOTFILE_DIRS tag can be used to specify one or more directories that -# contain dot files that are included in the documentation (see the -# \dotfile command). - -DOTFILE_DIRS = - -# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_WIDTH = 1024 - -# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height -# (in pixels) of the graphs generated by dot. If a graph becomes larger than -# this value, doxygen will try to truncate the graph, so that it fits within -# the specified constraint. Beware that most browsers cannot cope with very -# large images. - -MAX_DOT_GRAPH_HEIGHT = 1024 - -# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the -# graphs generated by dot. A depth value of 3 means that only nodes reachable -# from the root by following a path via at most 3 edges will be shown. Nodes -# that lay further from the root node will be omitted. Note that setting this -# option to 1 or 2 may greatly reduce the computation time needed for large -# code bases. Also note that a graph may be further truncated if the graph's -# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH -# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), -# the graph is not depth-constrained. - -MAX_DOT_GRAPH_DEPTH = 0 - -# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent -# background. This is disabled by default, which results in a white background. -# Warning: Depending on the platform used, enabling this option may lead to -# badly anti-aliased labels on the edges of a graph (i.e. they become hard to -# read). - -DOT_TRANSPARENT = NO - -# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output -# files in one run (i.e. multiple -o and -T options on the command line). This -# makes dot run faster, but since only newer versions of dot (>1.8.10) -# support this, this feature is disabled by default. - -DOT_MULTI_TARGETS = NO - -# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will -# generate a legend page explaining the meaning of the various boxes and -# arrows in the dot generated graphs. - -GENERATE_LEGEND = YES - -# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will -# remove the intermediate dot files that are used to generate -# the various graphs. - -DOT_CLEANUP = YES - -#--------------------------------------------------------------------------- -# Configuration::additions related to the search engine -#--------------------------------------------------------------------------- - -# The SEARCHENGINE tag specifies whether or not a search engine should be -# used. If set to NO the values of all tags below this one will be ignored. - -SEARCHENGINE = NO +# Doxyfile 1.5.0 + +# This file describes the settings to be used by the documentation system +# doxygen (www.doxygen.org) for a project +# +# All text after a hash (#) is considered a comment and will be ignored +# The format is: +# TAG = value [value, ...] +# For lists items can also be appended using: +# TAG += value [value, ...] +# Values that contain spaces should be placed between quotes (" ") + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- + +# The PROJECT_NAME tag is a single word (or a sequence of words surrounded +# by quotes) that should identify the project. + +PROJECT_NAME = "XCB" + +# The PROJECT_NUMBER tag can be used to enter a project or revision number. +# This could be handy for archiving the generated documentation or +# if some version control system is used. + +PROJECT_NUMBER = @VERSION@ + +# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) +# base path where the generated documentation will be put. +# If a relative path is entered, it will be relative to the location +# where doxygen was started. If left blank the current directory will be used. + +OUTPUT_DIRECTORY = @top_builddir@/doc + +# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create +# 4096 sub-directories (in 2 levels) under the output directory of each output +# format and will distribute the generated files over these directories. +# Enabling this option can be useful when feeding doxygen a huge amount of +# source files, where putting all generated files in the same directory would +# otherwise cause performance problems for the file system. + +CREATE_SUBDIRS = NO + +# The OUTPUT_LANGUAGE tag is used to specify the language in which all +# documentation generated by doxygen is written. Doxygen will use this +# information to generate all constant output in the proper language. +# The default language is English, other supported languages are: +# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, +# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian, +# Italian, Japanese, Japanese-en (Japanese with English messages), Korean, +# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian, +# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian. + +OUTPUT_LANGUAGE = English + +# This tag can be used to specify the encoding used in the generated output. +# The encoding is not always determined by the language that is chosen, +# but also whether or not the output is meant for Windows or non-Windows users. +# In case there is a difference, setting the USE_WINDOWS_ENCODING tag to YES +# forces the Windows encoding (this is the default for the Windows binary), +# whereas setting the tag to NO uses a Unix-style encoding (the default for +# all platforms other than Windows). + +USE_WINDOWS_ENCODING = NO + +# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will +# include brief member descriptions after the members that are listed in +# the file and class documentation (similar to JavaDoc). +# Set to NO to disable this. + +BRIEF_MEMBER_DESC = YES + +# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend +# the brief description of a member or function before the detailed description. +# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the +# brief descriptions will be completely suppressed. + +REPEAT_BRIEF = YES + +# This tag implements a quasi-intelligent brief description abbreviator +# that is used to form the text in various listings. Each string +# in this list, if found as the leading text of the brief description, will be +# stripped from the text and the result after processing the whole list, is +# used as the annotated text. Otherwise, the brief description is used as-is. +# If left blank, the following values are used ("$name" is automatically +# replaced with the name of the entity): "The $name class" "The $name widget" +# "The $name file" "is" "provides" "specifies" "contains" +# "represents" "a" "an" "the" + +ABBREVIATE_BRIEF = + +# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then +# Doxygen will generate a detailed section even if there is only a brief +# description. + +ALWAYS_DETAILED_SEC = NO + +# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all +# inherited members of a class in the documentation of that class as if those +# members were ordinary class members. Constructors, destructors and assignment +# operators of the base classes will not be shown. + +INLINE_INHERITED_MEMB = NO + +# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full +# path before files name in the file list and in the header files. If set +# to NO the shortest path that makes the file name unique will be used. + +FULL_PATH_NAMES = NO + +# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag +# can be used to strip a user-defined part of the path. Stripping is +# only done if one of the specified strings matches the left-hand part of +# the path. The tag can be used to show relative paths in the file list. +# If left blank the directory from which doxygen is run is used as the +# path to strip. + +STRIP_FROM_PATH = + +# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of +# the path mentioned in the documentation of a class, which tells +# the reader which header file to include in order to use a class. +# If left blank only the name of the header file containing the class +# definition is used. Otherwise one should specify the include paths that +# are normally passed to the compiler using the -I flag. + +STRIP_FROM_INC_PATH = + +# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter +# (but less readable) file names. This can be useful is your file systems +# doesn't support long names like on DOS, Mac, or CD-ROM. + +SHORT_NAMES = NO + +# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen +# will interpret the first line (until the first dot) of a JavaDoc-style +# comment as the brief description. If set to NO, the JavaDoc +# comments will behave just like the Qt-style comments (thus requiring an +# explicit @brief command for a brief description. + +JAVADOC_AUTOBRIEF = NO + +# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen +# treat a multi-line C++ special comment block (i.e. a block of //! or /// +# comments) as a brief description. This used to be the default behaviour. +# The new default is to treat a multi-line C++ comment block as a detailed +# description. Set this tag to YES if you prefer the old behaviour instead. + +MULTILINE_CPP_IS_BRIEF = NO + +# If the DETAILS_AT_TOP tag is set to YES then Doxygen +# will output the detailed description near the top, like JavaDoc. +# If set to NO, the detailed description appears after the member +# documentation. + +DETAILS_AT_TOP = NO + +# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented +# member inherits the documentation from any documented member that it +# re-implements. + +INHERIT_DOCS = YES + +# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce +# a new page for each member. If set to NO, the documentation of a member will +# be part of the file/class/namespace that contains it. + +SEPARATE_MEMBER_PAGES = NO + +# The TAB_SIZE tag can be used to set the number of spaces in a tab. +# Doxygen uses this value to replace tabs by spaces in code fragments. + +TAB_SIZE = 8 + +# This tag can be used to specify a number of aliases that acts +# as commands in the documentation. An alias has the form "name=value". +# For example adding "sideeffect=\par Side Effects:\n" will allow you to +# put the command \sideeffect (or @sideeffect) in the documentation, which +# will result in a user-defined paragraph with heading "Side Effects:". +# You can put \n's in the value part of an alias to insert newlines. + +ALIASES = + +# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C +# sources only. Doxygen will then generate output that is more tailored for C. +# For instance, some of the names that are used will be different. The list +# of all members will be omitted, etc. + +OPTIMIZE_OUTPUT_FOR_C = YES + +# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java +# sources only. Doxygen will then generate output that is more tailored for Java. +# For instance, namespaces will be presented as packages, qualified scopes +# will look different, etc. + +OPTIMIZE_OUTPUT_JAVA = NO + +# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to +# include (a tag file for) the STL sources as input, then you should +# set this tag to YES in order to let doxygen match functions declarations and +# definitions whose arguments contain STL classes (e.g. func(std::string); v.s. +# func(std::string) {}). This also make the inheritance and collaboration +# diagrams that involve STL classes more complete and accurate. + +BUILTIN_STL_SUPPORT = NO + +# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC +# tag is set to YES, then doxygen will reuse the documentation of the first +# member in the group (if any) for the other members of the group. By default +# all members of a group must be documented explicitly. + +DISTRIBUTE_GROUP_DOC = NO + +# Set the SUBGROUPING tag to YES (the default) to allow class member groups of +# the same type (for instance a group of public functions) to be put as a +# subgroup of that type (e.g. under the Public Functions section). Set it to +# NO to prevent subgrouping. Alternatively, this can be done per class using +# the \nosubgrouping command. + +SUBGROUPING = YES + +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- + +# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in +# documentation are documented, even if no documentation was available. +# Private class members and static file members will be hidden unless +# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES + +EXTRACT_ALL = NO + +# If the EXTRACT_PRIVATE tag is set to YES all private members of a class +# will be included in the documentation. + +EXTRACT_PRIVATE = NO + +# If the EXTRACT_STATIC tag is set to YES all static members of a file +# will be included in the documentation. + +EXTRACT_STATIC = NO + +# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) +# defined locally in source files will be included in the documentation. +# If set to NO only classes defined in header files are included. + +EXTRACT_LOCAL_CLASSES = YES + +# This flag is only useful for Objective-C code. When set to YES local +# methods, which are defined in the implementation section but not in +# the interface are included in the documentation. +# If set to NO (the default) only methods in the interface are included. + +EXTRACT_LOCAL_METHODS = NO + +# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all +# undocumented members of documented classes, files or namespaces. +# If set to NO (the default) these members will be included in the +# various overviews, but no documentation section is generated. +# This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_MEMBERS = NO + +# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all +# undocumented classes that are normally visible in the class hierarchy. +# If set to NO (the default) these classes will be included in the various +# overviews. This option has no effect if EXTRACT_ALL is enabled. + +HIDE_UNDOC_CLASSES = NO + +# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all +# friend (class|struct|union) declarations. +# If set to NO (the default) these declarations will be included in the +# documentation. + +HIDE_FRIEND_COMPOUNDS = NO + +# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any +# documentation blocks found inside the body of a function. +# If set to NO (the default) these blocks will be appended to the +# function's detailed documentation block. + +HIDE_IN_BODY_DOCS = NO + +# The INTERNAL_DOCS tag determines if documentation +# that is typed after a \internal command is included. If the tag is set +# to NO (the default) then the documentation will be excluded. +# Set it to YES to include the internal documentation. + +INTERNAL_DOCS = NO + +# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate +# file names in lower-case letters. If set to YES upper-case letters are also +# allowed. This is useful if you have classes or files whose names only differ +# in case and if your file system supports case sensitive file names. Windows +# and Mac users are advised to set this option to NO. + +CASE_SENSE_NAMES = YES + +# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen +# will show members with their full class and namespace scopes in the +# documentation. If set to YES the scope will be hidden. + +HIDE_SCOPE_NAMES = NO + +# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen +# will put a list of the files that are included by a file in the documentation +# of that file. + +SHOW_INCLUDE_FILES = YES + +# If the INLINE_INFO tag is set to YES (the default) then a tag [inline] +# is inserted in the documentation for inline members. + +INLINE_INFO = YES + +# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen +# will sort the (detailed) documentation of file and class members +# alphabetically by member name. If set to NO the members will appear in +# declaration order. + +SORT_MEMBER_DOCS = YES + +# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the +# brief documentation of file, namespace and class members alphabetically +# by member name. If set to NO (the default) the members will appear in +# declaration order. + +SORT_BRIEF_DOCS = NO + +# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be +# sorted by fully-qualified names, including namespaces. If set to +# NO (the default), the class list will be sorted only by class name, +# not including the namespace part. +# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. +# Note: This option applies only to the class list, not to the +# alphabetical list. + +SORT_BY_SCOPE_NAME = NO + +# The GENERATE_TODOLIST tag can be used to enable (YES) or +# disable (NO) the todo list. This list is created by putting \todo +# commands in the documentation. + +GENERATE_TODOLIST = YES + +# The GENERATE_TESTLIST tag can be used to enable (YES) or +# disable (NO) the test list. This list is created by putting \test +# commands in the documentation. + +GENERATE_TESTLIST = YES + +# The GENERATE_BUGLIST tag can be used to enable (YES) or +# disable (NO) the bug list. This list is created by putting \bug +# commands in the documentation. + +GENERATE_BUGLIST = YES + +# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or +# disable (NO) the deprecated list. This list is created by putting +# \deprecated commands in the documentation. + +GENERATE_DEPRECATEDLIST= YES + +# The ENABLED_SECTIONS tag can be used to enable conditional +# documentation sections, marked by \if sectionname ... \endif. + +ENABLED_SECTIONS = + +# The MAX_INITIALIZER_LINES tag determines the maximum number of lines +# the initial value of a variable or define consists of for it to appear in +# the documentation. If the initializer consists of more lines than specified +# here it will be hidden. Use a value of 0 to hide initializers completely. +# The appearance of the initializer of individual variables and defines in the +# documentation can be controlled using \showinitializer or \hideinitializer +# command in the documentation regardless of this setting. + +MAX_INITIALIZER_LINES = 30 + +# Set the SHOW_USED_FILES tag to NO to disable the list of files generated +# at the bottom of the documentation of classes and structs. If set to YES the +# list will mention the files that were used to generate the documentation. + +SHOW_USED_FILES = YES + +# If the sources in your project are distributed over multiple directories +# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy +# in the documentation. The default is NO. + +SHOW_DIRECTORIES = NO + +# The FILE_VERSION_FILTER tag can be used to specify a program or script that +# doxygen should invoke to get the current version for each file (typically from the +# version control system). Doxygen will invoke the program by executing (via +# popen()) the command , where is the value of +# the FILE_VERSION_FILTER tag, and is the name of an input file +# provided by doxygen. Whatever the program writes to standard output +# is used as the file version. See the manual for examples. + +FILE_VERSION_FILTER = + +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- + +# The QUIET tag can be used to turn on/off the messages that are generated +# by doxygen. Possible values are YES and NO. If left blank NO is used. + +QUIET = YES + +# The WARNINGS tag can be used to turn on/off the warning messages that are +# generated by doxygen. Possible values are YES and NO. If left blank +# NO is used. + +WARNINGS = YES + +# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings +# for undocumented members. If EXTRACT_ALL is set to YES then this flag will +# automatically be disabled. + +# XXX: In the future this should be turned on. For now it generates too much noise. +WARN_IF_UNDOCUMENTED = NO + +# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for +# potential errors in the documentation, such as not documenting some +# parameters in a documented function, or documenting parameters that +# don't exist or using markup commands wrongly. + +WARN_IF_DOC_ERROR = YES + +# This WARN_NO_PARAMDOC option can be abled to get warnings for +# functions that are documented, but have no documentation for their parameters +# or return value. If set to NO (the default) doxygen will only warn about +# wrong or incomplete parameter documentation, but not about the absence of +# documentation. + +WARN_NO_PARAMDOC = YES + +# The WARN_FORMAT tag determines the format of the warning messages that +# doxygen can produce. The string should contain the $file, $line, and $text +# tags, which will be replaced by the file and line number from which the +# warning originated and the warning text. Optionally the format may contain +# $version, which will be replaced by the version of the file (if it could +# be obtained via FILE_VERSION_FILTER) + +WARN_FORMAT = "$file:$line: $text" + +# The WARN_LOGFILE tag can be used to specify a file to which warning +# and error messages should be written. If left blank the output is written +# to stderr. + +WARN_LOGFILE = + +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- + +# The INPUT tag can be used to specify the files and/or directories that contain +# documented source files. You may enter file names like "myfile.cpp" or +# directories like "/usr/src/myproject". Separate the files or directories +# with spaces. + +INPUT = @top_srcdir@/src @top_builddir@/src + +# If the value of the INPUT tag contains directories, you can use the +# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank the following patterns are tested: +# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx +# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py + +FILE_PATTERNS = + +# The RECURSIVE tag can be used to turn specify whether or not subdirectories +# should be searched for input files as well. Possible values are YES and NO. +# If left blank NO is used. + +RECURSIVE = NO + +# The EXCLUDE tag can be used to specify files and/or directories that should +# excluded from the INPUT source files. This way you can easily exclude a +# subdirectory from a directory tree whose root is specified with the INPUT tag. + +EXCLUDE = + +# The EXCLUDE_SYMLINKS tag can be used select whether or not files or +# directories that are symbolic links (a Unix filesystem feature) are excluded +# from the input. + +EXCLUDE_SYMLINKS = NO + +# If the value of the INPUT tag contains directories, you can use the +# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude +# certain files from those directories. Note that the wildcards are matched +# against the file with absolute path, so to exclude all test directories +# for example use the pattern */test/* + +EXCLUDE_PATTERNS = + +# The EXAMPLE_PATH tag can be used to specify one or more files or +# directories that contain example code fragments that are included (see +# the \include command). + +EXAMPLE_PATH = + +# If the value of the EXAMPLE_PATH tag contains directories, you can use the +# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp +# and *.h) to filter out the source-files in the directories. If left +# blank all files are included. + +EXAMPLE_PATTERNS = + +# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be +# searched for input files to be used with the \include or \dontinclude +# commands irrespective of the value of the RECURSIVE tag. +# Possible values are YES and NO. If left blank NO is used. + +EXAMPLE_RECURSIVE = NO + +# The IMAGE_PATH tag can be used to specify one or more files or +# directories that contain image that are included in the documentation (see +# the \image command). + +IMAGE_PATH = + +# The INPUT_FILTER tag can be used to specify a program that doxygen should +# invoke to filter for each input file. Doxygen will invoke the filter program +# by executing (via popen()) the command , where +# is the value of the INPUT_FILTER tag, and is the name of an +# input file. Doxygen will then use the output that the filter program writes +# to standard output. If FILTER_PATTERNS is specified, this tag will be +# ignored. + +INPUT_FILTER = + +# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern +# basis. Doxygen will compare the file name with each pattern and apply the +# filter if there is a match. The filters are a list of the form: +# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further +# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER +# is applied to all files. + +FILTER_PATTERNS = + +# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using +# INPUT_FILTER) will be used to filter the input files when producing source +# files to browse (i.e. when SOURCE_BROWSER is set to YES). + +FILTER_SOURCE_FILES = NO + +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- + +# If the SOURCE_BROWSER tag is set to YES then a list of source files will +# be generated. Documented entities will be cross-referenced with these sources. +# Note: To get rid of all source code in the generated output, make sure also +# VERBATIM_HEADERS is set to NO. + +SOURCE_BROWSER = NO + +# Setting the INLINE_SOURCES tag to YES will include the body +# of functions and classes directly in the documentation. + +INLINE_SOURCES = NO + +# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct +# doxygen to hide any special comment blocks from generated source code +# fragments. Normal C and C++ comments will always remain visible. + +STRIP_CODE_COMMENTS = YES + +# If the REFERENCED_BY_RELATION tag is set to YES (the default) +# then for each documented function all documented +# functions referencing it will be listed. + +REFERENCED_BY_RELATION = YES + +# If the REFERENCES_RELATION tag is set to YES (the default) +# then for each documented function all documented entities +# called/used by that function will be listed. + +REFERENCES_RELATION = YES + +# If the REFERENCES_LINK_SOURCE tag is set to YES (the default) +# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from +# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will +# link to the source code. Otherwise they will link to the documentstion. + +REFERENCES_LINK_SOURCE = YES + +# If the USE_HTAGS tag is set to YES then the references to source code +# will point to the HTML generated by the htags(1) tool instead of doxygen +# built-in source browser. The htags tool is part of GNU's global source +# tagging system (see http://www.gnu.org/software/global/global.html). You +# will need version 4.8.6 or higher. + +USE_HTAGS = NO + +# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen +# will generate a verbatim copy of the header file for each class for +# which an include is specified. Set to NO to disable this. + +VERBATIM_HEADERS = YES + +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- + +# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index +# of all compounds will be generated. Enable this if the project +# contains a lot of classes, structs, unions or interfaces. + +ALPHABETICAL_INDEX = NO + +# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then +# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns +# in which this list will be split (can be a number in the range [1..20]) + +COLS_IN_ALPHA_INDEX = 5 + +# In case all classes in a project start with a common prefix, all +# classes will be put under the same header in the alphabetical index. +# The IGNORE_PREFIX tag can be used to specify one or more prefixes that +# should be ignored while generating the index headers. + +IGNORE_PREFIX = + +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- + +# If the GENERATE_HTML tag is set to YES (the default) Doxygen will +# generate HTML output. + +GENERATE_HTML = YES + +# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `html' will be used as the default path. + +HTML_OUTPUT = manual + +# The HTML_FILE_EXTENSION tag can be used to specify the file extension for +# each generated HTML page (for example: .htm,.php,.asp). If it is left blank +# doxygen will generate files with .html extension. + +HTML_FILE_EXTENSION = .html + +# The HTML_HEADER tag can be used to specify a personal HTML header for +# each generated HTML page. If it is left blank doxygen will generate a +# standard header. + +HTML_HEADER = + +# The HTML_FOOTER tag can be used to specify a personal HTML footer for +# each generated HTML page. If it is left blank doxygen will generate a +# standard footer. + +HTML_FOOTER = + +# The HTML_STYLESHEET tag can be used to specify a user-defined cascading +# style sheet that is used by each HTML page. It can be used to +# fine-tune the look of the HTML output. If the tag is left blank doxygen +# will generate a default style sheet. Note that doxygen will try to copy +# the style sheet file to the HTML output directory, so don't put your own +# stylesheet in the HTML output directory as well, or it will be erased! + +HTML_STYLESHEET = + +# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes, +# files or namespaces will be aligned in HTML using tables. If set to +# NO a bullet list will be used. + +HTML_ALIGN_MEMBERS = YES + +# If the GENERATE_HTMLHELP tag is set to YES, additional index files +# will be generated that can be used as input for tools like the +# Microsoft HTML help workshop to generate a compressed HTML help file (.chm) +# of the generated HTML documentation. + +GENERATE_HTMLHELP = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can +# be used to specify the file name of the resulting .chm file. You +# can add a path in front of the file if the result should not be +# written to the html output directory. + +CHM_FILE = + +# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can +# be used to specify the location (absolute path including file name) of +# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run +# the HTML help compiler on the generated index.hhp. + +HHC_LOCATION = + +# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag +# controls if a separate .chi index file is generated (YES) or that +# it should be included in the master .chm file (NO). + +GENERATE_CHI = NO + +# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag +# controls whether a binary table of contents is generated (YES) or a +# normal table of contents (NO) in the .chm file. + +BINARY_TOC = NO + +# The TOC_EXPAND flag can be set to YES to add extra items for group members +# to the contents of the HTML help documentation and to the tree view. + +TOC_EXPAND = NO + +# The DISABLE_INDEX tag can be used to turn on/off the condensed index at +# top of each HTML page. The value NO (the default) enables the index and +# the value YES disables it. + +DISABLE_INDEX = NO + +# This tag can be used to set the number of enum values (range [1..20]) +# that doxygen will group on one line in the generated HTML documentation. + +ENUM_VALUES_PER_LINE = 4 + +# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be +# generated containing a tree-like index structure (just like the one that +# is generated for HTML Help). For this to work a browser that supports +# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+, +# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are +# probably better off using the HTML help feature. + +GENERATE_TREEVIEW = NO + +# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be +# used to set the initial width (in pixels) of the frame in which the tree +# is shown. + +TREEVIEW_WIDTH = 250 + +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- + +# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will +# generate Latex output. + +GENERATE_LATEX = NO + +# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `latex' will be used as the default path. + +LATEX_OUTPUT = latex + +# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be +# invoked. If left blank `latex' will be used as the default command name. + +LATEX_CMD_NAME = latex + +# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to +# generate index for LaTeX. If left blank `makeindex' will be used as the +# default command name. + +MAKEINDEX_CMD_NAME = makeindex + +# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact +# LaTeX documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_LATEX = NO + +# The PAPER_TYPE tag can be used to set the paper type that is used +# by the printer. Possible values are: a4, a4wide, letter, legal and +# executive. If left blank a4wide will be used. + +PAPER_TYPE = a4wide + +# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX +# packages that should be included in the LaTeX output. + +EXTRA_PACKAGES = + +# The LATEX_HEADER tag can be used to specify a personal LaTeX header for +# the generated latex document. The header should contain everything until +# the first chapter. If it is left blank doxygen will generate a +# standard header. Notice: only use this tag if you know what you are doing! + +LATEX_HEADER = + +# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated +# is prepared for conversion to pdf (using ps2pdf). The pdf file will +# contain links (just like the HTML output) instead of page references +# This makes the output suitable for online browsing using a pdf viewer. + +PDF_HYPERLINKS = NO + +# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of +# plain latex in the generated Makefile. Set this option to YES to get a +# higher quality PDF documentation. + +USE_PDFLATEX = NO + +# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. +# command to the generated LaTeX files. This will instruct LaTeX to keep +# running if errors occur, instead of asking the user for help. +# This option is also used when generating formulas in HTML. + +LATEX_BATCHMODE = NO + +# If LATEX_HIDE_INDICES is set to YES then doxygen will not +# include the index chapters (such as File Index, Compound Index, etc.) +# in the output. + +LATEX_HIDE_INDICES = NO + +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- + +# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output +# The RTF output is optimized for Word 97 and may not look very pretty with +# other RTF readers or editors. + +GENERATE_RTF = NO + +# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `rtf' will be used as the default path. + +RTF_OUTPUT = rtf + +# If the COMPACT_RTF tag is set to YES Doxygen generates more compact +# RTF documents. This may be useful for small projects and may help to +# save some trees in general. + +COMPACT_RTF = NO + +# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated +# will contain hyperlink fields. The RTF file will +# contain links (just like the HTML output) instead of page references. +# This makes the output suitable for online browsing using WORD or other +# programs which support those fields. +# Note: wordpad (write) and others do not support links. + +RTF_HYPERLINKS = NO + +# Load stylesheet definitions from file. Syntax is similar to doxygen's +# config file, i.e. a series of assignments. You only have to provide +# replacements, missing definitions are set to their default value. + +RTF_STYLESHEET_FILE = + +# Set optional variables used in the generation of an rtf document. +# Syntax is similar to doxygen's config file. + +RTF_EXTENSIONS_FILE = + +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- + +# If the GENERATE_MAN tag is set to YES (the default) Doxygen will +# generate man pages + +GENERATE_MAN = NO + +# The MAN_OUTPUT tag is used to specify where the man pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `man' will be used as the default path. + +MAN_OUTPUT = man + +# The MAN_EXTENSION tag determines the extension that is added to +# the generated man pages (default is the subroutine's section .3) + +MAN_EXTENSION = .3 + +# If the MAN_LINKS tag is set to YES and Doxygen generates man output, +# then it will generate one additional man file for each entity +# documented in the real man page(s). These additional files +# only source the real man page, but without them the man command +# would be unable to find the correct page. The default is NO. + +MAN_LINKS = NO + +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- + +# If the GENERATE_XML tag is set to YES Doxygen will +# generate an XML file that captures the structure of +# the code including all documentation. + +GENERATE_XML = NO + +# The XML_OUTPUT tag is used to specify where the XML pages will be put. +# If a relative path is entered the value of OUTPUT_DIRECTORY will be +# put in front of it. If left blank `xml' will be used as the default path. + +XML_OUTPUT = xml + +# The XML_SCHEMA tag can be used to specify an XML schema, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_SCHEMA = + +# The XML_DTD tag can be used to specify an XML DTD, +# which can be used by a validating XML parser to check the +# syntax of the XML files. + +XML_DTD = + +# If the XML_PROGRAMLISTING tag is set to YES Doxygen will +# dump the program listings (including syntax highlighting +# and cross-referencing information) to the XML output. Note that +# enabling this will significantly increase the size of the XML output. + +XML_PROGRAMLISTING = YES + +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- + +# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will +# generate an AutoGen Definitions (see autogen.sf.net) file +# that captures the structure of the code including all +# documentation. Note that this feature is still experimental +# and incomplete at the moment. + +GENERATE_AUTOGEN_DEF = NO + +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- + +# If the GENERATE_PERLMOD tag is set to YES Doxygen will +# generate a Perl module file that captures the structure of +# the code including all documentation. Note that this +# feature is still experimental and incomplete at the +# moment. + +GENERATE_PERLMOD = NO + +# If the PERLMOD_LATEX tag is set to YES Doxygen will generate +# the necessary Makefile rules, Perl scripts and LaTeX code to be able +# to generate PDF and DVI output from the Perl module output. + +PERLMOD_LATEX = NO + +# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be +# nicely formatted so it can be parsed by a human reader. This is useful +# if you want to understand what is going on. On the other hand, if this +# tag is set to NO the size of the Perl module output will be much smaller +# and Perl will parse it just the same. + +PERLMOD_PRETTY = YES + +# The names of the make variables in the generated doxyrules.make file +# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. +# This is useful so different doxyrules.make files included by the same +# Makefile don't overwrite each other's variables. + +PERLMOD_MAKEVAR_PREFIX = + +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- + +# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will +# evaluate all C-preprocessor directives found in the sources and include +# files. + +ENABLE_PREPROCESSING = YES + +# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro +# names in the source code. If set to NO (the default) only conditional +# compilation will be performed. Macro expansion can be done in a controlled +# way by setting EXPAND_ONLY_PREDEF to YES. + +MACRO_EXPANSION = NO + +# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES +# then the macro expansion is limited to the macros specified with the +# PREDEFINED and EXPAND_AS_DEFINED tags. + +EXPAND_ONLY_PREDEF = NO + +# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files +# in the INCLUDE_PATH (see below) will be search if a #include is found. + +SEARCH_INCLUDES = YES + +# The INCLUDE_PATH tag can be used to specify one or more directories that +# contain include files that are not input files but should be processed by +# the preprocessor. + +INCLUDE_PATH = + +# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard +# patterns (like *.h and *.hpp) to filter out the header-files in the +# directories. If left blank, the patterns specified with FILE_PATTERNS will +# be used. + +INCLUDE_FILE_PATTERNS = + +# The PREDEFINED tag can be used to specify one or more macro names that +# are defined before the preprocessor is started (similar to the -D option of +# gcc). The argument of the tag is a list of macros of the form: name +# or name=definition (no spaces). If the definition and the = are +# omitted =1 is assumed. To prevent a macro definition from being +# undefined via #undef or recursively expanded use the := operator +# instead of the = operator. + +PREDEFINED = + +# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then +# this tag can be used to specify a list of macro names that should be expanded. +# The macro definition that is found in the sources will be used. +# Use the PREDEFINED tag if you want to use a different macro definition. + +EXPAND_AS_DEFINED = + +# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then +# doxygen's preprocessor will remove all function-like macros that are alone +# on a line, have an all uppercase name, and do not end with a semicolon. Such +# function macros are typically used for boiler-plate code, and will confuse +# the parser if not removed. + +SKIP_FUNCTION_MACROS = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- + +# The TAGFILES option can be used to specify one or more tagfiles. +# Optionally an initial location of the external documentation +# can be added for each tagfile. The format of a tag file without +# this location is as follows: +# TAGFILES = file1 file2 ... +# Adding location for the tag files is done as follows: +# TAGFILES = file1=loc1 "file2 = loc2" ... +# where "loc1" and "loc2" can be relative or absolute paths or +# URLs. If a location is present for each tag, the installdox tool +# does not have to be run to correct the links. +# Note that each tag file must have a unique name +# (where the name does NOT include the path) +# If a tag file is not located in the directory in which doxygen +# is run, you must also specify the path to the tagfile here. + +TAGFILES = + +# When a file name is specified after GENERATE_TAGFILE, doxygen will create +# a tag file that is based on the input files it reads. + +GENERATE_TAGFILE = + +# If the ALLEXTERNALS tag is set to YES all external classes will be listed +# in the class index. If set to NO only the inherited external classes +# will be listed. + +ALLEXTERNALS = NO + +# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed +# in the modules index. If set to NO, only the current project's groups will +# be listed. + +EXTERNAL_GROUPS = YES + +# The PERL_PATH should be the absolute path and name of the perl script +# interpreter (i.e. the result of `which perl'). + +PERL_PATH = /usr/bin/perl + +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- + +# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will +# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base +# or super classes. Setting the tag to NO turns the diagrams off. Note that +# this option is superseded by the HAVE_DOT option below. This is only a +# fallback. It is recommended to install and use dot, since it yields more +# powerful graphs. + +CLASS_DIAGRAMS = YES + +# If set to YES, the inheritance and collaboration graphs will hide +# inheritance and usage relations if the target is undocumented +# or is not a class. + +HIDE_UNDOC_RELATIONS = YES + +# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is +# available from the path. This tool is part of Graphviz, a graph visualization +# toolkit from AT&T and Lucent Bell Labs. The other options in this section +# have no effect if this option is set to NO (the default) + +HAVE_DOT = YES + +# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect inheritance relations. Setting this tag to YES will force the +# the CLASS_DIAGRAMS tag to NO. + +CLASS_GRAPH = YES + +# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for each documented class showing the direct and +# indirect implementation dependencies (inheritance, containment, and +# class references variables) of the class with other documented classes. + +COLLABORATION_GRAPH = YES + +# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen +# will generate a graph for groups, showing the direct groups dependencies + +GROUP_GRAPHS = YES + +# If the UML_LOOK tag is set to YES doxygen will generate inheritance and +# collaboration diagrams in a style similar to the OMG's Unified Modeling +# Language. + +UML_LOOK = NO + +# If set to YES, the inheritance and collaboration graphs will show the +# relations between templates and their instances. + +TEMPLATE_RELATIONS = NO + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT +# tags are set to YES then doxygen will generate a graph for each documented +# file showing the direct and indirect include dependencies of the file with +# other documented files. + +INCLUDE_GRAPH = YES + +# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and +# HAVE_DOT tags are set to YES then doxygen will generate a graph for each +# documented header file showing the documented files that directly or +# indirectly include this file. + +INCLUDED_BY_GRAPH = YES + +# If the CALL_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a call dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable call graphs for selected +# functions only using the \callgraph command. + +CALL_GRAPH = NO + +# If the CALLER_GRAPH and HAVE_DOT tags are set to YES then doxygen will +# generate a caller dependency graph for every global function or class method. +# Note that enabling this option will significantly increase the time of a run. +# So in most cases it will be better to enable caller graphs for selected +# functions only using the \callergraph command. + +CALLER_GRAPH = NO + +# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen +# will graphical hierarchy of all classes instead of a textual one. + +GRAPHICAL_HIERARCHY = YES + +# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES +# then doxygen will show the dependencies a directory has on other directories +# in a graphical way. The dependency relations are determined by the #include +# relations between the files in the directories. + +DIRECTORY_GRAPH = YES + +# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images +# generated by dot. Possible values are png, jpg, or gif +# If left blank png will be used. + +DOT_IMAGE_FORMAT = png + +# The tag DOT_PATH can be used to specify the path where the dot tool can be +# found. If left blank, it is assumed the dot tool can be found in the path. + +DOT_PATH = + +# The DOTFILE_DIRS tag can be used to specify one or more directories that +# contain dot files that are included in the documentation (see the +# \dotfile command). + +DOTFILE_DIRS = + +# The MAX_DOT_GRAPH_WIDTH tag can be used to set the maximum allowed width +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_WIDTH = 1024 + +# The MAX_DOT_GRAPH_HEIGHT tag can be used to set the maximum allows height +# (in pixels) of the graphs generated by dot. If a graph becomes larger than +# this value, doxygen will try to truncate the graph, so that it fits within +# the specified constraint. Beware that most browsers cannot cope with very +# large images. + +MAX_DOT_GRAPH_HEIGHT = 1024 + +# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the +# graphs generated by dot. A depth value of 3 means that only nodes reachable +# from the root by following a path via at most 3 edges will be shown. Nodes +# that lay further from the root node will be omitted. Note that setting this +# option to 1 or 2 may greatly reduce the computation time needed for large +# code bases. Also note that a graph may be further truncated if the graph's +# image dimensions are not sufficient to fit the graph (see MAX_DOT_GRAPH_WIDTH +# and MAX_DOT_GRAPH_HEIGHT). If 0 is used for the depth value (the default), +# the graph is not depth-constrained. + +MAX_DOT_GRAPH_DEPTH = 0 + +# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent +# background. This is disabled by default, which results in a white background. +# Warning: Depending on the platform used, enabling this option may lead to +# badly anti-aliased labels on the edges of a graph (i.e. they become hard to +# read). + +DOT_TRANSPARENT = NO + +# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output +# files in one run (i.e. multiple -o and -T options on the command line). This +# makes dot run faster, but since only newer versions of dot (>1.8.10) +# support this, this feature is disabled by default. + +DOT_MULTI_TARGETS = NO + +# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will +# generate a legend page explaining the meaning of the various boxes and +# arrows in the dot generated graphs. + +GENERATE_LEGEND = YES + +# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will +# remove the intermediate dot files that are used to generate +# the various graphs. + +DOT_CLEANUP = YES + +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- + +# The SEARCHENGINE tag specifies whether or not a search engine should be +# used. If set to NO the values of all tags below this one will be ignored. + +SEARCHENGINE = NO -- cgit v1.2.3