2
* Copyright © 2001 Red Hat, Inc.
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.
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.
21
* Author: Owen Taylor, Red Hat, Inc.
27
#include <X11/Xmd.h> /* For CARD16 */
29
#include "xsettings-manager.h"
31
struct _XSettingsManager
41
XSettingsTerminateFunc terminate;
44
XSettingsList *settings;
48
static XSettingsList *settings;
53
Atom timestamp_prop_atom;
57
timestamp_predicate (Display *display,
61
TimeStampInfo *info = (TimeStampInfo *)arg;
63
if (xevent->type == PropertyNotify &&
64
xevent->xproperty.window == info->window &&
65
xevent->xproperty.atom == info->timestamp_prop_atom)
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.
78
* Routine to get the current X server time stamp.
80
* Return value: the time stamp.
83
get_server_time (Display *display,
86
unsigned char c = 'a';
90
info.timestamp_prop_atom = XInternAtom (display, "_TIMESTAMP_PROP", False);
93
XChangeProperty (display, window,
94
info.timestamp_prop_atom, info.timestamp_prop_atom,
95
8, PropModeReplace, &c, 1);
97
XIfEvent (display, &xevent,
98
timestamp_predicate, (XPointer)&info);
100
return xevent.xproperty.time;
104
xsettings_manager_check_running (Display *display,
110
sprintf(buffer, "_XSETTINGS_S%d", screen);
111
selection_atom = XInternAtom (display, buffer, False);
113
if (XGetSelectionOwner (display, selection_atom))
120
xsettings_manager_new (Display *display,
122
XSettingsTerminateFunc terminate,
125
XSettingsManager *manager;
127
XClientMessageEvent xev;
131
manager = malloc (sizeof *manager);
135
manager->display = display;
136
manager->screen = screen;
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);
143
manager->terminate = terminate;
144
manager->cb_data = cb_data;
146
manager->settings = NULL;
149
manager->window = XCreateSimpleWindow (display,
150
RootWindow (display, screen),
152
WhitePixel (display, screen),
153
WhitePixel (display, screen));
155
XSelectInput (display, manager->window, PropertyChangeMask);
156
timestamp = get_server_time (display, manager->window);
158
XSetSelectionOwner (display, manager->selection_atom,
159
manager->window, timestamp);
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
165
if (XGetSelectionOwner (display, manager->selection_atom) ==
168
xev.type = ClientMessage;
169
xev.window = RootWindow (display, screen);
170
xev.message_type = manager->manager_atom;
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 */
178
XSendEvent (display, RootWindow (display, screen),
179
False, StructureNotifyMask, (XEvent *)&xev);
183
manager->terminate (manager->cb_data);
190
xsettings_manager_destroy (XSettingsManager *manager)
192
XDestroyWindow (manager->display, manager->window);
194
xsettings_list_free (manager->settings);
199
xsettings_manager_get_window (XSettingsManager *manager)
201
return manager->window;
205
xsettings_manager_process_event (XSettingsManager *manager,
208
if (xev->xany.window == manager->window &&
209
xev->xany.type == SelectionClear &&
210
xev->xselectionclear.selection == manager->selection_atom)
212
manager->terminate (manager->cb_data);
220
xsettings_manager_delete_setting (XSettingsManager *manager,
223
return xsettings_list_delete (&settings, name);
227
xsettings_manager_set_setting (XSettingsManager *manager,
228
XSettingsSetting *setting)
230
XSettingsSetting *old_setting = xsettings_list_lookup (settings, setting->name);
231
XSettingsSetting *new_setting;
232
XSettingsResult result;
236
if (xsettings_setting_equal (old_setting, setting))
237
return XSETTINGS_SUCCESS;
239
xsettings_list_delete (&settings, setting->name);
242
new_setting = xsettings_setting_copy (setting);
244
return XSETTINGS_NO_MEM;
246
new_setting->last_change_serial = manager->serial;
248
result = xsettings_list_insert (&settings, new_setting);
250
if (result != XSETTINGS_SUCCESS)
251
xsettings_setting_free (new_setting);
257
xsettings_manager_set_int (XSettingsManager *manager,
261
XSettingsSetting setting;
263
setting.name = (char *)name;
264
setting.type = XSETTINGS_TYPE_INT;
265
setting.data.v_int = value;
267
return xsettings_manager_set_setting (manager, &setting);
271
xsettings_manager_set_string (XSettingsManager *manager,
275
XSettingsSetting setting;
277
setting.name = (char *)name;
278
setting.type = XSETTINGS_TYPE_STRING;
279
setting.data.v_string = (char *)value;
281
return xsettings_manager_set_setting (manager, &setting);
285
xsettings_manager_set_color (XSettingsManager *manager,
287
XSettingsColor *value)
289
XSettingsSetting setting;
291
setting.name = (char *)name;
292
setting.type = XSETTINGS_TYPE_COLOR;
293
setting.data.v_color = *value;
295
return xsettings_manager_set_setting (manager, &setting);
299
setting_length (XSettingsSetting *setting)
301
size_t length = 8; /* type + pad + name-len + last-change-serial */
302
length += XSETTINGS_PAD (strlen (setting->name), 4);
304
switch (setting->type)
306
case XSETTINGS_TYPE_INT:
309
case XSETTINGS_TYPE_STRING:
310
length += 4 + XSETTINGS_PAD (strlen (setting->data.v_string), 4);
312
case XSETTINGS_TYPE_COLOR:
321
setting_store (XSettingsSetting *setting,
322
XSettingsBuffer *buffer)
327
*(buffer->pos++) = setting->type;
328
*(buffer->pos++) = 0;
330
string_len = strlen (setting->name);
331
*(CARD16 *)(buffer->pos) = string_len;
334
length = XSETTINGS_PAD (string_len, 4);
335
memcpy (buffer->pos, setting->name, string_len);
336
length -= string_len;
337
buffer->pos += string_len;
341
*(buffer->pos++) = 0;
345
*(CARD32 *)(buffer->pos) = setting->last_change_serial;
348
switch (setting->type)
350
case XSETTINGS_TYPE_INT:
351
*(CARD32 *)(buffer->pos) = setting->data.v_int;
354
case XSETTINGS_TYPE_STRING:
355
string_len = strlen (setting->data.v_string);
356
*(CARD32 *)(buffer->pos) = string_len;
359
length = XSETTINGS_PAD (string_len, 4);
360
memcpy (buffer->pos, setting->data.v_string, string_len);
361
length -= string_len;
362
buffer->pos += string_len;
366
*(buffer->pos++) = 0;
370
case XSETTINGS_TYPE_COLOR:
371
*(CARD16 *)(buffer->pos) = setting->data.v_color.red;
372
*(CARD16 *)(buffer->pos + 2) = setting->data.v_color.green;
373
*(CARD16 *)(buffer->pos + 4) = setting->data.v_color.blue;
374
*(CARD16 *)(buffer->pos + 6) = setting->data.v_color.alpha;
381
xsettings_manager_notify (XSettingsManager *manager)
383
XSettingsBuffer buffer;
387
buffer.len = 12; /* byte-order + pad + SERIAL + N_SETTINGS */
392
buffer.len += setting_length (iter->setting);
397
buffer.data = buffer.pos = malloc (buffer.len);
399
return XSETTINGS_NO_MEM;
401
*buffer.pos = xsettings_byte_order ();
404
*(CARD32 *)buffer.pos = manager->serial++;
406
*(CARD32 *)buffer.pos = n_settings;
412
setting_store (iter->setting, &buffer);
416
XChangeProperty (manager->display, manager->window,
417
manager->xsettings_atom, manager->xsettings_atom,
418
8, PropModeReplace, buffer.data, buffer.len);
422
return XSETTINGS_SUCCESS;