1c4a5f94b716a5424eba8d1050814fd10ce9a4ea
[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
95     nscreens = all_screens(dpy, &screens);
96     if (nscreens < 1) {
97         printf(_("found no screens to run on\n"));
98         display_unref(dpy);
99         return 0;
100     }
101
102     while ((ev = xcb_wait_for_event(dpy->conn))) {
103         printf("event %d\n", ev->response_type);
104
105         if (!ev->response_type) {
106             display_error(dpy, (xcb_generic_error_t*)ev);
107             free(ev);
108             continue;
109         }
110
111         switch (ev->response_type) {
112         case XCB_CREATE_NOTIFY:
113         {
114             xcb_create_notify_event_t *cev;
115             d_screen_t *sc;
116
117             cev = (xcb_create_notify_event_t*)ev;
118             sc = screen_from_root(screens, nscreens, cev->parent);
119             if (!sc) break;
120             screen_add_window(sc, cev->window);
121             break;
122         }
123         case XCB_DESTROY_NOTIFY:
124         {
125             xcb_destroy_notify_event_t *dev;
126             d_screen_t *sc;
127             d_window_t *w;
128
129             dev = (xcb_destroy_notify_event_t*)ev;
130             sc = screen_from_root(screens, nscreens, dev->event);
131             if (!sc) break;
132             w = screen_find_window(sc, dev->window);
133             w->hide(w);
134             screen_remove_window(sc, w);
135             break;
136         }
137         case XCB_REPARENT_NOTIFY:
138         {
139             xcb_reparent_notify_event_t *rev;
140             d_screen_t *sc;
141             d_window_t *w;
142
143             rev = (xcb_reparent_notify_event_t*)ev;
144             sc = screen_from_root(screens, nscreens, rev->event);
145             if (!sc) break;
146             w = screen_find_window(sc, rev->window);
147             if (rev->parent == sc->super.root)
148                 screen_add_window(sc, rev->window);
149             else {
150                 w->hide(w);
151                 screen_remove_window(sc, w);
152             }
153             break;
154         }
155         case XCB_MAP_NOTIFY:
156         {
157             xcb_map_notify_event_t *mev;
158             d_screen_t *sc;
159             d_window_t *w;
160
161             mev = (xcb_map_notify_event_t*)ev;
162             sc = screen_from_root(screens, nscreens, mev->event);
163             if (!sc) break;
164             w = screen_find_window(sc, mev->window);
165             window_show(w);
166             break;
167         }
168         case XCB_UNMAP_NOTIFY:
169         {
170             xcb_unmap_notify_event_t *mev;
171             d_screen_t *sc;
172             d_window_t *w;
173
174             mev = (xcb_unmap_notify_event_t*)ev;
175             sc = screen_from_root(screens, nscreens, mev->event);
176             if (!sc) break;
177             w = screen_find_window(sc, mev->window);
178             window_hide(w);
179             break;
180         }
181         default:
182             break;
183         }
184         free(ev);
185     }
186
187     display_unref(dpy);
188     return 0;
189 }