承接前三篇(建立視窗、繪圖、事件處理),本篇示範在 X 視窗繪製文字,並探討 X Server 核心字體系統與 Xft 的差異。
#include <stdlib.h> #include <stdio.h> #include <string.h>
#include <inttypes.h> #include <xcb/xcb.h>
#define WIDTH 600 #define HEIGHT 400
#define TEST_COOKIE(fn, errMsg) \
cookie = fn; \
error = xcb_request_check(connection, cookie); \
if (error) { fprintf(stderr, "Error: %s : %" PRIu8 "\n", errMsg, error->error_code); }
static void drawText(xcb_connection_t *conn, xcb_screen_t *screen, xcb_window_t win,
int16_t x, int16_t y, const char *font_name, const char *str) {
xcb_void_cookie_t cookie; xcb_generic_error_t *error;
xcb_font_t font = xcb_generate_id(conn);
TEST_COOKIE(xcb_open_font_checked(conn, font, strlen(font_name), font_name), "Can't open font");
xcb_gcontext_t gc = xcb_generate_id(conn);
uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
uint32_t values[3] = {screen->black_pixel, screen->white_pixel, font};
TEST_COOKIE(xcb_create_gc_checked(conn, gc, win, mask, values), "Can't create GC");
TEST_COOKIE(xcb_image_text_8_checked(conn, strlen(str), win, gc, x, y, str), "Can't draw text");
xcb_close_font(conn, font); xcb_free_gc(conn, gc);
}
int main() {
xcb_connection_t *conn = xcb_connect(NULL, NULL);
xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data;
xcb_window_t win = xcb_generate_id(conn);
uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
uint32_t vals[2] = {screen->white_pixel,
XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS |
XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION};
xcb_create_window(conn, screen->root_depth, win, screen->root, 20, 200,
WIDTH, HEIGHT, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
screen->root_visual, mask, vals);
xcb_map_window(conn, win); xcb_flush(conn);
xcb_generic_event_t *ev;
while ((ev = xcb_wait_for_event(conn))) {
switch (ev->response_type & ~0x80) {
case XCB_EXPOSE:
drawText(conn, screen, win, 10, 20, "fixed", "Press ESC key to exit.");
drawText(conn, screen, win, 10, 40, "Dejavu Sans Mono", "Press ESC key to exit.");
drawText(conn, screen, win, 10, 60, "文泉驛正黑", "按ESC鍵退出。");
break;
case XCB_KEY_RELEASE: {
xcb_key_release_event_t *kr = (xcb_key_release_event_t*)ev;
if (kr->detail == 9) { free(ev); xcb_disconnect(conn); return 0; }
}
}
free(ev);
}
return 0;
}

僅 fixed 字體成功繪製,其餘字體報錯「無法開啟字體」。
xlsfonts 列出)。-misc-fixed-medium-r-normal--13-120-75-75-c-70-iso10646-1),安裝需 mkfontdir、mkfontscale 等繁瑣步驟。xcb_generate_id() 產生字體 IDxcb_open_font_checked() 開啟字體mask 包含 XCB_GC_FONT,values 填入 font IDxcb_image_text_8_checked() 繪製 8-bit 文字(另有 _16/_32 版本支援 UTF-16/32)xcb_close_font()、xcb_free_gc() 釋放資源程式開頭定義 TEST_COOKIE 巨集,簡化 _checked 版本函式的 Cookie 檢查流程,提升可讀性。