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);
98 /* TODO: better error detection for broken pipe */
101 perror("XCBSync failed");
106 void *run(void *param)
108 int idx = (int)param;
115 windows[idx].w.window = XCBWINDOWNew(c);
116 windows[idx].p.pixmap = XCBPIXMAPNew(c);
117 windows[idx].width = 300;
118 line[0].x = xo = windows[idx].width / 2;
119 windows[idx].height = 300;
120 line[0].y = yo = windows[idx].height / 2;
121 windows[idx].angv = 0.05;
124 int ws = windows[idx].width * windows[idx].width;
125 int hs = windows[idx].height * windows[idx].height;
126 r = sqrt(ws + hs) + 1.0;
130 CARD32 mask = XCBCWBackPixel | XCBCWEventMask | XCBCWDontPropagate;
132 XCBRECTANGLE rect = { 0, 0, windows[idx].width, windows[idx].height };
133 values[0] = root->white_pixel;
134 values[1] = XCBEventMaskButtonRelease | XCBEventMaskExposure;
135 values[2] = XCBEventMaskButtonPress;
137 XCBCreateWindow(c, depth, windows[idx].w.window, root->root,
138 /* x */ 0, /* y */ 0,
139 windows[idx].width, windows[idx].height,
140 /* border */ 0, XCBWindowClassInputOutput,
141 /* visual */ root->root_visual,
144 XCBMapWindow(c, windows[idx].w.window);
146 XCBCreatePixmap(c, depth,
147 windows[idx].p.pixmap, windows[idx].w,
148 windows[idx].width, windows[idx].height);
150 XCBPolyFillRectangle(c, windows[idx].p, white, 1, &rect);
157 line[1].x = xo + r * cos(theta);
158 line[1].y = yo + r * sin(theta);
159 XCBPolyLine(c, XCBCoordModeOrigin, windows[idx].p, black,
162 line[1].x = xo + r * cos(theta + LAG);
163 line[1].y = yo + r * sin(theta + LAG);
164 XCBPolyLine(c, XCBCoordModeOrigin, windows[idx].p, white,
168 theta += windows[idx].angv;
169 while(theta > 2 * PI)
174 usleep(1000000 / FRAME_RATE);
180 int lookup_window(XCBWINDOW w)
183 for(i = 0; i < WINS; ++i)
184 if(windows[i].w.window.xid == w.xid)
189 void *event_thread(void *param)
196 e = XCBWaitForEvent(c);
199 if(e->response_type == XCBExpose)
201 XCBExposeEvent *ee = (XCBExposeEvent *) e;
202 idx = lookup_window(ee->window);
204 fprintf(stderr, "Expose on unknown window!\n");
207 XCBCopyArea(c, windows[idx].p, windows[idx].w,
208 white, ee->x, ee->y, ee->x, ee->y,
209 ee->width, ee->height);
214 else if(e->response_type == XCBButtonRelease)
216 XCBButtonReleaseEvent *bre = (XCBButtonReleaseEvent *) e;
217 idx = lookup_window(bre->event);
219 fprintf(stderr, "ButtonRelease on unknown window!\n");
222 if(bre->detail.id == XCBButton1)
223 windows[idx].angv = -windows[idx].angv;
224 else if(bre->detail.id == XCBButton4)
225 windows[idx].angv += 0.001;
226 else if(bre->detail.id == XCBButton5)
227 windows[idx].angv -= 0.001;