This example creates a new Display
and Window
using the common Xlib functions XOpenDisplay
and XCreateSimpleWindow
. It then calls a helper function attach_cursor
that uses both XCB and Xlib facilities to set the cursor of the provided Window
to whatever shape the client provides (in this case a question mark with an arrow as defined by XC_question_arrow
).
#include <X11/Xlib-xcb.h>
#include <X11/cursorfont.h>
#include <unistd.h>
void attach_cursor(Display *dpy, Window w, int shape)
{
static const int fgred = 0, fggreen = 0, fgblue = 0,
bgred = 0xFFFF, bggreen = 0xFFFF, bgblue = 0xFFFF;
xcb_connection_t *c = XGetXCBConnection(dpy);
xcb_cursor_t cursor = xcb_generate_id(c);
xcb_window_t window = (xcb_window_t) w;
xcb_font_t font = xcb_generate_id(c),
*mask_font = &font; /* An alias to clarify what is being passed
to XCBCreateGlyphCursor. */
xcb_open_font(c, font, sizeof("cursor"), "cursor");
xcb_create_glyph_cursor (c, cursor, font, *mask_font, shape, shape + 1,
fgred, fggreen, fgblue, bgred, bggreen, bgblue);
XDefineCursor(dpy, window, cursor);
xcb_free_cursor(c, cursor);
xcb_close_font(c, font);
}
int main(void)
{
static const int DEPTH = 0, X = 0, Y = 0, BORDER_WIDTH = 1;
static const size_t WIDTH = 150, HEIGHT = 150;
Display *dpy;
int screen_num;
unsigned int bordercolor, bgcolor;
Window window;
dpy = XOpenDisplay(NULL);
screen_num = DefaultScreen(dpy);
bordercolor = BlackPixel(dpy, screen_num);
bgcolor = WhitePixel(dpy, screen_num);
window = XCreateSimpleWindow(dpy, RootWindow(dpy, screen_num), X, Y, WIDTH,
HEIGHT, BORDER_WIDTH, bordercolor, bgcolor);
attach_cursor(dpy, window, XC_question_arrow);
XMapWindow(dpy, window);
XSync(dpy, 0);
pause(); /* Hit C-c to break out of this loop. */
return 0;
}
Suppose that the attach_cursor
function was to be ported entirely to use XCB's functionality. How could the pointer's cursor be set to the specified symbol without using XDefineCursor
?