X Window Programming/XCB
Introduction
[edit | edit source]XCB (X C Binding) is a C language binding for the X Window System. It aims to replace XLib. The project was started in 2001 by Bart Massey.
Xlib/XCB provides application binary interface compatibility with both Xlib and XCB, providing an incremental porting path.
Aims of XCB
[edit | edit source]The main aims of XCB are:
- reduction in library size and complexity;
- direct access to the X11 protocol.
Secondary aims include making the C interface asynchronous, facilitating better multithreading and making extensions easier to implement (via XML protocol descriptions).
The core and extension protocol descriptions are in XML, with the C bindings created via XSLT. A tertiary aim is to repurpose these protocol descriptions for the creation of protocol documentation, further language bindings, and server-side stubs.
Massey has worked to prove XCB formally correct, using Z notation. (Xlib has long been known to contain errors.)
Example
[edit | edit source]/* Simple XCB application drawing a box in a window */
#include <xcb/xcb.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
int
main (int argc, char **argv)
{
xcb_connection_t *c;
xcb_screen_t *s;
xcb_window_t w;
xcb_gcontext_t g;
xcb_generic_event_t *e;
uint32_t mask;
uint32_t values[2];
int done;
xcb_rectangle_t r = { 20, 20, 60, 60 };
/* open connection with the server */
c = xcb_connect (NULL, NULL);
if (xcb_connection_has_error(c) > 0)
{
printf ("Cannot open display\n");
exit (1);
}
s = xcb_setup_roots_iterator (xcb_get_setup (c)).data;
/* create window */
mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
values[0] = s->white_pixel;
values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
w = xcb_generate_id (c);
xcb_create_window (c, XCB_COPY_FROM_PARENT, w, s->root,
10, 10, 100, 100, 1,
XCB_WINDOW_CLASS_INPUT_OUTPUT,
s->root_visual,
mask, values);
/* create black graphics context */
mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
values[0] = s->black_pixel;
values[1] = 0;
g = xcb_generate_id (c);
xcb_create_gc (c, g, w, mask, values);
/* map (show) the window */
xcb_map_window (c, w);
xcb_flush (c);
/* event loop */
done = 0;
while (!done && (e = xcb_wait_for_event (c)))
{
switch (e->response_type)
{
/* (re)draw the window */
case XCB_EXPOSE:
printf ("EXPOSE\n");
xcb_poly_fill_rectangle (c, w, g, 1, &r);
xcb_flush (c);
break;
/* exit on keypress */
case XCB_KEY_PRESS:
done = 1;
break;
}
free (e);
}
/* close connection to server */
xcb_disconnect (c);
return 0;
}
Old Example
[edit | edit source] /* Simple XCB application drawing a box in a window */
/* note that this is old code, modern XCB has dropped
* CamelCase, eg XCBConnection -> xcb_connection_t
*/
#include <X11/XCB/xcb.h>
#include <stdio.h>
#include <stdlib.h>
int main()
{
XCBConnection *c;
XCBSCREEN *s;
XCBDRAWABLE w;
XCBGCONTEXT g;
XCBGenericEvent *e;
CARD32 mask;
CARD32 values[2];
int done = 0;
XCBRECTANGLE r = { 20, 20, 60, 60 };
/* open connection with the server */
c = XCBConnect(NULL,NULL);
if (c == NULL) {
printf("Cannot open display\n");
exit(1);
}
/* get the first screen */
s = XCBSetupRootsIter( XCBGetSetup(c) ).data;
/* create black graphics context */
g = XCBGCONTEXTNew(c);
w.window = s->root;
mask = XCBGCForeground | XCBGCGraphicsExposures;
values[0] = s->black_pixel;
values[1] = 0;
XCBCreateGC(c, g, w, mask, values);
/* create window */
w.window = XCBWINDOWNew(c);
mask = XCBCWBackPixel | XCBCWEventMask;
values[0] = s->white_pixel;
values[1] = XCBEventMaskExposure | XCBEventMaskKeyPress;
XCBCreateWindow(c, s->root_depth, w.window, s->root,
10, 10, 100, 100, 1,
XCBWindowClassInputOutput, s->root_visual,
mask, values);
/* map (show) the window */
XCBMapWindow(c, w.window);
XCBFlush(c);
/* event loop */
while (!done && (e = XCBWaitForEvent(c))) {
switch (e->response_type & ~0x80) {
case XCBExpose: /* draw or redraw the window */
XCBPolyFillRectangle(c, w, g, 1, &r);
XCBFlush(c);
break;
case XCBKeyPress: /* exit on key press */
done = 1;
break;
}
free(e);
}
/* close connection to server */
XCBDisconnect(c);
return 0;
}
XCB has a comparable, but slightly lower-level API than XLib, as can be seen with these examples.
References
[edit | edit source]- XCB: An X Protocol C Binding () (Bart Massey and Jamey Sharp, 19 September 2001, presented at XFree86 Technical Conference 2001)
- XCL: An Xlib Compatibility Layer For XCB (Jamey Sharp and Bart Massey, 15 April 2002, presented at USENIX 2002)
- X Meets Z: Verifying Correctness In The Presence Of POSIX Threads (Bart Massey and Robert Bauer, 15 April 2002, presented at USENIX 2002)