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.
8 #include <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 xcb_connection_t *c;
25 static xcb_screen_t *root;
26 static xcb_gcontext_t white, black;
38 void *run(void *param);
39 void *event_thread(void *param);
41 static void get_depth()
43 xcb_drawable_t drawable = { root->root };
44 xcb_get_geometry_reply_t *geom;
45 geom = xcb_get_geometry_reply(c, xcb_get_geometry(c, drawable), 0);
48 perror("GetGeometry(root) failed");
53 fprintf(stderr, "Root 0x%x: %dx%dx%d\n",
54 root->root, geom->width, geom->height, geom->depth);
63 uint32_t mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
65 xcb_drawable_t rootwin;
68 c = xcb_connect(0, &screen_num);
69 root = xcb_aux_get_screen(c, screen_num);
73 white = xcb_generate_id(c);
74 black = xcb_generate_id(c);
76 pthread_create(&thr, 0, event_thread, 0);
78 values[1] = 0; /* no graphics exposures */
80 values[0] = root->white_pixel;
81 xcb_create_gc(c, white, rootwin, mask, values);
83 values[0] = root->black_pixel;
84 xcb_create_gc(c, black, rootwin, mask, values);
86 for(i = 1; i < WINS; ++i)
87 pthread_create(&thr, 0, run, (void*)i);
94 void *run(void *param)
103 windows[idx].w = xcb_generate_id(c);
104 windows[idx].p = xcb_generate_id(c);
105 windows[idx].width = 300;
106 line[0].x = xo = windows[idx].width / 2;
107 windows[idx].height = 300;
108 line[0].y = yo = windows[idx].height / 2;
109 windows[idx].angv = 0.05;
112 int ws = windows[idx].width * windows[idx].width;
113 int hs = windows[idx].height * windows[idx].height;
114 r = sqrt(ws + hs) + 1.0;
118 uint32_t mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK | XCB_CW_DONT_PROPAGATE;
120 xcb_rectangle_t rect = { 0, 0, windows[idx].width, windows[idx].height };
121 values[0] = root->white_pixel;
122 values[1] = XCB_EVENT_MASK_BUTTON_RELEASE | XCB_EVENT_MASK_EXPOSURE;
123 values[2] = XCB_EVENT_MASK_BUTTON_PRESS;
125 xcb_create_window(c, depth, windows[idx].w, root->root,
126 /* x */ 0, /* y */ 0,
127 windows[idx].width, windows[idx].height,
128 /* border */ 0, XCB_WINDOW_CLASS_INPUT_OUTPUT,
129 /* visual */ root->root_visual,
132 xcb_map_window(c, windows[idx].w);
134 xcb_create_pixmap(c, depth,
135 windows[idx].p, windows[idx].w,
136 windows[idx].width, windows[idx].height);
138 xcb_poly_fill_rectangle(c, windows[idx].p, white, 1, &rect);
145 line[1].x = xo + r * cos(theta);
146 line[1].y = yo + r * sin(theta);
147 xcb_poly_line(c, XCB_COORD_MODE_ORIGIN, windows[idx].p, black,
150 line[1].x = xo + r * cos(theta + LAG);
151 line[1].y = yo + r * sin(theta + LAG);
152 xcb_poly_line(c, XCB_COORD_MODE_ORIGIN, windows[idx].p, white,
155 xcb_copy_area(c, windows[idx].p, windows[idx].w, white, 0, 0, 0, 0,
156 windows[idx].width, windows[idx].height);
157 if(xcb_flush(c) <= 0)
160 theta += windows[idx].angv;
161 while(theta > 2 * PI)
166 usleep(1000000 / FRAME_RATE);
172 int lookup_window(xcb_window_t w)
175 for(i = 0; i < WINS; ++i)
176 if(windows[i].w == w)
181 void *event_thread(void *param)
183 xcb_generic_event_t *e;
188 e = xcb_wait_for_event(c);
191 if(e->response_type == XCB_EXPOSE)
193 xcb_expose_event_t *ee = (xcb_expose_event_t *) e;
194 idx = lookup_window(ee->window);
196 fprintf(stderr, "Expose on unknown window!\n");
199 xcb_copy_area(c, windows[idx].p, windows[idx].w,
200 white, ee->x, ee->y, ee->x, ee->y,
201 ee->width, ee->height);
206 else if(e->response_type == XCB_BUTTON_RELEASE)
208 xcb_button_release_event_t *bre = (xcb_button_release_event_t *) e;
209 idx = lookup_window(bre->event);
211 fprintf(stderr, "ButtonRelease on unknown window!\n");
214 if(bre->detail == XCB_BUTTON_INDEX_1)
215 windows[idx].angv = -windows[idx].angv;
216 else if(bre->detail == XCB_BUTTON_INDEX_4)
217 windows[idx].angv += 0.001;
218 else if(bre->detail == XCB_BUTTON_INDEX_5)
219 windows[idx].angv -= 0.001;