2 #include <X11/XCB/xcb.h>
3 #include <X11/XCB/xcb_aux.h>
4 #include <X11/XCB/render.h>
12 void print_version_info(XCBRenderQueryVersionRep *reply);
13 int print_formats_info(XCBRenderQueryPictFormatsRep *reply);
14 int draw_window(XCBConnection *conn, XCBRenderQueryPictFormatsRep *reply);
15 XCBRenderPICTFORMAT get_pictformat_from_visual(XCBRenderQueryPictFormatsRep *reply, XCBVISUALID visual);
16 XCBRenderPICTFORMINFO *get_pictforminfo(XCBRenderQueryPictFormatsRep *reply, XCBRenderPICTFORMINFO *query);
19 XCBRenderPICTFORMAT pf;
21 XCBRenderFIXED make_fixed(INT16 i, INT16 f)
23 return (i << 16) | (f & 0xffff);
26 void print_version_info(XCBRenderQueryVersionRep *reply)
29 fprintf(stdout, "Render Version: %ld.%ld\n", reply->major_version,
30 reply->minor_version);
33 int print_formats_info(XCBRenderQueryPictFormatsRep *reply)
35 XCBRenderPICTFORMINFO *first_forminfo;
40 XCBRenderPICTFORMINFOIter forminfo_iter;
41 XCBRenderPICTSCREENIter screen_iter;
43 forminfo_iter = XCBRenderQueryPictFormatsFormatsIter(reply);
44 screen_iter = XCBRenderQueryPictFormatsScreensIter(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 XCBRenderPICTFORMINFO *forminfo = (XCBRenderPICTFORMINFO *)forminfo_iter.data;
55 fprintf(stdout, "PICTFORMINFO #%d\n", 1 + num_formats - forminfo_iter.rem);
56 fprintf(stdout, " PICTFORMAT ID: %ld\n", forminfo->id.xid);
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 XCBRenderPICTFORMINFONext(&forminfo_iter);
71 num_screens = reply->num_screens;
72 while(screen_iter.rem)
74 XCBRenderPICTDEPTHIter depth_iter;
75 XCBRenderPICTSCREEN *cscreen = screen_iter.data;
77 fprintf(stdout, "Screen #%d\n", 1 + num_screens - screen_iter.rem);
78 fprintf(stdout, " Depths for this screen: %ld\n", cscreen->num_depths);
79 fprintf(stdout, " Fallback PICTFORMAT: %ld\n", cscreen->fallback.xid);
80 depth_iter = XCBRenderPICTSCREENDepthsIter(cscreen);
82 num_depths = cscreen->num_depths;
85 XCBRenderPICTVISUALIter visual_iter;
86 XCBRenderPICTDEPTH *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 = XCBRenderPICTDEPTHVisualsIter(cdepth);
93 num_visuals = cdepth->num_visuals;
94 while(visual_iter.rem)
96 XCBRenderPICTVISUAL *cvisual = visual_iter.data;
98 fprintf(stdout, " Visual #%d\n", 1 + num_visuals - visual_iter.rem);
99 fprintf(stdout, " VISUALID: %ld\n", cvisual->visual.id);
100 fprintf(stdout, " PICTFORMAT: %ld\n", cvisual->format.xid);
101 XCBRenderPICTVISUALNext(&visual_iter);
103 XCBRenderPICTDEPTHNext(&depth_iter);
105 XCBRenderPICTSCREENNext(&screen_iter);
110 int draw_window(XCBConnection *conn, XCBRenderQueryPictFormatsRep *reply)
113 XCBDRAWABLE window_drawable, tmp, root_drawable;
114 XCBPIXMAP surfaces[4], alpha_surface;
115 XCBRenderPICTFORMAT alpha_mask_format, window_format, surface_format, no_format = {0};
116 XCBRenderPICTURE window_pict, pict_surfaces[4], alpha_pict,
117 no_picture = {0}, root_picture;
118 XCBRenderPICTFORMINFO *forminfo_ptr, *alpha_forminfo_ptr, query;
119 CARD32 value_mask, value_list[4];
120 XCBRECTANGLE pict_rect[1], window_rect;
121 XCBRenderCOLOR pict_color[4], back_color, alpha_color;
123 XCBRenderTRAP traps[4];
124 XCBRenderTRIANGLE triangles[4];
125 XCBRenderPOINTFIX tristrips[9];
126 XCBRenderPOINTFIX trifans[9];
129 root = XCBSetupRootsIter(XCBGetSetup(c)).data;
130 root_drawable.window = root->root;
132 /* Setting query so that it will search for an 8 bit alpha surface. */
134 query.type = XCBRenderPictTypeDirect;
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 XCBRenderPICTFORMAT associated with the window. */
142 window_format = get_pictformat_from_visual(reply, root->root_visual);
144 /* Get the XCBRenderPICTFORMAT we will use for the alpha mask */
145 alpha_forminfo_ptr = get_pictforminfo(reply, &query);
146 alpha_mask_format.xid = alpha_forminfo_ptr->id.xid;
148 /* resetting certain parts of query to search for the surface format */
150 query.direct.alpha_mask = 0;
152 /* Get the surface forminfo and XCBRenderPICTFORMAT */
153 forminfo_ptr = get_pictforminfo(reply, &query);
154 surface_format.xid = forminfo_ptr->id.xid;
156 /* assign XIDs to all of the drawables and pictures */
157 for(index = 0; index < 4; index++)
159 surfaces[index] = XCBPIXMAPNew(conn);
160 pict_surfaces[index] = XCBRenderPICTURENew(conn);
162 alpha_surface = XCBPIXMAPNew(conn);
163 alpha_pict = XCBRenderPICTURENew(conn);
164 window = XCBWINDOWNew(conn);
165 window_pict = XCBRenderPICTURENew(conn);
166 window_drawable.window = window;
167 root_picture = XCBRenderPICTURENew(conn);
169 /* Here we will create the pixmaps that we will use */
170 for(index = 0; index < 4; index++)
172 surfaces[index] = XCBPIXMAPNew(conn);
173 XCBCreatePixmap(conn, 32, surfaces[index], root_drawable, 600, 600);
175 alpha_surface = XCBPIXMAPNew(conn);
176 XCBCreatePixmap(conn, 8, alpha_surface, root_drawable, 600, 600);
178 /* initialize the value list */
179 value_mask = XCBCWEventMask;
180 value_list[0] = XCBExpose;
182 /* Create the window */
183 XCBCreateWindow(conn, /* XCBConnection */
184 0, /* depth, 0 means it will copy it from the parent */
185 window, root_drawable.window, /* window and parent */
187 600, 600, /* width and height */
188 0, /* border width */
189 XCBWindowClassInputOutput, /* class */
190 root->root_visual, /* XCBVISUALID */
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 XCBRenderCreatePicture(conn, root_picture, root_drawable, window_format,
200 value_mask, value_list);
201 XCBRenderCreatePicture(conn, window_pict, window_drawable, window_format,
202 value_mask, value_list);
203 tmp.pixmap = alpha_surface;
204 XCBRenderCreatePicture(conn, alpha_pict, tmp, alpha_mask_format,
205 value_mask, value_list);
206 for(index = 0; index < 4; index++)
208 tmp.pixmap = surfaces[index];
209 XCBRenderCreatePicture(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 XCBMapWindow(conn, window);
323 * Play around with Render
326 XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, alpha_pict, alpha_color, 1, pict_rect);
327 XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, pict_surfaces[0], pict_color[0], 1, pict_rect);
328 XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, pict_surfaces[1], pict_color[1], 1, pict_rect);
329 XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, pict_surfaces[2], pict_color[2], 1, pict_rect);
330 XCBRenderFillRectangles(conn, XCBRenderPictOpSrc, pict_surfaces[3], pict_color[3], 1, pict_rect);
335 XCBRenderFillRectangles(conn, XCBRenderPictOpOver, window_pict, back_color, 1, &window_rect);
341 /* Composite the first pict_surface onto the window picture */
342 XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[0], no_picture /* alpha_pict */, window_pict,
343 0, 0, 0, 0, 200, 200,
348 XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[0], alpha_pict, window_pict,
354 XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[1], no_picture /* alpha_pict */, window_pict,
360 XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[2], no_picture /* alpha_pict */, window_pict,
366 XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[3], no_picture /* alpha_pict */, window_pict,
372 XCBRenderTrapezoids(conn, XCBRenderPictOpOver, pict_surfaces[0], window_pict, alpha_mask_format, 0, 0, 1, &traps[0]);
376 XCBRenderTriangles(conn, XCBRenderPictOpOver, pict_surfaces[1], window_pict, no_format, 0, 0, 1, &triangles[0]);
380 XCBRenderTriStrip(conn, XCBRenderPictOpOver, pict_surfaces[2], window_pict, no_format, 0, 0, 9, &tristrips[0]);
384 XCBRenderTriFan(conn, XCBRenderPictOpOver, 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 XCBFreePixmap(conn, surfaces[index]);
393 XCBRenderFreePicture(conn, pict_surfaces[index]);
395 XCBFreePixmap(conn, alpha_surface);
396 XCBRenderFreePicture(conn, alpha_pict);
397 XCBRenderFreePicture(conn, window_pict);
398 XCBRenderFreePicture(conn, root_picture);
400 /* sync up and leave the function */
406 /**********************************************************
407 * This function searches through the reply for a
408 * PictVisual who's XCBVISUALID is the same as the one
409 * specified in query. The function will then return the
410 * XCBRenderPICTFORMAT from that PictVIsual structure.
411 * This is useful for getting the XCBRenderPICTFORMAT that is
412 * the same visual type as the root window.
413 **********************************************************/
414 XCBRenderPICTFORMAT get_pictformat_from_visual(XCBRenderQueryPictFormatsRep *reply, XCBVISUALID query)
416 XCBRenderPICTSCREENIter screen_iter;
417 XCBRenderPICTSCREEN *cscreen;
418 XCBRenderPICTDEPTHIter depth_iter;
419 XCBRenderPICTDEPTH *cdepth;
420 XCBRenderPICTVISUALIter visual_iter;
421 XCBRenderPICTVISUAL *cvisual;
422 XCBRenderPICTFORMAT return_value;
424 screen_iter = XCBRenderQueryPictFormatsScreensIter(reply);
426 while(screen_iter.rem)
428 cscreen = screen_iter.data;
430 depth_iter = XCBRenderPICTSCREENDepthsIter(cscreen);
431 while(depth_iter.rem)
433 cdepth = depth_iter.data;
435 visual_iter = XCBRenderPICTDEPTHVisualsIter(cdepth);
436 while(visual_iter.rem)
438 cvisual = visual_iter.data;
440 if(cvisual->visual.id == query.id)
442 return cvisual->format;
444 XCBRenderPICTVISUALNext(&visual_iter);
446 XCBRenderPICTDEPTHNext(&depth_iter);
448 XCBRenderPICTSCREENNext(&screen_iter);
450 return_value.xid = 0;
454 XCBRenderPICTFORMINFO *get_pictforminfo(XCBRenderQueryPictFormatsRep *reply, XCBRenderPICTFORMINFO *query)
456 XCBRenderPICTFORMINFOIter forminfo_iter;
458 forminfo_iter = XCBRenderQueryPictFormatsFormatsIter(reply);
460 while(forminfo_iter.rem)
462 XCBRenderPICTFORMINFO *cformat;
463 cformat = forminfo_iter.data;
464 XCBRenderPICTFORMINFONext(&forminfo_iter);
466 if( (query->id.xid != 0) && (query->id.xid != cformat->id.xid) )
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 XCBRenderQueryVersionCookie version_cookie;
512 XCBRenderQueryVersionRep *version_reply;
513 XCBRenderQueryPictFormatsCookie formats_cookie;
514 XCBRenderQueryPictFormatsRep *formats_reply;
515 XCBRenderPICTFORMAT rootformat;
519 XCBRenderPICTFORMINFO forminfo_query, *forminfo_result;
521 c = XCBConnect(0, &screen_num);
522 root = XCBAuxGetScreen(c, screen_num);
524 version_cookie = XCBRenderQueryVersion(c, (CARD32)0, (CARD32)3);
525 version_reply = XCBRenderQueryVersionReply(c, version_cookie, 0);
527 print_version_info(version_reply);
529 formats_cookie = XCBRenderQueryPictFormats(c);
530 formats_reply = XCBRenderQueryPictFormatsReply(c, formats_cookie, 0);
532 draw_window(c, formats_reply);
534 print_formats_info(formats_reply);
536 forminfo_query.id.xid = 0;
537 forminfo_query.type = XCBRenderPictTypeDirect;
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: %ld *****\n",
546 forminfo_result->id.xid);
547 rootformat = get_pictformat_from_visual(formats_reply, root->root_visual);
548 fprintf(stdout, "\n***** found root PICTFORMAT: %ld *****\n", rootformat.xid);
551 draw_window(c, formats_reply);
554 /* It's very important to free the replys. We don't want memory leaks. */