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);
79 screen_remove_window(sc, w);
80 if (vis) screen_refresh(sc);
83 case XCB_REPARENT_NOTIFY:
85 xcb_reparent_notify_event_t *rev;
89 rev = (xcb_reparent_notify_event_t*)ev;
90 sc = display_screen_from_root(dpy, rev->event);
92 w = screen_find_window(sc, rev->window);
93 if (rev->parent == sc->super.root)
94 screen_add_window(sc, rev->window);
97 screen_remove_window(sc, w);
99 screen_refresh(w->sc);
104 xcb_map_notify_event_t *mev;
108 mev = (xcb_map_notify_event_t*)ev;
109 sc = display_screen_from_root(dpy, mev->event);
111 w = screen_find_window(sc, mev->window);
113 screen_refresh(w->sc);
116 case XCB_UNMAP_NOTIFY:
118 xcb_unmap_notify_event_t *mev;
122 mev = (xcb_unmap_notify_event_t*)ev;
123 sc = display_screen_from_root(dpy, mev->event);
125 w = screen_find_window(sc, mev->window);
127 screen_refresh(w->sc);
130 case XCB_CONFIGURE_NOTIFY:
132 xcb_configure_notify_event_t *cev;
134 d_window_t *w, *above;
135 int x, y, width, height, bwidth;
137 cev = (xcb_configure_notify_event_t*)ev;
138 sc = display_screen_from_root(dpy, cev->event);
140 w = screen_find_window(sc, cev->window);
141 window_get_area(w, &x, &y, &width, &height, &bwidth);
142 if (x != cev->x || y != cev->y || width != cev->width ||
143 height != cev->height || bwidth != cev->border_width)
145 window_configure(w, cev->x, cev->y,
146 cev->width, cev->height,
148 if (window_is_mapped(w) &&
149 (width != cev->width ||
150 height != cev->height || bwidth != cev->border_width))
151 sc->window_resize(w);
153 above = screen_find_window(sc, cev->above_sibling);
154 screen_stacking_move_above(sc, w, above);
155 screen_refresh(w->sc);
159 if (ev->response_type - dpy->damage.event == XCB_DAMAGE_NOTIFY) {
160 xcb_damage_notify_event_t *dev;
163 dev = (xcb_damage_notify_event_t*)ev;
164 for (it = list_top(dpy->screens); it; it = it->next) {
165 d_screen_t *sc = it->data;
168 w = screen_find_window(sc, dev->drawable);
170 screen_refresh(w->sc);
174 xcb_damage_subtract(dpy->conn, dev->damage,
180 xcb_flush(dpy->conn);
185 paint(d_display_t *dpy)
190 gettimeofday(&now, NULL);
192 for (it = list_top(dpy->screens); it; it = it->next) {
193 d_screen_t *sc = it->data;
195 if (time_compare(&sc->next_repaint, &now) <= 0)
196 sc->screen_paint(sc);
201 run(d_display_t *dpy)
204 struct timeval next, now, *wait;
212 for (it = list_top(dpy->screens); it; it = it->next) {
213 d_screen_t *sc = it->data;
214 if (sc->need_repaint &&
215 (!npaint || time_compare(&sc->next_repaint, &next) < 0))
217 next = sc->next_repaint;
222 gettimeofday(&now, 0);
225 /* wait forever, there is nothing that needs drawing */
227 else if (time_compare(&next, &now) > 0) {
228 /* wait until the next allowed redraw time */
229 time_difference(&next, &now, &next);
233 /* don't wait cuz a redraw is due now already */
240 FD_SET(dpy->fd, &fds);
242 //printf("select %d\n", npaint);
244 r = select(dpy->fd+1, &fds, NULL, NULL, wait);
246 //printf("select timeout\n");
248 xcb_flush(dpy->conn);
251 if (xcb_connection_has_error(dpy->conn))
257 setup_functions(d_display_t *dpy)
261 for (it = list_top(dpy->screens); it; it = it->next) {
262 d_screen_t *sc = it->data;
264 screen_setup_default_functions(sc);
266 /* these can be plugins.. */
268 render_init(sc, id++);
273 cleanup_functions(d_display_t *dpy)
277 for (it = list_top(dpy->screens); it; it = it->next) {
278 d_screen_t *sc = it->data;
280 /* these can be plugins.. */
286 main(int argc, char **argv)
291 read_options(argc, argv, &opts);
293 dpy = display_open(NULL);
295 printf(_("Unable to connect to display\n"));
299 if (!dpy->composite.present) {
300 printf(_("no composite extension present on the display\n"));
304 if (!dpy->xfixes.present) {
305 printf(_("no xfixes extension present on the display\n"));
309 if (!dpy->damage.present) {
310 printf(_("no damage extension present on the display\n"));
314 if (!dpy->render.present) {
315 printf(_("no render extension present on the display\n"));
319 if (dpy->composite.major_version <= 0 && dpy->composite.minor_version < 3)
321 printf(_("composite extension does not support the overlay window"));
326 if (!display_claim_screens(dpy)) {
327 printf(_("found no screens to run on\n"));
332 signal(SIGINT, signal_quit_handler);
333 signal(SIGHUP, signal_quit_handler);
334 signal(SIGTERM, signal_quit_handler);
335 signal(SIGQUIT, signal_quit_handler);
337 setup_functions(dpy);
340 /* some of the windows may already be visible */
343 for (sc_it = list_top(dpy->screens); sc_it; sc_it = sc_it->next) {
344 d_screen_t *sc = sc_it->data;
346 for (it = list_bottom(sc->stacking); it; it = it->prev)
347 if (window_is_mapped(it->data))
348 sc->window_show(it->data);
355 /* make everything hidden */
358 for (sc_it = list_top(dpy->screens); sc_it; sc_it = sc_it->next) {
359 d_screen_t *sc = sc_it->data;
361 for (it = list_top(sc->stacking); it; it = it->next) {
362 if (window_is_mapped(it->data))
363 sc->window_hide(it->data);
368 cleanup_functions(dpy);