11 #include <sys/select.h>
15 #include <xcb/damage.h>
22 read_options(int argc, char **argv, d_options_t *opts)
24 opts->foo = argc && argv;
28 event(d_display_t *dpy)
30 xcb_generic_event_t *ev;
32 while ((ev = xcb_poll_for_event(dpy->conn))) {
33 //printf("event %d\n", ev->response_type);
35 if (!ev->response_type) {
36 display_error(dpy, (xcb_generic_error_t*)ev);
41 switch (ev->response_type) {
42 case XCB_CREATE_NOTIFY:
44 xcb_create_notify_event_t *cev;
47 cev = (xcb_create_notify_event_t*)ev;
48 sc = display_screen_from_root(dpy, cev->parent);
50 screen_add_window(sc, cev->window);
53 case XCB_DESTROY_NOTIFY:
55 xcb_destroy_notify_event_t *dev;
60 dev = (xcb_destroy_notify_event_t*)ev;
61 sc = display_screen_from_root(dpy, dev->event);
63 w = screen_find_window(sc, dev->window);
64 vis = window_is_mapped(w);
66 screen_remove_window(sc, w);
67 if (vis) screen_refresh(sc);
70 case XCB_REPARENT_NOTIFY:
72 xcb_reparent_notify_event_t *rev;
76 rev = (xcb_reparent_notify_event_t*)ev;
77 sc = display_screen_from_root(dpy, rev->event);
79 w = screen_find_window(sc, rev->window);
80 if (rev->parent == sc->super.root)
81 screen_add_window(sc, rev->window);
84 screen_remove_window(sc, w);
86 screen_refresh(w->sc);
91 xcb_map_notify_event_t *mev;
95 mev = (xcb_map_notify_event_t*)ev;
96 sc = display_screen_from_root(dpy, mev->event);
98 w = screen_find_window(sc, mev->window);
100 screen_refresh(w->sc);
103 case XCB_UNMAP_NOTIFY:
105 xcb_unmap_notify_event_t *mev;
109 mev = (xcb_unmap_notify_event_t*)ev;
110 sc = display_screen_from_root(dpy, mev->event);
112 w = screen_find_window(sc, mev->window);
114 screen_refresh(w->sc);
117 case XCB_CONFIGURE_NOTIFY:
119 xcb_configure_notify_event_t *cev;
121 d_window_t *w, *above;
122 int x, y, width, height, bwidth;
124 cev = (xcb_configure_notify_event_t*)ev;
125 sc = display_screen_from_root(dpy, cev->event);
127 w = screen_find_window(sc, cev->window);
128 window_get_area(w, &x, &y, &width, &height, &bwidth);
129 if (x != cev->x || y != cev->y || width != cev->width ||
130 height != cev->height || bwidth != cev->border_width)
132 window_configure(w, cev->x, cev->y,
133 cev->width, cev->height,
135 if (window_is_mapped(w))
136 sc->window_reconfigure(w);
138 above = screen_find_window(sc, cev->above_sibling);
139 screen_stacking_move_above(sc, w, above);
140 screen_refresh(w->sc);
144 if (ev->response_type - dpy->damage.event == XCB_DAMAGE_NOTIFY) {
145 xcb_damage_notify_event_t *dev;
148 dev = (xcb_damage_notify_event_t*)ev;
149 for (it = list_top(dpy->screens); it; it = it->next) {
150 d_screen_t *sc = it->data;
153 w = screen_find_window(sc, dev->drawable);
155 screen_refresh(w->sc);
159 xcb_damage_subtract(dpy->conn, dev->damage,
165 xcb_flush(dpy->conn);
170 paint(d_display_t *dpy)
175 gettimeofday(&now, NULL);
177 for (it = list_top(dpy->screens); it; it = it->next) {
178 d_screen_t *sc = it->data;
180 if (time_compare(&sc->next_repaint, &now) <= 0)
181 sc->screen_paint(sc);
186 run(d_display_t *dpy)
192 struct timeval next, now, *wait;
200 for (it = list_top(dpy->screens); it; it = it->next) {
201 d_screen_t *sc = it->data;
202 if (sc->need_repaint &&
203 (!npaint || time_compare(&sc->next_repaint, &next) < 0))
205 next = sc->next_repaint;
210 gettimeofday(&now, 0);
213 /* wait forever, there is nothing that needs drawing */
215 else if (time_compare(&next, &now) > 0) {
216 /* wait until the next allowed redraw time */
217 time_difference(&next, &now, &next);
221 /* don't wait cuz a redraw is due now already */
228 FD_SET(dpy->fd, &fds);
230 //printf("select %d\n", npaint);
232 r = select(dpy->fd+1, &fds, NULL, NULL, wait);
234 printf("select error\n");
236 //printf("select timeout\n");
238 xcb_flush(dpy->conn);
241 if (xcb_connection_has_error(dpy->conn))
247 setup_functions(d_display_t *dpy)
251 for (it = list_top(dpy->screens); it; it = it->next) {
252 d_screen_t *sc = it->data;
253 screen_setup_default_functions(sc);
255 /* these can be plugins.. */
261 cleanup_functions(d_display_t *dpy)
265 for (it = list_top(dpy->screens); it; it = it->next) {
266 d_screen_t *sc = it->data;
268 /* these can be plugins.. */
274 main(int argc, char **argv)
279 read_options(argc, argv, &opts);
281 dpy = display_open(NULL);
283 printf(_("Unable to connect to display\n"));
287 if (!dpy->composite.present) {
288 printf(_("no composite extension present on the display\n"));
292 if (!dpy->xfixes.present) {
293 printf(_("no xfixes extension present on the display\n"));
297 if (!dpy->damage.present) {
298 printf(_("no damage extension present on the display\n"));
302 if (!dpy->render.present) {
303 printf(_("no render extension present on the display\n"));
307 if (dpy->composite.major_version <= 0 && dpy->composite.minor_version < 3)
309 printf(_("composite extension does not support the overlay window"));
314 if (!display_claim_screens(dpy)) {
315 printf(_("found no screens to run on\n"));
320 setup_functions(dpy);
323 /* some of the windows may already be visible */
326 for (sc_it = list_top(dpy->screens); sc_it; sc_it = sc_it->next) {
327 d_screen_t *sc = sc_it->data;
329 for (it = list_top(sc->stacking); it; it = it->next)
330 if (window_is_mapped(it->data))
331 sc->window_show(it->data);
337 cleanup_functions(dpy);