In the previous example, we never cared whether the function and X server communication were synchronous or asynchronous when the XCB function was called. Because in the previous example, we basically don't care about the return value of the XCB function, only the return value of the XCB function is involved in the previous article because some operations need to be concerned about whether they succeeded (such as whether the font was successfully opened, whether the GC was successfully created, and so on).
In this article, we will take a step further, because it is to get the properties of the window, so be sure to focus on the data obtained from X server, at this point, it will be related to the XCB function and X server communication is synchronous or asynchronous. What is synchronization? This means that after calling a function to make a request to X server, the function waits until the data function of the X server reply returns. What is async? That is, after calling a XCB function to make a request to X server, the function returns without waiting for the X server to reply to the data. Traditional Xlib use synchronous methods, while XCB is used asynchronously. It is clear that the use of async can achieve better efficiency. This is also a major reason for XCB to replace Xlib.
So since XCB is using an asynchronous approach, calling a XCB function does not wait for the X server to reply and the function has returned, so what do we really need to do with the data that X server replies? For this problem, a workaround is used in XCB: The XCB function returns a cookie, the data transfer takes place in the background, is automatically processed by the XCB, and when the data obtained from X server needs to be used, another function is called to fetch the data through the cookie. You'll see a concrete example later.
Manipulating the properties of a window
The previous shows how to create a window and how to draw in a window. In fact, for the window, you can also have more operations. You can assume that these operations are done by getting and setting the properties of the window. Windows can have many properties, and these properties are set differently. Here's a look at the function of creating a window:
xcb_void_cookie_t Xcb_create_window (xcb_connection_t*connection,/*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 this 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,Constuint32_t *value_list);
Can see: 1, a part of the property is directly through the parameters of the Xcb_create_window set, such as the window's color depth, position, size, border width, etc. 2, the properties of some windows are set by mask, values, such as the foreground color, background color, Events that require attention, etc. 3. There are also some properties that need to be set in a different way, which I have not shown before, which is set by the Xcb_change_property function, which is more specific, each of which is called Atom. As you can see from the Xcb_create_window function signature, Xcb_create_window does return a value of xcb_void_cookie_t type, which is the return of a cookie. This verifies that I have previously said that the XCB function is asynchronous.
The function signature of Xcb_change_property is as follows:
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, +, +)*/uint32_t Data_len,/*Length of the data parameter*/ Const void*data/*Data*/);
As you can see, the function should also focus on the Atom's ID, Atom type, and Atom's value, as well as the format and length of the value. In other words, each atom is identified by an ID, which can have its own type and value. For example, an atom might be a number, and another atom might be a string. The function's mode parameter can remove one of the face values:
Xcb_prop_mode_replacexcb_prop_mode_prependxcb_prop_mode_append
Using Atom to represent the properties of a window is primarily to communicate with other programs, such as the window manager. Here is an example of setting the window title and the taskbar title after the window is minimized:
#include <string.h>#include<xcb/xcb.h>#include<xcb/xcb_atom.h>intMain () {/*Open the connection to the X server*/xcb_connection_t*connection =xcb_connect (null, NULL); /*get the first screen*/xcb_screen_t*screen =Xcb_setup_roots_iterator (Xcb_get_setup (connection)). Data; /*Create the Window*/xcb_window_t window=xcb_generate_id (connection); Xcb_create_window (Connection,0,/*Depth*/window, screen->root,/*parent Window*/ 0,0,/*x, y*/ -, Max,/*width, height*/ Ten,/*Border_width*/Xcb_window_class_input_output,/*class*/ Screen->root_visual,/*Visual*/ 0, NULL);/*masks, not used*/ /*set the title of the window*/ Char*title ="Hello World!"; Xcb_change_property (Connection, xcb_prop_mode_replace, window, Xcb_atom_wm_name, Xcb_atom_string,8, strlen (title), title); /*set the title of the window icon*/ Char*icontitle ="Hello World! (iconified)"; Xcb_change_property (Connection, xcb_prop_mode_replace, window, Xcb_atom_wm_icon_name, Xcb_atom_string, 8, strlen (icontitle), icontitle); /*Map the window on the screen*/Xcb_map_window (Connection, window); Xcb_flush (connection); /*event Loop (in this case, no events to handle)*/ while(1) {} return 0; }
If you want to change the window's size, position, border width and other properties, you can do the following functions:
xcb_void_cookie_t Xcb_configure_window ( *c,/* The connection to the X server* / xcb_window_t window, /**/ uint16_t Value_mask, /* */ const uint32_t *value_list/ **/ );
As you can see, this function again uses mask, valuelist this mode. The properties that the function can manipulate are as follows:
xcb_config_window_x // new X coord Inate 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
For a long while, I haven't written the usage of the XCB function and the X server asynchronous communication. In order not to write this essay too smelly and long, xcb_configure_window specific how to use me not for example. You can read XCB's official tutorials on your own. Let's see what is asynchronous.
Get the properties of a window
There are a lot of functions to get the properties of the window, such as the most common xcb_get_geometry and xcb_get_geometry_reply , see geometry will certainly think of the length of the width of height, vertical axis and so on. Indeed, these two functions are used to get some information about the position and size of the window. And these two functions always appear in pairs. Because Xcb_get_geometry is called, it is returned immediately, then the X server data has not been transmitted back, so, and so on, and so on the data sent back, but also to call xcb_get_geometry_reply to read out the data. The signatures of these two functions are as follows:
xcb_get_geometry_cookie_t xcb_get_geometry ( *connection, xcb_drawable_t *xcb_ Get_geometry_reply ( xcb_connection_t *connection, xcb_get_geometry_cookie_t cookies, xcb_generic_error_t * *error);
As you can see, the first function returns a cookie of type xcb_get_geometry_cookie_t, and the second function returns the specific geometry information with that cookie as an argument, which is asynchronous. This information is a pointer of type xcb_get_geometry_reply_t, which is defined as follows:
typedefstruct{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;
As I said earlier, the window has many properties. The Geometry property indicates a portion of the properties of the window, so there are a couple more of the functions that get the window properties and the data structures they use, as follows:
typedefstruct{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_get_window_attributes_cookie_t Xcb_get_window_attributes (xcb_connection_t *connection, xcb_window_t window); xcb_get_window_attributes_reply_t*xcb_get_window_attributes_reply (xcb_connection_t*connection, xcb_get_window_attributes_cookie_t cookie, xcb_generic_error_t**e);
These are still basic. Writing a simple window program is enough to understand these basic methods. But GUI programming, there are always some advanced requirements, such as enumerating all the windows in the system. I use the word "enumeration" here because the Win32 API uses the word. In X window, such an operation is called "traversal". Obviously, in the GUI system, all the windows are organized in a tree-like way by the parent and child, so it is not difficult to "enumerate" all the windows in the system by "traversing" the window tree. This task requires the use of such functions and data structures:
typedefstruct{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[ -];} xcb_query_tree_reply_t;xcb_query_tree_cookie_t Xcb_query_tree (xcb_connection_t*connection, xcb_window_t window); xcb_query_tree_reply_t*xcb_query_tree_reply (xcb_connection_t*connection, xcb_query_tree_cookie_t cookie, xcb_generic_error_t**error);
However, it seems that the function can only look up the parent window from a child window, obviously to complete the traversal, but also to find the child window from the parent window. Is there a way to find child windows through the parent window in X window? Let's study slowly.
(Jingshan Ranger in 2014-07-21 published in the blog Park, reproduced please indicate the source. )