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>
16 #include "lissajoux.h"
30 XCBShmSegmentInfo shminfo;
37 gettimeofday(&timev, NULL);
39 return (double)timev.tv_sec + (((double)timev.tv_usec) / 1000000);
43 draw_lissajoux (Data *datap)
46 double a1, a2, p1, p2;
52 i = XCBImageSHMGet (datap->conn, datap->draw,
53 datap->image, shminfo,
60 datap->image = XCBImageGet (datap->conn, datap->draw,
62 XCBAllPlanes, datap->format);
70 p1 = 4.0*t_previous*pi*0.05;
74 for (i = 0 ; i < nbr ; i++)
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);
86 for (i = 0 ; i < nbr ; i++)
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);
96 XCBImageSHMPut (datap->conn, datap->draw, datap->gc,
97 datap->image, shminfo,
98 0, 0, 0, 0, W_W, W_H, 0);
101 XCBImagePut (datap->conn, datap->draw, datap->gc, datap->image,
102 0, 0, 0, 0, W_W, W_H);
103 XCBImageDestroy (datap->image);
111 t = get_time () - time_start;
115 draw_lissajoux (datap);
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 */
125 XCBImageSHMDestroy (datap->image);
126 XCBDisconnect (datap->conn);
131 /* Return 0 if shm is not available, 1 otherwise */
133 shm_test (Data *datap)
135 XCBShmQueryVersionRep *rep;
137 rep = XCBShmQueryVersionReply (datap->conn,
138 XCBShmQueryVersion (datap->conn),
145 if (rep->shared_pixmaps &&
146 (rep->major_version > 1 || rep->minor_version > 0))
147 format = rep->pixmap_format;
150 datap->image = XCBImageSHMCreate (datap->conn, datap->depth,
151 format, NULL, W_W, W_H);
152 assert(datap->image);
154 shminfo.shmid = shmget (IPC_PRIVATE,
155 datap->image->bytes_per_line*datap->image->height,
157 assert(shminfo.shmid != -1);
158 shminfo.shmaddr = shmat (shminfo.shmid, 0, 0);
159 assert(shminfo.shmaddr);
160 datap->image->data = shminfo.shmaddr;
162 shminfo.shmseg = XCBShmSEGNew (datap->conn);
163 XCBShmAttach (datap->conn, shminfo.shmseg,
165 shmctl_status = shmctl(shminfo.shmid, IPC_RMID, 0);
166 assert(shmctl_status != -1);
172 printf ("Use of shm.\n");
177 printf ("Can't use shm. Use standard functions.\n");
178 shmdt (shminfo.shmaddr);
179 shmctl (shminfo.shmid, IPC_RMID, 0);
185 main (int argc, char *argv[])
195 XCBRECTANGLE rect_coord = { 0, 0, W_W, W_H};
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");
212 try_shm = atoi (argv[1]);
216 data.conn = XCBConnect (0, &screen_num);
217 screen = XCBAuxGetScreen(data.conn, screen_num);
218 data.depth = XCBAuxGetDepth (data.conn, screen);
220 win.window = screen->root;
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);
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);
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,
244 XCBWindowClassInputOutput,
247 XCBMapWindow (data.conn, data.draw.window);
249 rect.pixmap = XCBPIXMAPNew (data.conn);
250 XCBCreatePixmap (data.conn, data.depth,
251 rect.pixmap, data.draw,
253 XCBPolyFillRectangle(data.conn, rect, bgcolor, 1, &rect_coord);
255 data.format = XCBImageFormatZPixmap;
256 XCBSync (data.conn, 0);
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);
266 time_start = get_time ();
270 e = XCBPollForEvent(data.conn, NULL);
273 switch (e->response_type)
276 XCBCopyArea(data.conn, rect, data.draw, bgcolor,
277 0, 0, 0, 0, W_W, W_H);
278 XCBSync (data.conn, 0);
284 XCBFlush (data.conn);