Update .gitignores for .o files and autofoo stuff.
[free-sw/xcb/demo] / rendertest.c
1
2 #include <X11/XCB/xcb.h>
3 #include <X11/XCB/xcb_aux.h>
4 #include <X11/XCB/render.h>
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
8
9 /*
10  * FUNCTION PROTOTYPES
11  */
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);
17
18 XCBConnection   *c;
19 XCBRenderPICTFORMAT pf;
20
21 XCBRenderFIXED make_fixed(INT16 i, INT16 f)
22 {
23     return (i << 16) | (f & 0xffff);
24 }
25
26 void print_version_info(XCBRenderQueryVersionRep *reply)
27 {
28     
29     fprintf(stdout, "Render Version: %ld.%ld\n", reply->major_version, 
30             reply->minor_version);
31 }
32
33 int print_formats_info(XCBRenderQueryPictFormatsRep *reply)
34 {
35     XCBRenderPICTFORMINFO *first_forminfo;
36     int num_formats;
37     int num_screens;
38     int num_depths;
39     int num_visuals;
40     XCBRenderPICTFORMINFOIter forminfo_iter;
41     XCBRenderPICTSCREENIter     screen_iter;
42     
43     forminfo_iter = XCBRenderQueryPictFormatsFormatsIter(reply);
44     screen_iter =  XCBRenderQueryPictFormatsScreensIter(reply);
45
46     fprintf(stdout, "Number of PictFormInfo iterations: %d\n", forminfo_iter.rem);
47
48     num_formats = reply->num_formats;
49     first_forminfo = forminfo_iter.data;
50     pf = first_forminfo->id;
51     while(forminfo_iter.rem)
52     {
53         XCBRenderPICTFORMINFO *forminfo = (XCBRenderPICTFORMINFO *)forminfo_iter.data;
54
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);
69     }
70
71     num_screens = reply->num_screens;
72     while(screen_iter.rem)
73     {
74         XCBRenderPICTDEPTHIter depth_iter;
75         XCBRenderPICTSCREEN *cscreen = screen_iter.data;
76         
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);
81
82         num_depths = cscreen->num_depths;
83         while(depth_iter.rem)
84         {
85             XCBRenderPICTVISUALIter    visual_iter;
86             XCBRenderPICTDEPTH *cdepth = depth_iter.data;
87
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);
92
93             num_visuals = cdepth->num_visuals;
94             while(visual_iter.rem)
95             {
96                 XCBRenderPICTVISUAL *cvisual = visual_iter.data;
97                 
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);
102             }
103             XCBRenderPICTDEPTHNext(&depth_iter);
104         }
105         XCBRenderPICTSCREENNext(&screen_iter);
106     }
107     return 0;
108 }
109
110 int draw_window(XCBConnection *conn, XCBRenderQueryPictFormatsRep *reply)
111 {
112     XCBWINDOW          window;
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;
122     XCBSCREEN          *root;
123     XCBRenderTRAP            traps[4];
124     XCBRenderTRIANGLE        triangles[4];
125     XCBRenderPOINTFIX        tristrips[9];
126     XCBRenderPOINTFIX        trifans[9];
127     int index;
128
129     root = XCBConnSetupSuccessRepRootsIter(XCBGetSetup(c)).data;
130     root_drawable.window = root->root;
131    
132     /* Setting query so that it will search for an 8 bit alpha surface. */
133     query.id.xid = 0;
134     query.type = XCBRenderPictTypeDirect;
135     query.depth = 8;
136     query.direct.red_mask = 0;
137     query.direct.green_mask = 0;
138     query.direct.blue_mask = 0;
139     query.direct.alpha_mask = 255;
140
141     /* Get the XCBRenderPICTFORMAT associated with the window. */
142     window_format = get_pictformat_from_visual(reply, root->root_visual);
143
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;
147     
148     /* resetting certain parts of query to search for the surface format */
149     query.depth = 32;
150     query.direct.alpha_mask = 0;
151   
152     /* Get the surface forminfo and XCBRenderPICTFORMAT */
153     forminfo_ptr = get_pictforminfo(reply, &query);
154     surface_format.xid = forminfo_ptr->id.xid;
155     
156     /* assign XIDs to all of the drawables and pictures */
157     for(index = 0; index < 4; index++)
158     {
159         surfaces[index] = XCBPIXMAPNew(conn);
160         pict_surfaces[index] = XCBRenderPICTURENew(conn);
161     }
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);
168     
169     /* Here we will create the pixmaps that we will use */
170     for(index = 0; index < 4; index++)
171     {
172         surfaces[index] = XCBPIXMAPNew(conn);
173         XCBCreatePixmap(conn, 32, surfaces[index], root_drawable, 600, 600);
174     }
175     alpha_surface = XCBPIXMAPNew(conn);
176     XCBCreatePixmap(conn, 8, alpha_surface, root_drawable, 600, 600);
177     
178     /* initialize the value list */
179     value_mask = XCBCWEventMask;
180     value_list[0] = XCBExpose;
181     
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 */
186             0, 0,   /* x and y */
187             600, 600,   /* width and height */
188             0,  /* border width */
189             InputOutput,    /* class */
190             root->root_visual,   /* XCBVISUALID */
191             value_mask, value_list); /* LISTofVALUES */
192     
193     /* 
194      * Create the pictures 
195      */
196     value_mask = 1<<0; /* repeat (still needs to be added to xcb_render.m4) */
197     value_list[0] = 1;
198
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++)
207     {
208         tmp.pixmap = surfaces[index];
209         XCBRenderCreatePicture(conn, pict_surfaces[index], tmp, surface_format,
210                 value_mask, value_list);
211     }
212
213     /* 
214      * initialize the rectangles
215      */
216     window_rect.x = 0;
217     window_rect.y = 0;
218     window_rect.width = 600;
219     window_rect.height = 600;
220
221     pict_rect[0].x = 0;
222     pict_rect[0].y = 0;
223     pict_rect[0].width = 600;
224     pict_rect[0].height = 600;
225    
226     /* 
227      * initialize the colors
228      */
229     back_color.red = 0xffff;
230     back_color.green = 0xffff;
231     back_color.blue = 0xffff;
232     back_color.alpha = 0xffff;
233    
234     pict_color[0].red = 0x5fff;
235     pict_color[0].green = 0x0000;
236     pict_color[0].blue = 0x0000;
237     pict_color[0].alpha = 0x5fff;
238     
239     pict_color[1].red = 0x0000;
240     pict_color[1].green = 0x5fff;
241     pict_color[1].blue = 0x0000;
242     pict_color[1].alpha = 0x5fff;
243
244     pict_color[2].red = 0x0000;
245     pict_color[2].green = 0x0000;
246     pict_color[2].blue = 0x5fff;
247     pict_color[2].alpha = 0x5fff;
248
249     pict_color[3].red = 0x0000;
250     pict_color[3].green = 0x0000;
251     pict_color[3].blue = 0x5fff;
252     pict_color[3].alpha = 0x5fff;
253
254     alpha_color.red = 0x0000;
255     alpha_color.green = 0x0000;
256     alpha_color.blue = 0x0000;
257     alpha_color.alpha = 0xffff;
258
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);
270
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);
278
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);
298
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);
316
317     /* 
318      * Map the window
319      */
320     XCBMapWindow(conn, window);
321     
322     /*
323      * Play around with Render
324      */
325
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);
331
332     XCBFlush(conn);
333     sleep(1);
334
335     XCBRenderFillRectangles(conn, XCBRenderPictOpOver, window_pict, back_color, 1, &window_rect);
336
337     XCBFlush(conn);
338     sleep(1);
339
340
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,
344             400, 400);
345     XCBFlush(conn);
346     sleep(1);
347 /*
348     XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[0], alpha_pict, window_pict,
349             0, 0, 0, 0, 0, 0,
350             200, 200);
351     XCBFlush(conn);
352     sleep(1);
353 */
354     XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[1], no_picture /* alpha_pict */, window_pict,
355             0, 0, 0, 0, 0, 0,
356             400, 400);
357     XCBFlush(conn);
358     sleep(1);
359     
360     XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[2], no_picture /* alpha_pict */, window_pict,
361             0, 0, 0, 0, 200, 0,
362             400, 400);
363     XCBFlush(conn);
364     sleep(1);
365     
366     XCBRenderComposite(conn, XCBRenderPictOpOver, pict_surfaces[3],  no_picture /* alpha_pict */, window_pict,
367             0, 0, 0, 0, 0, 200,
368             400, 400);
369     XCBFlush(conn);
370     sleep(1);
371
372     XCBRenderTrapezoids(conn, XCBRenderPictOpOver, pict_surfaces[0], window_pict, alpha_mask_format, 0, 0, 1, &traps[0]);
373     XCBFlush(conn);
374     sleep(1);
375
376     XCBRenderTriangles(conn, XCBRenderPictOpOver, pict_surfaces[1], window_pict, no_format, 0, 0, 1, &triangles[0]);
377     XCBFlush(conn);
378     sleep(1);
379     
380     XCBRenderTriStrip(conn, XCBRenderPictOpOver, pict_surfaces[2], window_pict, no_format, 0, 0, 9, &tristrips[0]);
381     XCBFlush(conn);
382     sleep(1);
383     
384     XCBRenderTriFan(conn, XCBRenderPictOpOver, pict_surfaces[3], window_pict, no_format, 0, 0, 8, &trifans[0]);
385     XCBFlush(conn);
386     sleep(2);
387     
388     
389     /* Free up all of the resources we used */
390     for(index = 0; index < 4; index++)
391     {
392         XCBFreePixmap(conn, surfaces[index]);
393         XCBRenderFreePicture(conn, pict_surfaces[index]);
394     }
395     XCBFreePixmap(conn, alpha_surface);
396     XCBRenderFreePicture(conn, alpha_pict);
397     XCBRenderFreePicture(conn, window_pict);
398     XCBRenderFreePicture(conn, root_picture);
399    
400     /* sync up and leave the function */
401     XCBSync(conn, 0);
402     return 0;
403 }
404
405
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)
415 {
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;
423     
424     screen_iter = XCBRenderQueryPictFormatsScreensIter(reply);
425
426     while(screen_iter.rem)
427     {
428         cscreen = screen_iter.data;
429         
430         depth_iter = XCBRenderPICTSCREENDepthsIter(cscreen);
431         while(depth_iter.rem)
432         {
433             cdepth = depth_iter.data;
434
435             visual_iter = XCBRenderPICTDEPTHVisualsIter(cdepth);
436             while(visual_iter.rem)
437             {
438                 cvisual = visual_iter.data;
439
440                 if(cvisual->visual.id == query.id)
441                 {
442                     return cvisual->format;
443                 }
444                 XCBRenderPICTVISUALNext(&visual_iter);
445             }
446             XCBRenderPICTDEPTHNext(&depth_iter);
447         }
448         XCBRenderPICTSCREENNext(&screen_iter);
449     }
450     return_value.xid = 0;
451     return return_value;
452 }
453
454 XCBRenderPICTFORMINFO *get_pictforminfo(XCBRenderQueryPictFormatsRep *reply, XCBRenderPICTFORMINFO *query)
455 {
456     XCBRenderPICTFORMINFOIter forminfo_iter;
457     
458     forminfo_iter = XCBRenderQueryPictFormatsFormatsIter(reply);
459
460     while(forminfo_iter.rem)
461     {
462         XCBRenderPICTFORMINFO *cformat;
463         cformat  = forminfo_iter.data;
464         XCBRenderPICTFORMINFONext(&forminfo_iter);
465
466         if( (query->id.xid != 0) && (query->id.xid != cformat->id.xid) )
467         {
468             continue;
469         }
470
471         if(query->type != cformat->type)
472         {
473             continue;
474         }
475         
476         if( (query->depth != 0) && (query->depth != cformat->depth) )
477         {
478             continue;
479         }
480         
481         if( (query->direct.red_mask  != 0)&& (query->direct.red_mask != cformat->direct.red_mask))
482         {
483             continue;
484         }
485         
486         if( (query->direct.green_mask != 0) && (query->direct.green_mask != cformat->direct.green_mask))
487         {
488             continue;
489         }
490         
491         if( (query->direct.blue_mask != 0) && (query->direct.blue_mask != cformat->direct.blue_mask))
492         {
493             continue;
494         }
495         
496         if( (query->direct.alpha_mask != 0) && (query->direct.alpha_mask != cformat->direct.alpha_mask))
497         {
498             continue;
499         }
500         
501         /* This point will only be reached if the pict format   *
502          * matches what the user specified                      */
503         return cformat; 
504     }
505     
506     return NULL;
507 }
508
509 int main(int argc, char *argv[])
510 {
511     XCBRenderQueryVersionCookie version_cookie;
512     XCBRenderQueryVersionRep    *version_reply;
513     XCBRenderQueryPictFormatsCookie formats_cookie;
514     XCBRenderQueryPictFormatsRep *formats_reply;
515     XCBRenderPICTFORMAT  rootformat;
516     XCBSCREEN *root;
517     int screen_num;
518     
519     XCBRenderPICTFORMINFO  forminfo_query, *forminfo_result;
520     
521     c = XCBConnect(0, &screen_num);
522     root = XCBAuxGetScreen(c, screen_num);
523     
524     version_cookie = XCBRenderQueryVersion(c, (CARD32)0, (CARD32)3);
525     version_reply = XCBRenderQueryVersionReply(c, version_cookie, 0);
526
527     print_version_info(version_reply);
528     
529     formats_cookie = XCBRenderQueryPictFormats(c);
530     formats_reply = XCBRenderQueryPictFormatsReply(c, formats_cookie, 0);
531
532     draw_window(c, formats_reply);
533     
534     print_formats_info(formats_reply);
535    
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;
543     
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);
549    
550 #if 0
551     draw_window(c, formats_reply);
552 #endif
553     
554     /* It's very important to free the replys. We don't want memory leaks. */
555     free(version_reply);
556     free(formats_reply);
557
558     XCBDisconnect(c);
559
560     exit(0);
561 }