~seb128/unity-settings-daemon/battery-info-key

« back to all changes in this revision

Viewing changes to plugins/xsettings/xsettings-manager.c

  • Committer: William Jon McCann
  • Author(s): William Jon McCann
  • Date: 2007-12-14 05:06:55 UTC
  • Revision ID: git-v1:b7f5d9895c19338f10b0bdd494b221b13b540d9d
Initial checkin. Previously lived in gdm module.

2007-12-14  William Jon McCann  <mccann@jhu.edu>

        * configure.ac, etc: Initial checkin.  Previously
        lived in gdm module.


svn path=/trunk/; revision=2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
static 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_delete_setting (XSettingsManager *manager,
 
221
                                  const char       *name)
 
222
{
 
223
  return xsettings_list_delete (&settings, name);
 
224
}
 
225
 
 
226
XSettingsResult
 
227
xsettings_manager_set_setting (XSettingsManager *manager,
 
228
                               XSettingsSetting *setting)
 
229
{
 
230
  XSettingsSetting *old_setting = xsettings_list_lookup (settings, setting->name);
 
231
  XSettingsSetting *new_setting;
 
232
  XSettingsResult result;
 
233
 
 
234
  if (old_setting)
 
235
    {
 
236
      if (xsettings_setting_equal (old_setting, setting))
 
237
        return XSETTINGS_SUCCESS;
 
238
 
 
239
      xsettings_list_delete (&settings, setting->name);
 
240
    }
 
241
 
 
242
  new_setting = xsettings_setting_copy (setting);
 
243
  if (!new_setting)
 
244
    return XSETTINGS_NO_MEM;
 
245
  
 
246
  new_setting->last_change_serial = manager->serial;
 
247
  
 
248
  result = xsettings_list_insert (&settings, new_setting);
 
249
  
 
250
  if (result != XSETTINGS_SUCCESS)
 
251
    xsettings_setting_free (new_setting);
 
252
 
 
253
  return result;
 
254
}
 
255
 
 
256
XSettingsResult
 
257
xsettings_manager_set_int (XSettingsManager *manager,
 
258
                           const char       *name,
 
259
                           int               value)
 
260
{
 
261
  XSettingsSetting setting;
 
262
 
 
263
  setting.name = (char *)name;
 
264
  setting.type = XSETTINGS_TYPE_INT;
 
265
  setting.data.v_int = value;
 
266
 
 
267
  return xsettings_manager_set_setting (manager, &setting);
 
268
}
 
269
 
 
270
XSettingsResult
 
271
xsettings_manager_set_string (XSettingsManager *manager,
 
272
                              const char       *name,
 
273
                              const char       *value)
 
274
{
 
275
  XSettingsSetting setting;
 
276
 
 
277
  setting.name = (char *)name;
 
278
  setting.type = XSETTINGS_TYPE_STRING;
 
279
  setting.data.v_string = (char *)value;
 
280
 
 
281
  return xsettings_manager_set_setting (manager, &setting);
 
282
}
 
283
 
 
284
XSettingsResult
 
285
xsettings_manager_set_color (XSettingsManager *manager,
 
286
                             const char       *name,
 
287
                             XSettingsColor   *value)
 
288
{
 
289
  XSettingsSetting setting;
 
290
 
 
291
  setting.name = (char *)name;
 
292
  setting.type = XSETTINGS_TYPE_COLOR;
 
293
  setting.data.v_color = *value;
 
294
 
 
295
  return xsettings_manager_set_setting (manager, &setting);
 
296
}
 
297
 
 
298
static size_t
 
299
setting_length (XSettingsSetting *setting)
 
300
{
 
301
  size_t length = 8;    /* type + pad + name-len + last-change-serial */
 
302
  length += XSETTINGS_PAD (strlen (setting->name), 4);
 
303
 
 
304
  switch (setting->type)
 
305
    {
 
306
    case XSETTINGS_TYPE_INT:
 
307
      length += 4;
 
308
      break;
 
309
    case XSETTINGS_TYPE_STRING:
 
310
      length += 4 + XSETTINGS_PAD (strlen (setting->data.v_string), 4);
 
311
      break;
 
312
    case XSETTINGS_TYPE_COLOR:
 
313
      length += 8;
 
314
      break;
 
315
    }
 
316
 
 
317
  return length;
 
318
}
 
319
 
 
320
static void
 
321
setting_store (XSettingsSetting *setting,
 
322
               XSettingsBuffer *buffer)
 
323
{
 
324
  size_t string_len;
 
325
  size_t length;
 
326
 
 
327
  *(buffer->pos++) = setting->type;
 
328
  *(buffer->pos++) = 0;
 
329
 
 
330
  string_len = strlen (setting->name);
 
331
  *(CARD16 *)(buffer->pos) = string_len;
 
332
  buffer->pos += 2;
 
333
 
 
334
  length = XSETTINGS_PAD (string_len, 4);
 
335
  memcpy (buffer->pos, setting->name, string_len);
 
336
  length -= string_len;
 
337
  buffer->pos += string_len;
 
338
  
 
339
  while (length > 0)
 
340
    {
 
341
      *(buffer->pos++) = 0;
 
342
      length--;
 
343
    }
 
344
 
 
345
  *(CARD32 *)(buffer->pos) = setting->last_change_serial;
 
346
  buffer->pos += 4;
 
347
 
 
348
  switch (setting->type)
 
349
    {
 
350
    case XSETTINGS_TYPE_INT:
 
351
      *(CARD32 *)(buffer->pos) = setting->data.v_int;
 
352
      buffer->pos += 4;
 
353
      break;
 
354
    case XSETTINGS_TYPE_STRING:
 
355
      string_len = strlen (setting->data.v_string);
 
356
      *(CARD32 *)(buffer->pos) = string_len;
 
357
      buffer->pos += 4;
 
358
      
 
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;
 
363
      
 
364
      while (length > 0)
 
365
        {
 
366
          *(buffer->pos++) = 0;
 
367
          length--;
 
368
        }
 
369
      break;
 
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;
 
375
      buffer->pos += 8;
 
376
      break;
 
377
    }
 
378
}
 
379
 
 
380
XSettingsResult
 
381
xsettings_manager_notify (XSettingsManager *manager)
 
382
{
 
383
  XSettingsBuffer buffer;
 
384
  XSettingsList *iter;
 
385
  int n_settings = 0;
 
386
 
 
387
  buffer.len = 12;              /* byte-order + pad + SERIAL + N_SETTINGS */
 
388
 
 
389
  iter = settings;
 
390
  while (iter)
 
391
    {
 
392
      buffer.len += setting_length (iter->setting);
 
393
      n_settings++;
 
394
      iter = iter->next;
 
395
    }
 
396
 
 
397
  buffer.data = buffer.pos = malloc (buffer.len);
 
398
  if (!buffer.data)
 
399
    return XSETTINGS_NO_MEM;
 
400
 
 
401
  *buffer.pos = xsettings_byte_order ();
 
402
 
 
403
  buffer.pos += 4;
 
404
  *(CARD32 *)buffer.pos = manager->serial++;
 
405
  buffer.pos += 4;
 
406
  *(CARD32 *)buffer.pos = n_settings;
 
407
  buffer.pos += 4;
 
408
 
 
409
  iter = settings;
 
410
  while (iter)
 
411
    {
 
412
      setting_store (iter->setting, &buffer);
 
413
      iter = iter->next;
 
414
    }
 
415
 
 
416
  XChangeProperty (manager->display, manager->window,
 
417
                   manager->xsettings_atom, manager->xsettings_atom,
 
418
                   8, PropModeReplace, buffer.data, buffer.len);
 
419
 
 
420
  free (buffer.data);
 
421
 
 
422
  return XSETTINGS_SUCCESS;
 
423
}
 
424