3 #include <xcb/xcb_aux.h>
4 #include <xcb/render.h>
12 void print_version_info(xcb_render_query_version_reply_t *reply);
13 int print_formats_info(xcb_render_query_pict_formats_reply_t *reply);
14 int draw_window(xcb_connection_t *conn, xcb_render_query_pict_formats_reply_t *reply);
15 xcb_render_pictformat_t get_pictformat_from_visual(xcb_render_query_pict_formats_reply_t *reply, xcb_visualid_t visual);
16 xcb_render_pictforminfo_t *get_pictforminfo(xcb_render_query_pict_formats_reply_t *reply, xcb_render_pictforminfo_t *query);
19 xcb_render_pictformat_t pf;
21 xcb_render_fixed_t make_fixed(int16_t i, int16_t f)
23 return (i << 16) | (f & 0xffff);
26 void print_version_info(xcb_render_query_version_reply_t *reply)
29 fprintf(stdout, "Render Version: %d.%d\n", reply->major_version,
30 reply->minor_version);
33 int print_formats_info(xcb_render_query_pict_formats_reply_t *reply)
35 xcb_render_pictforminfo_t *first_forminfo;
40 xcb_render_pictforminfo_iterator_t forminfo_iter;
41 xcb_render_pictscreen_iterator_t screen_iter;
43 forminfo_iter = xcb_render_query_pict_formats_formats_iterator(reply);
44 screen_iter = xcb_render_query_pict_formats_screens_iterator(reply);
46 fprintf(stdout, "Number of PictFormInfo iterations: %d\n", forminfo_iter.rem);
48 num_formats = reply->num_formats;
49 first_forminfo = forminfo_iter.data;
50 pf = first_forminfo->id;
51 while(forminfo_iter.rem)
53 xcb_render_pictforminfo_t *forminfo = (xcb_render_pictforminfo_t *)forminfo_iter.data;
55 fprintf(stdout, "PICTFORMINFO #%d\n", 1 + num_formats - forminfo_iter.rem);
56 fprintf(stdout, " PICTFORMAT ID: %d\n", forminfo->id);
57 fprintf(stdout, " PICTFORMAT Type: %d\n", forminfo->type);
58 fprintf(stdout, " PICTFORMAT Depth: %d\n", forminfo->depth);
59 fprintf(stdout, " Direct RedShift: %d\n", forminfo->direct.red_shift);
60 fprintf(stdout, " Direct RedMask: %d\n", forminfo->direct.red_mask);
61 fprintf(stdout, " Direct BlueShift: %d\n", forminfo->direct.blue_shift);
62 fprintf(stdout, " Direct BlueMask: %d\n", forminfo->direct.blue_mask);
63 fprintf(stdout, " Direct GreenShift: %d\n", forminfo->direct.green_shift);
64 fprintf(stdout, " Direct GreenMask: %d\n", forminfo->direct.green_mask);
65 fprintf(stdout, " Direct AlphaShift: %d\n", forminfo->direct.alpha_shift);
66 fprintf(stdout, " Direct AlphaMask: %d\n", forminfo->direct.alpha_mask);
67 fprintf(stdout, "\n");
68 xcb_render_pictforminfo_next(&forminfo_iter);
71 num_screens = reply->num_screens;
72 while(screen_iter.rem)
74 xcb_render_pictdepth_iterator_t depth_iter;
75 xcb_render_pictscreen_t *cscreen = screen_iter.data;
77 fprintf(stdout, "Screen #%d\n", 1 + num_screens - screen_iter.rem);
78 fprintf(stdout, " Depths for this screen: %d\n", cscreen->num_depths);
79 fprintf(stdout, " Fallback PICTFORMAT: %d\n", cscreen->fallback);
80 depth_iter = xcb_render_pictscreen_depths_iterator(cscreen);
82 num_depths = cscreen->num_depths;
85 xcb_render_pictvisual_iterator_t visual_iter;
86 xcb_render_pictdepth_t *cdepth = depth_iter.data;
88 fprintf(stdout, " Depth #%d\n", 1 + num_depths - depth_iter.rem);
89 fprintf(stdout, " Visuals for this depth: %d\n", cdepth->num_visuals);
90 fprintf(stdout, " Depth: %d\n", cdepth->depth);
91 visual_iter = xcb_render_pictdepth_visuals_iterator(cdepth);
93 num_visuals = cdepth->num_visuals;
94 while(visual_iter.rem)
96 xcb_render_pictvisual_t *cvisual = visual_iter.data;
98 fprintf(stdout, " Visual #%d\n", 1 + num_visuals - visual_iter.rem);
99 fprintf(stdout, " VISUALID: %d\n", cvisual->visual);
100 fprintf(stdout, " PICTFORMAT: %d\n", cvisual->format);
101 xcb_render_pictvisual_next(&visual_iter);
103 xcb_render_pictdepth_next(&depth_iter);
105 xcb_render_pictscreen_next(&screen_iter);
110 int draw_window(xcb_connection_t *conn, xcb_render_query_pict_formats_reply_t *reply)
113 xcb_drawable_t window_drawable, tmp, root_drawable;
114 xcb_pixmap_t surfaces[4], alpha_surface;
115 xcb_render_pictformat_t alpha_mask_format, window_format, surface_format, no_format = {0};
116 xcb_render_picture_t window_pict, pict_surfaces[4], alpha_pict,
117 no_picture = {0}, root_picture;
118 xcb_render_pictforminfo_t *forminfo_ptr, *alpha_forminfo_ptr, query;
119 uint32_t value_mask, value_list[4];
120 xcb_rectangle_t pict_rect[1], window_rect;
121 xcb_render_color_t pict_color[4], back_color, alpha_color;
123 xcb_render_trapezoid_t traps[4];
124 xcb_render_triangle_t triangles[4];
125 xcb_render_pointfix_t tristrips[9];
126 xcb_render_pointfix_t trifans[9];
129 root = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
130 root_drawable = root->root;
132 /* Setting query so that it will search for an 8 bit alpha surface. */
134 query.type = XCB_RENDER_PICT_TYPE_DIRECT;
136 query.direct.red_mask = 0;
137 query.direct.green_mask = 0;
138 query.direct.blue_mask = 0;
139 query.direct.alpha_mask = 255;
141 /* Get the xcb_render_pictformat_t associated with the window. */
142 window_format = get_pictformat_from_visual(reply, root->root_visual);
144 /* Get the xcb_render_pictformat_t we will use for the alpha mask */
145 alpha_forminfo_ptr = get_pictforminfo(reply, &query);
146 alpha_mask_format = alpha_forminfo_ptr->id;
148 /* resetting certain parts of query to search for the surface format */
150 query.direct.alpha_mask = 0;
152 /* Get the surface forminfo and xcb_render_pictformat_t */
153 forminfo_ptr = get_pictforminfo(reply, &query);
154 surface_format = forminfo_ptr->id;
156 /* assign XIDs to all of the drawables and pictures */
157 for(index = 0; index < 4; index++)
159 surfaces[index] = xcb_generate_id(conn);
160 pict_surfaces[index] = xcb_generate_id(conn);
162 alpha_surface = xcb_generate_id(conn);
163 alpha_pict = xcb_generate_id(conn);
164 window = xcb_generate_id(conn);
165 window_pict = xcb_generate_id(conn);
166 window_drawable = window;
167 root_picture = xcb_generate_id(conn);
169 /* Here we will create the pixmaps that we will use */
170 for(index = 0; index < 4; index++)
172 surfaces[index] = xcb_generate_id(conn);
173 xcb_create_pixmap(conn, 32, surfaces[index], root_drawable, 600, 600);
175 alpha_surface = xcb_generate_id(conn);
176 xcb_create_pixmap(conn, 8, alpha_surface, root_drawable, 600, 600);
178 /* initialize the value list */
179 value_mask = XCB_CW_EVENT_MASK;
180 value_list[0] = XCB_EXPOSE;
182 /* Create the window */
183 xcb_create_window(conn, /* xcb_connection_t */
184 0, /* depth, 0 means it will copy it from the parent */
185 window, root_drawable, /* window and parent */
187 600, 600, /* width and height */
188 0, /* border width */
189 XCB_WINDOW_CLASS_INPUT_OUTPUT, /* class */
190 root->root_visual, /* xcb_visualid_t */
191 value_mask, value_list); /* LISTofVALUES */
194 * Create the pictures
196 value_mask = 1<<0; /* repeat (still needs to be added to xcb_render.m4) */
199 xcb_render_create_picture(conn, root_picture, root_drawable, window_format,
200 value_mask, value_list);
201 xcb_render_create_picture(conn, window_pict, window_drawable, window_format,
202 value_mask, value_list);
204 xcb_render_create_picture(conn, alpha_pict, tmp, alpha_mask_format,
205 value_mask, value_list);
206 for(index = 0; index < 4; index++)
208 tmp = surfaces[index];
209 xcb_render_create_picture(conn, pict_surfaces[index], tmp, surface_format,
210 value_mask, value_list);
214 * initialize the rectangles
218 window_rect.width = 600;
219 window_rect.height = 600;
223 pict_rect[0].width = 600;
224 pict_rect[0].height = 600;
227 * initialize the colors
229 back_color.red = 0xffff;
230 back_color.green = 0xffff;
231 back_color.blue = 0xffff;
232 back_color.alpha = 0xffff;
234 pict_color[0].red = 0x5fff;
235 pict_color[0].green = 0x0000;
236 pict_color[0].blue = 0x0000;
237 pict_color[0].alpha = 0x5fff;
239 pict_color[1].red = 0x0000;
240 pict_color[1].green = 0x5fff;
241 pict_color[1].blue = 0x0000;
242 pict_color[1].alpha = 0x5fff;
244 pict_color[2].red = 0x0000;
245 pict_color[2].green = 0x0000;
246 pict_color[2].blue = 0x5fff;
247 pict_color[2].alpha = 0x5fff;
249 pict_color[3].red = 0x0000;
250 pict_color[3].green = 0x0000;
251 pict_color[3].blue = 0x5fff;
252 pict_color[3].alpha = 0x5fff;
254 alpha_color.red = 0x0000;
255 alpha_color.green = 0x0000;
256 alpha_color.blue = 0x0000;
257 alpha_color.alpha = 0xffff;
259 /* Create the trapeziod dimensions */
260 traps[0].top = make_fixed(300, 32000);
261 traps[0].bottom = make_fixed(416, 0);
262 traps[0].left.p1.y = make_fixed(250, 0);
263 traps[0].left.p1.x = make_fixed(300, 0);
264 traps[0].left.p2.y = make_fixed(500, 0);
265 traps[0].left.p2.x = make_fixed(100, 0);
266 traps[0].right.p1.y = make_fixed(250, 0);
267 traps[0].right.p1.x = make_fixed(300, 0);
268 traps[0].right.p2.y = make_fixed(505, 6000);
269 traps[0].right.p2.x = make_fixed(456, 512);
271 /* Create the triangle dimensions */
272 triangles[0].p1.x = make_fixed(100, 40000);
273 triangles[0].p1.y = make_fixed(100, 0);
274 triangles[0].p2.x = make_fixed(400, 0);
275 triangles[0].p2.y = make_fixed(150, 30000);
276 triangles[0].p3.x = make_fixed(30, 0);
277 triangles[0].p3.y = make_fixed(456, 0);
279 /* Create the tristrip dimensions */
280 tristrips[0].x = make_fixed(400, 0);
281 tristrips[0].y = make_fixed(50, 0);
282 tristrips[1].x = make_fixed(436, 0);
283 tristrips[1].y = make_fixed(50, 0);
284 tristrips[2].x = make_fixed(398, 0);
285 tristrips[2].y = make_fixed(127, 0);
286 tristrips[3].x = make_fixed(450, 0);
287 tristrips[3].y = make_fixed(120, 0);
288 tristrips[4].x = make_fixed(450, 0);
289 tristrips[4].y = make_fixed(180, 0);
290 tristrips[5].x = make_fixed(503, 0);
291 tristrips[5].y = make_fixed(124, 0);
292 tristrips[6].x = make_fixed(500, 0);
293 tristrips[6].y = make_fixed(217, 0);
294 tristrips[7].x = make_fixed(542, 0);
295 tristrips[7].y = make_fixed(237, 0);
296 tristrips[8].x = make_fixed(501, 0);
297 tristrips[8].y = make_fixed(250, 0);
299 /* Create the trifan dimensions */
300 trifans[0].x = make_fixed(424, 0);
301 trifans[0].y = make_fixed(415, 0);
302 trifans[1].x = make_fixed(375, 0);
303 trifans[1].y = make_fixed(355, 0);
304 trifans[2].x = make_fixed(403, 0);
305 trifans[2].y = make_fixed(350, 0);
306 trifans[3].x = make_fixed(430, 0);
307 trifans[3].y = make_fixed(380, 0);
308 trifans[4].x = make_fixed(481, 0);
309 trifans[4].y = make_fixed(400, 0);
310 trifans[5].x = make_fixed(475, 0);
311 trifans[5].y = make_fixed(437, 0);
312 trifans[6].x = make_fixed(430, 0);
313 trifans[6].y = make_fixed(444, 0);
314 trifans[7].x = make_fixed(400, 0);
315 trifans[7].y = make_fixed(430, 0);
320 xcb_map_window(conn, window);
323 * Play around with Render
326 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, alpha_pict, alpha_color, 1, pict_rect);
327 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, pict_surfaces[0], pict_color[0], 1, pict_rect);
328 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, pict_surfaces[1], pict_color[1], 1, pict_rect);
329 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, pict_surfaces[2], pict_color[2], 1, pict_rect);
330 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_SRC, pict_surfaces[3], pict_color[3], 1, pict_rect);
335 xcb_render_fill_rectangles(conn, XCB_RENDER_PICT_OP_OVER, window_pict, back_color, 1, &window_rect);
341 /* Composite the first pict_surface onto the window picture */
342 xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[0], no_picture /* alpha_pict */, window_pict,
343 0, 0, 0, 0, 200, 200,
348 xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[0], alpha_pict, window_pict,
354 xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[1], no_picture /* alpha_pict */, window_pict,
360 xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[2], no_picture /* alpha_pict */, window_pict,
366 xcb_render_composite(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[3], no_picture /* alpha_pict */, window_pict,
372 xcb_render_trapezoids(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[0], window_pict, alpha_mask_format, 0, 0, 1, &traps[0]);
376 xcb_render_triangles(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[1], window_pict, no_format, 0, 0, 1, &triangles[0]);
380 xcb_render_tri_strip(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[2], window_pict, no_format, 0, 0, 9, &tristrips[0]);
384 xcb_render_tri_fan(conn, XCB_RENDER_PICT_OP_OVER, pict_surfaces[3], window_pict, no_format, 0, 0, 8, &trifans[0]);
389 /* Free up all of the resources we used */
390 for(index = 0; index < 4; index++)
392 xcb_free_pixmap(conn, surfaces[index]);
393 xcb_render_free_picture(conn, pict_surfaces[index]);
395 xcb_free_pixmap(conn, alpha_surface);
396 xcb_render_free_picture(conn, alpha_pict);
397 xcb_render_free_picture(conn, window_pict);
398 xcb_render_free_picture(conn, root_picture);
400 /* sync up and leave the function */
406 /**********************************************************
407 * This function searches through the reply for a
408 * PictVisual who's xcb_visualid_t is the same as the one
409 * specified in query. The function will then return the
410 * xcb_render_pictformat_t from that PictVIsual structure.
411 * This is useful for getting the xcb_render_pictformat_t that is
412 * the same visual type as the root window.
413 **********************************************************/
414 xcb_render_pictformat_t get_pictformat_from_visual(xcb_render_query_pict_formats_reply_t *reply, xcb_visualid_t query)
416 xcb_render_pictscreen_iterator_t screen_iter;
417 xcb_render_pictscreen_t *cscreen;
418 xcb_render_pictdepth_iterator_t depth_iter;
419 xcb_render_pictdepth_t *cdepth;
420 xcb_render_pictvisual_iterator_t visual_iter;
421 xcb_render_pictvisual_t *cvisual;
422 xcb_render_pictformat_t return_value;
424 screen_iter = xcb_render_query_pict_formats_screens_iterator(reply);
426 while(screen_iter.rem)
428 cscreen = screen_iter.data;
430 depth_iter = xcb_render_pictscreen_depths_iterator(cscreen);
431 while(depth_iter.rem)
433 cdepth = depth_iter.data;
435 visual_iter = xcb_render_pictdepth_visuals_iterator(cdepth);
436 while(visual_iter.rem)
438 cvisual = visual_iter.data;
440 if(cvisual->visual == query)
442 return cvisual->format;
444 xcb_render_pictvisual_next(&visual_iter);
446 xcb_render_pictdepth_next(&depth_iter);
448 xcb_render_pictscreen_next(&screen_iter);
454 xcb_render_pictforminfo_t *get_pictforminfo(xcb_render_query_pict_formats_reply_t *reply, xcb_render_pictforminfo_t *query)
456 xcb_render_pictforminfo_iterator_t forminfo_iter;
458 forminfo_iter = xcb_render_query_pict_formats_formats_iterator(reply);
460 while(forminfo_iter.rem)
462 xcb_render_pictforminfo_t *cformat;
463 cformat = forminfo_iter.data;
464 xcb_render_pictforminfo_next(&forminfo_iter);
466 if( (query->id != 0) && (query->id != cformat->id) )
471 if(query->type != cformat->type)
476 if( (query->depth != 0) && (query->depth != cformat->depth) )
481 if( (query->direct.red_mask != 0)&& (query->direct.red_mask != cformat->direct.red_mask))
486 if( (query->direct.green_mask != 0) && (query->direct.green_mask != cformat->direct.green_mask))
491 if( (query->direct.blue_mask != 0) && (query->direct.blue_mask != cformat->direct.blue_mask))
496 if( (query->direct.alpha_mask != 0) && (query->direct.alpha_mask != cformat->direct.alpha_mask))
501 /* This point will only be reached if the pict format *
502 * matches what the user specified */
509 int main(int argc, char *argv[])
511 xcb_render_query_version_cookie_t version_cookie;
512 xcb_render_query_version_reply_t *version_reply;
513 xcb_render_query_pict_formats_cookie_t formats_cookie;
514 xcb_render_query_pict_formats_reply_t *formats_reply;
515 xcb_render_pictformat_t rootformat;
519 xcb_render_pictforminfo_t forminfo_query, *forminfo_result;
521 c = xcb_connect(0, &screen_num);
522 root = xcb_aux_get_screen(c, screen_num);
524 version_cookie = xcb_render_query_version(c, (uint32_t)0, (uint32_t)3);
525 version_reply = xcb_render_query_version_reply(c, version_cookie, 0);
527 print_version_info(version_reply);
529 formats_cookie = xcb_render_query_pict_formats(c);
530 formats_reply = xcb_render_query_pict_formats_reply(c, formats_cookie, 0);
532 draw_window(c, formats_reply);
534 print_formats_info(formats_reply);
536 forminfo_query.id = 0;
537 forminfo_query.type = XCB_RENDER_PICT_TYPE_DIRECT;
538 forminfo_query.depth = 8;
539 forminfo_query.direct.red_mask = 0;
540 forminfo_query.direct.green_mask = 0;
541 forminfo_query.direct.blue_mask = 0;
542 forminfo_query.direct.alpha_mask = 255;
544 forminfo_result = get_pictforminfo(formats_reply, &forminfo_query);
545 fprintf(stdout, "\n***** found PICTFORMAT: %d *****\n",
546 forminfo_result->id);
547 rootformat = get_pictformat_from_visual(formats_reply, root->root_visual);
548 fprintf(stdout, "\n***** found root PICTFORMAT: %d *****\n", rootformat);
551 draw_window(c, formats_reply);
554 /* It's very important to free the replys. We don't want memory leaks. */