X-Git-Url: http://git.demorecorder.com/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=doc%2Ftutorial%2Findex.html;h=ea083374503701bc0fd0a5f6119ca2628a460cf9;hb=422458b66380e4103c4937f0e2e8bb93e31f273a;hp=2e62c7da2d7edeb00aaa61af474e3ace326b9a39;hpb=342e9cefcc7d942714488f6b424fee7a5bdc741f;p=free-sw%2Fxcb%2Flibxcb diff --git a/doc/tutorial/index.html b/doc/tutorial/index.html index 2e62c7d..ea08337 100644 --- a/doc/tutorial/index.html +++ b/doc/tutorial/index.html @@ -59,9 +59,10 @@
-xcb_connection_t *xcb_connect (const char *displayname, -int *screenp); +xcb_connection_t *xcb_connect (const char *displayname, + int *screenp);
The second parameter returns the screen number used for the @@ -596,24 +598,24 @@ gcc -Wall prog.c -o prog `pkg-config --cflags --libs xcb` and is opaque. Here is how the connection can be opened:
-#include <xcb/xcb.h> +#include <xcb/xcb.h> -int -main () +int +main () { -xcb_connection_t *c; + 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; + return 0; }
To close a connection, it suffices to use:
-void xcb_disconnect (xcb_connection_t *c); +void xcb_disconnect (xcb_connection_t *c);
-
+Once we have opened a connection to an X server, we should check some @@ -706,7 +707,7 @@ main () } printf ("\n"); - printf ("Informations of screen %ld:\n", screen->root.xid); + 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); @@ -723,9 +724,7 @@ main () characterized by an Id. So, in XCB, a window is of type:
-typedef struct { - uint32_t xid; -} xcb_window_t; +typedef uint32_t xcb_window_t;
We first ask for a new Id for our window, with this function: @@ -887,9 +886,7 @@ int xcb_aux_sync (xcb_connection_t *c); a Graphics Context is, as a window, characterized by an Id:
-typedef struct { - uint32_t xid; -} xcb_gcontext_t; +typedef uint32_t xcb_gcontext_t;
We first ask the X server to attribute an Id to our graphic @@ -982,8 +979,9 @@ main () 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: + 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 */ @@ -1333,7 +1331,7 @@ main () /* We draw the polygonal line */ xcb_poly_line (c, XCB_COORD_MODE_PREVIOUS, win, foreground, 4, polyline); - /* We draw the segements */ + /* We draw the segments */ xcb_poly_segment (c, win, foreground, 2, segments); /* We draw the rectangles */ @@ -1455,7 +1453,7 @@ typedef enum {
If the window has already been created, we can use the - xcb_configure_window() function to set + 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 @@ -1468,14 +1466,14 @@ const static uint32_t values[] = { XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_BUTT /* The connection c and the window win are supposed to be defined */ -xcb_configure_window (c, win, XCB_CW_EVENT_MASK, values); +xcb_change_window_attributes (c, win, XCB_CW_EVENT_MASK, values);
- Note: A common bug programmers do is adding code to handle new + Note: A common bug programmers have 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 + programmer would then sit there for hours debugging their 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. @@ -1832,7 +1830,7 @@ typedef xcb_enter_notify_event_t xcb_leave_notify_event_t; 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 + cause an event to be sent to our program (if it registered for these event types...).
- In order to support flexible fonts, a font structure is + In order to support flexible fonts, a font type is defined. You know what ? It's an Id:
-typedef struct { - uint32_t xid; -} xcb_font_t; +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); ++
+ 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()). +
++ 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 example 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); ++
+ 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. +
+- TODO: example for picking a font and displaying some text. - Even better, also demonstrate translating keypresses to text. + 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; +} +
@@ -2097,9 +2387,7 @@ typedef struct { Id. Their type are xcb_atom_t:
-typedef struct { - uint32_t xid; -} xcb_atom_t; +typedef uint32_t xcb_atom_t;
To change the property of a window, we use the following @@ -2116,7 +2404,7 @@ xcb_void_cookie_t xcb_change_property (xcb_connection_t *c, /* Connection const void *data); /* Data */
- The mode parameter coud be one of + The mode parameter could be one of the following values (defined in enumeration xcb_prop_mode_t in the xproto.h header file):
@@ -2651,7 +2939,7 @@ xcb_get_window_attributes_reply_t *xcb_get_window_attributes_reply (xcb_connecti 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 + colors into something quite bizarre. In fact, this is the effect you get with X applications that use the "-install" command line option. @@ -2659,9 +2947,7 @@ xcb_get_window_attributes_reply_t *xcb_get_window_attributes_reply (xcb_connecti In XCB, a color map is (as often in X) an Id:-typedef struct { - uint32_t xid; -} xcb_colormap_t; +typedef uint32_t xcb_colormap_t;
In order to access the screen's default color map, you just @@ -2902,19 +3188,14 @@ main () of X pixmap in XCB is an Id like a window:
-typedef struct { - uint32_t xid; -} xcb_pixmap_t; +typedef uint32_t xcb_pixmap_t;
- In order to make the difference between a window and a pixmap, - XCB introduces a drawable type, which is a union + Like Xlib, there is no difference between a Drawable, a Window + or a Pixmap:
-typedef union { - xcb_window_t window; - xcb_pixmap_t pixmap; -} xcb_drawable_t; +typedef uint32_t xcb_drawable_t;
in order to avoid confusion between a window and a pixmap. The @@ -3021,10 +3302,10 @@ xcb_void_cookie_t xcb_free_pixmap (xcb_connection_t *c, /* Pointer to the
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 + called the X pointer) when in certain states, as we often 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 + the hourglass cursor over its main window, to give the user a visual + hint that they should wait. Let's see how we can change the mouse cursor of our windows.
-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 */ +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 @@ -3060,7 +3341,7 @@ xcb_void_cookie_t xcb_create_glyph_cursor_checked (xcb_connection_t *c,
So we first open that font (see Loading a Font) - and create the new cursor. As for every X ressource, we have to + and create the new cursor. As for every X resource, we have to ask for an X id with xcb_generate_id first:
@@ -3116,7 +3397,7 @@ uint32_t value_list; /* The cursor is already created */ mask = XCB_CWCURSOR; -value_list = cursor.xid; +value_list = cursor; xcb_change_window_attributes (conn, window, mask, &value_list);@@ -3124,8 +3405,391 @@ xcb_change_window_attributes (conn, window, mask, &value_list);
- TODO: to do... + 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; +} +
@@ -3438,8 +4102,7 @@ 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 */
-
+xcb_connection_t *c; xcb_screen_t *screen; @@ -3529,7 +4192,7 @@ if (screen) { visual_iter = xcb_depth_visuals_iterator (depth_iter.data); for (; visual_iter.rem; xcb_visualtype_next (&visual_iter)) { - if (screen->root_visual.id == visual_iter.data->visual_id.id) { + if (screen->root_visual == visual_iter.data->visual_id) { visual_type = visual_iter.data; break; }