2 * Copyright (C) 2001-2002 Bart Massey and Jamey Sharp.
3 * All Rights Reserved. See the file COPYING in this directory
4 * for licensing information.
7 #include <X11/XCB/xcb.h>
8 #include <X11/XCB/xcb_aux.h>
9 #include "reply_formats.h"
11 #include <stdlib.h> /* for free(3) */
12 #include <unistd.h> /* for usleep(3) */
16 #define LAG 0.3 /* lag angle for the follow line */
18 /* If I've done my math right, Linux maxes out at 100 fps on Intel (1000 fps
19 * on Alpha) due to the granularity of the kernel timer. */
20 #define FRAME_RATE 10.0 /* frames per second */
24 static XCBConnection *c;
25 static XCBSCREEN *root;
26 static XCBGCONTEXT white, black;
38 void *run(void *param);
39 void *event_thread(void *param);
41 static void get_depth()
43 XCBDRAWABLE drawable = { root->root };
44 XCBGetGeometryRep *geom;
45 geom = XCBGetGeometryReply(c, XCBGetGeometry(c, drawable), 0);
48 perror("GetGeometry(root) failed");
53 fprintf(stderr, "Root 0x%x: %dx%dx%d\n",
54 root->root.xid, geom->width, geom->height, geom->depth);
63 CARD32 mask = XCBGCForeground | XCBGCGraphicsExposures;
68 c = XCBConnect(0, &screen_num);
69 root = XCBAuxGetScreen(c, screen_num);
72 rootwin.window = root->root;
73 white = XCBGCONTEXTNew(c);
74 black = XCBGCONTEXTNew(c);
76 pthread_create(&thr, 0, event_thread, 0);
78 values[1] = 0; /* no graphics exposures */
80 values[0] = root->white_pixel;
81 XCBCreateGC(c, white, rootwin, mask, values);
83 values[0] = root->black_pixel;
84 XCBCreateGC(c, black, rootwin, mask, values);
86 for(i = 1; i < WINS; ++i)
87 pthread_create(&thr, 0, run, (void*)i);
96 XCBCopyArea(c, windows[idx].p, windows[idx].w, white, 0, 0, 0, 0,
97 windows[idx].width, windows[idx].height);
100 perror("XCBSync failed");
105 void *run(void *param)
107 int idx = (int)param;
114 windows[idx].w.window = XCBWINDOWNew(c);
115 windows[idx].p.pixmap = XCBPIXMAPNew(c);
116 windows[idx].width = 300;
117 line[0].x = xo = windows[idx].width / 2;
118 windows[idx].height = 300;
119 line[0].y = yo = windows[idx].height / 2;
120 windows[idx].angv = 0.05;
123 int ws = windows[idx].width * windows[idx].width;
124 int hs = windows[idx].height * windows[idx].height;
125 r = sqrt(ws + hs) + 1.0;
129 CARD32 mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
131 XCBRECTANGLE rect = { 0, 0, windows[idx].width, windows[idx].height };
132 values[0] = root->white_pixel;
133 values[1] = XCBEventMaskButtonRelease | XCBEventMaskExposure;
134 values[2] = XCBEventMaskButtonPress;
136 XCBCreateWindow(c, depth, windows[idx].w.window, root->root,
137 /* x */ 0, /* y */ 0,
138 windows[idx].width, windows[idx].height,
139 /* border */ 0, XCBWindowClassInputOutput,
140 /* visual */ root->root_visual,
143 XCBMapWindow(c, windows[idx].w.window);
145 XCBCreatePixmap(c, depth,
146 windows[idx].p.pixmap, windows[idx].w,
147 windows[idx].width, windows[idx].height);
149 XCBPolyFillRectangle(c, windows[idx].p, white, 1, &rect);
156 line[1].x = xo + r * cos(theta);
157 line[1].y = yo + r * sin(theta);
158 XCBPolyLine(c, XCBCoordModeOrigin, windows[idx].p, black,
161 line[1].x = xo + r * cos(theta + LAG);
162 line[1].y = yo + r * sin(theta + LAG);
163 XCBPolyLine(c, XCBCoordModeOrigin, windows[idx].p, white,
167 theta += windows[idx].angv;
168 while(theta > 2 * PI)
173 usleep(1000000 / FRAME_RATE);
179 int lookup_window(XCBWINDOW w)
182 for(i = 0; i < WINS; ++i)
183 if(windows[i].w.window.xid == w.xid)
188 void *event_thread(void *param)
195 e = XCBWaitForEvent(c);
198 if(e->response_type == XCBExpose)
200 XCBExposeEvent *ee = (XCBExposeEvent *) e;
201 idx = lookup_window(ee->window);
203 fprintf(stderr, "Expose on unknown window!\n");
206 XCBCopyArea(c, windows[idx].p, windows[idx].w,
207 white, ee->x, ee->y, ee->x, ee->y,
208 ee->width, ee->height);
213 else if(e->response_type == XCBButtonRelease)
215 XCBButtonReleaseEvent *bre = (XCBButtonReleaseEvent *) e;
216 idx = lookup_window(bre->event);
218 fprintf(stderr, "ButtonRelease on unknown window!\n");
221 if(bre->detail.id == XCBButton1)
222 windows[idx].angv = -windows[idx].angv;
223 else if(bre->detail.id == XCBButton4)
224 windows[idx].angv += 0.001;
225 else if(bre->detail.id == XCBButton5)
226 windows[idx].angv -= 0.001;