modernc.org/99c@v1.0.1-0.20181109153923-a9e8197063d9/examples/xcb/fontcompleteexample.c (about) 1 // 99c fontcompleteexample.c -lxcb && ./a.out 2 3 // +build ignore 4 5 // src: https://www.x.org/releases/current/doc/libxcb/tutorial/index.html#fontcompleteexample 6 7 #include <stdlib.h> 8 #include <stdio.h> 9 #include <string.h> 10 11 #include <xcb/xcb.h> 12 13 #define WIDTH 300 14 #define HEIGHT 100 15 16 static xcb_gc_t gc_font_get(xcb_connection_t * c, xcb_screen_t * screen, xcb_window_t window, const char *font_name); 17 18 static void text_draw(xcb_connection_t * c, xcb_screen_t * screen, xcb_window_t window, int16_t x1, int16_t y1, const char *label); 19 20 static void text_draw(xcb_connection_t * c, xcb_screen_t * screen, xcb_window_t window, int16_t x1, int16_t y1, const char *label) 21 { 22 xcb_void_cookie_t cookie_gc; 23 xcb_void_cookie_t cookie_text; 24 xcb_generic_error_t *error; 25 xcb_gcontext_t gc; 26 uint8_t length; 27 28 length = strlen(label); 29 30 gc = gc_font_get(c, screen, window, "7x13"); 31 32 cookie_text = xcb_image_text_8_checked(c, length, window, gc, x1, y1, label); 33 error = xcb_request_check(c, cookie_text); 34 if (error) { 35 fprintf(stderr, "ERROR: can't paste text : %d\n", error->error_code); 36 xcb_disconnect(c); 37 exit(-1); 38 } 39 40 cookie_gc = xcb_free_gc(c, gc); 41 error = xcb_request_check(c, cookie_gc); 42 if (error) { 43 fprintf(stderr, "ERROR: can't free gc : %d\n", error->error_code); 44 xcb_disconnect(c); 45 exit(-1); 46 } 47 } 48 49 static xcb_gc_t gc_font_get(xcb_connection_t * c, xcb_screen_t * screen, xcb_window_t window, const char *font_name) 50 { 51 uint32_t value_list[3]; 52 xcb_void_cookie_t cookie_font; 53 xcb_void_cookie_t cookie_gc; 54 xcb_generic_error_t *error; 55 xcb_font_t font; 56 xcb_gcontext_t gc; 57 uint32_t mask; 58 59 font = xcb_generate_id(c); 60 cookie_font = xcb_open_font_checked(c, font, strlen(font_name), font_name); 61 62 error = xcb_request_check(c, cookie_font); 63 if (error) { 64 fprintf(stderr, "ERROR: can't open font : %d\n", error->error_code); 65 xcb_disconnect(c); 66 return -1; 67 } 68 69 gc = xcb_generate_id(c); 70 mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT; 71 value_list[0] = screen->black_pixel; 72 value_list[1] = screen->white_pixel; 73 value_list[2] = font; 74 cookie_gc = xcb_create_gc_checked(c, gc, window, mask, value_list); 75 error = xcb_request_check(c, cookie_gc); 76 if (error) { 77 fprintf(stderr, "ERROR: can't create gc : %d\n", error->error_code); 78 xcb_disconnect(c); 79 exit(-1); 80 } 81 82 cookie_font = xcb_close_font_checked(c, font); 83 error = xcb_request_check(c, cookie_font); 84 if (error) { 85 fprintf(stderr, "ERROR: can't close font : %d\n", error->error_code); 86 xcb_disconnect(c); 87 exit(-1); 88 } 89 90 return gc; 91 } 92 93 int main() 94 { 95 xcb_screen_iterator_t screen_iter; 96 xcb_connection_t *c; 97 const xcb_setup_t *setup; 98 xcb_screen_t *screen; 99 xcb_generic_event_t *e; 100 xcb_generic_error_t *error; 101 xcb_void_cookie_t cookie_window; 102 xcb_void_cookie_t cookie_map; 103 xcb_window_t window; 104 uint32_t mask; 105 uint32_t values[2]; 106 int screen_number; 107 108 /* getting the connection */ 109 c = xcb_connect(NULL, &screen_number); 110 if (!c) { 111 fprintf(stderr, "ERROR: can't connect to an X server\n"); 112 return -1; 113 } 114 115 /* getting the current screen */ 116 setup = xcb_get_setup(c); 117 118 screen = NULL; 119 screen_iter = xcb_setup_roots_iterator(setup); 120 for (; screen_iter.rem != 0; --screen_number, xcb_screen_next(&screen_iter)) 121 if (screen_number == 0) { 122 screen = screen_iter.data; 123 break; 124 } 125 if (!screen) { 126 fprintf(stderr, "ERROR: can't get the current screen\n"); 127 xcb_disconnect(c); 128 return -1; 129 } 130 131 /* creating the window */ 132 window = xcb_generate_id(c); 133 mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK; 134 values[0] = screen->white_pixel; 135 values[1] = XCB_EVENT_MASK_KEY_RELEASE | XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_POINTER_MOTION; 136 cookie_window = xcb_create_window_checked(c, screen->root_depth, window, screen->root, 20, 200, WIDTH, HEIGHT, 0, XCB_WINDOW_CLASS_INPUT_OUTPUT, screen->root_visual, mask, values); 137 cookie_map = xcb_map_window_checked(c, window); 138 139 /* error managing */ 140 error = xcb_request_check(c, cookie_window); 141 if (error) { 142 fprintf(stderr, "ERROR: can't create window : %d\n", error->error_code); 143 xcb_disconnect(c); 144 return -1; 145 } 146 error = xcb_request_check(c, cookie_map); 147 if (error) { 148 fprintf(stderr, "ERROR: can't map window : %d\n", error->error_code); 149 xcb_disconnect(c); 150 return -1; 151 } 152 153 xcb_flush(c); 154 155 while (1) { 156 e = xcb_poll_for_event(c); 157 if (e) { 158 switch (e->response_type & ~0x80) { 159 case XCB_EXPOSE:{ 160 char *text; 161 162 text = "Press ESC key to exit..."; 163 text_draw(c, screen, window, 10, HEIGHT - 10, text); 164 break; 165 } 166 case XCB_KEY_RELEASE:{ 167 xcb_key_release_event_t *ev; 168 169 ev = (xcb_key_release_event_t *) e; 170 171 switch (ev->detail) { 172 /* ESC */ 173 case 9: 174 free(e); 175 xcb_disconnect(c); 176 return 0; 177 } 178 } 179 } 180 free(e); 181 } 182 } 183 184 return 0; 185 }