xsettings-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,110 @@
1
+ /*
2
+ * Copyright � 2001 Red Hat, Inc.
3
+ *
4
+ * Permission to use, copy, modify, distribute, and sell this software and its
5
+ * documentation for any purpose is hereby granted without fee, provided that
6
+ * the above copyright notice appear in all copies and that both that
7
+ * copyright notice and this permission notice appear in supporting
8
+ * documentation, and that the name of Red Hat not be used in advertising or
9
+ * publicity pertaining to distribution of the software without specific,
10
+ * written prior permission. Red Hat makes no representations about the
11
+ * suitability of this software for any purpose. It is provided "as is"
12
+ * without express or implied warranty.
13
+ *
14
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
16
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
+ *
21
+ * Author: Owen Taylor, Red Hat, Inc.
22
+ */
23
+ #ifndef XSETTINGS_COMMON_H
24
+ #define XSETTINGS_COMMON_H
25
+
26
+ #ifdef __cplusplus
27
+ extern "C" {
28
+ #endif /* __cplusplus */
29
+
30
+ typedef struct _XSettingsBuffer XSettingsBuffer;
31
+ typedef struct _XSettingsColor XSettingsColor;
32
+ typedef struct _XSettingsList XSettingsList;
33
+ typedef struct _XSettingsSetting XSettingsSetting;
34
+
35
+ /* Types of settings possible. Enum values correspond to
36
+ * protocol values.
37
+ */
38
+ typedef enum
39
+ {
40
+ XSETTINGS_TYPE_INT = 0,
41
+ XSETTINGS_TYPE_STRING = 1,
42
+ XSETTINGS_TYPE_COLOR = 2
43
+ } XSettingsType;
44
+
45
+ typedef enum
46
+ {
47
+ XSETTINGS_SUCCESS,
48
+ XSETTINGS_NO_MEM,
49
+ XSETTINGS_ACCESS,
50
+ XSETTINGS_FAILED,
51
+ XSETTINGS_NO_ENTRY,
52
+ XSETTINGS_DUPLICATE_ENTRY
53
+ } XSettingsResult;
54
+
55
+ struct _XSettingsBuffer
56
+ {
57
+ char byte_order;
58
+ size_t len;
59
+ unsigned char *data;
60
+ unsigned char *pos;
61
+ };
62
+
63
+ struct _XSettingsColor
64
+ {
65
+ unsigned short red, green, blue, alpha;
66
+ };
67
+
68
+ struct _XSettingsList
69
+ {
70
+ XSettingsSetting *setting;
71
+ XSettingsList *next;
72
+ };
73
+
74
+ struct _XSettingsSetting
75
+ {
76
+ char *name;
77
+ XSettingsType type;
78
+
79
+ union {
80
+ int v_int;
81
+ char *v_string;
82
+ XSettingsColor v_color;
83
+ } data;
84
+
85
+ unsigned long last_change_serial;
86
+ };
87
+
88
+ XSettingsSetting *xsettings_setting_copy (XSettingsSetting *setting);
89
+ void xsettings_setting_free (XSettingsSetting *setting);
90
+ int xsettings_setting_equal (XSettingsSetting *setting_a,
91
+ XSettingsSetting *setting_b);
92
+
93
+ void xsettings_list_free (XSettingsList *list);
94
+ XSettingsList *xsettings_list_copy (XSettingsList *list);
95
+ XSettingsResult xsettings_list_insert (XSettingsList **list,
96
+ XSettingsSetting *setting);
97
+ XSettingsSetting *xsettings_list_lookup (XSettingsList *list,
98
+ const char *name);
99
+ XSettingsResult xsettings_list_delete (XSettingsList **list,
100
+ const char *name);
101
+
102
+ char xsettings_byte_order (void);
103
+
104
+ #define XSETTINGS_PAD(n,m) ((n + m - 1) & (~(m-1)))
105
+
106
+ #ifdef __cplusplus
107
+ }
108
+ #endif /* __cplusplus */
109
+
110
+ #endif /* XSETTINGS_COMMON_H */
@@ -0,0 +1,419 @@
1
+ /*
2
+ * Copyright � 2001 Red Hat, Inc.
3
+ *
4
+ * Permission to use, copy, modify, distribute, and sell this software and its
5
+ * documentation for any purpose is hereby granted without fee, provided that
6
+ * the above copyright notice appear in all copies and that both that
7
+ * copyright notice and this permission notice appear in supporting
8
+ * documentation, and that the name of Red Hat not be used in advertising or
9
+ * publicity pertaining to distribution of the software without specific,
10
+ * written prior permission. Red Hat makes no representations about the
11
+ * suitability of this software for any purpose. It is provided "as is"
12
+ * without express or implied warranty.
13
+ *
14
+ * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
15
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT
16
+ * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
17
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
18
+ * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
19
+ * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20
+ *
21
+ * Author: Owen Taylor, Red Hat, Inc.
22
+ */
23
+ #include <stdio.h>
24
+ #include <stdlib.h>
25
+ #include <string.h>
26
+
27
+ #include <X11/Xmd.h> /* For CARD16 */
28
+
29
+ #include "xsettings-manager.h"
30
+
31
+ struct _XSettingsManager
32
+ {
33
+ Display *display;
34
+ int screen;
35
+
36
+ Window window;
37
+ Atom manager_atom;
38
+ Atom selection_atom;
39
+ Atom xsettings_atom;
40
+
41
+ XSettingsTerminateFunc terminate;
42
+ void *cb_data;
43
+
44
+ XSettingsList *settings;
45
+ unsigned long serial;
46
+ };
47
+
48
+ XSettingsList *settings;
49
+
50
+ typedef struct
51
+ {
52
+ Window window;
53
+ Atom timestamp_prop_atom;
54
+ } TimeStampInfo;
55
+
56
+ static Bool
57
+ timestamp_predicate (Display *display,
58
+ XEvent *xevent,
59
+ XPointer arg)
60
+ {
61
+ TimeStampInfo *info = (TimeStampInfo *)arg;
62
+
63
+ if (xevent->type == PropertyNotify &&
64
+ xevent->xproperty.window == info->window &&
65
+ xevent->xproperty.atom == info->timestamp_prop_atom)
66
+ return True;
67
+
68
+ return False;
69
+ }
70
+
71
+ /**
72
+ * get_server_time:
73
+ * @display: display from which to get the time
74
+ * @window: a #Window, used for communication with the server.
75
+ * The window must have PropertyChangeMask in its
76
+ * events mask or a hang will result.
77
+ *
78
+ * Routine to get the current X server time stamp.
79
+ *
80
+ * Return value: the time stamp.
81
+ **/
82
+ static Time
83
+ get_server_time (Display *display,
84
+ Window window)
85
+ {
86
+ unsigned char c = 'a';
87
+ XEvent xevent;
88
+ TimeStampInfo info;
89
+
90
+ info.timestamp_prop_atom = XInternAtom (display, "_TIMESTAMP_PROP", False);
91
+ info.window = window;
92
+
93
+ XChangeProperty (display, window,
94
+ info.timestamp_prop_atom, info.timestamp_prop_atom,
95
+ 8, PropModeReplace, &c, 1);
96
+
97
+ XIfEvent (display, &xevent,
98
+ timestamp_predicate, (XPointer)&info);
99
+
100
+ return xevent.xproperty.time;
101
+ }
102
+
103
+ Bool
104
+ xsettings_manager_check_running (Display *display,
105
+ int screen)
106
+ {
107
+ char buffer[256];
108
+ Atom selection_atom;
109
+
110
+ sprintf(buffer, "_XSETTINGS_S%d", screen);
111
+ selection_atom = XInternAtom (display, buffer, False);
112
+
113
+ if (XGetSelectionOwner (display, selection_atom))
114
+ return True;
115
+ else
116
+ return False;
117
+ }
118
+
119
+ XSettingsManager *
120
+ xsettings_manager_new (Display *display,
121
+ int screen,
122
+ XSettingsTerminateFunc terminate,
123
+ void *cb_data)
124
+ {
125
+ XSettingsManager *manager;
126
+ Time timestamp;
127
+ XClientMessageEvent xev;
128
+
129
+ char buffer[256];
130
+
131
+ manager = malloc (sizeof *manager);
132
+ if (!manager)
133
+ return NULL;
134
+
135
+ manager->display = display;
136
+ manager->screen = screen;
137
+
138
+ sprintf(buffer, "_XSETTINGS_S%d", screen);
139
+ manager->selection_atom = XInternAtom (display, buffer, False);
140
+ manager->xsettings_atom = XInternAtom (display, "_XSETTINGS_SETTINGS", False);
141
+ manager->manager_atom = XInternAtom (display, "MANAGER", False);
142
+
143
+ manager->terminate = terminate;
144
+ manager->cb_data = cb_data;
145
+
146
+ manager->settings = NULL;
147
+ manager->serial = 0;
148
+
149
+ manager->window = XCreateSimpleWindow (display,
150
+ RootWindow (display, screen),
151
+ 0, 0, 10, 10, 0,
152
+ WhitePixel (display, screen),
153
+ WhitePixel (display, screen));
154
+
155
+ XSelectInput (display, manager->window, PropertyChangeMask);
156
+ timestamp = get_server_time (display, manager->window);
157
+
158
+ XSetSelectionOwner (display, manager->selection_atom,
159
+ manager->window, timestamp);
160
+
161
+ /* Check to see if we managed to claim the selection. If not,
162
+ * we treat it as if we got it then immediately lost it
163
+ */
164
+
165
+ if (XGetSelectionOwner (display, manager->selection_atom) ==
166
+ manager->window)
167
+ {
168
+ xev.type = ClientMessage;
169
+ xev.window = RootWindow (display, screen);
170
+ xev.message_type = manager->manager_atom;
171
+ xev.format = 32;
172
+ xev.data.l[0] = timestamp;
173
+ xev.data.l[1] = manager->selection_atom;
174
+ xev.data.l[2] = manager->window;
175
+ xev.data.l[3] = 0; /* manager specific data */
176
+ xev.data.l[4] = 0; /* manager specific data */
177
+
178
+ XSendEvent (display, RootWindow (display, screen),
179
+ False, StructureNotifyMask, (XEvent *)&xev);
180
+ }
181
+ else
182
+ {
183
+ manager->terminate (manager->cb_data);
184
+ }
185
+
186
+ return manager;
187
+ }
188
+
189
+ void
190
+ xsettings_manager_destroy (XSettingsManager *manager)
191
+ {
192
+ XDestroyWindow (manager->display, manager->window);
193
+
194
+ xsettings_list_free (manager->settings);
195
+ free (manager);
196
+ }
197
+
198
+ Window
199
+ xsettings_manager_get_window (XSettingsManager *manager)
200
+ {
201
+ return manager->window;
202
+ }
203
+
204
+ Bool
205
+ xsettings_manager_process_event (XSettingsManager *manager,
206
+ XEvent *xev)
207
+ {
208
+ if (xev->xany.window == manager->window &&
209
+ xev->xany.type == SelectionClear &&
210
+ xev->xselectionclear.selection == manager->selection_atom)
211
+ {
212
+ manager->terminate (manager->cb_data);
213
+ return True;
214
+ }
215
+
216
+ return False;
217
+ }
218
+
219
+ XSettingsResult
220
+ xsettings_manager_set_setting (XSettingsManager *manager,
221
+ XSettingsSetting *setting)
222
+ {
223
+ XSettingsSetting *old_setting = xsettings_list_lookup (settings, setting->name);
224
+ XSettingsSetting *new_setting;
225
+ XSettingsResult result;
226
+
227
+ if (old_setting)
228
+ {
229
+ if (xsettings_setting_equal (old_setting, setting))
230
+ return XSETTINGS_SUCCESS;
231
+
232
+ xsettings_list_delete (&settings, setting->name);
233
+ }
234
+
235
+ new_setting = xsettings_setting_copy (setting);
236
+ if (!new_setting)
237
+ return XSETTINGS_NO_MEM;
238
+
239
+ new_setting->last_change_serial = manager->serial;
240
+
241
+ result = xsettings_list_insert (&settings, new_setting);
242
+
243
+ if (result != XSETTINGS_SUCCESS)
244
+ xsettings_setting_free (new_setting);
245
+
246
+ return result;
247
+ }
248
+
249
+ XSettingsResult
250
+ xsettings_manager_set_int (XSettingsManager *manager,
251
+ const char *name,
252
+ int value)
253
+ {
254
+ XSettingsSetting setting;
255
+
256
+ setting.name = (char *)name;
257
+ setting.type = XSETTINGS_TYPE_INT;
258
+ setting.data.v_int = value;
259
+
260
+ return xsettings_manager_set_setting (manager, &setting);
261
+ }
262
+
263
+ XSettingsResult
264
+ xsettings_manager_set_string (XSettingsManager *manager,
265
+ const char *name,
266
+ const char *value)
267
+ {
268
+ XSettingsSetting setting;
269
+
270
+ setting.name = (char *)name;
271
+ setting.type = XSETTINGS_TYPE_STRING;
272
+ setting.data.v_string = (char *)value;
273
+
274
+ return xsettings_manager_set_setting (manager, &setting);
275
+ }
276
+
277
+ XSettingsResult
278
+ xsettings_manager_set_color (XSettingsManager *manager,
279
+ const char *name,
280
+ XSettingsColor *value)
281
+ {
282
+ XSettingsSetting setting;
283
+
284
+ setting.name = (char *)name;
285
+ setting.type = XSETTINGS_TYPE_COLOR;
286
+ setting.data.v_color = *value;
287
+
288
+ return xsettings_manager_set_setting (manager, &setting);
289
+ }
290
+
291
+ static size_t
292
+ setting_length (XSettingsSetting *setting)
293
+ {
294
+ size_t length = 8; /* type + pad + name-len + last-change-serial */
295
+ length += XSETTINGS_PAD (strlen (setting->name), 4);
296
+
297
+ switch (setting->type)
298
+ {
299
+ case XSETTINGS_TYPE_INT:
300
+ length += 4;
301
+ break;
302
+ case XSETTINGS_TYPE_STRING:
303
+ length += 4 + XSETTINGS_PAD (strlen (setting->data.v_string), 4);
304
+ break;
305
+ case XSETTINGS_TYPE_COLOR:
306
+ length += 8;
307
+ break;
308
+ }
309
+
310
+ return length;
311
+ }
312
+
313
+ /* Serialize setting into buffer (which must be large enough) */
314
+ static void
315
+ setting_store (XSettingsSetting *setting,
316
+ XSettingsBuffer *buffer)
317
+ {
318
+ size_t string_len;
319
+ size_t length;
320
+
321
+ *(buffer->pos++) = setting->type;
322
+ *(buffer->pos++) = 0;
323
+
324
+ string_len = strlen (setting->name);
325
+ *(CARD16 *)(buffer->pos) = string_len;
326
+ buffer->pos += 2;
327
+
328
+ length = XSETTINGS_PAD (string_len, 4);
329
+ memcpy (buffer->pos, setting->name, string_len);
330
+ length -= string_len;
331
+ buffer->pos += string_len;
332
+
333
+ while (length > 0)
334
+ {
335
+ *(buffer->pos++) = 0;
336
+ length--;
337
+ }
338
+
339
+ *(CARD32 *)(buffer->pos) = setting->last_change_serial;
340
+ buffer->pos += 4;
341
+
342
+ switch (setting->type)
343
+ {
344
+ case XSETTINGS_TYPE_INT:
345
+ *(CARD32 *)(buffer->pos) = setting->data.v_int;
346
+ buffer->pos += 4;
347
+ break;
348
+ case XSETTINGS_TYPE_STRING:
349
+ string_len = strlen (setting->data.v_string);
350
+ *(CARD32 *)(buffer->pos) = string_len;
351
+ buffer->pos += 4;
352
+
353
+ length = XSETTINGS_PAD (string_len, 4);
354
+ memcpy (buffer->pos, setting->data.v_string, string_len);
355
+ length -= string_len;
356
+ buffer->pos += string_len;
357
+
358
+ while (length > 0)
359
+ {
360
+ *(buffer->pos++) = 0;
361
+ length--;
362
+ }
363
+ break;
364
+ case XSETTINGS_TYPE_COLOR:
365
+ *(CARD16 *)(buffer->pos) = setting->data.v_color.red;
366
+ *(CARD16 *)(buffer->pos + 2) = setting->data.v_color.green;
367
+ *(CARD16 *)(buffer->pos + 4) = setting->data.v_color.blue;
368
+ *(CARD16 *)(buffer->pos + 6) = setting->data.v_color.alpha;
369
+ buffer->pos += 8;
370
+ break;
371
+ }
372
+ }
373
+
374
+ /* Serialize current settings and write property */
375
+ XSettingsResult
376
+ xsettings_manager_notify (XSettingsManager *manager)
377
+ {
378
+ XSettingsBuffer buffer;
379
+ XSettingsList *iter;
380
+ int n_settings = 0;
381
+
382
+ buffer.len = 12; /* byte-order + pad + SERIAL + N_SETTINGS */
383
+
384
+ iter = settings;
385
+ while (iter)
386
+ {
387
+ buffer.len += setting_length (iter->setting);
388
+ n_settings++;
389
+ iter = iter->next;
390
+ }
391
+
392
+ buffer.data = buffer.pos = malloc (buffer.len);
393
+ if (!buffer.data)
394
+ return XSETTINGS_NO_MEM;
395
+
396
+ *buffer.pos = xsettings_byte_order ();
397
+
398
+ buffer.pos += 4;
399
+ *(CARD32 *)buffer.pos = manager->serial++;
400
+ buffer.pos += 4;
401
+ *(CARD32 *)buffer.pos = n_settings;
402
+ buffer.pos += 4;
403
+
404
+ iter = settings;
405
+ while (iter)
406
+ {
407
+ setting_store (iter->setting, &buffer);
408
+ iter = iter->next;
409
+ }
410
+
411
+ XChangeProperty (manager->display, manager->window,
412
+ manager->xsettings_atom, manager->xsettings_atom,
413
+ 8, PropModeReplace, buffer.data, buffer.len);
414
+
415
+ free (buffer.data);
416
+
417
+ return XSETTINGS_SUCCESS;
418
+ }
419
+