]> Dogcows Code - chaz/openbox/blob - cwmcc/prop.c
proper cwmcc_ prefixing.
[chaz/openbox] / 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
This page took 0.04379 seconds and 5 git commands to generate.