take the selecton for the screens that we will be managing, and skip the ones where...
[dana/dcompmgr.git] / dcompmgr.c
1 #include <glib.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <xcb/xcb.h>
5
6 #define _(a) (a)
7
8 /* inherits from xcb_screen_t */
9 typedef struct {
10     xcb_screen_t super;
11     int          num;
12     xcb_window_t selwin; /* for the selection */
13 } d_screen_t;
14
15 static xcb_connection_t  *conn;
16 static const xcb_setup_t *setup;
17 static d_screen_t        *screens = NULL;
18
19 static gboolean
20 register_screen (d_screen_t *sc)
21 {
22     char *name;
23     int len, s;
24     xcb_window_t w;
25     xcb_intern_atom_cookie_t ack;
26     xcb_intern_atom_reply_t *arep;
27     xcb_get_selection_owner_cookie_t sck;
28     xcb_get_selection_owner_reply_t *srep;
29     gboolean taken;
30
31     w = xcb_generate_id(conn);
32     xcb_create_window(conn, XCB_COPY_FROM_PARENT, w, sc->super.root,
33                       0, 0, 1, 1, 0, XCB_WINDOW_CLASS_INPUT_ONLY,
34                       sc->super.root_visual, 0, NULL);
35
36     name = g_strdup_printf("_NET_WM_CM_S%d", sc->num);
37     ack = xcb_intern_atom(conn, FALSE, strlen(name), name);
38     arep = xcb_intern_atom_reply(conn, ack, NULL);
39     g_free(name);
40
41     sck = xcb_get_selection_owner(conn, arep->atom);
42     srep = xcb_get_selection_owner_reply(conn, sck, NULL);
43     taken = !!srep->owner;
44     free(srep);
45     if (taken) {
46         printf(_("screen %d already has a composite manager, skipping\n"),
47                sc->num);
48         return FALSE;
49     }
50
51     xcb_set_selection_owner(conn, w, arep->atom, XCB_CURRENT_TIME);
52     sck = xcb_get_selection_owner(conn, arep->atom);
53     srep = xcb_get_selection_owner_reply(conn, sck, NULL);
54     taken = srep->owner == w;
55     if (taken) {
56         sc->selwin = w;
57         return TRUE;
58     }
59     else {
60         xcb_destroy_window(conn, w);
61         return FALSE;
62     }
63 }
64
65 static gint
66 all_screens()
67 {
68     xcb_screen_iterator_t it;
69     int count, i;
70     d_screen_t sc;
71
72     count = i = 0;
73     for (it = xcb_setup_roots_iterator(setup); it.rem; xcb_screen_next(&it)) {
74         sc.super = *it.data;
75         sc.num = i++;
76         if (register_screen(&sc)) {
77             ++count;
78             screens = g_renew(d_screen_t, screens, count);
79             screens[count-1] = sc;
80             printf(_("managing screen %d\n"), sc.num);
81         }
82     }
83     return count;
84 }
85
86 int
87 main(int argc, char **argv)
88 {
89     conn = xcb_connect(NULL, NULL);
90     if (!conn) {
91         printf(_("Unable to connect to display\n"));
92         return 1;
93     }
94     setup = xcb_get_setup(conn);
95
96     all_screens();
97     
98
99     xcb_disconnect(conn);
100     return 0;
101 }