X 窗口编程/XCB
外观
< X 窗口编程
XCB(X C 绑定)是 C 语言绑定,用于 X 窗口系统。它的目标是取代 XLib。该项目由 Bart Massey 于 2001 年启动。
Xlib/XCB 提供了与 Xlib 和 XCB 的应用程序二进制接口兼容性,提供了一个增量移植路径。
XCB 的主要目标是
- 减少库的大小和复杂性;
- 直接访问 X11 协议。
次要目标包括使 C 接口异步,促进更好的多线程,并使扩展更容易实现(通过 XML 协议描述)。
核心和扩展协议描述位于 XML 中,C 绑定通过 XSLT 创建。第三个目标是将这些协议描述重新用于创建协议文档、其他语言绑定和服务器端存根。
Massey 致力于使用 Z 符号正式证明 XCB 的正确性。(Xlib 长期以来一直被认为包含错误。)
/* 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;
}
/* 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 具有与 XLib 相当但略微底层的 API,可以通过这些示例看到。
- XCB:X 协议 C 绑定 ()(Bart Massey 和 Jamey Sharp,2001 年 9 月 19 日,在 XFree86 技术大会 2001 上发表)
- XCL:XCB 的 Xlib 兼容性层(Jamey Sharp 和 Bart Massey,2002 年 4 月 15 日,在美国 USENIX 2002 上发表)
- X 遇上 Z:在 POSIX 线程存在的情况下验证正确性(Bart Massey 和 Robert Bauer,2002 年 4 月 15 日,在美国 USENIX 2002 上发表)