win32

create 32bit-deep window in X.
Log | Files | Refs

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 }