create a d_display_t type that encompasses a connection to a display
[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     nscreens = all_screens(dpy, &screens);
75     if (nscreens < 1) {
76         printf(_("found no screens to run on\n"));
77         display_unref(dpy);
78         return 0;
79     }
80
81     while ((ev = xcb_wait_for_event(dpy->conn))) {
82         printf("event %d\n", ev->response_type);
83
84         if (!ev->response_type) {
85             display_error(dpy, (xcb_generic_error_t*)ev);
86             free(ev);
87             continue;
88         }
89
90         switch (ev->response_type) {
91         case XCB_CREATE_NOTIFY:
92         {
93             xcb_create_notify_event_t *cev;
94             d_screen_t *sc;
95
96             cev = (xcb_create_notify_event_t*)ev;
97             sc = screen_from_root(screens, nscreens, cev->parent);
98             if (!sc) break;
99             screen_add_window(sc, cev->window);
100             break;
101         }
102         case XCB_DESTROY_NOTIFY:
103         {
104             xcb_destroy_notify_event_t *dev;
105             d_screen_t *sc;
106             d_window_t *w;
107
108             dev = (xcb_destroy_notify_event_t*)ev;
109             sc = screen_from_root(screens, nscreens, dev->event);
110             if (!sc) break;
111             w = screen_find_window(sc, dev->window);
112             w->hide(w);
113             screen_remove_window(sc, w);
114             break;
115         }
116         case XCB_REPARENT_NOTIFY:
117         {
118             xcb_reparent_notify_event_t *rev;
119             d_screen_t *sc;
120             d_window_t *w;
121
122             rev = (xcb_reparent_notify_event_t*)ev;
123             sc = screen_from_root(screens, nscreens, rev->event);
124             if (!sc) break;
125             w = screen_find_window(sc, rev->window);
126             if (rev->parent == sc->super.root)
127                 screen_add_window(sc, rev->window);
128             else {
129                 w->hide(w);
130                 screen_remove_window(sc, w);
131             }
132             break;
133         }
134         case XCB_MAP_NOTIFY:
135         {
136             xcb_map_notify_event_t *mev;
137             d_screen_t *sc;
138             d_window_t *w;
139
140             mev = (xcb_map_notify_event_t*)ev;
141             sc = screen_from_root(screens, nscreens, mev->event);
142             if (!sc) break;
143             w = screen_find_window(sc, mev->window);
144             window_show(w);
145             break;
146         }
147         case XCB_UNMAP_NOTIFY:
148         {
149             xcb_unmap_notify_event_t *mev;
150             d_screen_t *sc;
151             d_window_t *w;
152
153             mev = (xcb_unmap_notify_event_t*)ev;
154             sc = screen_from_root(screens, nscreens, mev->event);
155             if (!sc) break;
156             w = screen_find_window(sc, mev->window);
157             window_hide(w);
158             break;
159         }
160         default:
161             break;
162         }
163         free(ev);
164     }
165
166     display_unref(dpy);
167     return 0;
168 }