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 (width != cev->width ||
137 height != cev->height || bwidth != cev->border_width))
138 sc->window_resize(w);
140 above = screen_find_window(sc, cev->above_sibling);
141 screen_stacking_move_above(sc, w, above);
142 screen_refresh(w->sc);
146 if (ev->response_type - dpy->damage.event == XCB_DAMAGE_NOTIFY) {
147 xcb_damage_notify_event_t *dev;
150 dev = (xcb_damage_notify_event_t*)ev;
151 for (it = list_top(dpy->screens); it; it = it->next) {
152 d_screen_t *sc = it->data;
155 w = screen_find_window(sc, dev->drawable);
157 screen_refresh(w->sc);
161 xcb_damage_subtract(dpy->conn, dev->damage,
167 xcb_flush(dpy->conn);
172 paint(d_display_t *dpy)
177 gettimeofday(&now, NULL);
179 for (it = list_top(dpy->screens); it; it = it->next) {
180 d_screen_t *sc = it->data;
182 if (time_compare(&sc->next_repaint, &now) <= 0)
183 sc->screen_paint(sc);
188 run(d_display_t *dpy)
194 struct timeval next, now, *wait;
202 for (it = list_top(dpy->screens); it; it = it->next) {
203 d_screen_t *sc = it->data;
204 if (sc->need_repaint &&
205 (!npaint || time_compare(&sc->next_repaint, &next) < 0))
207 next = sc->next_repaint;
212 gettimeofday(&now, 0);
215 /* wait forever, there is nothing that needs drawing */
217 else if (time_compare(&next, &now) > 0) {
218 /* wait until the next allowed redraw time */
219 time_difference(&next, &now, &next);
223 /* don't wait cuz a redraw is due now already */
230 FD_SET(dpy->fd, &fds);
232 //printf("select %d\n", npaint);
234 r = select(dpy->fd+1, &fds, NULL, NULL, wait);
236 printf("select error\n");
238 //printf("select timeout\n");
240 xcb_flush(dpy->conn);
243 if (xcb_connection_has_error(dpy->conn))
249 setup_functions(d_display_t *dpy)
253 for (it = list_top(dpy->screens); it; it = it->next) {
254 d_screen_t *sc = it->data;
256 screen_setup_default_functions(sc);
258 /* these can be plugins.. */
260 render_init(sc, id++);
265 cleanup_functions(d_display_t *dpy)
269 for (it = list_top(dpy->screens); it; it = it->next) {
270 d_screen_t *sc = it->data;
272 /* these can be plugins.. */
278 main(int argc, char **argv)
283 read_options(argc, argv, &opts);
285 dpy = display_open(NULL);
287 printf(_("Unable to connect to display\n"));
291 if (!dpy->composite.present) {
292 printf(_("no composite extension present on the display\n"));
296 if (!dpy->xfixes.present) {
297 printf(_("no xfixes extension present on the display\n"));
301 if (!dpy->damage.present) {
302 printf(_("no damage extension present on the display\n"));
306 if (!dpy->render.present) {
307 printf(_("no render extension present on the display\n"));
311 if (dpy->composite.major_version <= 0 && dpy->composite.minor_version < 3)
313 printf(_("composite extension does not support the overlay window"));
318 if (!display_claim_screens(dpy)) {
319 printf(_("found no screens to run on\n"));
324 setup_functions(dpy);
327 /* some of the windows may already be visible */
330 for (sc_it = list_top(dpy->screens); sc_it; sc_it = sc_it->next) {
331 d_screen_t *sc = sc_it->data;
333 for (it = list_top(sc->stacking); it; it = it->next)
334 if (window_is_mapped(it->data))
335 sc->window_show(it->data);
341 cleanup_functions(dpy);