]> icculus.org git repositories - mikachu/openbox.git/blob - cwmcc/client_props.c
add get functions for all the client properties
[mikachu/openbox.git] / cwmcc / client_props.c
1 #include "cwmcc_internal.h"
2 #include "atom.h"
3 #include "prop.h"
4 #include "client_props.h"
5 #include "render/render.h"
6
7 #include <X11/Xutil.h>
8
9 void cwmcc_client_get_protocols(Window win, Atom **protocols)
10 {
11     gulong num;
12
13     if (!prop_get_array32(win, CWMCC_ATOM(client, wm_protocols),
14                           CWMCC_ATOM(type, atom), protocols, &num)) {
15         *protocols = NULL;
16     }
17 }
18
19 int cwmcc_client_get_wm_state(Window win)
20 {
21     gulong s;
22
23     if (!prop_get32(win, CWMCC_ATOM(client, wm_state),
24                     CWMCC_ATOM(client, wm_state), &s)) {
25         g_warning("Failed to read WM_STATE from 0x%lx", win);
26         s = NormalState;
27     }
28     return s;
29 }
30
31 void cwmcc_client_get_name(Window win, char **name)
32 {
33     if (!prop_get_string_utf8(win, CWMCC_ATOM(client, net_wm_name), name))
34         if (!prop_get_string_locale(win, CWMCC_ATOM(client, wm_name), name)) {
35             g_warning("Failed to read a name from 0x%lx", win);
36             *name = g_strdup("Unnamed Window");
37         }
38 }
39
40 void cwmcc_client_get_icon_name(Window win, char **name)
41 {
42     if (!prop_get_string_utf8(win, CWMCC_ATOM(client, net_wm_icon_name), name))
43         if (!prop_get_string_locale(win,
44                                     CWMCC_ATOM(client, wm_icon_name), name)) {
45             g_warning("Failed to read an icon name from 0x%lx", win);
46             *name = g_strdup("Unnamed Window");
47         }
48 }
49
50 void cwmcc_client_get_class(Window win, char **class, char **name)
51 {
52     char **s;
53
54     if (!prop_get_strings_locale(win, CWMCC_ATOM(client, wm_class), &s)) {
55         g_warning("Failed to read WM_CLASS from 0x%lx", win);
56         *class = g_strdup("");
57         *name = g_strdup("");
58     } else {
59         if (!s[0]) {
60             g_warning("Failed to read class element of WM_CLASS from 0x%lx",
61                       win);
62             *class = g_strdup("");
63         } else
64             *class = g_strdup(s[0]);
65         if (!s[0] || !s[1]) {
66             g_warning("Failed to read name element of WM_CLASS from 0x%lx",
67                       win);
68             *name = g_strdup("");
69         } else
70             *name = g_strdup(s[1]);
71     }
72     g_strfreev(s);
73 }
74
75 void cwmcc_client_get_role(Window win, char **role)
76 {
77     if (!prop_get_string_locale(win,
78                                 CWMCC_ATOM(client, wm_window_role), role)) {
79         g_warning("Failed to read WM_WINDOW_ROLE from 0x%lx", win);
80         *role = g_strdup("");
81     }
82 }
83
84 void cwmcc_client_get_mwmhints(Window win, struct Cwmcc_MwmHints *hints)
85 {
86     gulong *l = NULL, num;
87
88     if (!prop_get_array32(win, CWMCC_ATOM(client, motif_wm_hints),
89                           CWMCC_ATOM(client, motif_wm_hints), &l, &num)) {
90         g_warning("Failed to read Motif WM Hints from 0x%lx", win);
91         hints->flags = 0;
92     } else if (num < 3) {
93         g_warning("Read incomplete Motif WM Hints from 0x%lx", win);
94         hints->flags = 0;
95     } else {
96         hints->flags = l[0];
97         hints->functions = l[1];
98         hints->decorations = l[2];
99     }
100     g_free(l);
101 }
102
103 void cwmcc_client_get_desktop(Window win, gulong *desk)
104 {
105     if (!prop_get32(win, CWMCC_ATOM(client, net_wm_desktop),
106                     CWMCC_ATOM(type, cardinal), desk)) {
107         g_warning("Failed to read NET_WM_DESKTOP from 0x%lx", win);
108         *desk = 0;
109     }
110 }
111
112 void cwmcc_client_get_type(Window win, gulong **types)
113 {
114     gulong num;
115
116     if (!prop_get_array32(win, CWMCC_ATOM(client, net_wm_window_type),
117                     CWMCC_ATOM(type, atom), types, &num)) {
118         g_warning("Failed to read NET_WM_WINDOW_TYPE from 0x%lx", win);
119         *types = g_new(Atom, 2);
120         (*types)[0] = CWMCC_ATOM(data, net_wm_window_type_normal);
121         (*types)[1] = 0;
122     }
123 }
124
125 void cwmcc_client_get_state(Window win, gulong **states)
126 {
127     gulong num;
128
129     if (!prop_get_array32(win, CWMCC_ATOM(client, net_wm_state),
130                     CWMCC_ATOM(type, atom), states, &num)) {
131         g_warning("Failed to read NET_WM_STATE from 0x%lx", win);
132         *states = g_new(Atom, 1);
133         (*states)[0] = 0;
134     }
135 }
136
137 void cwmcc_client_get_strut(Window win, int *l, int *t, int *r, int *b)
138 {
139     gulong *data = NULL, num;
140
141     if (!prop_get_array32(win, CWMCC_ATOM(client, net_wm_strut),
142                     CWMCC_ATOM(type, cardinal), &data, &num)) {
143         g_warning("Failed to read NET_WM_STRUT from 0x%lx", win);
144         *l = *t = *r = *b = 0;
145     } else if (num != 4) {
146         g_warning("Read invalid NET_WM_STRUT from 0x%lx", win);
147         *l = *t = *r = *b = 0;
148     } else {
149         *l = data[0];
150         *r = data[1];
151         *t = data[2];
152         *b = data[3];
153     }
154     g_free(l);
155 }
156
157 static void convert_pixmap_to_icon(Pixmap pix, Pixmap mask,
158                                    struct Cwmcc_Icon *icon)
159 {
160 /*
161     guint pw, ph, mw, mh, depth;
162     Window wjunk;
163     int ijunk;
164     guint uijunk;
165     guint x, y;
166
167     if (!XGetGeometry(cwmcc_display, pix, &wjunk, &ijunk, &ijunk, &pw, &ph,
168                       &uijunk, &depth)) {
169         g_message("Unable to read pixmap icon's geometry");
170         icon->width = icon->height = 0;
171         icon->data = NULL;
172         return;
173     }
174     if (!XGetGeometry(cwmcc_display, mask, &wjunk, &ijunk, &ijunk, &mw, &mh,
175                       &uijunk, &ujunk)) {
176         g_message("Unable to read pixmap icon's mask's geometry");
177         icon->width = icon->height = 0;
178         icon->data = NULL;
179         return;
180     }
181     if (pw != mw || ph !_ mh) {
182         g_warning("Pixmap icon's mask does not match icon's dimensions");
183         icon->width = icon->height = 0;
184         icon->data = NULL;
185         return;
186     }
187
188     for (y = 0; y < ph; ++y)
189         for (x = 0; x < pw; ++x) {
190         }
191 */
192     icon->width = icon->height = 0;
193     icon->data = NULL;
194 }
195
196 void cwmcc_client_get_icon(Window win, struct Cwmcc_Icon **icons)
197 {
198     gulong *data = NULL, num;
199     gulong w, h, i;
200     int j;
201     int nicons;
202
203     if (!prop_get_array32(win, CWMCC_ATOM(client, net_wm_icon),
204                           CWMCC_ATOM(type, cardinal), &data, &num)) {
205         g_warning("Failed to read NET_WM_ICON from 0x%lx", win);
206         *icons = NULL;
207         nicons = 0;
208     } else { 
209         /* figure out how many valid icons are in here */
210         i = 0;
211         nicons = 0;
212         while (num - i > 2) {
213             w = data[i++];
214             h = data[i++];
215             i += w * h;
216             if (i > num) break;
217             ++nicons;
218         }
219
220         *icons = g_new(struct Cwmcc_Icon, nicons + 1);
221         (*icons)[nicons].data = NULL;
222     
223         /* store the icons */
224         i = 0;
225         for (j = 0; j < nicons; ++j) {
226             w = (*icons)[j].width = data[i++];
227             h = (*icons)[j].height = data[i++];
228             (*icons)[j].data =
229                 g_memdup(&data[i], w * h * sizeof(gulong));
230             i += w * h;
231             g_assert(i <= num);
232         }
233     }
234     g_free(data);
235
236     data = NULL;
237     if (!prop_get_array32(win, CWMCC_ATOM(client, kwm_win_icon),
238                           CWMCC_ATOM(client, kwm_win_icon), &data, &num)) {
239         g_warning("Failed to read KWM_WIN_ICON from 0x%lx", win);
240     } else if (num != 2) {
241         g_warning("Read invalid KWM_WIN_ICON from 0x%lx", win);
242     } else {
243         Pixmap p, m;
244         struct Cwmcc_Icon icon;
245
246         p = data[0];
247         m = data[1];
248
249         convert_pixmap_to_icon(p, m, &icon);
250
251         if (icon.data) {
252             *icons = g_renew(struct Cwmcc_Icon, *icons, nicons + 2);
253             (*icons[nicons + 1]).data = NULL;
254             g_memmove(&(*icons)[nicons], &icon, sizeof(struct Cwmcc_Icon));
255         }
256     }
257     g_free(data);
258
259 }
260
261 void cwmcc_client_get_premax(Window win, int *x, int *y, int *w, int *h)
262 {
263     gulong *l = NULL, num;
264
265     if (!prop_get_array32(win, CWMCC_ATOM(client, openbox_premax),
266                     CWMCC_ATOM(type, cardinal), &l, &num)) {
267         g_warning("Failed to read OPENBOX_PREMAX from 0x%lx", win);
268         *x = *y = *w = *h = 0;
269     } else if (num != 4) {
270         g_warning("Read invalid OPENBOX_PREMAX from 0x%lx", win);
271         *x = *y = *w = *h = 0;
272     } else {
273         *x = l[0];
274         *y = l[1];
275         *w = l[2];
276         *h = l[3];
277     }
278     g_free(l);
279 }
280
281 void cwmcc_client_set_premax(Window win, int x, int y, int w, int h)
282 {
283     gulong l[4];
284
285     l[0] = x;
286     l[1] = y;
287     l[2] = w;
288     l[3] = h;
289     XChangeProperty(cwmcc_display, win, CWMCC_ATOM(client, openbox_premax),
290                     CWMCC_ATOM(type, cardinal), 32, PropModeReplace,
291                     (guchar*)l, 4);
292 }