~alan-griffiths/compiz-core/Bug-931283

« back to all changes in this revision

Viewing changes to plugins/gconf.c

  • Committer: David Reveman
  • Date: 2006-02-09 06:03:09 UTC
  • Revision ID: git-v1:9959c2b13ded64a5e66359a8097250dc9d87fc1c
Initial revision

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2005 Novell, Inc.
 
3
 *
 
4
 * Permission to use, copy, modify, distribute, and sell this software
 
5
 * and its documentation for any purpose is hereby granted without
 
6
 * fee, provided that the above copyright notice appear in all copies
 
7
 * and that both that copyright notice and this permission notice
 
8
 * appear in supporting documentation, and that the name of
 
9
 * Novell, Inc. not be used in advertising or publicity pertaining to
 
10
 * distribution of the software without specific, written prior permission.
 
11
 * Novell, Inc. makes no representations about the suitability of this
 
12
 * software for any purpose. It is provided "as is" without express or
 
13
 * implied warranty.
 
14
 *
 
15
 * NOVELL, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 
16
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN
 
17
 * NO EVENT SHALL NOVELL, INC. BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 
18
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
 
19
 * OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
 
20
 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
 
21
 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
22
 *
 
23
 * Author: David Reveman <davidr@novell.com>
 
24
 */
 
25
 
 
26
#define _GNU_SOURCE
 
27
#include <string.h>
 
28
#include <stdio.h>
 
29
#include <stdlib.h>
 
30
#include <ctype.h>
 
31
 
 
32
#include <glib.h>
 
33
#include <glib/gprintf.h>
 
34
#include <gconf/gconf-client.h>
 
35
 
 
36
#include <compiz.h>
 
37
 
 
38
#define APP_NAME "/apps/compiz"
 
39
#define KEY_CHANGE_TIMEOUT 250
 
40
 
 
41
struct _GConfModifier {
 
42
    char *name;
 
43
    int  modifier;
 
44
} modifiers[] = {
 
45
    { "<Shift>",      ShiftMask          },
 
46
    { "<Control>",    ControlMask        },
 
47
    { "<Mod1>",       Mod1Mask           },
 
48
    { "<Mod2>",       Mod2Mask           },
 
49
    { "<Mod3>",       Mod3Mask           },
 
50
    { "<Mod4>",       Mod4Mask           },
 
51
    { "<Mod5>",       Mod5Mask           },
 
52
    { "<Alt>",        CompAltMask        },
 
53
    { "<Meta>",       CompMetaMask       },
 
54
    { "<Super>",      CompSuperMask      },
 
55
    { "<Hyper>",      CompHyperMask      },
 
56
    { "<ModeSwitch>", CompModeSwitchMask },
 
57
    { "<Release>",    CompReleaseMask    }
 
58
};
 
59
 
 
60
#define N_MODIFIERS (sizeof (modifiers) / sizeof (struct _GConfModifier))
 
61
 
 
62
static int displayPrivateIndex;
 
63
 
 
64
typedef struct _GConfDisplay {
 
65
    int screenPrivateIndex;
 
66
 
 
67
    GConfClient       *client;
 
68
    CompTimeoutHandle timeoutHandle;
 
69
 
 
70
    InitPluginForDisplayProc      initPluginForDisplay;
 
71
    SetDisplayOptionProc          setDisplayOption;
 
72
    SetDisplayOptionForPluginProc setDisplayOptionForPlugin;
 
73
} GConfDisplay;
 
74
 
 
75
typedef struct _GConfScreen {
 
76
    InitPluginForScreenProc      initPluginForScreen;
 
77
    SetScreenOptionProc          setScreenOption;
 
78
    SetScreenOptionForPluginProc setScreenOptionForPlugin;
 
79
} GConfScreen;
 
80
 
 
81
#define GET_GCONF_DISPLAY(d)                                  \
 
82
    ((GConfDisplay *) (d)->privates[displayPrivateIndex].ptr)
 
83
 
 
84
#define GCONF_DISPLAY(d)                     \
 
85
    GConfDisplay *gd = GET_GCONF_DISPLAY (d)
 
86
 
 
87
#define GET_GCONF_SCREEN(s, gd)                                  \
 
88
    ((GConfScreen *) (s)->privates[(gd)->screenPrivateIndex].ptr)
 
89
 
 
90
#define GCONF_SCREEN(s)                                                    \
 
91
    GConfScreen *gs = GET_GCONF_SCREEN (s, GET_GCONF_DISPLAY (s->display))
 
92
 
 
93
static int
 
94
strcmpskipifequal (char **ptr, char *s)
 
95
{
 
96
    int ret, len;
 
97
 
 
98
    len = strlen (s);
 
99
    ret = strncmp (*ptr, s, len);
 
100
    if (ret == 0)
 
101
        *ptr = (*ptr) + len;
 
102
 
 
103
    return ret;
 
104
}
 
105
 
 
106
static GConfValueType
 
107
gconfTypeFromCompType (CompOptionType type)
 
108
{
 
109
    switch (type) {
 
110
    case CompOptionTypeBool:
 
111
        return GCONF_VALUE_BOOL;
 
112
    case CompOptionTypeInt:
 
113
        return GCONF_VALUE_INT;
 
114
    case CompOptionTypeFloat:
 
115
        return GCONF_VALUE_FLOAT;
 
116
    case CompOptionTypeString:
 
117
        return GCONF_VALUE_STRING;
 
118
    case CompOptionTypeColor:
 
119
        return GCONF_VALUE_STRING;
 
120
    case CompOptionTypeBinding:
 
121
        return GCONF_VALUE_STRING;
 
122
    case CompOptionTypeList:
 
123
        return GCONF_VALUE_LIST;
 
124
    default:
 
125
        break;
 
126
    }
 
127
 
 
128
    return GCONF_VALUE_INVALID;
 
129
}
 
130
 
 
131
static void
 
132
gconfSetValue (CompDisplay     *d,
 
133
               CompOptionValue *value,
 
134
               CompOptionType  type,
 
135
               GConfValue      *gvalue)
 
136
{
 
137
    switch (type) {
 
138
    case CompOptionTypeBool:
 
139
        gconf_value_set_bool (gvalue, value->b);
 
140
        break;
 
141
    case CompOptionTypeInt:
 
142
        gconf_value_set_int (gvalue, value->i);
 
143
        break;
 
144
    case CompOptionTypeFloat:
 
145
        gconf_value_set_float (gvalue, value->f);
 
146
        break;
 
147
    case CompOptionTypeString:
 
148
        gconf_value_set_string (gvalue, value->s);
 
149
        break;
 
150
    case CompOptionTypeColor: {
 
151
        gchar *color;
 
152
 
 
153
        color = g_strdup_printf ("#%.2x%.2x%.2x",
 
154
                                 value->c[0] / 256,
 
155
                                 value->c[1] / 256,
 
156
                                 value->c[2] / 256);
 
157
 
 
158
        gconf_value_set_string (gvalue, color);
 
159
 
 
160
        g_free (color);
 
161
    } break;
 
162
    case CompOptionTypeBinding: {
 
163
        guint modMask;
 
164
 
 
165
        if (value->bind.type == CompBindingTypeButton)
 
166
            modMask = value->bind.u.button.modifiers;
 
167
        else
 
168
            modMask = value->bind.u.key.modifiers;
 
169
 
 
170
        if (modMask & (CompPressMask | CompReleaseMask))
 
171
        {
 
172
            gchar *m, *mods = g_strdup ("");
 
173
            gchar *binding;
 
174
            gint  i;
 
175
 
 
176
            for (i = 0; i < N_MODIFIERS; i++)
 
177
            {
 
178
                if (modMask & modifiers[i].modifier)
 
179
                {
 
180
                    m = g_strconcat (mods, modifiers[i].name, NULL);
 
181
                    if (m)
 
182
                    {
 
183
                        free (mods);
 
184
                        mods = m;
 
185
                    }
 
186
                }
 
187
            }
 
188
 
 
189
            if (value->bind.type == CompBindingTypeButton)
 
190
            {
 
191
                binding = g_strdup_printf ("%sButton%d", mods,
 
192
                                           value->bind.u.button.button);
 
193
            }
 
194
            else
 
195
            {
 
196
                KeySym keysym;
 
197
                gchar  *keyname;
 
198
 
 
199
                keysym = XKeycodeToKeysym (d->display,
 
200
                                           value->bind.u.key.keycode,
 
201
                                           0);
 
202
                keyname = XKeysymToString (keysym);
 
203
 
 
204
                if (keyname)
 
205
                    binding = g_strdup_printf ("%s%s", mods, keyname);
 
206
                else
 
207
                    binding = g_strdup_printf ("%s0x%x", mods,
 
208
                                               value->bind.u.key.keycode);
 
209
 
 
210
            }
 
211
 
 
212
            gconf_value_set_string (gvalue, binding);
 
213
 
 
214
            g_free (binding);
 
215
            g_free (mods);
 
216
        }
 
217
        else
 
218
        {
 
219
            gconf_value_set_string (gvalue, "Disabled");
 
220
        }
 
221
    } break;
 
222
    default:
 
223
        break;
 
224
    }
 
225
}
 
226
 
 
227
static void
 
228
gconfSetOption (CompDisplay *d,
 
229
                CompOption  *o,
 
230
                gchar       *screen,
 
231
                gchar       *plugin)
 
232
{
 
233
    GConfValue *gvalue;
 
234
    gchar      *key;
 
235
 
 
236
    GCONF_DISPLAY (d);
 
237
 
 
238
    if (plugin)
 
239
    {
 
240
        key = g_strjoin ("/", APP_NAME "/plugins", plugin, screen, "options",
 
241
                         o->name, NULL);
 
242
    }
 
243
    else
 
244
    {
 
245
        key = g_strjoin ("/", APP_NAME "/general", screen, "options", o->name,
 
246
                         NULL);
 
247
    }
 
248
 
 
249
    switch (o->type) {
 
250
    case CompOptionTypeBool:
 
251
    case CompOptionTypeInt:
 
252
    case CompOptionTypeFloat:
 
253
    case CompOptionTypeString:
 
254
    case CompOptionTypeColor:
 
255
    case CompOptionTypeBinding:
 
256
        gvalue = gconf_value_new (gconfTypeFromCompType (o->type));
 
257
        gconfSetValue (d, &o->value, o->type, gvalue);
 
258
        gconf_client_set (gd->client, key, gvalue, NULL);
 
259
        gconf_value_free (gvalue);
 
260
        break;
 
261
    case CompOptionTypeList: {
 
262
        GConfValueType type;
 
263
        GSList         *list = NULL;
 
264
        GConfValue     *gv;
 
265
        int            i;
 
266
 
 
267
        gvalue = gconf_value_new (GCONF_VALUE_LIST);
 
268
 
 
269
        type = gconfTypeFromCompType (o->value.list.type);
 
270
 
 
271
        for (i = 0; i < o->value.list.nValue; i++)
 
272
        {
 
273
            gv = gconf_value_new (type);
 
274
            gconfSetValue (d, &o->value.list.value[i], o->value.list.type, gv);
 
275
            list = g_slist_append (list, gv);
 
276
        }
 
277
 
 
278
        gconf_value_set_list_type (gvalue, type);
 
279
        gconf_value_set_list (gvalue, list);
 
280
        gconf_client_set (gd->client, key, gvalue, NULL);
 
281
 
 
282
        for (i = 0; i < o->value.list.nValue; i++)
 
283
        {
 
284
            gv = g_slist_nth_data (list, i);
 
285
            gconf_value_free (gv);
 
286
        }
 
287
        g_slist_free (list);
 
288
        gconf_value_free (gvalue);
 
289
    } break;
 
290
    default:
 
291
        break;
 
292
    }
 
293
 
 
294
    g_free (key);
 
295
}
 
296
 
 
297
static Bool
 
298
gconfGetValue (CompDisplay     *d,
 
299
               CompOptionValue *value,
 
300
               CompOptionType  type,
 
301
               GConfValue      *gvalue)
 
302
 
 
303
{
 
304
    if (type         == CompOptionTypeBool &&
 
305
        gvalue->type == GCONF_VALUE_BOOL)
 
306
    {
 
307
        value->b = gconf_value_get_bool (gvalue);
 
308
        return TRUE;
 
309
    }
 
310
    else if (type         == CompOptionTypeInt &&
 
311
             gvalue->type == GCONF_VALUE_INT)
 
312
    {
 
313
        value->i = gconf_value_get_int (gvalue);
 
314
        return TRUE;
 
315
    }
 
316
    else if (type         == CompOptionTypeFloat &&
 
317
             gvalue->type == GCONF_VALUE_FLOAT)
 
318
    {
 
319
        value->f = gconf_value_get_float (gvalue);
 
320
        return TRUE;
 
321
    }
 
322
    else if (type         == CompOptionTypeString &&
 
323
             gvalue->type == GCONF_VALUE_STRING)
 
324
    {
 
325
        value->s = (char *) gconf_value_get_string (gvalue);
 
326
        return TRUE;
 
327
    }
 
328
    else if (type         == CompOptionTypeColor &&
 
329
             gvalue->type == GCONF_VALUE_STRING)
 
330
    {
 
331
        const gchar *color;
 
332
        gint        c[3];
 
333
 
 
334
        color = gconf_value_get_string (gvalue);
 
335
 
 
336
        if (sscanf (color, "#%2x%2x%2x", &c[0], &c[1], &c[2]) == 3)
 
337
        {
 
338
            value->c[0] = c[0] << 8 | c[0];
 
339
            value->c[1] = c[1] << 8 | c[1];
 
340
            value->c[2] = c[2] << 8 | c[2];
 
341
            value->c[3] = 0xffff;
 
342
 
 
343
            return TRUE;
 
344
        }
 
345
    }
 
346
    else if (type         == CompOptionTypeBinding &&
 
347
             gvalue->type == GCONF_VALUE_STRING)
 
348
    {
 
349
        gchar *binding, *ptr;
 
350
        gint  i;
 
351
        guint mods = 0;
 
352
 
 
353
        binding = (gchar *) gconf_value_get_string (gvalue);
 
354
        if (strcasecmp (binding, "disabled") == 0)
 
355
        {
 
356
            value->bind.type = CompBindingTypeButton;
 
357
            value->bind.u.button.button = 1;
 
358
            value->bind.u.button.modifiers = 0;
 
359
        }
 
360
        else
 
361
        {
 
362
            for (i = 0; i < N_MODIFIERS; i++)
 
363
            {
 
364
                if (strcasestr (binding, modifiers[i].name))
 
365
                    mods |= modifiers[i].modifier;
 
366
            }
 
367
 
 
368
            /* if not explicetly set to be triggered at release
 
369
               assume it to be triggered at press */
 
370
            if (!(mods & CompReleaseMask))
 
371
                mods |= CompPressMask;
 
372
 
 
373
            ptr = strrchr (binding, '>');
 
374
            if (ptr)
 
375
                binding = ptr + 1;
 
376
 
 
377
            while (*binding && !isalnum (*binding))
 
378
                binding++;
 
379
 
 
380
            if (strcmpskipifequal (&binding, "Button") == 0)
 
381
            {
 
382
                gint button;
 
383
 
 
384
                if (sscanf (binding, "%d", &button) == 1)
 
385
                {
 
386
                    value->bind.type = CompBindingTypeButton;
 
387
                    value->bind.u.button.button = button;
 
388
                    value->bind.u.button.modifiers = mods;
 
389
 
 
390
                    return TRUE;
 
391
                }
 
392
            }
 
393
            else
 
394
            {
 
395
                KeySym keysym;
 
396
 
 
397
                keysym = XStringToKeysym (binding);
 
398
                if (keysym != NoSymbol)
 
399
                {
 
400
                    KeyCode keycode;
 
401
 
 
402
                    keycode = XKeysymToKeycode (d->display, keysym);
 
403
                    if (keycode)
 
404
                    {
 
405
                        value->bind.type = CompBindingTypeKey;
 
406
                        value->bind.u.key.keycode = keycode;
 
407
                        value->bind.u.key.modifiers = mods;
 
408
 
 
409
                        return TRUE;
 
410
                    }
 
411
                }
 
412
 
 
413
                if (strncmp (binding, "0x", 2) == 0)
 
414
                {
 
415
                    value->bind.type = CompBindingTypeKey;
 
416
                    value->bind.u.key.keycode = strtol (binding, NULL, 0);
 
417
                    value->bind.u.key.modifiers = mods;
 
418
 
 
419
                    return TRUE;
 
420
                }
 
421
            }
 
422
        }
 
423
    }
 
424
 
 
425
    return FALSE;
 
426
}
 
427
 
 
428
static Bool
 
429
gconfGetOptionValue (CompDisplay *d,
 
430
                     GConfEntry  *entry)
 
431
{
 
432
    CompPlugin *p = 0;
 
433
    CompScreen *s = 0;
 
434
    CompOption *o, *option;
 
435
    gchar      *ptr;
 
436
    gchar      *pluginPtr = 0;
 
437
    gint       pluginLen = 0;
 
438
    gint       nOption;
 
439
    Bool       status = FALSE;
 
440
 
 
441
    if (!entry)
 
442
        return FALSE;
 
443
 
 
444
    ptr = entry->key;
 
445
    if (strncmp (ptr, APP_NAME, strlen (APP_NAME)))
 
446
        return FALSE;
 
447
 
 
448
    ptr += strlen (APP_NAME);
 
449
 
 
450
    if (strcmpskipifequal (&ptr, "/plugins/") == 0)
 
451
    {
 
452
        pluginPtr = ptr;
 
453
        ptr = strchr (ptr, '/');
 
454
        if (!ptr)
 
455
            return FALSE;
 
456
 
 
457
        pluginLen = ptr - pluginPtr;
 
458
        if (pluginLen < 1)
 
459
            return FALSE;
 
460
    }
 
461
    else if (strcmpskipifequal (&ptr, "/general"))
 
462
        return FALSE;
 
463
 
 
464
    if (strcmpskipifequal (&ptr, "/screen") == 0)
 
465
    {
 
466
        int screenNum;
 
467
 
 
468
        screenNum = strtol (ptr, &ptr, 0);
 
469
 
 
470
        for (s = d->screens; s; s = s->next)
 
471
            if (s->screenNum == screenNum)
 
472
                break;
 
473
 
 
474
        if (!s || !ptr)
 
475
            return FALSE;
 
476
    }
 
477
    else if (strcmpskipifequal (&ptr, "/allscreens"))
 
478
        return FALSE;
 
479
 
 
480
    if (strcmpskipifequal (&ptr, "/options/"))
 
481
        return FALSE;
 
482
 
 
483
    if (pluginPtr)
 
484
    {
 
485
        pluginPtr = g_strndup (pluginPtr, pluginLen);
 
486
 
 
487
        option  = 0;
 
488
        nOption = 0;
 
489
 
 
490
        p = findActivePlugin (pluginPtr);
 
491
        if (p)
 
492
        {
 
493
            if (s)
 
494
            {
 
495
                if (p->vTable->getScreenOptions)
 
496
                    option = (*p->vTable->getScreenOptions) (s, &nOption);
 
497
            }
 
498
            else
 
499
            {
 
500
                if (p->vTable->getDisplayOptions)
 
501
                    option = (*p->vTable->getDisplayOptions) (d, &nOption);
 
502
            }
 
503
        }
 
504
    }
 
505
    else
 
506
    {
 
507
        if (s)
 
508
            option = compGetScreenOptions (s, &nOption);
 
509
        else
 
510
            option = compGetDisplayOptions (d, &nOption);
 
511
    }
 
512
 
 
513
    o = compFindOption (option, nOption, ptr, 0);
 
514
    if (o)
 
515
    {
 
516
        GConfValue      *gvalue;
 
517
        CompOptionValue value;
 
518
 
 
519
        gvalue = gconf_entry_get_value (entry);
 
520
        if (gvalue)
 
521
        {
 
522
            if (o->type      == CompOptionTypeList &&
 
523
                gvalue->type == GCONF_VALUE_LIST)
 
524
            {
 
525
                GConfValueType type;
 
526
 
 
527
                value.list.value  = 0;
 
528
                value.list.nValue = 0;
 
529
 
 
530
                type = gconf_value_get_list_type (gvalue);
 
531
                if (type == gconfTypeFromCompType (o->value.list.type))
 
532
                {
 
533
                    GSList *list;
 
534
                    int    i, length;
 
535
 
 
536
                    status = TRUE;
 
537
 
 
538
                    list = gconf_value_get_list (gvalue);
 
539
 
 
540
                    length = g_slist_length (list);
 
541
 
 
542
                    if (length)
 
543
                    {
 
544
                        value.list.value =
 
545
                            malloc (sizeof (CompOptionValue) * length);
 
546
                        if (value.list.value)
 
547
                        {
 
548
                            value.list.nValue = length;
 
549
                            for (i = 0; i < length; i++)
 
550
                            {
 
551
                                if (!gconfGetValue (d, &value.list.value[i],
 
552
                                                    o->value.list.type,
 
553
                                                    (GConfValue *) list->data))
 
554
                                    status = FALSE;
 
555
 
 
556
                                list = g_slist_next (list);
 
557
                            }
 
558
                        }
 
559
                        else
 
560
                            status = FALSE;
 
561
                    }
 
562
                }
 
563
                else
 
564
                    status = FALSE;
 
565
            }
 
566
            else
 
567
            {
 
568
                status = gconfGetValue (d, &value, o->type, gvalue);
 
569
            }
 
570
 
 
571
            if (status)
 
572
            {
 
573
                if (s)
 
574
                {
 
575
                    if (pluginPtr)
 
576
                        status = (*s->setScreenOptionForPlugin) (s,
 
577
                                                                 pluginPtr,
 
578
                                                                 ptr,
 
579
                                                                 &value);
 
580
                    else
 
581
                        status = (*s->setScreenOption) (s, ptr, &value);
 
582
                }
 
583
                else
 
584
                {
 
585
                    if (pluginPtr)
 
586
                        status = (*d->setDisplayOptionForPlugin) (d,
 
587
                                                                  pluginPtr,
 
588
                                                                  ptr,
 
589
                                                                  &value);
 
590
                    else
 
591
                        status = (*d->setDisplayOption) (d, ptr, &value);
 
592
                }
 
593
            }
 
594
 
 
595
            if (o->type      == CompOptionTypeList &&
 
596
                gvalue->type == GCONF_VALUE_LIST)
 
597
            {
 
598
                if (value.list.nValue && value.list.value)
 
599
                    free (value.list.value);
 
600
            }
 
601
        }
 
602
 
 
603
        if (!status)
 
604
        {
 
605
            gchar *screen = 0;
 
606
 
 
607
            if (s)
 
608
                screen = g_strdup_printf ("screen%d", s->screenNum);
 
609
 
 
610
            gconfSetOption (d, o, screen, pluginPtr);
 
611
 
 
612
            if (screen)
 
613
                g_free (screen);
 
614
        }
 
615
    }
 
616
 
 
617
    if (pluginPtr)
 
618
        g_free (pluginPtr);
 
619
 
 
620
    return status;
 
621
}
 
622
 
 
623
static void
 
624
gconfInitOption (CompDisplay *d,
 
625
                 CompOption  *o,
 
626
                 gchar       *screen,
 
627
                 gchar       *plugin)
 
628
{
 
629
    GConfEntry *entry;
 
630
    gchar      *key;
 
631
 
 
632
    GCONF_DISPLAY (d);
 
633
 
 
634
    if (plugin)
 
635
    {
 
636
        key = g_strjoin ("/", APP_NAME "/plugins", plugin, screen,
 
637
                         "options", o->name, NULL);
 
638
    }
 
639
    else
 
640
    {
 
641
        key = g_strjoin ("/", APP_NAME "/general", screen, "options",
 
642
                         o->name, NULL);
 
643
    }
 
644
 
 
645
    entry = gconf_client_get_entry (gd->client, key, NULL, FALSE, NULL);
 
646
 
 
647
    if (!gconfGetOptionValue (d, entry))
 
648
        gconfSetOption (d, o, screen, plugin);
 
649
 
 
650
    if (entry)
 
651
        gconf_entry_free (entry);
 
652
 
 
653
    g_free (key);
 
654
}
 
655
 
 
656
static void
 
657
gconfInitPlugin (CompDisplay *d,
 
658
                 CompPlugin  *p)
 
659
{
 
660
    gchar *gconfpath, *key;
 
661
 
 
662
    GCONF_DISPLAY (d);
 
663
 
 
664
    gconfpath = g_strjoin ("/", APP_NAME "/plugins", p->vTable->name, NULL);
 
665
 
 
666
    key = g_strconcat (gconfpath, "/short_description", NULL);
 
667
    gconf_client_set_string (gd->client, key, p->vTable->shortDesc, NULL);
 
668
    g_free (key);
 
669
 
 
670
    key = g_strconcat (gconfpath, "/long_description", NULL);
 
671
    gconf_client_set_string (gd->client, key, p->vTable->longDesc, NULL);
 
672
    g_free (key);
 
673
 
 
674
    g_free (gconfpath);
 
675
}
 
676
 
 
677
static Bool
 
678
gconfSetDisplayOption (CompDisplay     *d,
 
679
                       char            *name,
 
680
                       CompOptionValue *value)
 
681
{
 
682
    Bool status;
 
683
 
 
684
    GCONF_DISPLAY (d);
 
685
 
 
686
    UNWRAP (gd, d, setDisplayOption);
 
687
    status = (*d->setDisplayOption) (d, name, value);
 
688
    WRAP (gd, d, setDisplayOption, gconfSetDisplayOption);
 
689
 
 
690
    if (status)
 
691
    {
 
692
        CompOption *option;
 
693
        int        nOption;
 
694
 
 
695
        option = compGetDisplayOptions (d, &nOption);
 
696
        gconfSetOption (d, compFindOption (option, nOption, name, 0),
 
697
                        "allscreens", 0);
 
698
    }
 
699
 
 
700
    return status;
 
701
}
 
702
 
 
703
static Bool
 
704
gconfSetDisplayOptionForPlugin (CompDisplay     *d,
 
705
                                char            *plugin,
 
706
                                char            *name,
 
707
                                CompOptionValue *value)
 
708
{
 
709
    Bool status;
 
710
 
 
711
    GCONF_DISPLAY (d);
 
712
 
 
713
    UNWRAP (gd, d, setDisplayOptionForPlugin);
 
714
    status = (*d->setDisplayOptionForPlugin) (d, plugin, name, value);
 
715
    WRAP (gd, d, setDisplayOptionForPlugin, gconfSetDisplayOptionForPlugin);
 
716
 
 
717
    if (status)
 
718
    {
 
719
        CompPlugin *p;
 
720
 
 
721
        p = findActivePlugin (plugin);
 
722
        if (p && p->vTable->getDisplayOptions)
 
723
        {
 
724
            CompOption *option;
 
725
            int        nOption;
 
726
 
 
727
            option = (*p->vTable->getDisplayOptions) (d, &nOption);
 
728
            gconfSetOption (d, compFindOption (option, nOption, name, 0),
 
729
                            "allscreens", plugin);
 
730
        }
 
731
    }
 
732
 
 
733
    return status;
 
734
}
 
735
 
 
736
static Bool
 
737
gconfSetScreenOption (CompScreen      *s,
 
738
                      char            *name,
 
739
                      CompOptionValue *value)
 
740
{
 
741
    Bool status;
 
742
 
 
743
    GCONF_SCREEN (s);
 
744
 
 
745
    UNWRAP (gs, s, setScreenOption);
 
746
    status = (*s->setScreenOption) (s, name, value);
 
747
    WRAP (gs, s, setScreenOption, gconfSetScreenOption);
 
748
 
 
749
    if (status)
 
750
    {
 
751
        CompOption *option;
 
752
        int        nOption;
 
753
        gchar      *screen;
 
754
 
 
755
        screen = g_strdup_printf ("screen%d", s->screenNum);
 
756
 
 
757
        option = compGetScreenOptions (s, &nOption);
 
758
        gconfSetOption (s->display, compFindOption (option, nOption, name, 0),
 
759
                        screen, 0);
 
760
 
 
761
        g_free (screen);
 
762
    }
 
763
 
 
764
    return status;
 
765
}
 
766
 
 
767
static Bool
 
768
gconfSetScreenOptionForPlugin (CompScreen      *s,
 
769
                               char            *plugin,
 
770
                               char            *name,
 
771
                               CompOptionValue *value)
 
772
{
 
773
    Bool status;
 
774
 
 
775
    GCONF_SCREEN (s);
 
776
 
 
777
    UNWRAP (gs, s, setScreenOptionForPlugin);
 
778
    status = (*s->setScreenOptionForPlugin) (s, plugin, name, value);
 
779
    WRAP (gs, s, setScreenOptionForPlugin, gconfSetScreenOptionForPlugin);
 
780
 
 
781
    if (status)
 
782
    {
 
783
        CompPlugin *p;
 
784
 
 
785
        p = findActivePlugin (plugin);
 
786
        if (p && p->vTable->getScreenOptions)
 
787
        {
 
788
            CompOption *option;
 
789
            int        nOption;
 
790
            gchar      *screen;
 
791
 
 
792
            screen = g_strdup_printf ("screen%d", s->screenNum);
 
793
 
 
794
            option = (*p->vTable->getScreenOptions) (s, &nOption);
 
795
            gconfSetOption (s->display,
 
796
                            compFindOption (option, nOption, name, 0),
 
797
                            screen, plugin);
 
798
 
 
799
            g_free (screen);
 
800
        }
 
801
    }
 
802
 
 
803
    return status;
 
804
}
 
805
 
 
806
static Bool
 
807
gconfInitPluginForDisplay (CompPlugin  *p,
 
808
                           CompDisplay *d)
 
809
{
 
810
    Bool status;
 
811
 
 
812
    GCONF_DISPLAY (d);
 
813
 
 
814
    UNWRAP (gd, d, initPluginForDisplay);
 
815
    status = (*d->initPluginForDisplay) (p, d);
 
816
    WRAP (gd, d, initPluginForDisplay, gconfInitPluginForDisplay);
 
817
 
 
818
    if (status)
 
819
        gconfInitPlugin (d, p);
 
820
 
 
821
    if (status && p->vTable->getDisplayOptions)
 
822
    {
 
823
        CompOption *option;
 
824
        int        nOption;
 
825
 
 
826
        option = (*p->vTable->getDisplayOptions) (d, &nOption);
 
827
        while (nOption--)
 
828
            gconfInitOption (d, option++, "allscreens", p->vTable->name);
 
829
    }
 
830
 
 
831
    return status;
 
832
}
 
833
 
 
834
static Bool
 
835
gconfInitPluginForScreen (CompPlugin *p,
 
836
                          CompScreen *s)
 
837
{
 
838
    Bool status;
 
839
 
 
840
    GCONF_SCREEN (s);
 
841
 
 
842
    UNWRAP (gs, s, initPluginForScreen);
 
843
    status = (*s->initPluginForScreen) (p, s);
 
844
    WRAP (gs, s, initPluginForScreen, gconfInitPluginForScreen);
 
845
 
 
846
    if (status && p->vTable->getScreenOptions)
 
847
    {
 
848
        CompOption *option;
 
849
        int        nOption;
 
850
        gchar      *screen;
 
851
 
 
852
        screen = g_strdup_printf ("screen%d", s->screenNum);
 
853
 
 
854
        option = (*p->vTable->getScreenOptions) (s, &nOption);
 
855
        while (nOption--)
 
856
            gconfInitOption (s->display, option++, screen, p->vTable->name);
 
857
 
 
858
        g_free (screen);
 
859
    }
 
860
 
 
861
    return status;
 
862
}
 
863
 
 
864
static void
 
865
gconfKeyChanged (GConfClient *client,
 
866
                 guint       cnxn_id,
 
867
                 GConfEntry  *entry,
 
868
                 gpointer    user_data)
 
869
{
 
870
    CompDisplay *display = (CompDisplay *) user_data;
 
871
 
 
872
    gconfGetOptionValue (display, entry);
 
873
}
 
874
 
 
875
static Bool
 
876
gconfTimeout (void *closure)
 
877
{
 
878
    while (g_main_pending ()) g_main_iteration (FALSE);
 
879
 
 
880
    return TRUE;
 
881
}
 
882
 
 
883
static Bool
 
884
gconfInitDisplay (CompPlugin  *p,
 
885
                  CompDisplay *d)
 
886
{
 
887
    CompOption   *option;
 
888
    int          nOption;
 
889
    GConfDisplay *gd;
 
890
 
 
891
    gd = malloc (sizeof (GConfDisplay));
 
892
    if (!gd)
 
893
        return FALSE;
 
894
 
 
895
    gd->screenPrivateIndex = allocateScreenPrivateIndex (d);
 
896
    if (gd->screenPrivateIndex < 0)
 
897
    {
 
898
        free (gd);
 
899
        return FALSE;
 
900
    }
 
901
 
 
902
    g_type_init ();
 
903
 
 
904
    gd->client = gconf_client_get_default ();
 
905
 
 
906
    gconf_client_add_dir (gd->client, APP_NAME,
 
907
                          GCONF_CLIENT_PRELOAD_NONE, NULL);
 
908
 
 
909
    WRAP (gd, d, initPluginForDisplay, gconfInitPluginForDisplay);
 
910
    WRAP (gd, d, setDisplayOption, gconfSetDisplayOption);
 
911
    WRAP (gd, d, setDisplayOptionForPlugin, gconfSetDisplayOptionForPlugin);
 
912
 
 
913
    d->privates[displayPrivateIndex].ptr = gd;
 
914
 
 
915
    option = compGetDisplayOptions (d, &nOption);
 
916
    while (nOption--)
 
917
        gconfInitOption (d, option++, "allscreens", 0);
 
918
 
 
919
    gconf_client_notify_add (gd->client, APP_NAME, gconfKeyChanged, d,
 
920
                             NULL, NULL);
 
921
 
 
922
    gd->timeoutHandle = compAddTimeout (KEY_CHANGE_TIMEOUT, gconfTimeout, 0);
 
923
 
 
924
    return TRUE;
 
925
}
 
926
 
 
927
static void
 
928
gconfFiniDisplay (CompPlugin  *p,
 
929
                  CompDisplay *d)
 
930
{
 
931
    GCONF_DISPLAY (d);
 
932
 
 
933
    compRemoveTimeout (gd->timeoutHandle);
 
934
 
 
935
    g_object_unref (gd->client);
 
936
 
 
937
    freeScreenPrivateIndex (d, gd->screenPrivateIndex);
 
938
 
 
939
    free (gd);
 
940
}
 
941
 
 
942
static Bool
 
943
gconfInitScreen (CompPlugin *p,
 
944
                 CompScreen *s)
 
945
{
 
946
    CompOption  *option;
 
947
    int         nOption;
 
948
    GConfScreen *gs;
 
949
    gchar       *screen;
 
950
 
 
951
    GCONF_DISPLAY (s->display);
 
952
 
 
953
    gs = malloc (sizeof (GConfScreen));
 
954
    if (!gs)
 
955
        return FALSE;
 
956
 
 
957
    WRAP (gs, s, initPluginForScreen, gconfInitPluginForScreen);
 
958
    WRAP (gs, s, setScreenOption, gconfSetScreenOption);
 
959
    WRAP (gs, s, setScreenOptionForPlugin, gconfSetScreenOptionForPlugin);
 
960
 
 
961
    s->privates[gd->screenPrivateIndex].ptr = gs;
 
962
 
 
963
    screen = g_strdup_printf ("screen%d", s->screenNum);
 
964
 
 
965
    option = compGetScreenOptions (s, &nOption);
 
966
    while (nOption--)
 
967
        gconfInitOption (s->display, option++, screen, 0);
 
968
 
 
969
    g_free (screen);
 
970
 
 
971
    return TRUE;
 
972
}
 
973
 
 
974
static void
 
975
gconfFiniScreen (CompPlugin *p,
 
976
                 CompScreen *s)
 
977
{
 
978
    GCONF_SCREEN (s);
 
979
 
 
980
    UNWRAP (gs, s, initPluginForScreen);
 
981
    UNWRAP (gs, s, setScreenOption);
 
982
    UNWRAP (gs, s, setScreenOptionForPlugin);
 
983
 
 
984
    free (gs);
 
985
}
 
986
 
 
987
static Bool
 
988
gconfInit (CompPlugin *p)
 
989
{
 
990
    displayPrivateIndex = allocateDisplayPrivateIndex ();
 
991
    if (displayPrivateIndex < 0)
 
992
        return FALSE;
 
993
 
 
994
    return TRUE;
 
995
}
 
996
 
 
997
static void
 
998
gconfFini (CompPlugin *p)
 
999
{
 
1000
    if (displayPrivateIndex >= 0)
 
1001
        freeDisplayPrivateIndex (displayPrivateIndex);
 
1002
}
 
1003
 
 
1004
CompPluginDep gconfDeps[] = {
 
1005
    { CompPluginRuleBefore, "decoration" },
 
1006
    { CompPluginRuleBefore, "wobbly" },
 
1007
    { CompPluginRuleBefore, "fade" },
 
1008
    { CompPluginRuleBefore, "cube" },
 
1009
    { CompPluginRuleBefore, "expose" }
 
1010
};
 
1011
 
 
1012
CompPluginVTable gconfVTable = {
 
1013
    "gconf",
 
1014
    "GConf",
 
1015
    "GConf Control Backend",
 
1016
    gconfInit,
 
1017
    gconfFini,
 
1018
    gconfInitDisplay,
 
1019
    gconfFiniDisplay,
 
1020
    gconfInitScreen,
 
1021
    gconfFiniScreen,
 
1022
    0, /* InitWindow */
 
1023
    0, /* FiniWindow */
 
1024
    0, /* GetDisplayOptions */
 
1025
    0, /* SetDisplayOption */
 
1026
    0, /* GetScreenOptions */
 
1027
    0,  /* SetScreenOption */
 
1028
    gconfDeps,
 
1029
    sizeof (gconfDeps) / sizeof (gconfDeps[0])
 
1030
};
 
1031
 
 
1032
CompPluginVTable *
 
1033
getCompPluginInfo (void)
 
1034
{
 
1035
    return &gconfVTable;
 
1036
}