~ubuntu-branches/ubuntu/precise/libgnomekbd/precise

« back to all changes in this revision

Viewing changes to libgnomekbd/gkbd-keyboard-config.c

  • Committer: Bazaar Package Importer
  • Author(s): Laurent Bigonville
  • Date: 2011-03-21 13:22:31 UTC
  • mfrom: (1.3.6 upstream) (3.2.13 experimental)
  • Revision ID: james.westby@ubuntu.com-20110321132231-zoay06noilk1thky
Tags: 2.91.91-2
* debian/libgnomekbd-common.install:
  - Install /usr/share/GConf/gsettings and /usr/share/libgnomekbd/icons
  - Add libatk1.0-dev (>= 1.32.0-2~) build-dep to be sure we have .gir file

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <stdlib.h>
25
25
#include <X11/keysym.h>
26
26
 
27
 
#include <glib/gi18n.h>
 
27
#include <glib/gi18n-lib.h>
28
28
 
29
29
#include <gkbd-keyboard-config.h>
30
30
#include <gkbd-config-private.h>
 
31
#include <gkbd-util.h>
31
32
 
32
33
/**
33
34
 * GkbdKeyboardConfig
34
35
 */
35
 
#define GKBD_KEYBOARD_CONFIG_KEY_PREFIX GKBD_CONFIG_KEY_PREFIX "/kbd"
36
36
 
37
37
#define GROUP_SWITCHERS_GROUP "grp"
38
38
#define DEFAULT_GROUP_SWITCH "grp:shift_caps_toggle"
39
39
 
40
 
const gchar GKBD_KEYBOARD_CONFIG_DIR[] = GKBD_KEYBOARD_CONFIG_KEY_PREFIX;
41
 
const gchar GKBD_KEYBOARD_CONFIG_KEY_MODEL[] =
42
 
    GKBD_KEYBOARD_CONFIG_KEY_PREFIX "/model";
43
 
const gchar GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS[] =
44
 
    GKBD_KEYBOARD_CONFIG_KEY_PREFIX "/layouts";
45
 
const gchar GKBD_KEYBOARD_CONFIG_KEY_OPTIONS[] =
46
 
    GKBD_KEYBOARD_CONFIG_KEY_PREFIX "/options";
 
40
#define XMODMAP_CMD "xmodmap"
 
41
 
 
42
const gchar GKBD_KEYBOARD_CONFIG_KEY_MODEL[] = "model";
 
43
const gchar GKBD_KEYBOARD_CONFIG_KEY_LAYOUTS[] = "layouts";
 
44
const gchar GKBD_KEYBOARD_CONFIG_KEY_OPTIONS[] = "options";
47
45
 
48
46
const gchar *GKBD_KEYBOARD_CONFIG_ACTIVE[] = {
49
47
        GKBD_KEYBOARD_CONFIG_KEY_MODEL,
51
49
        GKBD_KEYBOARD_CONFIG_KEY_OPTIONS
52
50
};
53
51
 
 
52
const gchar *XMODMAP_KNOWN_FILES[] = { ".xmodmap", ".Xmodmap" };
 
53
 
54
54
/**
55
55
 * static common functions
56
56
 */
57
 
static void
58
 
gkbd_keyboard_config_string_list_reset (GSList ** plist)
59
 
{
60
 
        while (*plist != NULL) {
61
 
                GSList *p = *plist;
62
 
                *plist = (*plist)->next;
63
 
                g_free (p->data);
64
 
                g_slist_free_1 (p);
65
 
        }
66
 
}
67
57
 
68
58
static gboolean
69
 
gslist_str_equal (GSList * l1, GSList * l2)
 
59
g_strv_equal (gchar ** l1, gchar ** l2)
70
60
{
71
61
        if (l1 == l2)
72
62
                return TRUE;
73
 
        while (l1 != NULL && l2 != NULL) {
74
 
                if ((l1->data != l2->data) &&
75
 
                    (l1->data != NULL) &&
76
 
                    (l2->data != NULL) &&
77
 
                    g_ascii_strcasecmp (l1->data, l2->data))
78
 
                        return False;
79
 
 
80
 
                l1 = l1->next;
81
 
                l2 = l2->next;
 
63
        if (l1 == NULL)
 
64
                return g_strv_length (l2) == 0;
 
65
        if (l2 == NULL)
 
66
                return g_strv_length (l1) == 0;
 
67
 
 
68
        while ((*l1 != NULL) && (*l2 != NULL)) {
 
69
                if (*l1 != *l2) {
 
70
                        if (*l1 && *l2) {
 
71
                                if (g_ascii_strcasecmp (*l1, *l2))
 
72
                                        return FALSE;
 
73
                        } else
 
74
                                return FALSE;
 
75
                }
 
76
 
 
77
                l1++;
 
78
                l2++;
82
79
        }
83
 
        return (l1 == NULL && l2 == NULL);
 
80
        return (*l1 == NULL) && (*l2 == NULL);
84
81
}
85
82
 
86
83
gboolean
187
184
/**
188
185
 * static GkbdKeyboardConfig functions
189
186
 */
190
 
static void
191
 
gkbd_keyboard_config_options_add_full (GkbdKeyboardConfig * kbd_config,
192
 
                                       const gchar * full_option_name)
193
 
{
194
 
        kbd_config->options =
195
 
            g_slist_append (kbd_config->options,
196
 
                            g_strdup (full_option_name));
197
 
}
198
 
 
199
 
static void
200
 
gkbd_keyboard_config_layouts_add_full (GkbdKeyboardConfig * kbd_config,
201
 
                                       const gchar * full_layout_name)
202
 
{
203
 
        kbd_config->layouts_variants =
204
 
            g_slist_append (kbd_config->layouts_variants,
205
 
                            g_strdup (full_layout_name));
206
 
}
207
187
 
208
188
static void
209
189
gkbd_keyboard_config_copy_from_xkl_config (GkbdKeyboardConfig * kbd_config,
210
190
                                           XklConfigRec * pdata)
211
191
{
212
192
        char **p, **p1;
 
193
        int i;
213
194
        gkbd_keyboard_config_model_set (kbd_config, pdata->model);
214
195
        xkl_debug (150, "Loaded Kbd model: [%s]\n", pdata->model);
215
196
 
216
 
        gkbd_keyboard_config_layouts_reset (kbd_config);
217
 
        p = pdata->layouts;
218
 
        p1 = pdata->variants;
219
 
        while (p != NULL && *p != NULL) {
220
 
                const gchar *full_layout =
221
 
                    gkbd_keyboard_config_merge_items (*p, *p1);
222
 
                xkl_debug (150,
223
 
                           "Loaded Kbd layout (with variant): [%s]\n",
224
 
                           full_layout);
225
 
                gkbd_keyboard_config_layouts_add_full (kbd_config,
226
 
                                                       full_layout);
227
 
                p++;
228
 
                p1++;
 
197
        /* Layouts */
 
198
        g_strfreev (kbd_config->layouts_variants);
 
199
        kbd_config->layouts_variants = NULL;
 
200
        if (pdata->layouts != NULL) {
 
201
                p = pdata->layouts;
 
202
                p1 = pdata->variants;
 
203
                kbd_config->layouts_variants =
 
204
                    g_new0 (gchar *, g_strv_length (pdata->layouts) + 1);
 
205
                i = 0;
 
206
                while (*p != NULL) {
 
207
                        const gchar *full_layout =
 
208
                            gkbd_keyboard_config_merge_items (*p, *p1);
 
209
                        xkl_debug (150,
 
210
                                   "Loaded Kbd layout (with variant): [%s]\n",
 
211
                                   full_layout);
 
212
                        kbd_config->layouts_variants[i++] =
 
213
                            g_strdup (full_layout);
 
214
                        p++;
 
215
                        p1++;
 
216
                }
229
217
        }
230
218
 
231
 
        gkbd_keyboard_config_options_reset (kbd_config);
232
 
        p = pdata->options;
233
 
        while (p != NULL && *p != NULL) {
234
 
                char group[XKL_MAX_CI_NAME_LENGTH];
235
 
                char *option = *p;
236
 
                char *delim =
237
 
                    (option != NULL) ? strchr (option, ':') : NULL;
238
 
                int len;
239
 
                if ((delim != NULL) &&
240
 
                    ((len = (delim - option)) < XKL_MAX_CI_NAME_LENGTH)) {
241
 
                        strncpy (group, option, len);
242
 
                        group[len] = 0;
243
 
                        xkl_debug (150, "Loaded Kbd option: [%s][%s]\n",
244
 
                                   group, option);
245
 
                        gkbd_keyboard_config_options_add (kbd_config,
246
 
                                                          group, option);
 
219
        /* Options */
 
220
        g_strfreev (kbd_config->options);
 
221
        kbd_config->options = NULL;
 
222
 
 
223
        if (pdata->options != NULL) {
 
224
                p = pdata->options;
 
225
                kbd_config->options =
 
226
                    g_new0 (gchar *, g_strv_length (pdata->options) + 1);
 
227
                i = 0;
 
228
                while (*p != NULL) {
 
229
                        char group[XKL_MAX_CI_NAME_LENGTH];
 
230
                        char *option = *p;
 
231
                        char *delim =
 
232
                            (option != NULL) ? strchr (option, ':') : NULL;
 
233
                        int len;
 
234
                        if ((delim != NULL) &&
 
235
                            ((len =
 
236
                              (delim - option)) <
 
237
                             XKL_MAX_CI_NAME_LENGTH)) {
 
238
                                strncpy (group, option, len);
 
239
                                group[len] = 0;
 
240
                                xkl_debug (150,
 
241
                                           "Loaded Kbd option: [%s][%s]\n",
 
242
                                           group, option);
 
243
                                gkbd_keyboard_config_options_set
 
244
                                    (kbd_config, i++, group, option);
 
245
                        }
 
246
                        p++;
247
247
                }
248
 
                p++;
249
248
        }
250
249
}
251
250
 
261
260
 
262
261
        num_layouts =
263
262
            (kbd_config->layouts_variants ==
264
 
             NULL) ? 0 : g_slist_length (kbd_config->layouts_variants);
 
263
             NULL) ? 0 : g_strv_length (kbd_config->layouts_variants);
265
264
        num_options =
266
265
            (kbd_config->options ==
267
 
             NULL) ? 0 : g_slist_length (kbd_config->options);
 
266
             NULL) ? 0 : g_strv_length (kbd_config->options);
268
267
 
269
268
        xkl_debug (150, "Taking %d layouts\n", num_layouts);
270
269
        if (num_layouts != 0) {
271
 
                GSList *the_layout_variant = kbd_config->layouts_variants;
 
270
                gchar **the_layout_variant = kbd_config->layouts_variants;
272
271
                char **p1 = pdata->layouts =
273
272
                    g_new0 (char *, num_layouts + 1);
274
273
                char **p2 = pdata->variants =
276
275
                for (i = num_layouts; --i >= 0;) {
277
276
                        char *layout, *variant;
278
277
                        if (gkbd_keyboard_config_split_items
279
 
                            (the_layout_variant->data, &layout, &variant)
 
278
                            (*the_layout_variant, &layout, &variant)
280
279
                            && variant != NULL) {
281
280
                                *p1 =
282
281
                                    (layout ==
288
287
                                    g_strdup (variant);
289
288
                        } else {
290
289
                                *p1 =
291
 
                                    (the_layout_variant->data ==
 
290
                                    (*the_layout_variant ==
292
291
                                     NULL) ? g_strdup ("") :
293
 
                                    g_strdup (the_layout_variant->data);
 
292
                                    g_strdup (*the_layout_variant);
294
293
                                *p2 = g_strdup ("");
295
294
                        }
296
295
                        xkl_debug (150, "Adding [%s]/%p and [%s]/%p\n",
298
297
                                   *p2 ? *p2 : "(nil)", *p2);
299
298
                        p1++;
300
299
                        p2++;
301
 
                        the_layout_variant = the_layout_variant->next;
 
300
                        the_layout_variant++;
302
301
                }
303
302
        }
304
303
 
305
304
        if (num_options != 0) {
306
 
                GSList *the_option = kbd_config->options;
 
305
                gchar **the_option = kbd_config->options;
307
306
                char **p = pdata->options =
308
307
                    g_new0 (char *, num_options + 1);
309
308
                for (i = num_options; --i >= 0;) {
310
309
                        char *group, *option;
311
310
                        if (gkbd_keyboard_config_split_items
312
 
                            (the_option->data, &group, &option)
 
311
                            (*the_option, &group, &option)
313
312
                            && option != NULL)
314
313
                                *(p++) = g_strdup (option);
315
314
                        else {
316
315
                                *(p++) = g_strdup ("");
317
316
                                xkl_debug (150, "Could not split [%s]\n",
318
 
                                           the_option->data);
 
317
                                           *the_option);
319
318
                        }
320
 
                        the_option = the_option->next;
 
319
                        the_option++;
321
320
                }
322
321
        }
323
322
}
326
325
gkbd_keyboard_config_load_params (GkbdKeyboardConfig * kbd_config,
327
326
                                  const gchar * param_names[])
328
327
{
329
 
        GError *gerror = NULL;
330
328
        gchar *pc;
331
 
        GSList *pl, *l;
332
 
 
333
 
        pc = gconf_client_get_string (kbd_config->conf_client,
334
 
                                      param_names[0], &gerror);
335
 
        if (pc == NULL || gerror != NULL) {
336
 
                if (gerror != NULL) {
337
 
                        g_warning ("Error reading configuration:%s\n",
338
 
                                   gerror->message);
339
 
                        g_error_free (gerror);
340
 
                        g_free (pc);
341
 
                        gerror = NULL;
342
 
                }
 
329
 
 
330
        pc = g_settings_get_string (kbd_config->settings, param_names[0]);
 
331
 
 
332
        if (pc == NULL || pc[0] == '\0') {
343
333
                gkbd_keyboard_config_model_set (kbd_config, NULL);
344
334
        } else {
345
335
                gkbd_keyboard_config_model_set (kbd_config, pc);
346
 
                g_free (pc);
347
336
        }
 
337
        g_free (pc);
348
338
        xkl_debug (150, "Loaded Kbd model: [%s]\n",
349
339
                   kbd_config->model ? kbd_config->model : "(null)");
350
340
 
351
 
        gkbd_keyboard_config_layouts_reset (kbd_config);
352
 
 
353
 
        l = pl = gconf_client_get_list (kbd_config->conf_client,
354
 
                                        param_names[1],
355
 
                                        GCONF_VALUE_STRING, &gerror);
356
 
        if (pl == NULL || gerror != NULL) {
357
 
                if (gerror != NULL) {
358
 
                        g_warning ("Error reading configuration:%s\n",
359
 
                                   gerror->message);
360
 
                        g_error_free (gerror);
361
 
                        gerror = NULL;
362
 
                }
363
 
        }
364
 
 
365
 
        while (l != NULL) {
366
 
                xkl_debug (150, "Loaded Kbd layout: [%s]\n", l->data);
367
 
                gkbd_keyboard_config_layouts_add_full (kbd_config,
368
 
                                                       l->data);
369
 
                l = l->next;
370
 
        }
371
 
        gkbd_keyboard_config_string_list_reset (&pl);
372
 
 
373
 
        gkbd_keyboard_config_options_reset (kbd_config);
374
 
 
375
 
        l = pl = gconf_client_get_list (kbd_config->conf_client,
376
 
                                        param_names[2],
377
 
                                        GCONF_VALUE_STRING, &gerror);
378
 
        if (pl == NULL || gerror != NULL) {
379
 
                if (gerror != NULL) {
380
 
                        g_warning ("Error reading configuration:%s\n",
381
 
                                   gerror->message);
382
 
                        g_error_free (gerror);
383
 
                        gerror = NULL;
384
 
                }
385
 
        }
386
 
 
387
 
        while (l != NULL) {
388
 
                xkl_debug (150, "Loaded Kbd option: [%s]\n", l->data);
389
 
                gkbd_keyboard_config_options_add_full (kbd_config,
390
 
                                                       (const gchar *)
391
 
                                                       l->data);
392
 
                l = l->next;
393
 
        }
394
 
        gkbd_keyboard_config_string_list_reset (&pl);
 
341
        g_strfreev (kbd_config->layouts_variants);
 
342
 
 
343
        kbd_config->layouts_variants =
 
344
            g_settings_get_strv (kbd_config->settings, param_names[1]);
 
345
 
 
346
        if (kbd_config->layouts_variants != NULL
 
347
            && kbd_config->layouts_variants[0] == NULL) {
 
348
                g_strfreev (kbd_config->layouts_variants);
 
349
                kbd_config->layouts_variants = NULL;
 
350
        }
 
351
 
 
352
        g_strfreev (kbd_config->options);
 
353
 
 
354
        kbd_config->options =
 
355
            g_settings_get_strv (kbd_config->settings, param_names[2]);
 
356
 
 
357
        if (kbd_config->options != NULL && kbd_config->options[0] == NULL) {
 
358
                g_strfreev (kbd_config->options);
 
359
                kbd_config->options = NULL;
 
360
        }
395
361
}
396
362
 
397
363
static void
398
364
gkbd_keyboard_config_save_params (GkbdKeyboardConfig * kbd_config,
399
 
                                  GConfChangeSet * cs,
400
365
                                  const gchar * param_names[])
401
366
{
402
 
        GSList *pl;
 
367
        gchar **pl;
403
368
 
404
369
        if (kbd_config->model)
405
 
                gconf_change_set_set_string (cs, param_names[0],
406
 
                                             kbd_config->model);
 
370
                g_settings_set_string (kbd_config->settings,
 
371
                                       param_names[0], kbd_config->model);
407
372
        else
408
 
                gconf_change_set_unset (cs, param_names[0]);
 
373
                g_settings_set_string (kbd_config->settings,
 
374
                                       param_names[0], NULL);
409
375
        xkl_debug (150, "Saved Kbd model: [%s]\n",
410
376
                   kbd_config->model ? kbd_config->model : "(null)");
411
377
 
412
378
        if (kbd_config->layouts_variants) {
413
379
                pl = kbd_config->layouts_variants;
414
 
                while (pl != NULL) {
415
 
                        xkl_debug (150, "Saved Kbd layout: [%s]\n",
416
 
                                   pl->data);
417
 
                        pl = pl->next;
 
380
                while (*pl != NULL) {
 
381
                        xkl_debug (150, "Saved Kbd layout: [%s]\n", *pl);
 
382
                        pl++;
418
383
                }
419
 
                gconf_change_set_set_list (cs,
420
 
                                           param_names[1],
421
 
                                           GCONF_VALUE_STRING,
422
 
                                           kbd_config->layouts_variants);
 
384
                g_settings_set_strv (kbd_config->settings,
 
385
                                     param_names[1],
 
386
                                     (const gchar * const *)
 
387
                                     kbd_config->layouts_variants);
423
388
        } else {
424
389
                xkl_debug (150, "Saved Kbd layouts: []\n");
425
 
                gconf_change_set_unset (cs, param_names[1]);
 
390
                g_settings_set_strv (kbd_config->settings,
 
391
                                     param_names[1], NULL);
426
392
        }
427
393
 
428
394
        if (kbd_config->options) {
429
395
                pl = kbd_config->options;
430
 
                while (pl != NULL) {
431
 
                        xkl_debug (150, "Saved Kbd option: [%s]\n",
432
 
                                   pl->data);
433
 
                        pl = pl->next;
 
396
                while (*pl != NULL) {
 
397
                        xkl_debug (150, "Saved Kbd option: [%s]\n", *pl);
 
398
                        pl++;
434
399
                }
435
 
                gconf_change_set_set_list (cs,
436
 
                                           param_names[2],
437
 
                                           GCONF_VALUE_STRING,
438
 
                                           kbd_config->options);
 
400
                g_settings_set_strv (kbd_config->settings,
 
401
                                     param_names[2],
 
402
                                     (const gchar *
 
403
                                      const *) kbd_config->options);
439
404
        } else {
440
405
                xkl_debug (150, "Saved Kbd options: []\n");
441
 
                gconf_change_set_unset (cs, param_names[2]);
 
406
                g_settings_set_strv (kbd_config->settings,
 
407
                                     param_names[2], NULL);
442
408
        }
443
409
}
444
410
 
447
413
 */
448
414
void
449
415
gkbd_keyboard_config_init (GkbdKeyboardConfig * kbd_config,
450
 
                           GConfClient * conf_client, XklEngine * engine)
 
416
                           XklEngine * engine)
451
417
{
452
 
        GError *gerror = NULL;
453
 
 
454
418
        memset (kbd_config, 0, sizeof (*kbd_config));
455
 
        kbd_config->conf_client = conf_client;
 
419
        kbd_config->settings = g_settings_new (GKBD_KEYBOARD_SCHEMA);
456
420
        kbd_config->engine = engine;
457
 
        g_object_ref (kbd_config->conf_client);
458
 
 
459
 
        gconf_client_add_dir (kbd_config->conf_client,
460
 
                              GKBD_KEYBOARD_CONFIG_DIR,
461
 
                              GCONF_CLIENT_PRELOAD_NONE, &gerror);
462
 
        if (gerror != NULL) {
463
 
                g_warning ("err: %s\n", gerror->message);
464
 
                g_error_free (gerror);
465
 
                gerror = NULL;
466
 
        }
467
421
}
468
422
 
469
423
void
471
425
{
472
426
        gkbd_keyboard_config_model_set (kbd_config, NULL);
473
427
 
474
 
        gkbd_keyboard_config_layouts_reset (kbd_config);
475
 
        gkbd_keyboard_config_options_reset (kbd_config);
 
428
        g_strfreev (kbd_config->layouts_variants);
 
429
        kbd_config->layouts_variants = NULL;
 
430
        g_strfreev (kbd_config->options);
 
431
        kbd_config->options = NULL;
476
432
 
477
 
        g_object_unref (kbd_config->conf_client);
478
 
        kbd_config->conf_client = NULL;
 
433
        g_object_unref (kbd_config->settings);
 
434
        kbd_config->settings = NULL;
479
435
}
480
436
 
481
437
void
482
 
gkbd_keyboard_config_load_from_gconf (GkbdKeyboardConfig * kbd_config,
483
 
                                      GkbdKeyboardConfig *
484
 
                                      kbd_config_default)
 
438
gkbd_keyboard_config_load (GkbdKeyboardConfig * kbd_config,
 
439
                           GkbdKeyboardConfig * kbd_config_default)
485
440
{
486
441
        gkbd_keyboard_config_load_params (kbd_config,
487
442
                                          GKBD_KEYBOARD_CONFIG_ACTIVE);
488
443
 
489
444
        if (kbd_config_default != NULL) {
490
 
                GSList *pl;
491
445
 
492
446
                if (kbd_config->model == NULL)
493
447
                        kbd_config->model =
494
448
                            g_strdup (kbd_config_default->model);
495
449
 
496
450
                if (kbd_config->layouts_variants == NULL) {
497
 
                        pl = kbd_config_default->layouts_variants;
498
 
                        while (pl != NULL) {
499
 
                                kbd_config->layouts_variants =
500
 
                                    g_slist_append
501
 
                                    (kbd_config->layouts_variants,
502
 
                                     g_strdup (pl->data));
503
 
                                pl = pl->next;
504
 
                        }
 
451
                        kbd_config->layouts_variants =
 
452
                            g_strdupv
 
453
                            (kbd_config_default->layouts_variants);
505
454
                }
506
455
 
507
456
                if (kbd_config->options == NULL) {
508
 
                        pl = kbd_config_default->options;
509
 
                        while (pl != NULL) {
510
 
                                kbd_config->options =
511
 
                                    g_slist_append (kbd_config->options,
512
 
                                                    g_strdup (pl->data));
513
 
                                pl = pl->next;
514
 
                        }
 
457
                        kbd_config->options =
 
458
                            g_strdupv (kbd_config_default->options);
515
459
                }
516
460
        }
517
461
}
565
509
            (kbd_config2->model != NULL) &&
566
510
            g_ascii_strcasecmp (kbd_config1->model, kbd_config2->model))
567
511
                return False;
568
 
        return gslist_str_equal (kbd_config1->layouts_variants,
569
 
                                 kbd_config2->layouts_variants)
570
 
            && gslist_str_equal (kbd_config1->options,
571
 
                                 kbd_config2->options);
 
512
        return g_strv_equal (kbd_config1->layouts_variants,
 
513
                             kbd_config2->layouts_variants)
 
514
            && g_strv_equal (kbd_config1->options, kbd_config2->options);
572
515
}
573
516
 
574
517
void
575
 
gkbd_keyboard_config_save_to_gconf (GkbdKeyboardConfig * kbd_config)
 
518
gkbd_keyboard_config_save (GkbdKeyboardConfig * kbd_config)
576
519
{
577
 
        GConfChangeSet *cs;
578
 
        GError *gerror = NULL;
579
 
 
580
 
        cs = gconf_change_set_new ();
581
 
 
582
 
        gkbd_keyboard_config_save_params (kbd_config, cs,
 
520
        g_settings_delay (kbd_config->settings);
 
521
 
 
522
        gkbd_keyboard_config_save_params (kbd_config,
583
523
                                          GKBD_KEYBOARD_CONFIG_ACTIVE);
584
524
 
585
 
        gconf_client_commit_change_set (kbd_config->conf_client, cs, TRUE,
586
 
                                        &gerror);
587
 
        if (gerror != NULL) {
588
 
                g_warning ("Error saving active configuration: %s\n",
589
 
                           gerror->message);
590
 
                g_error_free (gerror);
591
 
                gerror = NULL;
592
 
        }
593
 
        gconf_change_set_unref (cs);
 
525
        g_settings_apply (kbd_config->settings);
594
526
}
595
527
 
596
528
void
605
537
}
606
538
 
607
539
void
608
 
gkbd_keyboard_config_layouts_add (GkbdKeyboardConfig * kbd_config,
609
 
                                  const gchar * layout_name,
610
 
                                  const gchar * variant_name)
611
 
{
612
 
        const gchar *merged;
613
 
        if (layout_name == NULL)
614
 
                return;
615
 
        merged =
616
 
            gkbd_keyboard_config_merge_items (layout_name, variant_name);
617
 
        if (merged == NULL)
618
 
                return;
619
 
        gkbd_keyboard_config_layouts_add_full (kbd_config, merged);
620
 
}
621
 
 
622
 
void
623
 
gkbd_keyboard_config_layouts_reset (GkbdKeyboardConfig * kbd_config)
624
 
{
625
 
        gkbd_keyboard_config_string_list_reset
626
 
            (&kbd_config->layouts_variants);
627
 
}
628
 
 
629
 
void
630
 
gkbd_keyboard_config_options_reset (GkbdKeyboardConfig * kbd_config)
631
 
{
632
 
        gkbd_keyboard_config_string_list_reset (&kbd_config->options);
633
 
}
634
 
 
635
 
void
636
 
gkbd_keyboard_config_options_add (GkbdKeyboardConfig * kbd_config,
637
 
                                  const gchar * group_name,
 
540
gkbd_keyboard_config_options_set (GkbdKeyboardConfig * kbd_config,
 
541
                                  gint idx, const gchar * group_name,
638
542
                                  const gchar * option_name)
639
543
{
640
544
        const gchar *merged;
644
548
            gkbd_keyboard_config_merge_items (group_name, option_name);
645
549
        if (merged == NULL)
646
550
                return;
647
 
        gkbd_keyboard_config_options_add_full (kbd_config, merged);
 
551
        kbd_config->options[idx] = g_strdup (merged);
648
552
}
649
553
 
650
554
gboolean
652
556
                                     const gchar * group_name,
653
557
                                     const gchar * option_name)
654
558
{
 
559
        gchar **p = kbd_config->options;
655
560
        const gchar *merged =
656
561
            gkbd_keyboard_config_merge_items (group_name, option_name);
657
562
        if (merged == NULL)
658
563
                return FALSE;
659
564
 
660
 
        return NULL != g_slist_find_custom (kbd_config->options, (gpointer)
661
 
                                            merged, (GCompareFunc)
662
 
                                            g_ascii_strcasecmp);
 
565
        while (p && *p) {
 
566
                if (!g_ascii_strcasecmp (merged, *p++))
 
567
                        return TRUE;
 
568
        }
 
569
        return FALSE;
663
570
}
664
571
 
665
572
gboolean
672
579
        rv = xkl_config_rec_activate (data, kbd_config->engine);
673
580
        g_object_unref (G_OBJECT (data));
674
581
 
 
582
        /* Small bit of extensibility by using xmodmap */
 
583
        if (rv) {
 
584
                int i =
 
585
                    sizeof (XMODMAP_KNOWN_FILES) /
 
586
                    sizeof (XMODMAP_KNOWN_FILES[0]);
 
587
                while (--i >= 0) {
 
588
                        gchar *xmodmap_file =
 
589
                            g_build_filename (g_get_home_dir (),
 
590
                                              XMODMAP_KNOWN_FILES[i],
 
591
                                              NULL);
 
592
                        if (g_file_test (xmodmap_file, G_FILE_TEST_EXISTS)) {
 
593
                                GError *error = NULL;
 
594
                                xkl_debug (150,
 
595
                                           "Loading custom xmodmap file %s\n",
 
596
                                           xmodmap_file);
 
597
                                gchar *command =
 
598
                                    g_strconcat (XMODMAP_CMD, " ",
 
599
                                                 xmodmap_file,
 
600
                                                 NULL);
 
601
                                /* Fire and forget - do not care about errors */
 
602
                                if (!g_spawn_command_line_async
 
603
                                    (command, &error)) {
 
604
                                        xkl_debug (0,
 
605
                                                   "Error loading custom xmodmap file: [%s]\n",
 
606
                                                   error->message);
 
607
                                        g_error_free (error);
 
608
                                }
 
609
                                g_free (command);
 
610
 
 
611
                                /* One file is enough */
 
612
                                i = 0;
 
613
                        }
 
614
 
 
615
                        g_free (xmodmap_file);
 
616
                }
 
617
        }
 
618
 
675
619
        return rv;
676
620
}
677
621
 
 
622
/**
 
623
 * gkbd_keyboard_config_start_listen:
 
624
 * @func: (scope notified): a function to call when settings are changed
 
625
 */
678
626
void
679
627
gkbd_keyboard_config_start_listen (GkbdKeyboardConfig * kbd_config,
680
 
                                   GConfClientNotifyFunc func,
681
 
                                   gpointer user_data)
 
628
                                   GCallback func, gpointer user_data)
682
629
{
683
 
        gkbd_desktop_config_add_listener (kbd_config->conf_client,
684
 
                                          GKBD_KEYBOARD_CONFIG_DIR, func,
685
 
                                          user_data,
686
 
                                          &kbd_config->config_listener_id);
 
630
        kbd_config->config_listener_id =
 
631
            g_signal_connect (kbd_config->settings, "changed", func,
 
632
                              user_data);
687
633
}
688
634
 
689
635
void
690
636
gkbd_keyboard_config_stop_listen (GkbdKeyboardConfig * kbd_config)
691
637
{
692
 
        gkbd_desktop_config_remove_listener (kbd_config->conf_client,
693
 
                                             &kbd_config->
694
 
                                             config_listener_id);
 
638
        g_signal_handler_disconnect (kbd_config->settings,
 
639
                                     kbd_config->config_listener_id);
 
640
        kbd_config->config_listener_id = 0;
695
641
}
696
642
 
697
643
gboolean
716
662
}
717
663
 
718
664
const gchar *
719
 
gkbd_keyboard_config_format_full_layout (const gchar * layout_descr,
720
 
                                         const gchar * variant_descr)
 
665
gkbd_keyboard_config_format_full_description (const gchar * layout_descr,
 
666
                                              const gchar * variant_descr)
721
667
{
722
 
        static gchar full_descr[XKL_MAX_CI_DESC_LENGTH * 2];
723
668
        if (variant_descr == NULL || variant_descr[0] == 0)
724
 
                g_snprintf (full_descr, sizeof (full_descr), "%s",
725
 
                            layout_descr);
 
669
                return layout_descr;
726
670
        else
727
 
                g_snprintf (full_descr, sizeof (full_descr), "%s %s",
728
 
                            layout_descr, variant_descr);
729
 
        return full_descr;
 
671
                return variant_descr;
730
672
}
731
673
 
732
674
gchar *
735
677
        gchar *layouts = NULL, *options = NULL;
736
678
        GString *buffer = g_string_new (NULL);
737
679
 
738
 
        GSList *iter;
 
680
        gchar **iter;
739
681
        gint count;
740
682
        gchar *result;
741
683
 
742
684
        if (config->layouts_variants) {
743
685
                /* g_slist_length is "expensive", so we determinate the length on the fly */
744
 
                for (iter = config->layouts_variants, count = 0; iter;
745
 
                     iter = iter->next, ++count) {
 
686
                for (iter = config->layouts_variants, count = 0; *iter;
 
687
                     iter++, ++count) {
746
688
                        if (buffer->len)
747
689
                                g_string_append (buffer, " ");
748
690
 
749
 
                        g_string_append (buffer,
750
 
                                         (const gchar *) iter->data);
 
691
                        g_string_append (buffer, *iter);
751
692
                }
752
693
 
753
694
                /* Translators: The count is related to the number of options. The %s
760
701
        }
761
702
        if (config->options) {
762
703
                /* g_slist_length is "expensive", so we determinate the length on the fly */
763
 
                for (iter = config->options, count = 0; iter;
764
 
                     iter = iter->next, ++count) {
 
704
                for (iter = config->options, count = 0; *iter;
 
705
                     iter++, ++count) {
765
706
                        if (buffer->len)
766
707
                                g_string_append (buffer, " ");
767
708
 
768
 
                        g_string_append (buffer,
769
 
                                         (const gchar *) iter->data);
 
709
                        g_string_append (buffer, *iter);
770
710
                }
771
711
 
772
712
                /* Translators: The count is related to the number of options. The %s
791
731
        return result;
792
732
}
793
733
 
794
 
GSList *
795
 
gkbd_keyboard_config_add_default_switch_option_if_necessary (GSList *
 
734
/**
 
735
 * gkbd_keyboard_config_add_default_switch_option_if_necessary:
 
736
 * Returns: (transfer full) (array zero-terminated=1): List of options
 
737
 */
 
738
gchar **
 
739
gkbd_keyboard_config_add_default_switch_option_if_necessary (gchar **
796
740
                                                             layouts_list,
797
 
                                                             GSList *
798
 
                                                             options_list, gboolean *was_appended)
 
741
                                                             gchar **
 
742
                                                             options_list,
 
743
                                                             gboolean *
 
744
                                                             was_appended)
799
745
{
800
746
        *was_appended = FALSE;
801
 
        if (g_slist_length (layouts_list) >= 2) {
 
747
        if (g_strv_length (layouts_list) >= 2) {
802
748
                gboolean any_switcher = False;
803
 
                GSList *option = options_list;
804
 
                while (option != NULL) {
805
 
                        char *g, *o;
806
 
                        if (gkbd_keyboard_config_split_items
807
 
                            (option->data, &g, &o)) {
808
 
                                if (!g_ascii_strcasecmp
809
 
                                    (g, GROUP_SWITCHERS_GROUP)) {
810
 
                                        any_switcher = True;
811
 
                                        break;
 
749
                if (*options_list != NULL) {
 
750
                        gchar **option = options_list;
 
751
                        while (*option != NULL) {
 
752
                                char *g, *o;
 
753
                                if (gkbd_keyboard_config_split_items
 
754
                                    (*option, &g, &o)) {
 
755
                                        if (!g_ascii_strcasecmp
 
756
                                            (g, GROUP_SWITCHERS_GROUP)) {
 
757
                                                any_switcher = True;
 
758
                                                break;
 
759
                                        }
812
760
                                }
 
761
                                option++;
813
762
                        }
814
 
                        option = option->next;
815
763
                }
816
764
                if (!any_switcher) {
817
765
                        const gchar *id =
819
767
                            (GROUP_SWITCHERS_GROUP,
820
768
                             DEFAULT_GROUP_SWITCH);
821
769
                        options_list =
822
 
                            g_slist_append (options_list, g_strdup (id));
 
770
                            gkbd_strv_append (options_list, g_strdup (id));
823
771
                        *was_appended = TRUE;
824
772
                }
825
773
        }