- XCBWINDOW window;
- XCBPIXMAP pixmap;
-} XCBDRAWABLE;
-</pre>
- <p>
- in order to avoid confusion between a window and a pixmap.The
- operations that will work indifferently on a window or a pixmap
- will require a <span class="code">XCBDRAWABLE</span>
- </p>
- <div class="emph">
- <p>
- Remark: In Xlib, there is no specific difference between a
- <span class="code">Drawable</span>, a
- <span class="code">Pixmap</span> or a
- <span class="code">Window</span>: all are 32 bit long
- integer.
- </p>
- </div>
- <li class="subtitle"><a name="pixmapscreate">Creating a pixmap</a></li>
- <p>
- 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.
- </p>
- <p>
- To create a new pixmap, we first ask the X server to give an
- Id to our pixmap, with this function:
- </p>
- <pre class="code">
-XCBPIXMAP XCBPIXMAPNew (XCBConnection *c);
-</pre>
- <p>
- Then, XCB supplies the following function to create new pixmaps:
- </p>
- <pre class="code">
-XCBVoidCookie XCBCreatePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
- CARD8 depth, /* Depth of the screen */
- XCBPIXMAP pid, /* Id of the pixmap */
- XCBDRAWABLE drawable,
- CARD16 width, /* Width of the window (in pixels) */
- CARD16 height); /* Height of the window (in pixels) */
-</pre>
- <p>
- <b>TODO</b>: Explain the drawable parameter, and give an
- example (like xpoints.c)
- </p>
- <li class="subtitle"><a name="pixmapsdraw"></a>Drawing a pixmap in a window</li>
- <p>
- Once we got a handle to a pixmap, we can draw it on some
- window, using the following function:
- </p>
- <pre class="code">
-XCBVoidCookie XCBCopyArea (XCBConnection *c, /* Pointer to the XCBConnection structure */
- XCBDRAWABLE src_drawable, /* The Drawable we want to paste */
- XCBDRAWABLE dst_drawable, /* The Drawable on which we copy the previous Drawable */
- XCBGCONTEXT gc, /* A Graphic Context */
- INT16 src_x, /* Top left x coordinate of the region we want to copy */
- INT16 src_y, /* Top left y coordinate of the region we want to copy */
- INT16 dst_x, /* Top left x coordinate of the region where we want to copy */
- INT16 dst_y, /* Top left y coordinate of the region where we want to copy */
- CARD16 width, /* Width of the region we want to copy */
- CARD16 height); /* Height of the region we want to copy */
-</pre>
- <p>
- 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.
- </p>
- <p>
- <b>One important note should be made</b>: it is possible to
- create pixmaps with different depths on the same screen. When
- we perform copy operations (a pixmaap 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
- <span class="code">XCBCopyPlane</span> function. In such an
- event, we can copy a specific plain 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 widow, but beyond the scope of this tutorial.
- </p>
- <li class="subtitle"><a name="pixmapsfree"></a>Freeing a pixmap</li>
- <p>
- 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:
- </p>
- <pre class="code">
-XCBVoidCookie XCBFreePixmap (XCBConnection *c, /* Pointer to the XCBConnection structure */
- XCBPIXMAP pixmap); /* A given pixmap */
-</pre>
- <p>
- Of course, after having freed it, we must not try accessing
- the pixmap again.
- </p>
- <p>
- <b>TODO</b>: Give an example, or a link to xpoints.c
- </p>
+ xcb_window_t window;
+ xcb_pixmap_t pixmap;
+} xcb_drawable_t;
+</pre>
+ <p>
+ 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 <span class="code">xcb_drawable_t</span>
+ </p>
+ <div class="emph">
+ <p>
+ Remark: In Xlib, there is no specific difference between a
+ <span class="code">Drawable</span>, a
+ <span class="code">Pixmap</span> or a
+ <span class="code">Window</span>: all are 32 bit long
+ integer. XCB wraps all these different IDs in structures to
+ provide some measure of type-safety.
+ </p>
+ </div>
+ <li class="subtitle"><a name="pixmapscreate">Creating a pixmap</a>
+ <p>
+ 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.
+ </p>
+ <p>
+ To create a new pixmap, we first ask the X server to give an
+ Id to our pixmap, with this function:
+ </p>
+ <pre class="code">
+xcb_pixmap_t xcb_generate_id (xcb_connection_t *c);
+</pre>
+ <p>
+ Then, XCB supplies the following function to create new pixmaps:
+ </p>
+ <pre class="code">
+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) */
+</pre>
+ <p>
+ <b>TODO</b>: Explain the drawable parameter, and give an
+ example (like <a href="xpoints.c">xpoints.c</a>)
+ </p>
+ <li class="subtitle"><a name="pixmapsdraw"></a>Drawing a pixmap in a window
+ <p>
+ Once we got a handle to a pixmap, we can draw it on some
+ window, using the following function:
+ </p>
+ <pre class="code">
+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 */
+</pre>
+ <p>
+ 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.
+ </p>
+ <p>
+ <b>One important note should be made</b>: 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
+ <span class="code">xcb_copy_plane_t</span> 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.
+ </p>
+ <li class="subtitle"><a name="pixmapsfree"></a>Freeing a pixmap
+ <p>
+ 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:
+ </p>
+ <pre class="code">
+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 */
+</pre>
+ <p>
+ Of course, after having freed it, we must not try accessing
+ the pixmap again.
+ </p>
+ <p>
+ <b>TODO</b>: Give an example, or a link to xpoints.c
+ </p>
+ </ol>
+ <li class="title"><a name="mousecursor">Messing with the mouse cursor</a>
+ <p>
+ 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.
+ </p>
+ <ol>
+ <li class="subtitle"><a name="mousecursorcreate">Creating and destroying a mouse cursor</a>
+ <p>
+ 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.
+ </p>
+ <p>
+ In the first method, we use a special font named "cursor", and
+ the function <span class="code">xcb_create_glyph_cursor</span>:
+ </p>
+ <pre class="code">
+xcb_void_cookie_t xcb_create_glyph_cursor_checked (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 */
+</pre>
+ <p>
+ <b>TODO</b>: Describe <span class="code">source_char</span>
+ and <span class="code">mask_char</span>, for example by giving
+ an example on how to get the values. There is a list there:
+ <a href="http://tronche.com/gui/x/xlib/appendix/b/">X Font Cursors</a>
+ </p>
+ <p>
+ So we first open that font (see <a href="#loadfont">Loading a Font</a>)
+ and create the new cursor. As for every X ressource, we have to
+ ask for an X id with <span class="code">xcb_generate_id</span>
+ first:
+ </p>
+ <pre class="code">
+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);
+</pre>
+ <p>
+ We have created the cursor "right hand" by specifying 58 to
+ the <span class="code">source_fon</span>t argument and 58 + 1
+ to the <span class="code">mask_font</span>.
+ </p>
+ <p>
+ The cursor is destroyed by using the function
+ </p>
+ <pre class="code">
+xcb_void_cookie_t xcb_free_cursor (xcb_connection_t *c,
+ xcb_cursor_t cursor);
+</pre>
+ <p>
+ 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.
+ </p>
+ <p>
+ <b>TODO</b>: give an example.
+ </p>
+ <li class="subtitle"><a name="mousecursorset">Setting a window's mouse cursor</a>
+ <p>
+ Once the cursor is created, we can modify the cursor of our
+ window by using <span class="code">xcb_change_window_attributes</span>
+ and using the <span class="code">XCB_CWCURSOR</span> attribute:
+ </p>
+ <pre class="code">
+uint32_t mask;
+uint32_t value_list;
+
+/* The connection and window are set */
+/* The cursor is already created */
+
+mask = XCB_CWCURSOR;
+value_list = cursor.xid;
+xcb_change_window_attributes (conn, window, mask, &value_list);
+</pre>
+ <p>
+ Of course, the cursor and the font must be freed.
+ </p>
+ <li class="subtitle"><a name="mousecursorexample">Complete example</a>
+ <p>
+ <b>TODO</b>: to do...
+ </p>