~ubuntu-branches/ubuntu/quantal/ibus/quantal

« back to all changes in this revision

Viewing changes to bus/registry.c

  • Committer: Bazaar Package Importer
  • Author(s): Barry Warsaw
  • Date: 2011-08-11 17:00:57 UTC
  • mfrom: (6.2.14 sid)
  • Revision ID: james.westby@ubuntu.com-20110811170057-6dmbfs4s3cchzl7x
Tags: 1.3.99.20110419-1ubuntu1
* Merge with Debian unstable.  Remaining Ubuntu changes:
  - Indicator support:
    + Add 05_appindicator.patch: Use an indicator rather than a notification
      icon.
    + debian/control: Recommend python-appindicator.
  - debian/control: Install im-switch instead of im-config by default.
  - debian/README.source: Removed, it was outdated and no longer correct
  - debian/patches/01_ubuntu_desktop: Fix "Desktop entry needs the
    X-Ubuntu-Gettext-Domain key"  (LP: #457632)
  - debian/patches/02_title_update.patch: Rename "IBus Preferences" to
    "Keyboard Input Methods"
  - debian/patches/06_locale_parser.patch: Cherry-picked from upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20
20
 * Boston, MA 02111-1307, USA.
21
21
 */
 
22
#include "registry.h"
22
23
#include <glib/gstdio.h>
23
24
#include <gio/gio.h>
24
25
#include <stdlib.h>
25
26
#include <string.h>
26
 
#include <ibusinternal.h>
27
 
#include "registry.h"
 
27
#include "types.h"
28
28
#include "option.h"
 
29
#include "marshalers.h"
 
30
#include "dbusimpl.h"
29
31
 
30
32
enum {
31
33
    CHANGED,
34
36
 
35
37
static guint             _signals[LAST_SIGNAL] = { 0 };
36
38
 
 
39
struct _BusRegistry {
 
40
    IBusObject parent;
 
41
 
 
42
    /* instance members */
 
43
 
 
44
    /* a list of IBusObservedPath objects. */
 
45
    GList *observed_paths;
 
46
    /* a list of BusComponent objects that are created from component XML files (or from the cache of them). */
 
47
    GList *components;
 
48
    /* a mapping from an engine name (e.g. 'pinyin') to the corresponding IBusEngineDesc object. */
 
49
    GHashTable *engine_table;
 
50
 
 
51
#ifdef G_THREADS_ENABLED
 
52
    GThread *thread;
 
53
    gboolean thread_running;
 
54
    GMutex  *mutex;
 
55
    GCond   *cond;
 
56
    gboolean changed;
 
57
#endif
 
58
};
 
59
 
 
60
struct _BusRegistryClass {
 
61
    IBusObjectClass parent;
 
62
 
 
63
    /* class members */
 
64
};
 
65
 
37
66
/* functions prototype */
38
67
static void              bus_registry_destroy           (BusRegistry        *registry);
39
68
static void              bus_registry_load              (BusRegistry        *registry);
47
76
G_DEFINE_TYPE (BusRegistry, bus_registry, IBUS_TYPE_OBJECT)
48
77
 
49
78
static void
50
 
bus_registry_class_init (BusRegistryClass *klass)
 
79
bus_registry_class_init (BusRegistryClass *class)
51
80
{
52
 
    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
53
 
    IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
 
81
    GObjectClass *gobject_class = G_OBJECT_CLASS (class);
 
82
    IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (class);
54
83
 
55
84
    _signals[CHANGED] =
56
85
        g_signal_new (I_("changed"),
57
86
            G_TYPE_FROM_CLASS (gobject_class),
58
87
            G_SIGNAL_RUN_LAST,
59
 
            0,
 
88
            0, /* does not associate a method in this class. the "changed" signal would be handled in other classes. */
60
89
            NULL, NULL,
61
 
            ibus_marshal_VOID__VOID,
 
90
            bus_marshal_VOID__VOID,
62
91
            G_TYPE_NONE,
63
92
            0);
64
93
 
111
140
    }
112
141
 
113
142
    for (p = registry->components; p != NULL; p = p->next) {
114
 
        IBusComponent *comp = (IBusComponent *)p->data;
 
143
        BusComponent *comp = (BusComponent *) p->data;
 
144
        GList *engines = bus_component_get_engines (comp);
115
145
        GList *p1;
116
 
 
117
 
        for (p1 = comp->engines; p1 != NULL; p1 = p1->next) {
118
 
            IBusEngineDesc *desc = (IBusEngineDesc *)p1->data;
119
 
            g_hash_table_insert (registry->engine_table, desc->name, desc);
120
 
            g_object_set_data ((GObject *)desc, "component", comp);
 
146
        for (p1 = engines; p1 != NULL; p1 = p1->next) {
 
147
            IBusEngineDesc *desc = (IBusEngineDesc *) p1->data;
 
148
            g_hash_table_insert (registry->engine_table,
 
149
                                 (gpointer) ibus_engine_desc_get_name (desc),
 
150
                                 desc);
121
151
        }
 
152
        g_list_free (engines);
122
153
    }
123
154
}
124
155
 
148
179
        /* Raise a signal to cause the loop in _checks_changes() exits
149
180
         * immediately, and then wait until the thread finishes, and release all
150
181
         * resources of the thread.
151
 
         * */
 
182
         */
152
183
        g_cond_signal (registry->cond);
153
184
        g_thread_join (registry->thread);
154
185
 
172
203
    IBUS_OBJECT_CLASS (bus_registry_parent_class)->destroy (IBUS_OBJECT (registry));
173
204
}
174
205
 
175
 
 
 
206
/**
 
207
 * bus_registry_load:
 
208
 *
 
209
 * Read all XML files in the PKGDATADIR (typically /usr/share/ibus/components/ *.xml) and update the registry object.
 
210
 */
176
211
static void
177
212
bus_registry_load (BusRegistry *registry)
178
213
{
190
225
 
191
226
    g_free (dirname);
192
227
 
 
228
#if 0
 
229
    /* FIXME Should we support install some IME in user dir? */
193
230
    dirname = g_build_filename (g_get_user_data_dir (), "ibus", "component", NULL);
194
231
 
195
232
    path = ibus_observed_path_new (dirname, TRUE);
196
233
    registry->observed_paths = g_list_append (registry->observed_paths, path);
197
234
 
198
 
    if (g_file_test(dirname, G_FILE_TEST_EXISTS)) {
 
235
    if (g_file_test (dirname, G_FILE_TEST_EXISTS)) {
199
236
        bus_registry_load_in_dir (registry, dirname);
200
237
    }
201
238
 
202
239
    g_free (dirname);
 
240
#endif
203
241
}
204
242
 
205
 
 
206
243
#define g_string_append_indent(string, indent)  \
207
244
    {                                           \
208
245
        gint i;                                 \
254
291
                IBusComponent *component;
255
292
                component = ibus_component_new_from_xml_node (pp->data);
256
293
                if (component) {
257
 
                    g_object_ref_sink (component);
258
 
                    registry->components = g_list_append (registry->components, component);
 
294
                    BusComponent *buscomp = bus_component_new (component,
 
295
                                                               NULL /* factory */);
 
296
                    g_object_ref_sink (buscomp);
 
297
                    registry->components =
 
298
                        g_list_append (registry->components, buscomp);
259
299
                }
260
300
            }
261
301
 
274
314
    GList *p;
275
315
 
276
316
    for (p = registry->observed_paths; p != NULL; p = p->next) {
277
 
        if (ibus_observed_path_check_modification ((IBusObservedPath *)p->data))
 
317
        if (ibus_observed_path_check_modification ((IBusObservedPath *) p->data))
278
318
            return TRUE;
279
319
    }
280
320
 
281
321
    for (p = registry->components; p != NULL; p = p->next) {
282
 
        if (ibus_component_check_modification ((IBusComponent *)p->data))
 
322
        if (ibus_component_check_modification (bus_component_get_component ((BusComponent *) p->data)))
283
323
            return TRUE;
284
324
    }
285
325
 
296
336
    GString *output;
297
337
    GList *p;
298
338
    FILE *pf;
 
339
    size_t items = 0;
299
340
 
300
341
    cachedir = g_build_filename (g_get_user_cache_dir (), "ibus", "bus", NULL);
301
342
    filename = g_build_filename (cachedir, "registry.xml", NULL);
320
361
        g_string_append_indent (output, 1);
321
362
        g_string_append (output, "<observed-paths>\n");
322
363
        for (p = registry->observed_paths; p != NULL; p = p->next) {
323
 
            ibus_observed_path_output ((IBusObservedPath *)p->data,
 
364
            ibus_observed_path_output ((IBusObservedPath *) p->data,
324
365
                                      output, 2);
325
366
        }
326
367
        g_string_append_indent (output, 1);
331
372
        g_string_append_indent (output, 1);
332
373
        g_string_append (output, "<components>\n");
333
374
        for (p = registry->components; p != NULL; p = p->next) {
334
 
            ibus_component_output ((IBusComponent *)p->data,
335
 
                                      output, 2);
 
375
            ibus_component_output (bus_component_get_component ((BusComponent *) p->data),
 
376
                                   output, 2);
336
377
        }
337
378
        g_string_append_indent (output, 1);
338
379
        g_string_append (output, "</components>\n");
339
380
    }
340
381
 
341
382
    g_string_append (output, "</ibus-registry>\n");
342
 
    fwrite (output->str, output->len, 1, pf);
 
383
    items = fwrite (output->str, output->len, 1, pf);
343
384
    g_string_free (output, TRUE);
344
385
    fclose (pf);
345
 
    return TRUE;
 
386
    return (items == 1 ? TRUE : FALSE);
346
387
}
347
388
 
 
389
/**
 
390
 * bus_registry_load_in_dir:
 
391
 *
 
392
 * Read all XML files in dirname, create a BusComponent object for each file, and add the component objects to the registry.
 
393
 */
348
394
static void
349
395
bus_registry_load_in_dir (BusRegistry *registry,
350
396
                          const gchar *dirname)
370
416
        IBusComponent *component;
371
417
 
372
418
        size = g_utf8_strlen (filename, -1);
373
 
        if (g_strcmp0 (MAX (filename, filename + size -4), ".xml" ) != 0)
 
419
        if (g_strcmp0 (MAX (filename, filename + size - 4), ".xml") != 0)
374
420
            continue;
375
421
 
376
422
        path = g_build_filename (dirname, filename, NULL);
377
423
        component = ibus_component_new_from_file (path);
378
424
        if (component != NULL) {
379
 
            g_object_ref_sink (component);
380
 
            registry->components = g_list_append (registry->components, component);
 
425
            BusComponent *buscomp = bus_component_new (component,
 
426
                                                       NULL /* factory */);
 
427
            registry->components = g_list_append (registry->components, buscomp);
381
428
        }
382
429
 
383
430
        g_free (path);
391
438
bus_registry_new (void)
392
439
{
393
440
    BusRegistry *registry;
394
 
    registry = (BusRegistry *)g_object_new (BUS_TYPE_REGISTRY, NULL);
 
441
    registry = (BusRegistry *) g_object_new (BUS_TYPE_REGISTRY, NULL);
395
442
    return registry;
396
443
}
397
444
 
398
445
static gint
399
 
_component_is_name (IBusComponent *component,
400
 
                    const gchar   *name)
 
446
bus_register_component_is_name_cb (BusComponent *component,
 
447
                                   const gchar  *name)
401
448
{
402
 
    g_assert (IBUS_IS_COMPONENT (component));
 
449
    g_assert (BUS_IS_COMPONENT (component));
403
450
    g_assert (name);
404
451
 
405
 
    return g_strcmp0 (component->name, name);
 
452
    return g_strcmp0 (bus_component_get_name (component), name);
406
453
}
407
454
 
408
 
IBusComponent *
 
455
BusComponent *
409
456
bus_registry_lookup_component_by_name (BusRegistry *registry,
410
457
                                       const gchar *name)
411
458
{
415
462
    GList *p;
416
463
    p = g_list_find_custom (registry->components,
417
464
                            name,
418
 
                            (GCompareFunc)_component_is_name);
 
465
                            (GCompareFunc) bus_register_component_is_name_cb);
419
466
    if (p) {
420
 
        return (IBusComponent *)p->data;
 
467
        return (BusComponent *) p->data;
421
468
    }
422
469
    else {
423
470
        return NULL;
440
487
    return g_hash_table_get_values (registry->engine_table);
441
488
}
442
489
 
443
 
 
444
490
GList *
445
491
bus_registry_get_engines_by_language (BusRegistry *registry,
446
492
                                      const gchar *language)
459
505
 
460
506
    for (p2 = p1; p2 != NULL; p2 = p2->next) {
461
507
        IBusEngineDesc *desc = (IBusEngineDesc *) p2->data;
462
 
        if (strncmp (desc->language, language, n) == 0) {
 
508
        if (strncmp (ibus_engine_desc_get_language (desc), language, n) == 0) {
463
509
            engines = g_list_append (engines, desc);
464
510
        }
465
511
    }
483
529
{
484
530
    g_assert (BUS_IS_REGISTRY (registry));
485
531
 
486
 
    g_list_foreach (registry->components, (GFunc) ibus_component_stop, NULL);
 
532
    g_list_foreach (registry->components, (GFunc) bus_component_stop, NULL);
487
533
 
488
534
}
489
535
 
539
585
    return NULL;
540
586
}
541
587
 
 
588
/**
 
589
 * bus_registry_start_monitor_changes:
 
590
 *
 
591
 * Start the monitor thread.
 
592
 */
542
593
void
543
594
bus_registry_start_monitor_changes (BusRegistry *registry)
544
595
{
548
599
    g_return_if_fail (registry->changed == FALSE);
549
600
 
550
601
    registry->thread_running = TRUE;
551
 
    registry->thread = g_thread_create ((GThreadFunc)_check_changes,
 
602
    registry->thread = g_thread_create ((GThreadFunc) _check_changes,
552
603
                                        registry,
553
604
                                        TRUE,
554
605
                                        NULL);
562
613
}
563
614
#endif
564
615
 
565
 
BusFactoryProxy *
 
616
void
566
617
bus_registry_name_owner_changed (BusRegistry *registry,
567
618
                                 const gchar *name,
568
619
                                 const gchar *old_name,
573
624
    g_assert (old_name);
574
625
    g_assert (new_name);
575
626
 
576
 
    IBusComponent *component;
 
627
    BusComponent *component;
577
628
    BusFactoryProxy *factory;
578
629
 
579
630
    component = bus_registry_lookup_component_by_name (registry, name);
580
631
 
581
632
    if (component == NULL) {
582
 
        return NULL;
 
633
        /* name is a unique name, or a well-known name we don't know. */
 
634
        return;
583
635
    }
584
636
 
585
637
    if (g_strcmp0 (old_name, "") != 0) {
586
 
        factory = bus_factory_proxy_get_from_component (component);
 
638
        /* the component is stopped. */
 
639
        factory = bus_component_get_factory (component);
587
640
 
588
641
        if (factory != NULL) {
589
 
            ibus_object_destroy ((IBusObject *)factory);
 
642
            ibus_proxy_destroy ((IBusProxy *) factory);
590
643
        }
591
644
    }
592
645
 
593
646
    if (g_strcmp0 (new_name, "") != 0) {
594
 
        factory = bus_factory_proxy_new (component, NULL);
595
 
        return factory;
 
647
        /* the component is started. */
 
648
        BusConnection *connection =
 
649
                bus_dbus_impl_get_connection_by_name (BUS_DEFAULT_DBUS,
 
650
                                                      new_name);
 
651
        if (connection == NULL)
 
652
            return;
 
653
 
 
654
        factory = bus_factory_proxy_new (connection);
 
655
        if (factory == NULL)
 
656
            return;
 
657
        g_object_ref_sink (factory);
 
658
        bus_component_set_factory (component, factory);
 
659
        g_object_unref (factory);
596
660
    }
597
 
 
598
 
    return NULL;
599
661
}