13 #include <sys/select.h>
18 #include <xcb/damage.h>
24 static gboolean quit = FALSE;
27 read_options(int argc, char **argv, d_options_t *opts)
29 opts->foo = argc && argv;
33 signal_quit_handler(int sig)
35 printf("caught signal %d, quitting\n", sig);
40 event(d_display_t *dpy)
42 xcb_generic_event_t *ev;
44 while ((ev = xcb_poll_for_event(dpy->conn)) && !quit) {
45 //printf("event %d\n", ev->response_type);
47 if (!ev->response_type) {
48 display_error(dpy, (xcb_generic_error_t*)ev);
53 switch (ev->response_type) {
54 case XCB_CREATE_NOTIFY:
56 xcb_create_notify_event_t *cev;
60 cev = (xcb_create_notify_event_t*)ev;
61 sc = display_screen_from_root(dpy, cev->parent);
63 w = screen_add_window(sc, cev->window);
66 case XCB_DESTROY_NOTIFY:
68 xcb_destroy_notify_event_t *dev;
73 dev = (xcb_destroy_notify_event_t*)ev;
74 sc = display_screen_from_root(dpy, dev->event);
76 w = screen_find_window(sc, dev->window);
77 vis = window_is_mapped(w);
80 screen_remove_window(sc, w);
81 if (vis) screen_refresh(sc);
84 case XCB_REPARENT_NOTIFY:
86 xcb_reparent_notify_event_t *rev;
90 rev = (xcb_reparent_notify_event_t*)ev;
91 sc = display_screen_from_root(dpy, rev->event);
93 w = screen_find_window(sc, rev->window);
94 if (rev->parent == sc->super.root)
95 screen_add_window(sc, rev->window);
97 if (window_is_mapped(w))
99 screen_remove_window(sc, w);
106 xcb_map_notify_event_t *mev;
110 mev = (xcb_map_notify_event_t*)ev;
111 sc = display_screen_from_root(dpy, mev->event);
113 w = screen_find_window(sc, mev->window);
115 screen_refresh(w->sc);
118 case XCB_UNMAP_NOTIFY:
120 xcb_unmap_notify_event_t *mev;
124 mev = (xcb_unmap_notify_event_t*)ev;
125 sc = display_screen_from_root(dpy, mev->event);
127 w = screen_find_window(sc, mev->window);
129 screen_refresh(w->sc);
132 case XCB_CONFIGURE_NOTIFY:
134 xcb_configure_notify_event_t *cev;
136 d_window_t *w, *above;
137 int x, y, width, height, bwidth;
139 cev = (xcb_configure_notify_event_t*)ev;
140 sc = display_screen_from_root(dpy, cev->event);
142 //printf("configure 0x%x", cev->window);
143 w = screen_find_window(sc, cev->window);
144 window_get_area(w, &x, &y, &width, &height, &bwidth);
145 if (x != cev->x || y != cev->y || width != cev->width ||
146 height != cev->height || bwidth != cev->border_width)
148 window_configure(w, cev->x, cev->y,
149 cev->width, cev->height,
151 if (window_is_mapped(w)) {
152 if (x != cev->x || y != cev->y)
154 if (width != cev->width ||
155 height != cev->height || bwidth != cev->border_width)
156 sc->window_resize(w);
159 above = screen_find_window(sc, cev->above_sibling);
160 screen_stacking_move_above(sc, w, above);
161 screen_refresh(w->sc);
165 if (ev->response_type - dpy->damage.event == XCB_DAMAGE_NOTIFY) {
166 xcb_damage_notify_event_t *dev;
169 dev = (xcb_damage_notify_event_t*)ev;
170 for (it = list_top(dpy->screens); it; it = it->next) {
171 d_screen_t *sc = it->data;
174 w = screen_find_window(sc, dev->drawable);
176 screen_refresh(w->sc);
180 xcb_damage_subtract(dpy->conn, dev->damage,
186 xcb_flush(dpy->conn);
191 paint(d_display_t *dpy)
196 gettimeofday(&now, NULL);
198 for (it = list_top(dpy->screens); it; it = it->next) {
199 d_screen_t *sc = it->data;
201 if (time_compare(&sc->next_repaint, &now) <= 0)
202 sc->screen_paint(sc);
207 run(d_display_t *dpy)
210 struct timeval next, now, *wait;
218 for (it = list_top(dpy->screens); it; it = it->next) {
219 d_screen_t *sc = it->data;
220 if (sc->need_repaint &&
221 (!npaint || time_compare(&sc->next_repaint, &next) < 0))
223 next = sc->next_repaint;
228 gettimeofday(&now, 0);
231 /* wait forever, there is nothing that needs drawing */
233 else if (time_compare(&next, &now) > 0) {
234 /* wait until the next allowed redraw time */
235 time_difference(&next, &now, &next);
239 /* don't wait cuz a redraw is due now already */
246 FD_SET(dpy->fd, &fds);
248 //printf("select %d\n", npaint);
250 r = select(dpy->fd+1, &fds, NULL, NULL, wait);
252 //printf("select timeout\n");
254 xcb_flush(dpy->conn);
257 if (xcb_connection_has_error(dpy->conn))
263 setup_functions(d_display_t *dpy)
267 for (it = list_top(dpy->screens); it; it = it->next) {
268 d_screen_t *sc = it->data;
270 screen_setup_default_functions(sc);
272 /* these can be plugins.. */
274 render_init(sc, id++);
279 cleanup_functions(d_display_t *dpy)
283 for (it = list_top(dpy->screens); it; it = it->next) {
284 d_screen_t *sc = it->data;
286 /* these can be plugins.. */
292 main(int argc, char **argv)
297 read_options(argc, argv, &opts);
299 dpy = display_open(NULL);
301 printf(_("Unable to connect to display\n"));
305 if (!dpy->composite.present) {
306 printf(_("no composite extension present on the display\n"));
310 if (!dpy->xfixes.present) {
311 printf(_("no xfixes extension present on the display\n"));
315 if (!dpy->damage.present) {
316 printf(_("no damage extension present on the display\n"));
320 if (!dpy->render.present) {
321 printf(_("no render extension present on the display\n"));
325 if (dpy->composite.major_version <= 0 && dpy->composite.minor_version < 3)
327 printf(_("composite extension does not support the overlay window"));
332 if (!display_claim_screens(dpy)) {
333 printf(_("found no screens to run on\n"));
338 signal(SIGINT, signal_quit_handler);
339 signal(SIGHUP, signal_quit_handler);
340 signal(SIGTERM, signal_quit_handler);
341 signal(SIGQUIT, signal_quit_handler);
343 setup_functions(dpy);
346 /* some of the windows may already be visible */
349 for (sc_it = list_top(dpy->screens); sc_it; sc_it = sc_it->next) {
350 d_screen_t *sc = sc_it->data;
352 for (it = list_bottom(sc->stacking); it; it = it->prev)
353 if (window_is_mapped(it->data)) {
354 /* make the window think it is unmapped so that the
356 window_fake_unmapped(it->data);
357 sc->window_show(it->data);
365 /* make everything hidden */
368 for (sc_it = list_top(dpy->screens); sc_it; sc_it = sc_it->next) {
369 d_screen_t *sc = sc_it->data;
371 for (it = list_top(sc->stacking); it; it = it->next) {
372 if (window_is_mapped(it->data))
373 sc->window_hide(it->data);
378 cleanup_functions(dpy);