xsettings-ruby 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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
+