Remove Xlib.h and X.h dependencies from julia and lissajoux demos.
[free-sw/xcb/demo] / tests / lissajoux.c
1 #include <assert.h>
2
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <math.h>
6 #include <sys/time.h>
7
8 #include <sys/ipc.h>
9 #include <sys/shm.h>
10
11 #include <X11/XCB/xcb.h>
12 #include <X11/XCB/shm.h>
13 #include <X11/XCB/xcb_aux.h>
14 #include <X11/XCB/xcb_image.h>
15
16 #include "lissajoux.h"
17
18 #define W_W 100
19 #define W_H 100
20
21 double time_start;
22 int    loop_count;
23 double t_previous;
24 double t;
25 int    do_shm = 0;
26
27 double tab_cos[3600];
28 double tab_sin[3600];
29
30 XCBShmSegmentInfo shminfo;
31
32 double
33 get_time(void)
34 {
35   struct timeval timev;
36   
37   gettimeofday(&timev, NULL);
38
39   return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
40 }
41
42 void
43 draw_lissajoux (Data *datap)
44 {
45   int       i, nbr;
46   double    a1, a2, p1, p2;
47   double    pi, period;
48   double    x, y;
49   
50   if (do_shm)
51     { 
52       i = XCBImageSHMGet (datap->conn, datap->draw,
53                           datap->image, shminfo,
54                           0, 0,
55                           XCBAllPlanes);
56       assert(i);
57     }
58   else
59     {
60       datap->image = XCBImageGet (datap->conn, datap->draw,
61                                   0, 0, W_W, W_H,
62                                   XCBAllPlanes, datap->format);
63       assert(datap->image);
64     }
65   
66   pi = 3.1415926535897;
67   period = 2.0 * pi;
68   a1 = 2.0;
69   a2 = 3.0;
70   p1 = 4.0*t_previous*pi*0.05;
71   p2 = 0.0;
72
73   nbr = 10000;
74   for (i = 0 ; i < nbr ; i++)
75       {
76         x = tab_cos[(int)(a1*i + p1*nbr) % 3600];
77         y = tab_sin[(int)(a2*i + p2*nbr) % 3600];
78         XCBImagePutPixel (datap->image,
79                           (int)((double)(W_W-5)*(x+1)/2.0),
80                           (int)((double)(W_H-5)*(y+1)/2.0), 65535);
81       }
82
83   p1 = 4.0*t*pi*0.05;
84   p2 = 0.0;
85
86   for (i = 0 ; i < nbr ; i++)
87       {
88         x = tab_cos[(int)(a1*i + p1*nbr) % 3600];
89         y = tab_sin[(int)(a2*i + p2*nbr) % 3600];
90         XCBImagePutPixel (datap->image,
91                           (int)((double)(W_W-5)*(x+1)/2.0),
92                           (int)((double)(W_H-5)*(y+1)/2.0), 0);
93       }
94
95   if (do_shm)
96     XCBImageSHMPut (datap->conn, datap->draw, datap->gc,
97                     datap->image, shminfo,
98                     0, 0, 0, 0, W_W, W_H, 0);
99   else
100     {
101       XCBImagePut (datap->conn, datap->draw, datap->gc, datap->image,
102                    0, 0, 0, 0, W_W, W_H);
103       XCBImageDestroy (datap->image);
104     }
105 }
106
107 void
108 step (Data *datap)
109 {
110   loop_count++;
111   t = get_time () - time_start;
112
113   if (t <= 20.0)
114     {
115       draw_lissajoux (datap);
116     }
117   else
118     {
119       printf("FRAME COUNT..: %i frames\n", loop_count);
120       printf("TIME.........: %3.3f seconds\n", t);
121       printf("AVERAGE FPS..: %3.3f fps\n", (double)loop_count / t);
122       /* if datap->image is not NULL, this means that */
123       /* we are using the SHM mode */
124       if (datap->image)
125         XCBImageSHMDestroy (datap->image);
126       XCBDisconnect (datap->conn);
127       exit(0);
128     }
129 }
130
131 /* Return 0 if shm is not available, 1 otherwise */
132 void
133 shm_test (Data *datap)
134 {
135   XCBShmQueryVersionRep *rep;
136
137   rep = XCBShmQueryVersionReply (datap->conn,
138                                  XCBShmQueryVersion (datap->conn),
139                                  NULL);
140   if (rep)
141     {
142       CARD8 format;
143       int shmctl_status;
144       
145       if (rep->shared_pixmaps && 
146           (rep->major_version > 1 || rep->minor_version > 0))
147         format = rep->pixmap_format;
148       else
149         format = 0;
150       datap->image = XCBImageSHMCreate (datap->conn, datap->depth,
151                                         format, NULL, W_W, W_H);
152       assert(datap->image);
153
154       shminfo.shmid = shmget (IPC_PRIVATE,
155                               datap->image->bytes_per_line*datap->image->height,
156                               IPC_CREAT | 0777);
157       assert(shminfo.shmid != -1);
158       shminfo.shmaddr = shmat (shminfo.shmid, 0, 0);
159       assert(shminfo.shmaddr);
160       datap->image->data = shminfo.shmaddr;
161
162       shminfo.shmseg = XCBShmSEGNew (datap->conn);
163       XCBShmAttach (datap->conn, shminfo.shmseg,
164                     shminfo.shmid, 0);
165       shmctl_status = shmctl(shminfo.shmid, IPC_RMID, 0);
166       assert(shmctl_status != -1);
167       free (rep);
168     }
169
170   if (datap->image)
171     {
172       printf ("Use of shm.\n");
173       do_shm = 1;
174     }
175   else
176     {
177       printf ("Can't use shm. Use standard functions.\n");
178       shmdt (shminfo.shmaddr);                 
179       shmctl (shminfo.shmid, IPC_RMID, 0);
180       datap->image = NULL;
181     }
182 }
183
184 int
185 main (int argc, char *argv[])
186 {
187   Data             data;
188   XCBSCREEN       *screen;
189   XCBDRAWABLE      win;
190   XCBDRAWABLE      rect;
191   XCBGCONTEXT      bgcolor;
192   CARD32           mask;
193   CARD32           valgc[2];
194   CARD32           valwin[3];
195   XCBRECTANGLE     rect_coord = { 0, 0, W_W, W_H};
196   XCBGenericEvent *e;
197   int              try_shm;
198   int              screen_num;
199   int              i;
200   
201   try_shm = 0;
202
203   /* Arguments test */
204   if (argc < 2)
205     {
206       printf ("Usage: lissajoux try_shm\n");
207       printf ("         try_shm == 0: shm not used\n");
208       printf ("         try_shm != 0: shm is used (if available)\n");
209       exit (0);
210     }
211   if (argc >= 2)
212     try_shm = atoi (argv[1]);
213   if (try_shm != 0)
214     try_shm = 1;
215
216   data.conn = XCBConnect (0, &screen_num);
217   screen = XCBAuxGetScreen(data.conn, screen_num);
218   data.depth = XCBAuxGetDepth (data.conn, screen);
219
220   win.window = screen->root;
221
222   data.gc = XCBGCONTEXTNew (data.conn);
223   mask = XCBGCForeground | XCBGCGraphicsExposures;
224   valgc[0] = screen->black_pixel;
225   valgc[1] = 0; /* no graphics exposures */
226   XCBCreateGC (data.conn, data.gc, win, mask, valgc);
227
228   bgcolor = XCBGCONTEXTNew (data.conn);
229   mask = XCBGCForeground | XCBGCGraphicsExposures;
230   valgc[0] = screen->white_pixel;
231   valgc[1] = 0; /* no graphics exposures */
232   XCBCreateGC (data.conn, bgcolor, win, mask, valgc);
233
234   data.draw.window = XCBWINDOWNew (data.conn);
235   mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
236   valwin[0] = screen->white_pixel;
237   valwin[1] = XCBEventMaskKeyPress | XCBEventMaskButtonRelease | XCBEventMaskExposure;
238   valwin[2] = XCBEventMaskButtonPress;
239   XCBCreateWindow (data.conn, 0,
240                    data.draw.window,
241                    screen->root,
242                    0, 0, W_W, W_H,
243                    10,
244                    XCBWindowClassInputOutput,
245                    screen->root_visual,
246                    mask, valwin);
247   XCBMapWindow (data.conn, data.draw.window);
248
249   rect.pixmap = XCBPIXMAPNew (data.conn);
250   XCBCreatePixmap (data.conn, data.depth,
251                    rect.pixmap, data.draw,
252                    W_W, W_H);
253   XCBPolyFillRectangle(data.conn, rect, bgcolor, 1, &rect_coord);
254
255   data.format = XCBImageFormatZPixmap;
256   XCBSync (data.conn, 0); 
257
258   if (try_shm)
259     shm_test (&data);
260
261   for (i = 0; i < 3600; i++) {
262     tab_cos[i] = cos (2.0 * 3.1415926535897 * (double)i / 3600.0);
263     tab_sin[i] = sin (2.0 * 3.1415926535897 * (double)i / 3600.0);
264   }
265
266   time_start = get_time ();
267   t_previous = 0.0;
268   while (1)
269     {
270       e = XCBPollForEvent(data.conn, NULL);
271       if (e)
272         {
273           switch (e->response_type)
274             {
275             case XCBExpose:
276               XCBCopyArea(data.conn, rect, data.draw, bgcolor,
277                           0, 0, 0, 0, W_W, W_H);
278               XCBSync (data.conn, 0);
279               break;
280             }
281           free (e);
282         }
283       step (&data);
284       XCBFlush (data.conn);
285       t_previous = t;
286     }
287   /*NOTREACHED*/
288 }