summaryrefslogtreecommitdiff
path: root/conf
diff options
context:
space:
mode:
authorPeng Huang <shawn.p.huang@gmail.com>2011-12-17 15:20:29 -0500
committerPeng Huang <shawn.p.huang@gmail.com>2012-02-21 11:51:51 -0500
commit303308e397f409e3c74be72eaf307efc2a7cb832 (patch)
treeb9ba7de8ee4df03a285f0a372b6ab3a7d03641ed /conf
parent07c3d35786349db0f0b561e4ccb5051b71c8b0ed (diff)
WIP move all conf components into conf dir
Diffstat (limited to 'conf')
-rw-r--r--conf/Makefile.am47
-rw-r--r--conf/dconf/Makefile.am83
-rw-r--r--conf/dconf/config.c429
-rw-r--r--conf/dconf/config.h47
-rw-r--r--conf/dconf/dconf.xml.in.in12
-rw-r--r--conf/dconf/main.c87
-rw-r--r--conf/gconf/Makefile.am79
-rw-r--r--conf/gconf/config.c346
-rw-r--r--conf/gconf/config.h28
-rw-r--r--conf/gconf/gconf.xml.in.in12
-rw-r--r--conf/gconf/main.c65
-rw-r--r--conf/memconf/Makefile.am76
-rw-r--r--conf/memconf/config.c202
-rw-r--r--conf/memconf/config.h45
-rw-r--r--conf/memconf/main.c83
-rw-r--r--conf/memconf/memconf.xml.in.in11
16 files changed, 1652 insertions, 0 deletions
diff --git a/conf/Makefile.am b/conf/Makefile.am
new file mode 100644
index 00000000..86127b2f
--- /dev/null
+++ b/conf/Makefile.am
@@ -0,0 +1,47 @@
+# 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
+
+if ENABLE_GCONF
+GCONF_DIR = \
+ gconf \
+ $(NULL)
+endif
+
+if ENABLE_MEMCONF
+MEMCONF_DIR = \
+ memconf \
+ $(NULL)
+endif
+
+if ENABLE_DCONF
+DCONF_DIR = \
+ dconf \
+ $(NULL)
+endif
+
+SUBDIRS = \
+ $(DCONF_DIR) \
+ $(GCONF_DIR) \
+ $(MEMCONF_DIR) \
+ $(NULL)
+
+-include $(top_srcdir)/git.mk
diff --git a/conf/dconf/Makefile.am b/conf/dconf/Makefile.am
new file mode 100644
index 00000000..148ba621
--- /dev/null
+++ b/conf/dconf/Makefile.am
@@ -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/conf/dconf/config.c b/conf/dconf/config.c
new file mode 100644
index 00000000..02506fba
--- /dev/null
+++ b/conf/dconf/config.c
@@ -0,0 +1,429 @@
+/* -*- 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"
+#define DCONF_PRESERVE_NAME_PREFIXES_KEY \
+ DCONF_PREFIX"/general/dconf-preserve-name-prefixes"
+
+struct _IBusConfigDConf {
+ IBusConfigService parent;
+ DConfClient *client;
+
+ /* if a dconf path matches one of preserve_name_prefixes, don't convert
+ key names from/to GSettings key names (see _to_gsettings_name
+ and _from_gsettings_name) */
+ GSList *preserve_name_prefixes;
+};
+
+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;
+}
+
+static gboolean
+_has_prefixes (const gchar *path, GSList *prefixes)
+{
+ GSList *head = prefixes;
+ for (; head; head = head->next) {
+ if (g_str_has_prefix (path, head->data)) {
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/* 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 tuple for a unset value */
+ variant = g_variant_new_tuple (NULL, 0);
+ }
+
+ gname = strrchr (gkeys[i], '/');
+ g_assert (gname);
+ *gname++ = '\0';
+
+ if (_has_prefixes (gkeys[i], config->preserve_name_prefixes)) {
+ path = gkeys[i];
+ name = gname;
+ } else {
+ path = _from_gsettings_path (gkeys[i]);
+ name = _from_gsettings_name (gname);
+ }
+
+ ibus_config_service_value_changed ((IBusConfigService *) config,
+ path + sizeof (DCONF_PREFIX),
+ name,
+ variant);
+ if (path != gkeys[i]) {
+ g_free (path);
+ }
+ if (name != gname) {
+ g_free (name);
+ }
+ g_variant_unref (variant);
+ }
+ g_strfreev (gkeys);
+}
+
+static void
+ibus_config_dconf_init (IBusConfigDConf *config)
+{
+ GVariant *variant;
+ 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"/");
+
+ config->preserve_name_prefixes = NULL;
+ variant = dconf_client_read (config->client,
+ DCONF_PRESERVE_NAME_PREFIXES_KEY);
+ if (variant != NULL) {
+ GVariantIter iter;
+ GVariant *child;
+
+ g_variant_iter_init (&iter, variant);
+ while ((child = g_variant_iter_next_value (&iter))) {
+ char *prefix = g_variant_dup_string (child, NULL);
+ config->preserve_name_prefixes =
+ g_slist_prepend (config->preserve_name_prefixes,
+ prefix);
+ g_variant_unref (child);
+ }
+ g_variant_unref (variant);
+ }
+}
+
+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;
+ }
+
+ g_slist_free_full (config->preserve_name_prefixes, (GDestroyNotify) g_free);
+ config->preserve_name_prefixes = 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)
+{
+ IBusConfigDConf *dconf = IBUS_CONFIG_DCONF (config);
+ DConfClient *client = dconf->client;
+ gchar *path, *gpath, *gname, *gkey;
+ gboolean retval;
+
+ path = g_strdup_printf (DCONF_PREFIX"/%s", section);
+ gpath = _to_gsettings_path (path);
+ g_free (path);
+
+ if (_has_prefixes (gpath, dconf->preserve_name_prefixes)) {
+ gname = (char *) name;
+ } else {
+ gname = _to_gsettings_name (name);
+ }
+ gkey = g_strconcat (gpath, "/", gname, NULL);
+ g_free (gpath);
+ if (gname != name) {
+ 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 tuple 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)
+{
+ IBusConfigDConf *dconf = IBUS_CONFIG_DCONF (config);
+ DConfClient *client = dconf->client;
+ gchar *path, *gpath, *gname, *gkey;
+ GVariant *variant;
+
+ path = g_strdup_printf (DCONF_PREFIX"/%s", section);
+ gpath = _to_gsettings_path (path);
+ g_free (path);
+
+ if (_has_prefixes (gpath, dconf->preserve_name_prefixes)) {
+ gname = (char *) name;
+ } else {
+ gname = _to_gsettings_name (name);
+ }
+ gkey = g_strconcat (gpath, "/", gname, NULL);
+ g_free (gpath);
+ if (gname != name) {
+ 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)
+{
+ IBusConfigDConf *dconf = IBUS_CONFIG_DCONF (config);
+ DConfClient *client = dconf->client;
+ gchar *dir, *gdir;
+ gint len;
+ gchar **entries, **p;
+ GVariantBuilder *builder;
+ gboolean preserve_name;
+
+ dir = g_strdup_printf (DCONF_PREFIX"/%s/", section);
+ gdir = _to_gsettings_path (dir);
+ g_free (dir);
+
+ preserve_name = _has_prefixes (gdir, dconf->preserve_name_prefixes);
+
+ 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 = *p;
+ if (!preserve_name) {
+ name = _from_gsettings_name (*p);
+ }
+ g_variant_builder_add (builder, "{sv}", name, value);
+ if (name != *p) {
+ 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/conf/dconf/config.h b/conf/dconf/config.h
new file mode 100644
index 00000000..9f602d6a
--- /dev/null
+++ b/conf/dconf/config.h
@@ -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/conf/dconf/dconf.xml.in.in b/conf/dconf/dconf.xml.in.in
new file mode 100644
index 00000000..0367008e
--- /dev/null
+++ b/conf/dconf/dconf.xml.in.in
@@ -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/conf/dconf/main.c b/conf/dconf/main.c
new file mode 100644
index 00000000..1b69baa3
--- /dev/null
+++ b/conf/dconf/main.c
@@ -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;
+}
diff --git a/conf/gconf/Makefile.am b/conf/gconf/Makefile.am
new file mode 100644
index 00000000..cf74a4ab
--- /dev/null
+++ b/conf/gconf/Makefile.am
@@ -0,0 +1,79 @@
+# 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-gconf \
+ $(NULL)
+
+ibus_gconf_SOURCES = \
+ main.c \
+ config.c \
+ config.h \
+ $(NULL)
+ibus_gconf_CFLAGS = \
+ @GLIB2_CFLAGS@ \
+ @GIO2_CFLAGS@ \
+ @GCONF_CFLAGS@ \
+ -DG_LOG_DOMAIN=\"IBUS\" \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ $(NULL)
+ibus_gconf_LDADD = \
+ @GOBJECT2_LIBS@ \
+ @GLIB2_LIBS@ \
+ @GIO2_LIBS@ \
+ @GCONF_LIBS@ \
+ $(libibus) \
+ $(NULL)
+ibus_gconf_DEPENDENCIES = \
+ $(libibus) \
+ $(NULL)
+
+component_DATA = \
+ gconf.xml \
+ $(NULL)
+
+componentdir = $(pkgdatadir)/component
+
+CLEANFILES = \
+ gconf.xml \
+ *.pyc \
+ $(NULL)
+
+EXTRA_DIST = \
+ gconf.xml.in.in \
+ $(NULL)
+
+gconf.xml: gconf.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/conf/gconf/config.c b/conf/gconf/config.c
new file mode 100644
index 00000000..64f1c47d
--- /dev/null
+++ b/conf/gconf/config.c
@@ -0,0 +1,346 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+
+#include <string.h>
+#include <ibus.h>
+#include "config.h"
+
+#define GCONF_PREFIX "/desktop/ibus"
+
+struct _IBusConfigGConf {
+ IBusConfigService parent;
+ GConfClient *client;
+};
+
+struct _IBusConfigGConfClass {
+ IBusConfigServiceClass parent;
+
+};
+
+/* functions prototype */
+static void ibus_config_gconf_class_init (IBusConfigGConfClass *class);
+static void ibus_config_gconf_init (IBusConfigGConf *config);
+static void ibus_config_gconf_destroy (IBusConfigGConf *config);
+static gboolean ibus_config_gconf_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GVariant *value,
+ GError **error);
+static GVariant *ibus_config_gconf_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GError **error);
+static GVariant *ibus_config_gconf_get_values (IBusConfigService *config,
+ const gchar *section,
+ GError **error);
+static gboolean ibus_config_gconf_unset_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GError **error);
+static GConfValue *_to_gconf_value (GVariant *value);
+static GVariant *_from_gconf_value (const GConfValue *gvalue);
+
+G_DEFINE_TYPE (IBusConfigGConf, ibus_config_gconf, IBUS_TYPE_CONFIG_SERVICE)
+
+static void
+ibus_config_gconf_class_init (IBusConfigGConfClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ IBUS_OBJECT_CLASS (object_class)->destroy = (IBusObjectDestroyFunc) ibus_config_gconf_destroy;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->set_value = ibus_config_gconf_set_value;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->get_value = ibus_config_gconf_get_value;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->get_values = ibus_config_gconf_get_values;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->unset_value = ibus_config_gconf_unset_value;
+}
+
+static void
+_value_changed_cb (GConfClient *client,
+ const gchar *key,
+ GConfValue *value,
+ IBusConfigGConf *config)
+{
+ gchar *p, *section, *name;
+
+ g_return_if_fail (key != NULL);
+
+ p = g_strdup (key);
+ section = p + sizeof (GCONF_PREFIX);
+ name = rindex (p, '/') + 1;
+ *(name - 1) = '\0';
+
+ GVariant *variant;
+ if (value) {
+ variant = _from_gconf_value (value);
+ }
+ else {
+ /* Use a empty typle for a unset value */
+ variant = g_variant_new_tuple (NULL, 0);
+ }
+ g_return_if_fail (variant != NULL);
+ ibus_config_service_value_changed ((IBusConfigService *) config,
+ section,
+ name,
+ variant);
+ g_variant_unref (variant);
+ g_free (p);
+}
+
+static void
+ibus_config_gconf_init (IBusConfigGConf *config)
+{
+ config->client = gconf_client_get_default ();
+ gconf_client_add_dir (config->client,
+ GCONF_PREFIX,
+ GCONF_CLIENT_PRELOAD_RECURSIVE,
+ NULL);
+ g_signal_connect (config->client, "value-changed", G_CALLBACK (_value_changed_cb), config);
+}
+
+static void
+ibus_config_gconf_destroy (IBusConfigGConf *config)
+{
+ if (config->client) {
+ g_signal_handlers_disconnect_by_func (config->client, G_CALLBACK (_value_changed_cb), config);
+ g_object_unref (config->client);
+ config->client = NULL;
+ }
+
+ IBUS_OBJECT_CLASS (ibus_config_gconf_parent_class)->destroy ((IBusObject *)config);
+}
+
+static GConfValue *
+_to_gconf_value (GVariant *value)
+{
+ GConfValue *gv = NULL;
+
+ switch (g_variant_classify (value)) {
+ case G_VARIANT_CLASS_STRING:
+ {
+ gv = gconf_value_new (GCONF_VALUE_STRING);
+ gconf_value_set_string (gv, g_variant_get_string (value, NULL));
+ }
+ break;
+ case G_VARIANT_CLASS_INT32:
+ {
+ gv = gconf_value_new (GCONF_VALUE_INT);
+ gconf_value_set_int (gv, g_variant_get_int32 (value));
+ }
+ break;
+ case G_VARIANT_CLASS_BOOLEAN:
+ {
+ gv = gconf_value_new (GCONF_VALUE_BOOL);
+ gconf_value_set_bool (gv, g_variant_get_boolean (value));
+ }
+ break;
+ case G_VARIANT_CLASS_DOUBLE:
+ {
+ gv = gconf_value_new (GCONF_VALUE_FLOAT);
+ gconf_value_set_float (gv, g_variant_get_double (value));
+ }
+ break;
+ case G_VARIANT_CLASS_ARRAY:
+ {
+ const GVariantType *element_type = g_variant_type_element (g_variant_get_type (value));
+
+ GConfValueType type = GCONF_VALUE_INVALID;
+ if (g_variant_type_equal (element_type, G_VARIANT_TYPE_STRING))
+ type = GCONF_VALUE_STRING;
+ else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_INT32))
+ type = GCONF_VALUE_INT;
+ else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_BOOLEAN))
+ type = GCONF_VALUE_BOOL;
+ else if (g_variant_type_equal (element_type, G_VARIANT_TYPE_DOUBLE))
+ type = GCONF_VALUE_FLOAT;
+ else
+ g_return_val_if_reached (NULL);
+
+ gv = gconf_value_new (GCONF_VALUE_LIST);
+ gconf_value_set_list_type (gv, type);
+
+ GSList *elements = NULL;
+ GVariantIter iter;
+ GVariant *child;
+ g_variant_iter_init (&iter, value);
+ while ((child = g_variant_iter_next_value (&iter)) != NULL) {
+ elements = g_slist_append (elements, _to_gconf_value (child));
+ g_variant_unref (child);
+ }
+ gconf_value_set_list_nocopy (gv, elements);
+ }
+ break;
+ default:
+ g_return_val_if_reached (NULL);
+ }
+
+ return gv;
+}
+
+static GVariant *
+_from_gconf_value (const GConfValue *gv)
+{
+ g_assert (gv != NULL);
+
+ switch (gv->type) {
+ case GCONF_VALUE_STRING:
+ return g_variant_new_string (gconf_value_get_string (gv));
+ case GCONF_VALUE_INT:
+ return g_variant_new_int32 (gconf_value_get_int (gv));
+ case GCONF_VALUE_FLOAT:
+ return g_variant_new_double (gconf_value_get_float (gv));
+ case GCONF_VALUE_BOOL:
+ return g_variant_new_boolean (gconf_value_get_bool (gv));
+ case GCONF_VALUE_LIST:
+ {
+ GVariantBuilder builder;
+ switch (gconf_value_get_list_type (gv)) {
+ case GCONF_VALUE_STRING:
+ g_variant_builder_init (&builder, G_VARIANT_TYPE("as")); break;
+ case GCONF_VALUE_INT:
+ g_variant_builder_init (&builder, G_VARIANT_TYPE("ai")); break;
+ case GCONF_VALUE_FLOAT:
+ g_variant_builder_init (&builder, G_VARIANT_TYPE("ad")); break;
+ case GCONF_VALUE_BOOL:
+ g_variant_builder_init (&builder, G_VARIANT_TYPE("ab")); break;
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+
+ GSList *list = gconf_value_get_list (gv);
+ GSList *p = list;
+ while (p != NULL) {
+ switch (gconf_value_get_list_type (gv)) {
+ case GCONF_VALUE_STRING:
+ g_variant_builder_add (&builder, "s", gconf_value_get_string ((GConfValue *)p->data));
+ break;
+ case GCONF_VALUE_INT:
+ g_variant_builder_add (&builder, "i", gconf_value_get_int ((GConfValue *)p->data));
+ break;
+ case GCONF_VALUE_FLOAT:
+ g_variant_builder_add (&builder, "d", gconf_value_get_float ((GConfValue *)p->data));
+ break;
+ case GCONF_VALUE_BOOL:
+ g_variant_builder_add (&builder, "b", gconf_value_get_bool ((GConfValue *)p->data));
+ break;
+ default:
+ g_assert_not_reached ();
+ }
+ p = p->next;
+ }
+ return g_variant_builder_end (&builder);
+ }
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+
+static gboolean
+ibus_config_gconf_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GVariant *value,
+ GError **error)
+{
+ gchar *key;
+ GConfValue *gv;
+
+ gv = _to_gconf_value (value);
+ if (gv == NULL) {
+ gchar *str = g_variant_print (value, TRUE);
+ *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Can not set config value [%s:%s] to %s.",
+ section, name, str);
+ g_free (str);
+ return FALSE;
+ }
+ key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
+ gconf_client_set (((IBusConfigGConf *)config)->client, key, gv, error);
+
+ g_free (key);
+ gconf_value_free (gv);
+
+ if (*error != NULL) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static GVariant *
+ibus_config_gconf_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GError **error)
+{
+ gchar *key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
+
+ GConfValue *gv = gconf_client_get (((IBusConfigGConf *) config)->client, key, NULL);
+
+ g_free (key);
+
+ if (gv == NULL) {
+ *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Config value [%s:%s] does not exist.", section, name);
+ return NULL;
+ }
+
+ GVariant *variant = _from_gconf_value (gv);
+ gconf_value_free (gv);
+
+ return variant;
+}
+
+static GVariant *
+ibus_config_gconf_get_values (IBusConfigService *config,
+ const gchar *section,
+ GError **error)
+{
+ gchar *dir = g_strdup_printf (GCONF_PREFIX"/%s", section);
+ gint len = strlen(dir) + 1;
+ GSList *entries = gconf_client_all_entries (((IBusConfigGConf *) config)->client, dir, NULL);
+ g_free (dir);
+
+ GSList *p;
+ GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+ for (p = entries; p != NULL; p = p->next) {
+ GConfEntry *entry = (GConfEntry *)p->data;
+ if (entry->key != NULL && entry->value != NULL) {
+ const gchar *name = entry->key + len;
+ GVariant *value = _from_gconf_value (entry->value);
+ g_variant_builder_add (builder, "{sv}", name, value);
+ }
+ gconf_entry_free (entry);
+ }
+ g_slist_free (entries);
+
+ return g_variant_builder_end (builder);
+}
+
+static gboolean
+ibus_config_gconf_unset_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GError **error)
+{
+ gchar *key = g_strdup_printf (GCONF_PREFIX"/%s/%s", section, name);
+
+ gconf_client_unset (((IBusConfigGConf *)config)->client, key, error);
+ g_free (key);
+
+ if (*error != NULL) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+IBusConfigGConf *
+ibus_config_gconf_new (GDBusConnection *connection)
+{
+ IBusConfigGConf *config;
+ config = (IBusConfigGConf *) g_object_new (IBUS_TYPE_CONFIG_GCONF,
+ "object-path", IBUS_PATH_CONFIG,
+ "connection", connection,
+ NULL);
+ return config;
+}
diff --git a/conf/gconf/config.h b/conf/gconf/config.h
new file mode 100644
index 00000000..32becaae
--- /dev/null
+++ b/conf/gconf/config.h
@@ -0,0 +1,28 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+#ifndef __CONFIG_GCONF_H__
+#define __CONFIG_GCONF_H__
+
+#include <ibus.h>
+#include <gconf/gconf-client.h>
+
+#define IBUS_TYPE_CONFIG_GCONF \
+ (ibus_config_gconf_get_type ())
+#define IBUS_CONFIG_GCONF(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_CONFIG_GCONF, IBusConfigGConf))
+#define IBUS_CONFIG_GCONF_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_CONFIG_GCONF, IBusConfigGConfClass))
+#define IBUS_IS_CONFIG_GCONF(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_CONFIG_GCONF))
+#define IBUS_IS_CONFIG_GCONF_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_CONFIG_GCONF))
+#define IBUS_CONFIG_GCONF_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_CONFIG_GCONF, IBusConfigGConfClass))
+
+typedef struct _IBusConfigGConf IBusConfigGConf;
+typedef struct _IBusConfigGConfClass IBusConfigGConfClass;
+
+GType ibus_config_gconf_get_type (void);
+IBusConfigGConf *ibus_config_gconf_new (GDBusConnection *connection);
+
+#endif
diff --git a/conf/gconf/gconf.xml.in.in b/conf/gconf/gconf.xml.in.in
new file mode 100644
index 00000000..0644d7e9
--- /dev/null
+++ b/conf/gconf/gconf.xml.in.in
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- filename: pinyin.xml -->
+<component>
+ <name>org.freedesktop.IBus.Config</name>
+ <description>GConf Config Component</description>
+ <exec>${libexecdir}/ibus-gconf</exec>
+ <version>@VERSION@</version>
+ <author>Peng Huang &lt;shawn.p.huang@gmail.com&gt;</author>
+ <license>GPL</license>
+ <homepage>http://code.google.com/p/ibus</homepage>
+ <textdomain>ibus</textdomain>
+</component>
diff --git a/conf/gconf/main.c b/conf/gconf/main.c
new file mode 100644
index 00000000..b1100aa0
--- /dev/null
+++ b/conf/gconf/main.c
@@ -0,0 +1,65 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+
+#include <ibus.h>
+#include <stdlib.h>
+#include <locale.h>
+#include "config.h"
+
+static IBusBus *bus = NULL;
+static IBusConfigGConf *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_gconf_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_gconf_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 gconf component");
+
+ g_option_context_add_main_entries (context, entries, "ibus-gconf");
+
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_print ("Option parsing failed: %s\n", error->message);
+ exit (-1);
+ }
+
+ ibus_gconf_start ();
+
+ return 0;
+}
diff --git a/conf/memconf/Makefile.am b/conf/memconf/Makefile.am
new file mode 100644
index 00000000..f5f5c082
--- /dev/null
+++ b/conf/memconf/Makefile.am
@@ -0,0 +1,76 @@
+# vim:set noet ts=4:
+#
+# ibus - The Input Bus
+#
+# Copyright (c) 2010, Google Inc. All rights reserved.
+# Copyright (c) 2007-2010 Peng Huang <shawn.p.huang@gmail.com>
+#
+# 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-memconf \
+ $(NULL)
+
+ibus_memconf_SOURCES = \
+ main.c \
+ config.c \
+ config.h \
+ $(NULL)
+ibus_memconf_CFLAGS = \
+ @GLIB2_CFLAGS@ \
+ @GIO2_CFLAGS@ \
+ -DG_LOG_DOMAIN=\"IBUS\" \
+ -I$(top_srcdir)/src \
+ -I$(top_builddir)/src \
+ $(NULL)
+ibus_memconf_LDADD = \
+ @GOBJECT2_LIBS@ \
+ @GLIB2_LIBS@ \
+ @GIO2_LIBS@ \
+ $(libibus) \
+ $(NULL)
+ibus_memconf_DEPENDENCIES = \
+ $(libibus) \
+ $(NULL)
+
+component_DATA = \
+ memconf.xml \
+ $(NULL)
+
+componentdir = $(pkgdatadir)/component
+
+CLEANFILES = \
+ memconf.xml \
+ $(NULL)
+
+EXTRA_DIST = \
+ memconf.xml.in.in \
+ $(NULL)
+
+memconf.xml: memconf.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/conf/memconf/config.c b/conf/memconf/config.c
new file mode 100644
index 00000000..dd18f2e7
--- /dev/null
+++ b/conf/memconf/config.c
@@ -0,0 +1,202 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * Copyright (C) 2010 Peng Huang <shawn.p.huang@gmail.com>
+ *
+ * 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"
+
+
+typedef struct _IBusConfigMemconfClass IBusConfigMemconfClass;
+
+struct _IBusConfigMemconf {
+ IBusConfigService parent;
+ GHashTable *values;
+};
+
+struct _IBusConfigMemconfClass {
+ IBusConfigServiceClass parent;
+};
+
+/* functions prototype */
+static void ibus_config_memconf_class_init (IBusConfigMemconfClass *class);
+static void ibus_config_memconf_init (IBusConfigMemconf *config);
+static void ibus_config_memconf_destroy (IBusConfigMemconf *config);
+static gboolean ibus_config_memconf_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GVariant *value,
+ GError **error);
+static GVariant *ibus_config_memconf_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GError **error);
+static GVariant *ibus_config_memconf_get_values (IBusConfigService *config,
+ const gchar *section,
+ GError **error);
+static gboolean ibus_config_memconf_unset_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GError **error);
+
+G_DEFINE_TYPE (IBusConfigMemconf, ibus_config_memconf, IBUS_TYPE_CONFIG_SERVICE)
+
+static void
+ibus_config_memconf_class_init (IBusConfigMemconfClass *class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (class);
+
+ IBUS_OBJECT_CLASS (object_class)->destroy = (IBusObjectDestroyFunc) ibus_config_memconf_destroy;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->set_value = ibus_config_memconf_set_value;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->get_value = ibus_config_memconf_get_value;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->get_values = ibus_config_memconf_get_values;
+ IBUS_CONFIG_SERVICE_CLASS (object_class)->unset_value = ibus_config_memconf_unset_value;
+}
+
+static void
+ibus_config_memconf_init (IBusConfigMemconf *config)
+{
+ config->values = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ (GDestroyNotify)g_free,
+ (GDestroyNotify)g_variant_unref);
+}
+
+static void
+ibus_config_memconf_destroy (IBusConfigMemconf *config)
+{
+ g_hash_table_destroy (config->values);
+ IBUS_OBJECT_CLASS (ibus_config_memconf_parent_class)->destroy ((IBusObject *)config);
+}
+
+static gboolean
+ibus_config_memconf_set_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GVariant *value,
+ GError **error)
+{
+ g_assert (IBUS_IS_CONFIG_MEMCONF (config));
+ g_assert (section);
+ g_assert (name);
+ g_assert (value);
+ g_assert (error == NULL || *error == NULL);
+
+ gchar *key = g_strdup_printf ("%s:%s", section, name);
+
+ g_hash_table_insert (IBUS_CONFIG_MEMCONF (config)->values,
+ key, g_variant_ref_sink (value));
+
+ ibus_config_service_value_changed (config, section, name, value);
+
+ return TRUE;
+}
+
+static GVariant *
+ibus_config_memconf_get_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GError **error)
+{
+ g_assert (IBUS_IS_CONFIG_MEMCONF (config));
+ g_assert (section);
+ g_assert (name);
+ g_assert (error == NULL || *error == NULL);
+
+ gchar *key = g_strdup_printf ("%s:%s", section, name);
+ GVariant *value = (GVariant *)g_hash_table_lookup (IBUS_CONFIG_MEMCONF (config)->values, key);
+ g_free (key);
+
+ if (value != NULL) {
+ g_variant_ref (value);
+ }
+ else if (error != NULL) {
+ *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Config value [%s:%s] does not exist.", section, name);
+ }
+ return value;
+}
+
+static GVariant *
+ibus_config_memconf_get_values (IBusConfigService *config,
+ const gchar *section,
+ GError **error)
+{
+ g_assert (IBUS_IS_CONFIG_MEMCONF (config));
+ g_assert (section);
+ g_assert (error == NULL || *error == NULL);
+
+ GHashTableIter iter;
+ const gchar *key;
+ GVariant *value;
+
+ GVariantBuilder *builder = g_variant_builder_new (G_VARIANT_TYPE ("a{sv}"));
+ g_hash_table_iter_init (&iter, IBUS_CONFIG_MEMCONF (config)->values);
+ while (g_hash_table_iter_next (&iter, (gpointer *)&key, (gpointer *)&value)) {
+ gchar **v = g_strsplit (key, ":", 2);
+ if (g_strcmp0 (v[0], section) == 0) {
+ g_variant_builder_add (builder, "{sv}", v[1], value);
+ }
+ g_strfreev(v);
+ }
+
+ return g_variant_builder_end (builder);
+}
+
+static gboolean
+ibus_config_memconf_unset_value (IBusConfigService *config,
+ const gchar *section,
+ const gchar *name,
+ GError **error)
+{
+ g_assert (IBUS_IS_CONFIG_MEMCONF (config));
+ g_assert (section);
+ g_assert (name);
+ g_assert (error == NULL || *error == NULL);
+
+ gchar *key = g_strdup_printf ("%s:%s", section, name);
+ gboolean retval = g_hash_table_remove (IBUS_CONFIG_MEMCONF (config)->values, key);
+ g_free (key);
+
+ if (retval) {
+ ibus_config_service_value_changed (config,
+ section,
+ name,
+ g_variant_new_tuple (NULL, 0));
+ }
+ else {
+ if (error && *error) {
+ *error = g_error_new (G_DBUS_ERROR, G_DBUS_ERROR_FAILED,
+ "Config value [%s:%s] does not exist.", section, name);
+ }
+ }
+ return retval;
+}
+
+IBusConfigMemconf *
+ibus_config_memconf_new (GDBusConnection *connection)
+{
+ IBusConfigMemconf *config;
+ config = (IBusConfigMemconf *) g_object_new (IBUS_TYPE_CONFIG_MEMCONF,
+ "object-path", IBUS_PATH_CONFIG,
+ "connection", connection,
+ NULL);
+ return config;
+}
diff --git a/conf/memconf/config.h b/conf/memconf/config.h
new file mode 100644
index 00000000..2b745d4f
--- /dev/null
+++ b/conf/memconf/config.h
@@ -0,0 +1,45 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * Copyright (C) 2010 Peng Huang <shawn.p.huang@gmail.com>
+ *
+ * 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_MEMCONF_H__
+#define __CONFIG_MEMCONF_H__
+
+#include <ibus.h>
+
+#define IBUS_TYPE_CONFIG_MEMCONF \
+ (ibus_config_memconf_get_type ())
+#define IBUS_CONFIG_MEMCONF(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_TYPE_CONFIG_MEMCONF, IBusConfigMemconf))
+#define IBUS_CONFIG_MEMCONF_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_TYPE_CONFIG_MEMCONF, IBusConfigMemconfClass))
+#define IBUS_IS_CONFIG_MEMCONF(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_TYPE_CONFIG_MEMCONF))
+#define IBUS_IS_CONFIG_MEMCONF_CLASS(klass) \
+ (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_TYPE_CONFIG_MEMCONF))
+#define IBUS_CONFIG_MEMCONF_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_TYPE_CONFIG_MEMCONF, IBusConfigMemconfClass))
+
+typedef struct _IBusConfigMemconf IBusConfigMemconf;
+
+GType ibus_config_memconf_get_type (void);
+IBusConfigMemconf *ibus_config_memconf_new (GDBusConnection *connection);
+
+#endif
diff --git a/conf/memconf/main.c b/conf/memconf/main.c
new file mode 100644
index 00000000..51dfd7f1
--- /dev/null
+++ b/conf/memconf/main.c
@@ -0,0 +1,83 @@
+/* -*- mode: C; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
+/* vim:set et sts=4: */
+/* ibus - The Input Bus
+ * Copyright (c) 2010, Google Inc. All rights reserved.
+ * Copyright (C) 2010 Peng Huang <shawn.p.huang@gmail.com>
+ *
+ * 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 IBusConfigMemconf *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_memconf_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_memconf_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 memconf component");
+
+ g_option_context_add_main_entries (context, entries, "ibus-memconf");
+
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_print ("Option parsing failed: %s\n", error->message);
+ exit (-1);
+ }
+
+ ibus_memconf_start ();
+
+ return 0;
+}
diff --git a/conf/memconf/memconf.xml.in.in b/conf/memconf/memconf.xml.in.in
new file mode 100644
index 00000000..b60dbf2e
--- /dev/null
+++ b/conf/memconf/memconf.xml.in.in
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="utf-8"?>
+<component>
+ <name>org.freedesktop.IBus.Config</name>
+ <description>On-memory Config Component</description>
+ <exec>${libexecdir}/ibus-memconf</exec>
+ <version>@VERSION@</version>
+ <author>Peng Huang &lt;shawn.p.huang@gmail.com&gt;, modified by the Chromium OS Authors</author>
+ <license>GPL</license>
+ <homepage>http://code.google.com/p/ibus</homepage>
+ <textdomain>ibus</textdomain>
+</component>