542f1adbe3c1588c5eda4182b7951e34895a10af
[dana/dcompmgr.git] / dcompmgr.c
1 #include "screen.h"
2 #include "window.h"
3 #include "display.h"
4 #include "gettext.h"
5
6 #include <glib.h>
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <string.h>
10 #include <xcb/xcb.h>
11
12 typedef struct {
13     int foo;
14 } d_options_t;
15
16 static gint
17 all_screens(d_display_t *dpy, d_screen_t **list)
18 {
19     static const xcb_setup_t *setup;
20     xcb_screen_iterator_t it;
21     int count, i;
22     d_screen_t sc;
23
24     setup = xcb_get_setup(dpy->conn);
25
26     count = i = 0;
27     for (it = xcb_setup_roots_iterator(setup); it.rem; xcb_screen_next(&it)) {
28         sc.super = *it.data;
29         sc.dpy = dpy;
30         sc.num = i++;
31         if (screen_register(&sc)) {
32             ++count;
33             *list = realloc(*list, sizeof(d_screen_t)*count);
34             (*list)[count-1] = sc;
35             printf(_("managing screen %d\n"), sc.num);
36         }
37     }
38     return count;
39 }
40
41 static d_screen_t*
42 screen_from_root(d_screen_t *list, int n, xcb_window_t root)
43 {
44     int i;
45     for (i = 0; i < n; ++i)
46         if (list->super.root == root) return &list[i];
47     g_assert_not_reached();
48     return NULL;
49 }
50
51 static
52 void read_options(int argc, char **argv, d_options_t *opts)
53 {
54     opts->foo = argc && argv;
55 }
56
57 int
58 main(int argc, char **argv)
59 {
60     d_display_t         *dpy;
61     d_screen_t          *screens = NULL;
62     int                  nscreens;
63     xcb_generic_event_t *ev;
64     d_options_t          opts;
65
66     read_options(argc, argv, &opts);
67
68     dpy = display_open(NULL);
69     if (!dpy) {
70         printf(_("Unable to connect to display\n"));
71         return 1;
72     }
73
74     if (!dpy->composite.present) {
75         printf(_("no composite extension present on the display\n"));
76         display_unref(dpy);
77         return 1;
78     }
79     if (!dpy->xfixes.present) {
80         printf(_("no xfixes extension present on the display\n"));
81         display_unref(dpy);
82         return 1;
83     }
84     if (!dpy->damage.present) {
85         printf(_("no damage extension present on the display\n"));
86         display_unref(dpy);
87         return 1;
88     }
89     if (!dpy->render.present) {
90         printf(_("no render extension present on the display\n"));
91         display_unref(dpy);
92         return 1;
93     }
94     if (dpy->composite.major_version <= 0 && dpy->composite.minor_version < 3)
95     {
96         printf(_("composite extension does not support the overlay window"));
97         display_unref(dpy);
98         return 1;
99     }
100
101     nscreens = all_screens(dpy, &screens);
102     if (nscreens < 1) {
103         printf(_("found no screens to run on\n"));
104         display_unref(dpy);
105         return 0;
106     }
107
108     while ((ev = xcb_wait_for_event(dpy->conn))) {
109         printf("event %d\n", ev->response_type);
110
111         if (!ev->response_type) {
112             display_error(dpy, (xcb_generic_error_t*)ev);
113             free(ev);
114             continue;
115         }
116
117         switch (ev->response_type) {
118         case XCB_CREATE_NOTIFY:
119         {
120             xcb_create_notify_event_t *cev;
121             d_screen_t *sc;
122
123             cev = (xcb_create_notify_event_t*)ev;
124             sc = screen_from_root(screens, nscreens, cev->parent);
125             if (!sc) break;
126             screen_add_window(sc, cev->window);
127             break;
128         }
129         case XCB_DESTROY_NOTIFY:
130         {
131             xcb_destroy_notify_event_t *dev;
132             d_screen_t *sc;
133             d_window_t *w;
134
135             dev = (xcb_destroy_notify_event_t*)ev;
136             sc = screen_from_root(screens, nscreens, dev->event);
137             if (!sc) break;
138             w = screen_find_window(sc, dev->window);
139             w->hide(w);
140             screen_remove_window(sc, w);
141             break;
142         }
143         case XCB_REPARENT_NOTIFY:
144         {
145             xcb_reparent_notify_event_t *rev;
146             d_screen_t *sc;
147             d_window_t *w;
148
149             rev = (xcb_reparent_notify_event_t*)ev;
150             sc = screen_from_root(screens, nscreens, rev->event);
151             if (!sc) break;
152             w = screen_find_window(sc, rev->window);
153             if (rev->parent == sc->super.root)
154                 screen_add_window(sc, rev->window);
155             else {
156                 w->hide(w);
157                 screen_remove_window(sc, w);
158             }
159             break;
160         }
161         case XCB_MAP_NOTIFY:
162         {
163             xcb_map_notify_event_t *mev;
164             d_screen_t *sc;
165             d_window_t *w;
166
167             mev = (xcb_map_notify_event_t*)ev;
168             sc = screen_from_root(screens, nscreens, mev->event);
169             if (!sc) break;
170             w = screen_find_window(sc, mev->window);
171             window_show(w);
172             break;
173         }
174         case XCB_UNMAP_NOTIFY:
175         {
176             xcb_unmap_notify_event_t *mev;
177             d_screen_t *sc;
178             d_window_t *w;
179
180             mev = (xcb_unmap_notify_event_t*)ev;
181             sc = screen_from_root(screens, nscreens, mev->event);
182             if (!sc) break;
183             w = screen_find_window(sc, mev->window);
184             window_hide(w);
185             break;
186         }
187         default:
188             break;
189         }
190         free(ev);
191     }
192
193     display_unref(dpy);
194     return 0;
195 }