Add ibus-dconf.
authorDaiki Ueno <ueno@unixuser.org>
Mon, 18 Jul 2011 09:44:23 +0000 (18:44 +0900)
committerDaiki Ueno <ueno@unixuser.org>
Mon, 18 Jul 2011 09:44:23 +0000 (18:44 +0900)
BUG=https://code.google.com/p/ibus/issues/detail?id=1235
TEST=manually with "make check" and interactive testing

Review URL: http://codereview.appspot.com/4750041

13 files changed:
Makefile.am
configure.ac
data/Makefile.am
data/dconf/Makefile.am [new file with mode: 0644]
data/dconf/ibus.convert [new file with mode: 0644]
data/dconf/make-dconf-override-db.sh [new file with mode: 0755]
data/dconf/profile/ibus [new file with mode: 0644]
data/ibus.schemas.in
dconf/Makefile.am [new file with mode: 0644]
dconf/config.c [new file with mode: 0644]
dconf/config.h [new file with mode: 0644]
dconf/dconf.xml.in.in [new file with mode: 0644]
dconf/main.c [new file with mode: 0644]

index 7be558b..ff0fabc 100644 (file)
@@ -48,6 +48,12 @@ MEMCONF_DIRS = \
        $(NULL)
 endif
 
+if ENABLE_DCONF
+DCONF_DIRS = \
+       dconf \
+       $(NULL)
+endif
+
 SUBDIRS =           \
        src             \
        util            \
@@ -61,6 +67,7 @@ SUBDIRS =           \
        $(PYTHON_DIRS)  \
        $(GCONF_DIRS)   \
        $(MEMCONF_DIRS) \
+       $(DCONF_DIRS)   \
        $(NULL)
 
 ACLOCAL_AMFLAGS = -I m4
index 5544dfa..c3bd423 100644 (file)
@@ -245,6 +245,24 @@ AC_ARG_ENABLE(memconf,
 )
 AM_CONDITIONAL([ENABLE_MEMCONF], [test "x$enable_memconf" = "xyes"])
 
+AC_ARG_ENABLE(dconf,
+    AS_HELP_STRING([--enable-dconf],
+                   [Enable configure base on dconf]),
+    [enable_dconf=$enableval],
+    [enable_dconf=no]
+)
+
+if test x"$enable_dconf" = x"yes"; then
+    # check dconf
+    PKG_CHECK_MODULES(DCONF,
+        [dconf >= 0.7.5], ,
+        enable_dconf=no
+    )
+    # check glib-compile-schemas
+    GLIB_GSETTINGS
+fi
+AM_CONDITIONAL([ENABLE_DCONF], [test x"$enable_dconf" = x"yes"])
+
 # check env
 AC_PATH_PROG(ENV_IBUS_TEST, env)
 AC_SUBST(ENV_IBUS_TEST)
@@ -412,6 +430,7 @@ util/IMdkit/Makefile
 data/Makefile
 data/icons/Makefile
 data/keymaps/Makefile
+data/dconf/Makefile
 docs/Makefile
 docs/reference/Makefile
 docs/reference/ibus/ibus-docs.sgml
@@ -430,6 +449,8 @@ gconf/Makefile
 gconf/gconf.xml.in
 bindings/Makefile
 bindings/vala/Makefile
+dconf/Makefile
+dconf/dconf.xml.in
 ])
 
 AC_OUTPUT
@@ -448,6 +469,7 @@ Build options:
   Build python modules      $enable_python
   Build gconf modules       $enable_gconf
   Build memconf modules     $enable_memconf
+  Build dconf modules       $enable_dconf
   Build introspection       $found_introspection
   IBus-1.0.gir scannerflags "$IBUS_GIR_SCANNERFLAGS"
   Build vala binding        $enable_vala
index ba9f4bb..99be41c 100644 (file)
@@ -25,6 +25,10 @@ SUBDIRS = \
        keymaps \
        $(NULL)
 
+if ENABLE_DCONF
+SUBDIRS += dconf
+endif
+
 schemasdir = $(GCONF_SCHEMA_FILE_DIR)
 schemas_in_files = ibus.schemas.in
 schemas_DATA = $(schemas_in_files:.schemas.in=.schemas)
diff --git a/data/dconf/Makefile.am b/data/dconf/Makefile.am
new file mode 100644 (file)
index 0000000..c0e9140
--- /dev/null
@@ -0,0 +1,58 @@
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2007-2010 Peng Huang <shawn.p.huang@gmail.com>
+# Copyright (c) 2011 Daiki Ueno <ueno@unixuser.org>
+# Copyright (c) 2007-2011 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA  02111-1307  USA
+
+gsettings_schemas_in_files = org.freedesktop.ibus.gschema.xml.in
+gsettings_SCHEMAS = $(gsettings_schemas_in_files:.gschema.xml.in=.gschema.xml)
+gsettingsconvertdir = $(datadir)/GConf/gsettings
+dist_gsettingsconvert_DATA = ibus.convert
+@GSETTINGS_RULES@
+@INTLTOOL_XML_NOMERGE_RULE@
+
+EXTRA_DIST = \
+       $(gsettings_schemas_in_files) \
+       make-dconf-override-db.sh \
+       $(NULL)
+
+DISTCLEANFILES = \
+       $(gsettings_SCHEMAS) \
+       $(NULL)
+
+MAINTAINERCLEANFILES = \
+       $(gsettings_schemas_in_files)
+       $(NULL)
+
+dconfprofiledir = $(sysconfdir)/dconf
+nobase_dist_dconfprofile_DATA = \
+       db/ibus \
+       profile/ibus
+
+org.freedesktop.ibus.gschema.xml.in: $(top_srcdir)/data/ibus.schemas.in
+       $(AM_V_GEN) gsettings-schema-convert --force --gconf --xml \
+               --schema-id "org.freedesktop.ibus" \
+               --output $@ $<
+
+db/ibus: $(srcdir)/make-dconf-override-db.sh $(gsettings_SCHEMAS)
+       @$(MKDIR_P) db
+       $(AM_V_GEN) $(srcdir)/make-dconf-override-db.sh $@ || \
+               { rc=$$?; $(RM) -rf $@; exit $$rc; }
+
diff --git a/data/dconf/ibus.convert b/data/dconf/ibus.convert
new file mode 100644 (file)
index 0000000..ff35e51
--- /dev/null
@@ -0,0 +1,25 @@
+[org.freedesktop.ibus.general]
+embed-preedit-text = /desktop/ibus/general/embed_preedit_text
+enable-by-default = /desktop/ibus/general/enable_by_default
+preload-engines = /desktop/ibus/general/preload_engines
+use-global-engine = /desktop/ibus/general/use_global_engine
+use-system-keyboard-layout = /desktop/ibus/general/use_system_keyboard_layout
+
+[org.freedesktop.ibus.general.hotkey]
+disable-unconditional = /desktop/ibus/general/disable_unconditional
+enable-unconditional = /desktop/ibus/general/enable_unconditional
+next-engine = /desktop/ibus/general/next_engine
+next-engine-in-menu = /desktop/ibus/general/next_engine_in_menu
+prev-engine = /desktop/ibus/general/prev_engine
+previous-engine = /desktop/ibus/general/previous_engine
+trigger = /desktop/ibus/general/trigger
+
+[org.freedesktop.ibus.panel]
+custom-font = /desktop/ibus/general/custom_font
+lookup-table-orientation = /desktop/ibus/general/lookup_table_orientation
+show = /desktop/ibus/general/show
+show-icon-on-systray = /desktop/ibus/general/show_icon_on_systray
+show-im-name = /desktop/ibus/general/show_im_name
+use-custom-font = /desktop/ibus/general/use_custom_font
+x = /desktop/ibus/general/x
+y = /desktop/ibus/general/y
diff --git a/data/dconf/make-dconf-override-db.sh b/data/dconf/make-dconf-override-db.sh
new file mode 100755 (executable)
index 0000000..0d8456b
--- /dev/null
@@ -0,0 +1,31 @@
+#!/bin/bash
+
+set -e
+
+export TMPDIR=$(mktemp -d --tmpdir="$PWD")
+export XDG_CONFIG_HOME="$TMPDIR/config"
+export XDG_CACHE_HOME="$TMPDIR/cache"
+export GSETTINGS_SCHEMA_DIR="$TMPDIR/schemas"
+mkdir -p $XDG_CONFIG_HOME $XDG_CACHE_HOME $GSETTINGS_SCHEMA_DIR
+
+eval `dbus-launch --sh-syntax`
+
+trap 'rm -rf $TMPDIR; kill $DBUS_SESSION_BUS_PID' ERR
+
+# in case that schema is not installed on the system
+glib-compile-schemas --targetdir "$GSETTINGS_SCHEMA_DIR" "$PWD"
+
+gsettings list-recursively org.freedesktop.ibus.general | \
+while read schema key val; do
+    gsettings set "$schema" "$key" "$val"
+done
+
+gsettings list-recursively org.freedesktop.ibus.panel | \
+while read schema key val; do
+    gsettings set "$schema" "$key" "$val"
+done
+
+mv $XDG_CONFIG_HOME/dconf/user "$1"
+rm -rf $TMPDIR
+
+kill $DBUS_SESSION_BUS_PID
diff --git a/data/dconf/profile/ibus b/data/dconf/profile/ibus
new file mode 100644 (file)
index 0000000..c4ac80e
--- /dev/null
@@ -0,0 +1,2 @@
+user
+ibus
index b75295e..663358c 100644 (file)
@@ -6,6 +6,7 @@
       <applyto>/desktop/ibus/general/preload_engines</applyto>
       <owner>ibus</owner>
       <type>list</type>
+      <default>[]</default>
       <list_type>string</list_type>
       <locale name="C">
         <short>Preload engines</short>
diff --git a/dconf/Makefile.am b/dconf/Makefile.am
new file mode 100644 (file)
index 0000000..148ba62
--- /dev/null
@@ -0,0 +1,83 @@
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2007-2010 Peng Huang <shawn.p.huang@gmail.com>
+# Copyright (c) 2007-2010 Red Hat, Inc.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this program; if not, write to the
+# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+# Boston, MA  02111-1307  USA
+
+libibus = $(top_builddir)/src/libibus-@IBUS_API_VERSION@.la
+
+libexec_PROGRAMS = \
+       ibus-dconf \
+       $(NULL)
+
+ibus_dconf_SOURCES = \
+       main.c \
+       config.c \
+       config.h \
+       $(NULL)
+ibus_dconf_CFLAGS = \
+       @GLIB2_CFLAGS@ \
+       @GIO2_CFLAGS@ \
+       @DCONF_CFLAGS@ \
+       -DG_LOG_DOMAIN=\"IBUS\" \
+       -I$(top_srcdir)/src \
+       -I$(top_builddir)/src \
+       $(NULL)
+ibus_dconf_LDADD = \
+       @GOBJECT2_LIBS@ \
+       @GLIB2_LIBS@ \
+       @GIO2_LIBS@ \
+       @DCONF_LIBS@ \
+       $(libibus) \
+       $(NULL)
+ibus_dconf_DEPENDENCIES = \
+       $(libibus) \
+       $(NULL)
+
+component_DATA = \
+       dconf.xml \
+       $(NULL)
+
+componentdir = $(pkgdatadir)/component
+
+CLEANFILES = \
+       dconf.xml \
+       *.pyc \
+       $(NULL)
+
+DISTCLEANFILES = \
+       dconf-override-db \
+       $(NULL)
+
+EXTRA_DIST = \
+       dconf.xml.in.in \
+       $(NULL)
+
+dconf.xml: dconf.xml.in
+       $(AM_V_GEN) \
+       ( \
+               libexecdir=${libexecdir}; \
+               s=`cat $<`; \
+               eval "echo \"$${s}\""; \
+       ) > $@
+
+$(libibus):
+       $(MAKE) -C $(top_builddir)/src
+
+-include $(top_srcdir)/git.mk
diff --git a/dconf/config.c b/dconf/config.c
new file mode 100644 (file)
index 0000000..511fda7
--- /dev/null
@@ -0,0 +1,354 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2011 Daiki Ueno <ueno@unixuser.org>
+ * Copyright (C) 2008-2011 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <string.h>
+#include <ibus.h>
+#include "config.h"
+
+#define DCONF_PREFIX "/desktop/ibus"
+
+struct _IBusConfigDConf {
+    IBusConfigService parent;
+    DConfClient *client;
+};
+
+struct _IBusConfigDConfClass {
+    IBusConfigServiceClass parent;
+};
+
+/* functions prototype */
+static void      ibus_config_dconf_class_init  (IBusConfigDConfClass *class);
+static void      ibus_config_dconf_init        (IBusConfigDConf      *config);
+static void      ibus_config_dconf_destroy     (IBusConfigDConf      *config);
+static gboolean  ibus_config_dconf_set_value   (IBusConfigService    *config,
+                                                const gchar          *section,
+                                                const gchar          *name,
+                                                GVariant             *value,
+                                                GError              **error);
+static GVariant *ibus_config_dconf_get_value   (IBusConfigService    *config,
+                                                const gchar          *section,
+                                                const gchar          *name,
+                                                GError              **error);
+static GVariant *ibus_config_dconf_get_values  (IBusConfigService    *config,
+                                                const gchar          *section,
+                                                GError              **error);
+static gboolean  ibus_config_dconf_unset_value (IBusConfigService    *config,
+                                                const gchar          *section,
+                                                const gchar          *name,
+                                                GError              **error);
+
+G_DEFINE_TYPE (IBusConfigDConf, ibus_config_dconf, IBUS_TYPE_CONFIG_SERVICE)
+
+static void
+ibus_config_dconf_class_init (IBusConfigDConfClass *class)
+{
+    IBusObjectClass *object_class = IBUS_OBJECT_CLASS (class);
+    IBusConfigServiceClass *config_class = IBUS_CONFIG_SERVICE_CLASS (class);
+
+    object_class->destroy = (IBusObjectDestroyFunc) ibus_config_dconf_destroy;
+    config_class->set_value = ibus_config_dconf_set_value;
+    config_class->get_value = ibus_config_dconf_get_value;
+    config_class->get_values = ibus_config_dconf_get_values;
+    config_class->unset_value = ibus_config_dconf_unset_value;
+}
+
+/* Convert key names from/to GSettings names.  While GSettings only
+ * accepts lowercase letters / numbers / and dash ('-'), IBus uses
+ * underscore ('_') and some engines even use uppercase letters.
+ *
+ * To minimize the gap, we do the following conversion:
+ *
+ * - when converting from IBus names to GSettings names, first convert
+ *   all letters to lowercase and then replace underscores with dashes.
+ * - when converting from GSettings names to IBus names, simply
+ *   replace dashes with underscores.
+ *
+ * Note that though the conversion does not always roundtrip, it does
+ * in most cases.
+ */
+static gchar *
+_to_gsettings_name (const gchar *name)
+{
+    return g_strcanon (g_ascii_strdown (name, -1),
+                       "abcdefghijklmnopqrstuvwxyz0123456789-",
+                       '-');
+}
+
+static gchar *
+_from_gsettings_name (const gchar *name)
+{
+    gchar *retval = g_strdup (name), *p;
+    for (p = retval; *p != '\0'; p++)
+        if (*p == '-')
+            *p = '_';
+    return retval;
+}
+
+typedef gchar *(* NameConvFunc) (const gchar *);
+
+static gchar *
+_conv_path (const gchar *path, NameConvFunc conv_func)
+{
+    gchar **strv = g_strsplit (path, "/", -1), **p;
+    gchar *retval;
+
+    for (p = strv; *p; p++) {
+        gchar *canon;
+        canon = (*conv_func) (*p);
+        g_free (*p);
+        *p = canon;
+    }
+
+    retval = g_strjoinv ("/", strv);
+    g_strfreev (strv);
+    return retval;
+}
+
+static gchar *
+_to_gsettings_path (const gchar *path)
+{
+    return _conv_path (path, _to_gsettings_name);
+}
+
+static gchar *
+_from_gsettings_path (const gchar *gpath)
+{
+    return _conv_path (gpath, _from_gsettings_name);
+}
+
+static void
+_watch_func (DConfClient         *client,
+             const gchar         *gpath,
+             const gchar * const *items,
+             gint                 n_items,
+             const gchar         *tag,
+             IBusConfigDConf     *config)
+{
+    gchar **gkeys = NULL;
+    gint i;
+
+    g_return_if_fail (gpath != NULL);
+    g_return_if_fail (n_items >= 0);
+
+    if (dconf_is_key (gpath, NULL)) {
+        /* If path is a key, the notification should be taken to mean
+           that one key may have changed. */
+        n_items = 1;
+        gkeys = g_malloc0_n (n_items + 1, sizeof (gchar *));
+        gkeys[0] = g_strdup (gpath);
+    } else {
+        if (n_items == 0) {
+            /* If path is a dir and items is empty then it is an
+               indication that any key under path may have
+               changed. */
+            gkeys = dconf_client_list (config->client, gpath, &n_items);
+        } else {
+            gkeys = g_boxed_copy (G_TYPE_STRV, items);
+        }
+        for (i = 0; i < n_items; i++) {
+            gchar *gname = gkeys[i];
+            gkeys[i] = g_strdup_printf ("%s/%s", gpath, gname);
+            g_free (gname);
+        }
+    }
+
+    for (i = 0; i < n_items; i++) {
+        gchar *gname, *path, *name;
+        GVariant *variant = dconf_client_read (config->client, gkeys[i]);
+
+        if (variant == NULL) {
+            /* Use a empty typle for a unset value */
+            variant = g_variant_new_tuple (NULL, 0);
+        }
+
+        gname = strrchr (gkeys[i], '/');
+        g_assert (gname);
+        *gname++ = '\0';
+
+        path = _from_gsettings_path (gkeys[i]);
+        name = _from_gsettings_name (gname);
+
+        ibus_config_service_value_changed ((IBusConfigService *) config,
+                                           path + sizeof (DCONF_PREFIX),
+                                           name,
+                                           variant);
+        g_free (path);
+        g_free (name);
+        g_variant_unref (variant);
+    }
+    g_strfreev (gkeys);
+}
+
+static void
+ibus_config_dconf_init (IBusConfigDConf *config)
+{
+    GError *error;
+
+    config->client = dconf_client_new ("ibus",
+                                       (DConfWatchFunc)_watch_func,
+                                       config,
+                                       NULL);
+
+    error = NULL;
+    if (!dconf_client_watch (config->client, DCONF_PREFIX"/", NULL, &error))
+        g_warning ("Can not watch dconf path %s", DCONF_PREFIX"/");
+}
+
+static void
+ibus_config_dconf_destroy (IBusConfigDConf *config)
+{
+    if (config->client) {
+        GError *error = NULL;
+        if (!dconf_client_unwatch (config->client, DCONF_PREFIX"/", NULL, &error))
+            g_warning ("Can not unwatch dconf path %s", DCONF_PREFIX"/");
+
+        g_object_unref (config->client);
+        config->client = NULL;
+    }
+
+    IBUS_OBJECT_CLASS (ibus_config_dconf_parent_class)->
+        destroy ((IBusObject *)config);
+}
+
+static gboolean
+ibus_config_dconf_set_value (IBusConfigService *config,
+                             const gchar       *section,
+                             const gchar       *name,
+                             GVariant          *value,
+                             GError           **error)
+{
+    DConfClient *client = ((IBusConfigDConf *)config)->client;
+    gchar *path, *gpath, *gname, *gkey;
+    gboolean retval;
+
+    path = g_strdup_printf (DCONF_PREFIX"/%s", section);
+
+    gpath = _to_gsettings_path (path);
+    gname = _to_gsettings_name (name);
+    gkey = g_strconcat (gpath, "/", gname, NULL);
+    g_free (gpath);
+    g_free (gname);
+
+    retval = dconf_client_write (client,
+                                 gkey,
+                                 value,
+                                 NULL,   /* tag */
+                                 NULL,   /* cancellable */
+                                 error);
+    g_free (gkey);
+
+    /* notify the caller that the value has changed, as dconf does not
+       call watch_func when the caller is the process itself */
+    if (retval) {
+        if (value == NULL) {
+            /* Use a empty typle for a unset value */
+            value = g_variant_new_tuple (NULL, 0);
+        }
+        ibus_config_service_value_changed (config, section, name, value);
+    }
+    return retval;
+}
+
+static GVariant *
+ibus_config_dconf_get_value (IBusConfigService *config,
+                             const gchar       *section,
+                             const gchar       *name,
+                             GError           **error)
+{
+    DConfClient *client = ((IBusConfigDConf *) config)->client;
+    gchar *path, *gpath, *gname, *gkey;
+    GVariant *variant;
+
+    path = g_strdup_printf (DCONF_PREFIX"/%s", section);
+
+    gpath = _to_gsettings_path (path);
+    gname = _to_gsettings_name (name);
+    gkey = g_strconcat (gpath, "/", gname, NULL);
+    g_free (gpath);
+    g_free (gname);
+
+    variant = dconf_client_read (client, gkey);
+    g_free (gkey);
+
+    if (variant == NULL) {
+        *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+                        "Config value [%s:%s] does not exist.", section, name);
+        return NULL;
+    }
+
+    return variant;
+}
+
+static GVariant *
+ibus_config_dconf_get_values (IBusConfigService *config,
+                              const gchar       *section,
+                              GError           **error)
+{
+    DConfClient *client = ((IBusConfigDConf *) config)->client;
+    gchar *dir, *gdir;
+    gint len;
+    gchar **entries, **p;
+    GVariantBuilder *builder;
+
+    dir = g_strdup_printf (DCONF_PREFIX"/%s/", section);
+    gdir = _to_gsettings_path (dir);
+    g_free (dir);
+
+    entries = dconf_client_list (client, gdir, &len);
+    builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+    for (p = entries; *p != NULL; p++) {
+        gchar *gkey = g_strconcat (gdir, *p, NULL);
+        GVariant *value = dconf_client_read (client, gkey);
+        g_free (gkey);
+        if (value) {
+            gchar *name = _from_gsettings_name (*p);
+            g_variant_builder_add (builder, "{sv}", name, value);
+            g_free (name);
+            g_variant_unref (value);
+        }
+    }
+    g_strfreev (entries);
+    g_free (gdir);
+
+    return g_variant_builder_end (builder);
+}
+
+static gboolean
+ibus_config_dconf_unset_value (IBusConfigService *config,
+                               const gchar       *section,
+                               const gchar       *name,
+                               GError           **error)
+{
+    return ibus_config_dconf_set_value (config, section, name, NULL, error);
+}
+
+IBusConfigDConf *
+ibus_config_dconf_new (GDBusConnection *connection)
+{
+    IBusConfigDConf *config;
+    config = (IBusConfigDConf *) g_object_new (IBUS_TYPE_CONFIG_DCONF,
+                                               "object-path", IBUS_PATH_CONFIG,
+                                               "connection", connection,
+                                               NULL);
+    return config;
+}
diff --git a/dconf/config.h b/dconf/config.h
new file mode 100644 (file)
index 0000000..9f602d6
--- /dev/null
@@ -0,0 +1,47 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __CONFIG_DCONF_H__
+#define __CONFIG_DCONF_H__
+
+#include <ibus.h>
+#include <dconf/dconf.h>
+
+#define IBUS_TYPE_CONFIG_DCONF            \
+    (ibus_config_dconf_get_type ())
+#define IBUS_CONFIG_DCONF(obj)            \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConf))
+#define IBUS_CONFIG_DCONF_CLASS(klass)     \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConfClass))
+#define IBUS_IS_CONFIG_DCONF(obj)          \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_CONFIG_DCONF))
+#define IBUS_IS_CONFIG_DCONF_CLASS(klass)  \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_CONFIG_DCONF))
+#define IBUS_CONFIG_DCONF_GET_CLASS(obj)   \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_CONFIG_DCONF, IBusConfigDConfClass))
+
+typedef struct _IBusConfigDConf IBusConfigDConf;
+typedef struct _IBusConfigDConfClass IBusConfigDConfClass;
+
+GType            ibus_config_dconf_get_type (void);
+IBusConfigDConf *ibus_config_dconf_new      (GDBusConnection *connection);
+
+#endif
diff --git a/dconf/dconf.xml.in.in b/dconf/dconf.xml.in.in
new file mode 100644 (file)
index 0000000..0367008
--- /dev/null
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- filename: dconf.xml -->
+<component>
+       <name>org.freedesktop.IBus.Config</name>
+       <description>Dconf Config Component</description>
+       <exec>${libexecdir}/ibus-dconf</exec>
+       <version>@VERSION@</version>
+       <author>Daiki Ueno &lt;ueno@unixuser.org&gt;</author>
+       <license>GPL</license>
+       <homepage>http://code.google.com/p/ibus</homepage>
+       <textdomain>ibus</textdomain>
+</component>
diff --git a/dconf/main.c b/dconf/main.c
new file mode 100644 (file)
index 0000000..1b69baa
--- /dev/null
@@ -0,0 +1,87 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (C) 2008-2010 Peng Huang <shawn.p.huang@gmail.com>
+ * Copyright (C) 2008-2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <ibus.h>
+#include <stdlib.h>
+#include <locale.h>
+#include "config.h"
+
+static IBusBus *bus = NULL;
+static IBusConfigDConf *config = NULL;
+
+/* options */
+static gboolean ibus = FALSE;
+static gboolean verbose = FALSE;
+
+static const GOptionEntry entries[] =
+{
+    { "ibus", 'i', 0, G_OPTION_ARG_NONE, &ibus, "component is executed by ibus",
+      NULL },
+    { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "verbose", NULL },
+    { NULL },
+};
+
+
+static void
+ibus_disconnected_cb (IBusBus  *bus,
+                      gpointer  user_data)
+{
+    ibus_quit ();
+}
+
+static void
+ibus_dconf_start (void)
+{
+    ibus_init ();
+    bus = ibus_bus_new ();
+    if (!ibus_bus_is_connected (bus)) {
+        exit (1);
+    }
+    g_signal_connect (bus, "disconnected", G_CALLBACK (ibus_disconnected_cb),
+                      NULL);
+    config = ibus_config_dconf_new (ibus_bus_get_connection (bus));
+    ibus_bus_request_name (bus, IBUS_SERVICE_CONFIG, 0);
+    ibus_main ();
+}
+
+gint
+main (gint argc, gchar **argv)
+{
+    GError *error = NULL;
+    GOptionContext *context;
+
+    setlocale (LC_ALL, "");
+
+    context = g_option_context_new ("- ibus dconf component");
+
+    g_option_context_add_main_entries (context, entries, "ibus-dconf");
+
+    if (!g_option_context_parse (context, &argc, &argv, &error)) {
+        g_print ("Option parsing failed: %s\n", error->message);
+        exit (-1);
+    }
+
+    ibus_set_log_handler (verbose);
+    ibus_dconf_start ();
+
+    return 0;
+}