]> icculus.org git repositories - dana/openbox.git/blob - cwmcc/prop.c
proper cwmcc_ prefixing.
[dana/openbox.git] / cwmcc / prop.c
1 #include "cwmcc_internal.h"
2 #include "atom.h"
3
4 #include <X11/Xutil.h>
5 #include <glib.h>
6 #include <string.h>
7
8 /* this just isn't used...
9 static gboolean get(Window win, Atom prop, Atom type, int size,
10                     guchar **data, gulong num)
11 {
12     gboolean ret = FALSE;
13     int res;
14     guchar *xdata = NULL;
15     Atom ret_type;
16     int ret_size;
17     gulong ret_items, bytes_left;
18     long num32 = 32 / size * num; /\* num in 32-bit elements *\/
19
20     res = XGetWindowProperty(cwmcc_display, win, prop, 0l, num32,
21                              FALSE, type, &ret_type, &ret_size,
22                              &ret_items, &bytes_left, &xdata);
23     if (res == Success && ret_items && xdata) {
24         if (ret_size == size && ret_items >= num) {
25             *data = g_memdup(xdata, num * (size / 8));
26             ret = TRUE;
27         }
28         XFree(xdata);
29     }
30     return ret;
31 }
32 */
33
34 static gboolean get_prealloc(Window win, Atom prop, Atom type, int size,
35                              guchar *data, gulong num)
36 {
37     gboolean ret = FALSE;
38     int res;
39     guchar *xdata = NULL;
40     Atom ret_type;
41     int ret_size;
42     gulong ret_items, bytes_left;
43     long num32 = 32 / size * num; /* num in 32-bit elements */
44
45     res = XGetWindowProperty(cwmcc_display, win, prop, 0l, num32,
46                              FALSE, type, &ret_type, &ret_size,
47                              &ret_items, &bytes_left, &xdata);
48     if (res == Success && ret_items && xdata) {
49         if (ret_size == size && ret_items >= num) {
50             gulong i;
51             for (i = 0; i < num; ++i)
52                 switch (size) {
53                 case 8:
54                     data[i] = xdata[i];
55                     break;
56                 case 16:
57                     ((guint16*)data)[i] = ((guint16*)xdata)[i];
58                     break;
59                 case 32:
60                     ((guint32*)data)[i] = ((guint32*)xdata)[i];
61                     break;
62                 default:
63                     g_assert_not_reached(); /* unhandled size */
64                 }
65             ret = TRUE;
66         }
67         XFree(xdata);
68     }
69     return ret;
70 }
71
72 static gboolean get_all(Window win, Atom prop, Atom type, int size,
73                         guchar **data, gulong *num)
74 {
75     gboolean ret = FALSE;
76     int res;
77     guchar *xdata = NULL;
78     Atom ret_type;
79     int ret_size;
80     gulong ret_items, bytes_left;
81
82     res = XGetWindowProperty(cwmcc_display, win, prop, 0l, G_MAXLONG,
83                              FALSE, type, &ret_type, &ret_size,
84                              &ret_items, &bytes_left, &xdata);
85     if (res == Success) {
86         if (ret_size == size && ret_items > 0) {
87             *data = g_malloc(ret_items * (size / 8) + sizeof(guchar*));
88             g_memmove(*data, xdata, ret_items * (size / 8));
89             data[ret_items * (size / 8)] = NULL;
90             *num = ret_items;
91             ret = TRUE;
92         }
93         XFree(xdata);
94     }
95     return ret;
96 }
97
98 static gboolean get_stringlist(Window win, Atom prop, char ***list, int *nstr)
99 {
100     XTextProperty tprop;
101     gboolean ret = FALSE;
102
103     if (XGetTextProperty(cwmcc_display, win, &tprop, prop) && tprop.nitems) {
104         if (XTextPropertyToStringList(&tprop, list, nstr))
105             ret = TRUE;
106         XFree(tprop.value);
107     }
108     return ret;
109 }
110
111 gboolean cwmcc_prop_get32(Window win, Atom prop, Atom type, gulong *ret)
112 {
113     return get_prealloc(win, prop, type, 32, (guchar*)ret, 1);
114 }
115
116 gboolean cwmcc_prop_get_array32(Window win, Atom prop, Atom type, gulong **ret,
117                           gulong *nret)
118 {
119     return get_all(win, prop, type, 32, (guchar**)ret, nret);
120 }
121
122 gboolean cwmcc_prop_get_string_locale(Window win, Atom prop, char **data)
123 {
124     char **list;
125     int nstr;
126
127     if (get_stringlist(win, prop, &list, &nstr) && nstr) {
128         *data = g_locale_to_utf8(list[0], -1, NULL, NULL, NULL);
129         XFreeStringList(list);
130         if (data) return TRUE;
131     }
132     return FALSE;
133 }
134
135 gboolean cwmcc_prop_get_string_utf8(Window win, Atom prop, char **ret)
136 {
137     char *raw;
138     gulong num;
139      
140     if (get_all(win, prop, CWMCC_ATOM(type, utf8), 8, (guchar**)&raw, &num)) {
141         *ret = g_strdup(raw); /* grab the first string from the list */
142         g_free(raw);
143         return TRUE;
144     }
145     return FALSE;
146 }
147
148 gboolean cwmcc_prop_get_strings_utf8(Window win, Atom prop, char ***ret)
149 {
150     char *raw, *p;
151     gulong num, i;
152
153     if (get_all(win, prop, CWMCC_ATOM(type, utf8), 8, (guchar**)&raw, &num)) {
154         *ret = g_new(char*, num + 1);
155         (*ret)[num] = NULL; /* null terminated list */
156
157         p = raw;
158         for (i = 0; i < num; ++i) {
159             (*ret)[i] = g_strdup(p);
160             p = strchr(p, '\0');
161         }
162         g_free(raw);
163         return TRUE;
164     }
165     return FALSE;
166 }
167
168 gboolean cwmcc_prop_get_strings_locale(Window win, Atom prop, char ***ret)
169 {
170     char *raw, *p;
171     gulong num, i;
172
173     if (get_all(win, prop, CWMCC_ATOM(type, string), 8, (guchar**)&raw, &num)){
174         *ret = g_new(char*, num + 1);
175         (*ret)[num] = NULL; /* null terminated list */
176
177         p = raw;
178         for (i = 0; i < num; ++i) {
179             (*ret)[i] = g_locale_to_utf8(p, -1, NULL, NULL, NULL);
180             /* make sure translation did not fail */
181             if (!(*ret)[i]) {
182                 g_strfreev(*ret); /* free what we did so far */
183                 break; /* the force is not strong with us */
184             }
185             p = strchr(p, '\0');
186         }
187         g_free(raw);
188         if (i == num)
189             return TRUE;
190     }
191     return FALSE;
192 }
193
194 void cwmcc_prop_set32(Window win, Atom prop, Atom type, gulong val)
195 {
196     XChangeProperty(cwmcc_display, win, prop, type, 32, PropModeReplace,
197                     (guchar*)&val, 1);
198 }
199
200 void cwmcc_prop_set_array32(Window win, Atom prop, Atom type,
201                             gulong *val, gulong num)
202 {
203     XChangeProperty(cwmcc_display, win, prop, type, 32, PropModeReplace,
204                     (guchar*)val, num);
205 }
206
207 void cwmcc_prop_set_string_utf8(Window win, Atom prop, char *val)
208 {
209     XChangeProperty(cwmcc_display, win, prop, CWMCC_ATOM(type, utf8), 8,
210                     PropModeReplace, (guchar*)val, strlen(val));
211 }
212
213 void cwmcc_prop_set_strings_utf8(Window win, Atom prop, char **strs)
214 {
215     GString *str;
216     guint i;
217
218     str = g_string_sized_new(0);
219     for (i = 0; strs[i]; ++i) {
220         str = g_string_append(str, strs[i]);
221         str = g_string_append_c(str, '\0');
222     }
223     XChangeProperty(cwmcc_display, win, prop, CWMCC_ATOM(type, utf8), 8,
224                     PropModeReplace, (guchar*)str->str, str->len);
225 }
226
227 void cwmcc_prop_erase(Window win, Atom prop)
228 {
229     XDeleteProperty(cwmcc_display, win, prop);
230 }
231