xcb.c (7562B)
1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <stdarg.h> 4 #include <string.h> 5 #include <xcb/xcb.h> 6 #include <xcb/xproto.h> 7 #include <xcb/render.h> 8 9 void fatal(char *msg); 10 void fatalf(char *fmt, ...); 11 int findVisual32(xcb_screen_t *screen, xcb_visualtype_t *return_visualtype); 12 int findPictFormat(xcb_connection_t *conn, int dept, xcb_render_pictformat_t *return_pictformat); 13 14 int main(void) { 15 xcb_connection_t *conn = xcb_connect(NULL, NULL); 16 if (xcb_connection_has_error(conn) != 0) { 17 fatal("can't connect to the display"); 18 } 19 xcb_screen_t *screen = xcb_setup_roots_iterator(xcb_get_setup(conn)).data; 20 xcb_window_t window = xcb_generate_id(conn); 21 uint32_t attr = XCB_EVENT_MASK_KEY_PRESS | XCB_EVENT_MASK_EXPOSURE; 22 int width = 800, height = 600; 23 xcb_create_window(conn, XCB_COPY_FROM_PARENT, window, screen->root, 24 0, 0, width, height, 0, 25 XCB_WINDOW_CLASS_INPUT_OUTPUT, 26 screen->root_visual, 27 XCB_CW_EVENT_MASK, &attr); 28 xcb_map_window(conn, window); 29 xcb_change_property(conn, XCB_PROP_MODE_REPLACE, window, XCB_ATOM_WM_NAME, XCB_ATOM_STRING, 8, strlen("xcb"), "xcb"); 30 31 xcb_render_pictformat_t pictformat = 0, pictformat24, pictformat32; 32 if (findPictFormat(conn, 32, &pictformat32) < 0) { 33 fatal("32bit pictformat not found"); 34 } 35 if (findPictFormat(conn, 24, &pictformat24) < 0) { 36 fatal("24bit pictformat not found"); 37 } 38 if (screen->root_depth == 32) { 39 pictformat = pictformat32; 40 } else if (screen->root_depth == 24) { 41 pictformat = pictformat24; 42 } else { 43 fatal("unsupported depth"); 44 } 45 46 xcb_render_picture_t picture = xcb_generate_id(conn); 47 xcb_render_create_picture(conn, picture, window, pictformat, 0, NULL); 48 xcb_render_color_t color = { .red = 0xffff, .green = 0xffff, .blue = 0xeaea, .alpha = 0xffff }; 49 xcb_rectangle_t rectangle = { .x = 0, .y = 0, .width = width, .height = height }; 50 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, picture, color, 1, &rectangle); 51 52 xcb_visualtype_t visual32; 53 if (findVisual32(screen, &visual32) < 0) { 54 fatal("32bit visual not found"); 55 } 56 xcb_colormap_t colormap32 = xcb_generate_id(conn); 57 xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, colormap32, screen->root, visual32.visual_id); 58 xcb_window_t window32 = xcb_generate_id(conn); 59 uint32_t attr32[2] = { 114514, colormap32 }; 60 xcb_create_window(conn, 32, window32, screen->root, 61 0, 0, 1, 1, 0, 62 XCB_WINDOW_CLASS_INPUT_OUTPUT, 63 visual32.visual_id, 64 XCB_CW_BORDER_PIXEL|XCB_CW_COLORMAP, &attr32); 65 66 int width1 = 300, height1 = 300; 67 xcb_pixmap_t pixmap32_1 = xcb_generate_id(conn); 68 xcb_create_pixmap(conn, 32, pixmap32_1, window32, width1, height1); 69 xcb_render_picture_t picture32_1 = xcb_generate_id(conn); 70 xcb_render_create_picture(conn, picture32_1, pixmap32_1, pictformat32, 0, NULL); 71 xcb_render_color_t color1 = { .red = 0xffff, .green = 0, .blue = 0, .alpha = 0x3fff }; 72 xcb_rectangle_t rectangle1 = { .x = 0, .y = 0, .width = width1, height = height1 }; 73 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, picture32_1, color1, 1, &rectangle1); 74 75 int width2 = 300, height2 = 200; 76 xcb_pixmap_t pixmap32_2 = xcb_generate_id(conn); 77 xcb_create_pixmap(conn, 32, pixmap32_2, window32, width2, height1); 78 xcb_render_picture_t picture32_2 = xcb_generate_id(conn); 79 xcb_render_create_picture(conn, picture32_2, pixmap32_2, pictformat32, 0, NULL); 80 xcb_render_color_t color2 = { .red = 0, .green = 0xffff, .blue = 0, .alpha = 0x3fff }; 81 xcb_rectangle_t rectangle2 = { .x = 0, .y = 0, .width = width2, height = height2 }; 82 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, picture32_2, color2, 2, &rectangle2); 83 84 int width3 = 300, height3 = 300; 85 xcb_pixmap_t pixmap32_3 = xcb_generate_id(conn); 86 xcb_create_pixmap(conn, 32, pixmap32_3, window32, width3, height1); 87 xcb_render_picture_t picture32_3 = xcb_generate_id(conn); 88 xcb_render_create_picture(conn, picture32_3, pixmap32_3, pictformat32, 0, NULL); 89 xcb_render_color_t color3 = { .red = 0, .green = 0, .blue = 0xffff, .alpha = 0x3fff }; 90 xcb_rectangle_t rectangle3 = { .x = 0, .y = 0, .width = width3, height = height3 }; 91 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, picture32_3, color3, 3, &rectangle3); 92 93 xcb_flush(conn); 94 95 int quit = 0; 96 xcb_generic_event_t *event; 97 while (!quit) { 98 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, picture, color, 1, &rectangle); 99 xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER, picture32_1, 0, picture, 0, 0, 0, 0, 100, 100, width1, height1); 100 xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER, picture32_2, 0, picture, 0, 0, 0, 0, 200, 150, width2, height2); 101 xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER, picture32_3, 0, picture, 0, 0, 0, 0, 150, 200, width3, height3); 102 xcb_flush(conn); 103 104 event = xcb_wait_for_event(conn); 105 if ((event->response_type & ~0x80) == XCB_KEY_PRESS && ((xcb_key_press_event_t *)event)->detail == 49) { 106 quit = 1; 107 } 108 } 109 xcb_render_free_picture(conn, picture32_3); 110 xcb_free_pixmap(conn, pixmap32_3); 111 xcb_render_free_picture(conn, picture32_2); 112 xcb_free_pixmap(conn, pixmap32_2); 113 xcb_render_free_picture(conn, picture32_1); 114 xcb_free_pixmap(conn, pixmap32_1); 115 xcb_free_colormap(conn, colormap32); 116 xcb_destroy_window(conn, window32); 117 118 xcb_render_free_picture(conn, picture); 119 xcb_destroy_window(conn, window); 120 121 xcb_disconnect(conn); 122 return 0; 123 } 124 125 void fatal(char *msg) { 126 fprintf(stderr, "%s\n", msg); 127 exit(1); 128 } 129 130 void fatalf(char *fmt, ...) { 131 va_list ap; 132 va_start(ap, fmt); 133 vfprintf(stderr, fmt, ap); 134 va_end(ap); 135 fprintf(stderr, "\n"); 136 exit(1); 137 } 138 139 int findVisual32(xcb_screen_t *screen, xcb_visualtype_t *return_visualtype) { 140 xcb_depth_iterator_t depth_iter = xcb_screen_allowed_depths_iterator(screen); 141 for (;depth_iter.rem > 0; xcb_depth_next(&depth_iter)) { 142 xcb_depth_t *d = depth_iter.data; 143 if (d->depth != 32) { 144 continue; 145 } 146 xcb_visualtype_iterator_t visual_iter = xcb_depth_visuals_iterator(d); 147 while (visual_iter.rem > 0) { 148 xcb_visualtype_t *v = visual_iter.data; 149 if (v->red_mask == 0xff0000 && v->green_mask == 0x00ff00 && v->blue_mask == 0x0000ff) { 150 *return_visualtype = *v; 151 return 0; 152 } 153 xcb_visualtype_next(&visual_iter); 154 } 155 } 156 return -1; 157 } 158 159 int findPictFormat(xcb_connection_t *conn, int depth, xcb_render_pictformat_t *return_pictformat) { 160 xcb_generic_error_t *error; 161 xcb_render_query_pict_formats_cookie_t cookie = xcb_render_query_pict_formats(conn); 162 xcb_render_query_pict_formats_reply_t *reply = xcb_render_query_pict_formats_reply(conn, cookie, &error); 163 if (error != NULL) { 164 fatal("render_query_pict_formats"); 165 } 166 xcb_render_pictforminfo_iterator_t iter = xcb_render_query_pict_formats_formats_iterator(reply); 167 while (iter.rem > 0) { 168 if (depth == 24 && iter.data->type == XCB_RENDER_PICT_TYPE_DIRECT && iter.data->depth == 24 && 169 iter.data->direct.red_shift == 16 && iter.data->direct.red_mask == 0xff && 170 iter.data->direct.green_shift == 8 && iter.data->direct.green_mask == 0xff && 171 iter.data->direct.blue_shift == 0 && iter.data->direct.blue_mask == 0xff) { 172 *return_pictformat = iter.data->id; 173 return 0; 174 } 175 if (depth == 32 && iter.data->type == XCB_RENDER_PICT_TYPE_DIRECT && iter.data->depth == 32 && 176 iter.data->direct.alpha_shift == 24 && iter.data->direct.alpha_mask == 0xff && 177 iter.data->direct.red_shift == 16 && iter.data->direct.red_mask == 0xff && 178 iter.data->direct.green_shift == 8 && iter.data->direct.green_mask == 0xff && 179 iter.data->direct.blue_shift == 0 && iter.data->direct.blue_mask == 0xff) { 180 *return_pictformat = iter.data->id; 181 return 0; 182 } 183 xcb_render_pictforminfo_next(&iter); 184 } 185 return -1; 186 }