使用XCB编写X Window程序(四) 在窗口中绘制文字2015-05-13在前面的几节中,我展示了使用XCB创建窗口、在窗口中画图以及捕获并处理事件。在这一篇中,我将展示在窗口中绘制文字。绘制文字当然离不开字体,所以我还会简单地探讨一下X Server的核心字体系统。老规矩,先上代码和运行效果图,代码如下:
1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <inttypes.h>
5 #include <xcb/xcb.h>
6
7
8 #defineWIDTH 600
9 #defineHEIGHT 400
10 #define TEST_COOKIE(fn,errMessage)
11 cookie=fn;
12 error=xcb_request_check(connection,cookie);
13 if(error){
14 fprintf(stderr, "Error: %s : %"PRIu8"
", errMessage, error->error_code);
15 }
16
17 static void drawText(xcb_connection_t *connection, xcb_screen_t *screen, xcb_window_t window,
18 int16_t x, int16_t y, const char *font_name, const char *string){
19 /*cookie and error, for TEST_COOKIE */
20 xcb_void_cookie_t cookie;
21 xcb_generic_error_t *error;
22
23 xcb_font_t font = xcb_generate_id(connection);
24 TEST_COOKIE(xcb_open_font_checked(connection, font, strlen(font_name), font_name), "Can"t open font");
25 xcb_gcontext_t gc = xcb_generate_id(connection);
26 uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT;
27 uint32_t values[3] = {screen->black_pixel, screen->white_pixel, font};
28 TEST_COOKIE(xcb_create_gc_checked(connection, gc, window, mask, values), "Can"t create GC")
29 /*draw the text*/
30 TEST_COOKIE(xcb_image_text_8_checked(connection, strlen(string), window, gc, x, y, string), "Can"t draw text");
31 /*close the font*/
32 xcb_close_font(connection, font);
33 xcb_free_gc(connection, gc);
34 }
35
36 int main()
37 {
38 xcb_connection_t *connection = xcb_connect(NULL, NULL);
39 xcb_screen_t *screen = xcb_setup_roots_iterator( xcb_get_setup(connection)).data;
40
41 /*Create the window*/
42 xcb_window_t window = xcb_generate_id(connection);
43 uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
44 uint32_t values[2];
45 values[0] = screen->white_pixel;
46 values[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS |
47 XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION;
48 xcb_create_window(connection, screen->root_depth,
49 window, screen->root, 20, 200,
50 WIDTH, HEIGHT,
51 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
52 screen->root_visual,
53 mask, values);
54 xcb_map_window(connection, window);
55 xcb_flush(connection);
56
57 /*event loop*/
58 xcb_generic_event_t *event;
59 while((event = xcb_wait_for_event(connection))){
60 switch(event->response_type & ~0x80){
61 case XCB_EXPOSE:
62 {
63 drawText(connection, screen, window, 10, 20,"fixed", "Press ESC key to exit.");
64 drawText(connection, screen, window, 10, 40, "Dejavu Sans Mono", "Press ESC key to exit.");
65 drawText(connection, screen, window, 10, 60, "文泉驿正黑", "按ESC键退出。");
66 break;
67 }
68 case XCB_KEY_RELEASE:
69 {
70 xcb_key_release_event_t *kr = (xcb_key_release_event_t*)event;
71 switch(kr->detail){
72 case 9: /* ESC */
73 {
74 free(event);
75 xcb_disconnect(connection);
76 return 0;
77 }
78 }
79 }
80 }
81 free(event);
82 }
83 return 0;
84 }