[ibus-m17n/f17] Update to 1.3.3-11.
Daiki Ueno
ueno at fedoraproject.org
Fri Mar 30 09:14:01 UTC 2012
commit 32b6abe9c4383f5e0818ede07594243a48d23c3b
Author: Daiki Ueno <ueno at unixuser.org>
Date: Fri Mar 30 18:13:52 2012 +0900
Update to 1.3.3-11.
ibus-m17n-HEAD.patch | 2860 ++++++++++++++++++++++++++++++++++
ibus-m17n-blacklist-engines.patch | 31 +-
ibus-m17n-custom-setup-element.patch | 49 -
ibus-m17n-default-xml-override.patch | 621 --------
ibus-m17n-hide-title-status.patch | 24 +-
ibus-m17n-iok.patch | 102 --
ibus-m17n-setup-refactor.patch | 843 ----------
ibus-m17n-virtkbd.patch | 882 ++++-------
ibus-m17n-xkb-options.patch | 54 +-
ibus-m17n-xx-icon-symbol.patch | 390 -----
ibus-m17n.spec | 44 +-
11 files changed, 3266 insertions(+), 2634 deletions(-)
---
diff --git a/ibus-m17n-HEAD.patch b/ibus-m17n-HEAD.patch
new file mode 100644
index 0000000..a6b875b
--- /dev/null
+++ b/ibus-m17n-HEAD.patch
@@ -0,0 +1,2860 @@
+From 7a0deadb02ff06e7d2db1177ce1fbb0661201bf1 Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Mon, 5 Sep 2011 09:41:21 +0900
+Subject: [PATCH 01/10] Update the format of default.xml to allow override.
+
+This patch allows value inheritance from the previous matches.
+With the new format:
+
+<engines>
+ <engine>
+ <name>*</name>
+ <rank>0</rank>
+ <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:ja:*</name>
+ <rank>2</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:ja:anthy</name>
+ <rank>1</rank>
+ </engine>
+</engines>
+
+We will get preedit-highlight == TRUE and rank == 1 for m17n:ja:anthy.
+
+BUG=none
+TEST=manual
+
+Review URL: http://codereview.appspot.com/4950059
+---
+ src/Makefile.am | 3 +-
+ src/default.xml.in.in | 221 +++++++++++++++++++------------------------------
+ src/engine.c | 2 +
+ src/m17nutil.c | 69 +++++++---------
+ src/m17nutil.h | 1 +
+ src/test.c | 66 +++++++++++++++
+ 6 files changed, 186 insertions(+), 176 deletions(-)
+ create mode 100644 src/test.c
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 282128a..e354149 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -40,11 +40,10 @@ TESTS = \
+
+
+ test_m17n_SOURCES = \
+- m17nutil.c \
++ test.c \
+ $(NULL)
+ test_m17n_CFLAGS = \
+ $(AM_CFLAGS) \
+- -DDEBUG \
+ $(NULL)
+ test_m17n_LDADD = \
+ libm17ncommon.a \
+diff --git a/src/default.xml.in.in b/src/default.xml.in.in
+index 5c5d67d..dc93fd3 100644
+--- a/src/default.xml.in.in
++++ b/src/default.xml.in.in
+@@ -1,246 +1,197 @@
+ <?xml version="1.0" encoding="utf-8"?>
+ <engines>
+ <!-- This file defines the default config value for each
+- engine. The "engine" elements below are checked in
+- first-to-last order and a "name" element in an "engine"
+- element allows wildcard patterns. Please keep more
+- specific entries to appear first. -->
+- <!-- Indic engines which represent languages. -->
++ engine. A "name" element in an "engine" element allows
++ wildcard patterns. "engine" elements are evaluated in
++ first-to-last order and the latter match may override the
++ existing default. -->
++ <!-- Default for other engines. -->
++ <engine>
++ <name>m17n:*</name>
++ <rank>0</rank>
++ <preedit-highlight>FALSE</preedit-highlight>
++ </engine>
++ <!-- Indic engines should be selected by default:
++ https://bugzilla.redhat.com/show_bug.cgi?id=640896 -->
++ <engine>
++ <name>m17n:as:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:bn:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:gu:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:hi:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:kn:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:ks:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:mai:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:ml:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:mr:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:ne:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:or:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:pa:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:sa:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:sd:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:si:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:ta:*</name>
++ <rank>1</rank>
++ </engine>
++ <engine>
++ <name>m17n:te:*</name>
++ <rank>1</rank>
++ </engine>
++ <!-- Assign higher rank to Indic engines which represent each
++ language. -->
+ <engine>
+ <name>m17n:as:phonetic</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:bn:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:gu:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:hi:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:kn:kgp</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:ks:kbd</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:mai:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:ml:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:mr:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:ne:rom</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:or:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:pa:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:sa:harvard-kyoto</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:sd:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:si:wijesekera</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:ta:tamil99</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:te:inscript</name>
+ <rank>2</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+ </engine>
+- <!-- Samanala should have lower rank than other Sinhala
+- engines since it is the only non-keyboard input method in
+- Sinhala. -->
++ <!-- Assign lower rank to Sinhala Samanala since it is a
++ non-keyboard input method in Sinhala. -->
+ <engine>
+ <name>m17n:si:samanala</name>
+ <rank>0</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <!-- Chinese and Japanese engines which require preedit decoration. -->
+- <engine>
+- <name>m17n:ja:anthy</name>
+- <rank>0</rank>
+- <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
++ <!-- Some CJK engines use preedit. -->
+ <engine>
+ <name>m17n:zh:cangjie</name>
+- <rank>0</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:zh:py-b5</name>
+- <rank>0</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:zh:py-gb</name>
+- <rank>0</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:zh:py</name>
+- <rank>0</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:zh:quick</name>
+- <rank>0</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:zh:tonepy-b5</name>
+- <rank>0</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:zh:tonepy-gb</name>
+- <rank>0</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+ <name>m17n:zh:tonepy</name>
+- <rank>0</rank>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+ <engine>
+- <name>m17n:zh:util</name>
+- <rank>0</rank>
++ <name>m17n:ja:anthy</name>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
+- <!-- Other Indic engines should be selected by default:
+- https://bugzilla.redhat.com/show_bug.cgi?id=640896 -->
+- <engine>
+- <name>m17n:as:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:bn:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:gu:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:hi:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:kn:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:ks:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:mai:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:ml:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:mr:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:ne:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:or:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:pa:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:sa:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:sd:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:si:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:ta:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <engine>
+- <name>m17n:te:*</name>
+- <rank>1</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+- <!-- Default for other engines. -->
+- <engine>
+- <name>m17n:*</name>
+- <rank>0</rank>
+- <preedit-highlight>FALSE</preedit-highlight>
+- </engine>
+ </engines>
+diff --git a/src/engine.c b/src/engine.c
+index cfb853c..dcff0c7 100644
+--- a/src/engine.c
++++ b/src/engine.c
+@@ -290,6 +290,8 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ &klass->lookup_table_orientation))
+ klass->lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
+
++ ibus_m17n_engine_config_free (engine_config);
++
+ g_signal_connect (config, "value-changed",
+ G_CALLBACK(ibus_m17n_config_value_changed),
+ klass);
+diff --git a/src/m17nutil.c b/src/m17nutil.c
+index 42aa8f6..54561f2 100644
+--- a/src/m17nutil.c
++++ b/src/m17nutil.c
+@@ -13,12 +13,17 @@ static MConverter *utf8_converter = NULL;
+
+ #define DEFAULT_XML (SETUPDIR "/default.xml")
+
+-struct _IBusM17NEngineConfigNode {
++typedef enum {
++ ENGINE_CONFIG_RANK_MASK = 1 << 0,
++ ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 1
++} EngineConfigMask;
++
++struct _EngineConfigNode {
+ gchar *name;
++ EngineConfigMask mask;
+ IBusM17NEngineConfig config;
+ };
+-
+-typedef struct _IBusM17NEngineConfigNode IBusM17NEngineConfigNode;
++typedef struct _EngineConfigNode EngineConfigNode;
+
+ static GSList *config_list = NULL;
+
+@@ -257,20 +262,31 @@ ibus_m17n_list_engines (void)
+ IBusM17NEngineConfig *
+ ibus_m17n_get_engine_config (const gchar *engine_name)
+ {
++ IBusM17NEngineConfig *config = g_slice_new0 (IBusM17NEngineConfig);
+ GSList *p;
+
+ for (p = config_list; p != NULL; p = p->next) {
+- IBusM17NEngineConfigNode *cnode = p->data;
++ EngineConfigNode *cnode = p->data;
+
+- if (g_pattern_match_simple (cnode->name, engine_name))
+- return &cnode->config;
++ if (g_pattern_match_simple (cnode->name, engine_name)) {
++ if (cnode->mask & ENGINE_CONFIG_RANK_MASK)
++ config->rank = cnode->config.rank;
++ if (cnode->mask & ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK)
++ config->preedit_highlight = cnode->config.preedit_highlight;
++ }
+ }
+- g_return_val_if_reached (NULL);
++ return config;
++}
++
++void
++ibus_m17n_engine_config_free (IBusM17NEngineConfig *config)
++{
++ g_slice_free (IBusM17NEngineConfig, config);
+ }
+
+ static gboolean
+-ibus_m17n_engine_config_parse_xml_node (IBusM17NEngineConfigNode *cnode,
+- XMLNode *node)
++ibus_m17n_engine_config_parse_xml_node (EngineConfigNode *cnode,
++ XMLNode *node)
+ {
+ GList *p;
+
+@@ -284,6 +300,7 @@ ibus_m17n_engine_config_parse_xml_node (IBusM17NEngineConfigNode *cnode,
+ }
+ if (g_strcmp0 (sub_node->name , "rank") == 0) {
+ cnode->config.rank = atoi (sub_node->text);
++ cnode->mask |= ENGINE_CONFIG_RANK_MASK;
+ continue;
+ }
+ if (g_strcmp0 (sub_node->name , "preedit-highlight") == 0) {
+@@ -292,6 +309,7 @@ ibus_m17n_engine_config_parse_xml_node (IBusM17NEngineConfigNode *cnode,
+ else if (g_ascii_strcasecmp ("FALSE", sub_node->text) != 0)
+ g_warning ("<%s> element contains invalid boolean value %s",
+ sub_node->name, sub_node->text);
++ cnode->mask |= ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK;
+ continue;
+ }
+ g_warning ("<engine> element contains invalid element <%s>",
+@@ -320,7 +338,7 @@ ibus_m17n_get_component (void)
+ if (node && g_strcmp0 (node->name, "engines") == 0) {
+ for (p = node->sub_nodes; p != NULL; p = p->next) {
+ XMLNode *sub_node = p->data;
+- IBusM17NEngineConfigNode *cnode;
++ EngineConfigNode *cnode;
+
+ if (g_strcmp0 (sub_node->name, "engine") != 0) {
+ g_warning ("<engines> element contains invalid element <%s>",
+@@ -328,9 +346,9 @@ ibus_m17n_get_component (void)
+ continue;
+ }
+
+- cnode = g_slice_new0 (IBusM17NEngineConfigNode);
++ cnode = g_slice_new0 (EngineConfigNode);
+ if (!ibus_m17n_engine_config_parse_xml_node (cnode, sub_node)) {
+- g_slice_free (IBusM17NEngineConfigNode, cnode);
++ g_slice_free (EngineConfigNode, cnode);
+ continue;
+ }
+ config_list = g_slist_prepend (config_list, cnode);
+@@ -448,30 +466,3 @@ ibus_m17n_config_get_int (IBusConfig *config,
+ return FALSE;
+ #endif /* !IBUS_CHECK_VERSION(1,3,99) */
+ }
+-
+-#ifdef DEBUG
+-#include <locale.h>
+-
+-int main ()
+-{
+- IBusComponent *component;
+- GString *output;
+-
+- setlocale (LC_ALL, "");
+- ibus_init ();
+- ibus_m17n_init_common ();
+-
+- component = ibus_m17n_get_component ();
+-
+- output = g_string_new ("");
+-
+- ibus_component_output (component, output, 1);
+-
+- g_debug ("\n%s", output->str);
+-
+- g_string_free (output, TRUE);
+- g_object_unref (component);
+-
+- return 0;
+-}
+-#endif
+diff --git a/src/m17nutil.h b/src/m17nutil.h
+index f083194..313e7bc 100644
+--- a/src/m17nutil.h
++++ b/src/m17nutil.h
+@@ -30,6 +30,7 @@ gunichar *ibus_m17n_mtext_to_ucs4 (MText *text,
+ guint ibus_m17n_parse_color (const gchar *hex);
+ IBusM17NEngineConfig
+ *ibus_m17n_get_engine_config (const gchar *engine_name);
++void ibus_m17n_engine_config_free (IBusM17NEngineConfig *config);
+ void ibus_m17n_config_set_string (IBusConfig *config,
+ const gchar *section,
+ const gchar *name,
+diff --git a/src/test.c b/src/test.c
+new file mode 100644
+index 0000000..0908818
+--- /dev/null
++++ b/src/test.c
+@@ -0,0 +1,66 @@
++/* vim:set et sts=4: */
++#ifdef HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#include <ibus.h>
++#include <locale.h>
++#include "m17nutil.h"
++
++static void
++test_output_component (void)
++{
++ IBusComponent *component;
++ GString *output;
++
++ component = ibus_m17n_get_component ();
++
++ output = g_string_new ("");
++
++ ibus_component_output (component, output, 1);
++
++ g_debug ("\n%s", output->str);
++
++ g_string_free (output, TRUE);
++ g_object_unref (component);
++}
++
++static void
++test_engine_config (void)
++{
++ IBusM17NEngineConfig *config;
++
++ config = ibus_m17n_get_engine_config ("m17n:non:exsistent");
++ g_assert_cmpint (config->rank, ==, 0);
++ g_assert_cmpint (config->preedit_highlight, ==, 0);
++ ibus_m17n_engine_config_free (config);
++
++ config = ibus_m17n_get_engine_config ("m17n:si:wijesekera");
++ g_assert_cmpint (config->rank, ==, 2);
++ g_assert_cmpint (config->preedit_highlight, ==, 0);
++ ibus_m17n_engine_config_free (config);
++
++ config = ibus_m17n_get_engine_config ("m17n:si:phonetic-dynamic");
++ g_assert_cmpint (config->rank, ==, 1);
++ g_assert_cmpint (config->preedit_highlight, ==, 0);
++ ibus_m17n_engine_config_free (config);
++
++ config = ibus_m17n_get_engine_config ("m17n:si:samanala");
++ g_assert_cmpint (config->rank, ==, 0);
++ g_assert_cmpint (config->preedit_highlight, ==, 0);
++ ibus_m17n_engine_config_free (config);
++}
++
++int main (int argc, char **argv)
++{
++ setlocale (LC_ALL, "");
++ ibus_init ();
++ ibus_m17n_init_common ();
++
++ g_test_init (&argc, &argv, NULL);
++
++ g_test_add_func ("/test-m17n/output-component", test_output_component);
++ g_test_add_func ("/test-m17n/engine-config", test_engine_config);
++
++ return g_test_run ();
++}
+--
+1.7.7.6
+
+
+From 5ff68ed781584d59f7f27e843f2f6da630c904ae Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Thu, 8 Sep 2011 09:51:02 +0900
+Subject: [PATCH 02/10] Refactor setup.c.
+
+Previously, each config item was saved when corresponding widget state was
+changed. With this change, changes won't be saved until a user close the
+setup dialog.
+
+BUG=none
+TEST=manual
+
+Review URL: http://codereview.appspot.com/4968066
+---
+ src/ibus-m17n-preferences.ui | 3 +-
+ src/setup.c | 668 +++++++++++++++++++++++-------------------
+ 2 files changed, 363 insertions(+), 308 deletions(-)
+
+diff --git a/src/ibus-m17n-preferences.ui b/src/ibus-m17n-preferences.ui
+index 6f6ace7..a46ab49 100644
+--- a/src/ibus-m17n-preferences.ui
++++ b/src/ibus-m17n-preferences.ui
+@@ -263,9 +263,10 @@
+ <property name="hscrollbar_policy">automatic</property>
+ <property name="vscrollbar_policy">automatic</property>
+ <child>
+- <object class="GtkTreeView" id="treeviewMimConfig">
++ <object class="GtkTreeView" id="treeview_mim_config">
+ <property name="visible">True</property>
+ <property name="can_focus">True</property>
++ <property name="has_tooltip">True</property>
+ <property name="enable_grid_lines">both</property>
+ </object>
+ </child>
+diff --git a/src/setup.c b/src/setup.c
+index aba0e92..02db691 100644
+--- a/src/setup.c
++++ b/src/setup.c
+@@ -17,19 +17,24 @@ enum {
+ NUM_COLS
+ };
+
+-struct _ConfigContext {
+- IBusConfig *config;
+- MSymbol language;
+- MSymbol name;
+- GtkListStore *store;
+- gchar *section;
++struct _SetupDialog {
++ GtkWidget *dialog;
++ GtkWidget *combobox_underline;
++ GtkWidget *combobox_orientation;
++ GtkWidget *checkbutton_foreground;
+ GtkWidget *colorbutton_foreground;
++ GtkWidget *checkbutton_background;
+ GtkWidget *colorbutton_background;
++ GtkWidget *treeview;
++ GtkListStore *store;
+
+-};
+-typedef struct _ConfigContext ConfigContext;
++ MSymbol lang;
++ MSymbol name;
+
+-static IBusConfig *config = NULL;
++ IBusConfig *config;
++ gchar *section;
++};
++typedef struct _SetupDialog SetupDialog;
+
+ static gchar *opt_name = NULL;
+ static const GOptionEntry options[] = {
+@@ -38,17 +43,8 @@ static const GOptionEntry options[] = {
+ {NULL}
+ };
+
+-void
+-ibus_m17n_init (IBusBus *bus)
+-{
+- config = ibus_bus_get_config (bus);
+- if (config)
+- g_object_ref_sink (config);
+- ibus_m17n_init_common ();
+-}
+-
+ static gchar *
+-format_value (MPlist *plist)
++format_m17n_value (MPlist *plist)
+ {
+ if (mplist_key (plist) == Msymbol)
+ return g_strdup (msymbol_name ((MSymbol) mplist_value (plist)));
+@@ -64,7 +60,7 @@ format_value (MPlist *plist)
+ }
+
+ static MPlist *
+-parse_value (MPlist *plist, gchar *text)
++parse_m17n_value (MPlist *plist, gchar *text)
+ {
+ MPlist *value;
+
+@@ -100,7 +96,7 @@ parse_value (MPlist *plist, gchar *text)
+ }
+
+ static void
+-insert_items (GtkListStore *store, MSymbol language, MSymbol name)
++insert_m17n_items (GtkListStore *store, MSymbol language, MSymbol name)
+ {
+ MPlist *plist;
+
+@@ -109,8 +105,8 @@ insert_items (GtkListStore *store, MSymbol language, MSymbol name)
+ for (; plist && mplist_key (plist) == Mplist; plist = mplist_next (plist)) {
+ GtkTreeIter iter;
+ MSymbol key;
+- MPlist *p, *value;
+- gchar *description;
++ MPlist *p, *mvalue;
++ gchar *description, *value;
+
+ p = mplist_value (plist);
+ key = mplist_value (p); /* name */
+@@ -118,15 +114,17 @@ insert_items (GtkListStore *store, MSymbol language, MSymbol name)
+ p = mplist_next (p); /* description */
+ description = ibus_m17n_mtext_to_utf8 ((MText *) mplist_value (p));
+ p = mplist_next (p); /* status */
+- value = mplist_next (p);
++ mvalue = mplist_next (p);
++ value = format_m17n_value (mvalue);
+
+ gtk_list_store_append (store, &iter);
+ gtk_list_store_set (store, &iter,
+ COLUMN_KEY, msymbol_name (key),
+ COLUMN_DESCRIPTION, description,
+- COLUMN_VALUE, format_value (value),
++ COLUMN_VALUE, value,
+ -1);
+ g_free (description);
++ g_free (value);
+ }
+ }
+
+@@ -138,7 +136,7 @@ on_query_tooltip (GtkWidget *widget,
+ GtkTooltip *tooltip,
+ gpointer user_data)
+ {
+- GtkTreeView *treeview = GTK_TREE_VIEW(widget);
++ GtkTreeView *treeview = GTK_TREE_VIEW (widget);
+ GtkTreeModel *model = gtk_tree_view_get_model (treeview);
+ GtkTreePath *path = NULL;
+ GtkTreeIter iter;
+@@ -163,173 +161,48 @@ on_edited (GtkCellRendererText *cell,
+ gchar *new_text,
+ gpointer data)
+ {
+- ConfigContext *context = data;
+- GtkTreeModel *model = GTK_TREE_MODEL (context->store);
++ SetupDialog *dialog = data;
++ GtkTreeModel *model = GTK_TREE_MODEL (dialog->store);
+ GtkTreeIter iter;
+ GtkTreePath *path = gtk_tree_path_new_from_string (path_string);
+- MPlist *plist, *p, *value;
+- gchar *key;
+
+ gtk_tree_model_get_iter (model, &iter, path);
+- gtk_tree_model_get (model, &iter, COLUMN_KEY, &key, -1);
+-
+- plist = minput_get_variable (context->language, context->name,
+- msymbol (key));
+- if (!plist)
+- goto fail;
+-
+- p = mplist_next (mplist_next (mplist_next (mplist_value (plist))));
+- if (!p)
+- goto fail;
+-
+- value = parse_value (p, new_text);
+- if (!value)
+- goto fail;
+-
+- if (minput_config_variable (context->language, context->name,
+- msymbol (key), value) != 0)
+- goto fail;
+
+- if (minput_save_config () != 1)
+- goto fail;
+-
+- gtk_list_store_set (context->store, &iter,
++ gtk_list_store_set (dialog->store, &iter,
+ COLUMN_VALUE, new_text,
+ -1);
+-
+- fail:
+ gtk_tree_path_free (path);
+ }
+
+ static void
+-color_to_gdk (guint color, GdkColor *color_gdk)
++toggle_colorbutton_sensitive (GtkToggleButton *togglebutton,
++ GtkWidget *colorbutton)
+ {
+- memset (color_gdk, 0, sizeof *color_gdk);
+- color_gdk->red = (color >> 8) & 0xFF00;
+- color_gdk->green = color & 0xFF00;
+- color_gdk->blue = (color & 0xFF) << 8;
+-}
+-
+-static void
+-set_color (ConfigContext *context, const gchar *name, GdkColor *color)
+-{
+- gchar buf[8];
+-
+- if (color)
+- sprintf (buf, "#%02X%02X%02X",
+- (color->red & 0xFF00) >> 8,
+- (color->green & 0xFF00) >> 8,
+- (color->blue & 0xFF00) >> 8);
+- else
+- strcpy (buf, "none");
+- ibus_m17n_config_set_string (config, context->section, name, buf);
+-}
+-
+-static void
+-on_foreground_color_set (GtkColorButton *widget,
+- gpointer user_data)
+-{
+- ConfigContext *context = user_data;
+- GdkColor color;
+-
+- gtk_color_button_get_color (GTK_COLOR_BUTTON(widget), &color);
+- set_color (context, "preedit_foreground", &color);
+-}
+-
+-static void
+-on_background_color_set (GtkColorButton *widget,
+- gpointer user_data)
+-{
+- ConfigContext *context = user_data;
+- GdkColor color;
+-
+- gtk_color_button_get_color (GTK_COLOR_BUTTON(widget), &color);
+- set_color (context, "preedit_background", &color);
+-}
+-
+-static void
+-on_underline_changed (GtkComboBox *combo,
+- gpointer user_data)
+-{
+- ConfigContext *context = user_data;
+- GtkTreeModel *model;
+- GtkTreeIter iter;
+- gint active;
+-
+- model = gtk_combo_box_get_model (combo);
+- gtk_combo_box_get_active_iter (combo, &iter);
+- gtk_tree_model_get (model, &iter, COLUMN_VALUE, &active, -1);
+-
+- ibus_m17n_config_set_int (config,
+- context->section,
+- "preedit_underline",
+- active);
+-}
+-
+-static void
+-on_orientation_changed (GtkComboBox *combo,
+- gpointer user_data)
+-{
+- ConfigContext *context = user_data;
+- GtkTreeModel *model;
+- GtkTreeIter iter;
+- gint active;
+-
+- model = gtk_combo_box_get_model (combo);
+- gtk_combo_box_get_active_iter (combo, &iter);
+- gtk_tree_model_get (model, &iter, COLUMN_VALUE, &active, -1);
+-
+- ibus_m17n_config_set_int (config,
+- context->section,
+- "lookup_table_orientation",
+- active);
+-}
+-
+-static void
+-toggle_color (ConfigContext *context,
+- GtkToggleButton *togglebutton,
+- GtkWidget *colorbutton,
+- const gchar *name)
+-{
+- GdkColor color;
+-
+- if (gtk_toggle_button_get_active (togglebutton)) {
++ if (gtk_toggle_button_get_active (togglebutton))
+ gtk_widget_set_sensitive (colorbutton, TRUE);
+- gtk_color_button_get_color (GTK_COLOR_BUTTON(colorbutton), &color);
+- set_color (context, name, &color);
+- } else {
++ else
+ gtk_widget_set_sensitive (colorbutton, FALSE);
+- gtk_color_button_get_color (GTK_COLOR_BUTTON(colorbutton), &color);
+- set_color (context, name, NULL);
+- }
+ }
+
+ static void
+ on_foreground_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+ {
+- ConfigContext *context = user_data;
+-
+- toggle_color (context,
+- togglebutton,
+- context->colorbutton_foreground,
+- "preedit_foreground");
++ SetupDialog *dialog = user_data;
++ toggle_colorbutton_sensitive (togglebutton, dialog->colorbutton_foreground);
+ }
+
+ static void
+ on_background_toggled (GtkToggleButton *togglebutton,
+ gpointer user_data)
+ {
+- ConfigContext *context = user_data;
+-
+- toggle_color (context,
+- togglebutton,
+- context->colorbutton_background,
+- "preedit_background");
++ SetupDialog *dialog = user_data;
++ toggle_colorbutton_sensitive (togglebutton, dialog->colorbutton_background);
+ }
+
+ static gint
+-get_combo_box_index_by_value (GtkComboBox *combobox, gint value)
++get_combo_box_index_by_value (GtkComboBox *combobox,
++ gint value)
+ {
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+@@ -351,185 +224,366 @@ get_combo_box_index_by_value (GtkComboBox *combobox, gint value)
+ }
+
+ static void
+-start (const gchar *engine_name)
++_gdk_color_from_uint (guint color,
++ GdkColor *color_gdk)
++{
++ color_gdk->pixel = 0;
++ color_gdk->red = (color >> 8) & 0xFF00;
++ color_gdk->green = color & 0xFF00;
++ color_gdk->blue = (color & 0xFF) << 8;
++}
++
++static void
++setup_dialog_load_config (SetupDialog *dialog)
+ {
+- IBusBus *bus;
+- gchar **strv, *lang, *name;
+- GtkBuilder *builder;
+- GtkWidget *dialog;
+- GtkWidget *combobox_underline, *combobox_orientation;
+- GtkWidget *checkbutton_foreground, *checkbutton_background;
+- GtkWidget *treeview;
+- GtkListStore *store;
+- GObject *object;
+- GError *error = NULL;
+- GtkCellRenderer *renderer;
+- ConfigContext context;
+ gchar *color;
+- gboolean is_foreground_set, is_background_set;
+- GdkColor foreground, background;
+- gint underline;
+- gint orientation;
++ gboolean bvalue;
++ gint ivalue;
++ GdkColor cvalue;
++ GtkCellRenderer *renderer;
+ gint index;
+
+- ibus_init ();
+-
+- bus = ibus_bus_new ();
+- //g_signal_connect (bus, "disconnected", G_CALLBACK (ibus_disconnected_cb), NULL);
+- ibus_m17n_init (bus);
+-
+- strv = g_strsplit (engine_name, ":", 3);
+-
+- g_assert (g_strv_length (strv) == 3);
+- g_assert (g_strcmp0 (strv[0], "m17n") == 0);
+-
+- lang = strv[1];
+- name = strv[2];
+-
+- config = ibus_bus_get_config (bus);
+- context.section = g_strdup_printf ("engine/M17N/%s/%s", lang, name);
+-
+- builder = gtk_builder_new ();
+- gtk_builder_set_translation_domain (builder, "ibus-m17n");
+- gtk_builder_add_from_file (builder,
+- SETUPDIR "/ibus-m17n-preferences.ui",
+- &error);
+- object = gtk_builder_get_object (builder, "dialog");
+- dialog = GTK_WIDGET(object);
+- object = gtk_builder_get_object (builder, "checkbutton_foreground");
+- checkbutton_foreground = GTK_WIDGET(object);
+- object = gtk_builder_get_object (builder, "colorbutton_foreground");
+- context.colorbutton_foreground = GTK_WIDGET(object);
+- object = gtk_builder_get_object (builder, "checkbutton_background");
+- checkbutton_background = GTK_WIDGET(object);
+- object = gtk_builder_get_object (builder, "colorbutton_background");
+- context.colorbutton_background = GTK_WIDGET(object);
+- object = gtk_builder_get_object (builder, "combobox_underline");
+- combobox_underline = GTK_WIDGET(object);
+- object = gtk_builder_get_object (builder, "combobox_orientation");
+- combobox_orientation = GTK_WIDGET(object);
+- object = gtk_builder_get_object (builder, "treeviewMimConfig");
+- treeview = GTK_WIDGET(object);
+-
+ /* General -> Pre-edit Appearance */
+ /* foreground color of pre-edit buffer */
+- is_foreground_set = FALSE;
+- color_to_gdk (PREEDIT_FOREGROUND, &foreground);
+- if (ibus_m17n_config_get_string (config,
+- context.section,
++ bvalue = FALSE;
++ _gdk_color_from_uint (PREEDIT_FOREGROUND, &cvalue);
++ if (ibus_m17n_config_get_string (dialog->config,
++ dialog->section,
+ "preedit_foreground",
+ &color)) {
+- if (g_strcmp0 (color, "none") != 0 &&
+- gdk_color_parse (color, &foreground))
+- is_foreground_set = TRUE;
++ if (g_strcmp0 (color, "none") != 0 && gdk_color_parse (color, &cvalue))
++ bvalue = TRUE;
+ g_free (color);
+ }
+
+- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(checkbutton_foreground),
+- is_foreground_set);
+- g_signal_connect (checkbutton_foreground, "toggled",
+- G_CALLBACK(on_foreground_toggled),
+- &context);
+- gtk_widget_set_sensitive (context.colorbutton_foreground,
+- is_foreground_set);
++ gtk_toggle_button_set_active
++ (GTK_TOGGLE_BUTTON (dialog->checkbutton_foreground),
++ bvalue);
++ g_signal_connect (dialog->checkbutton_foreground, "toggled",
++ G_CALLBACK (on_foreground_toggled), dialog);
++ gtk_widget_set_sensitive (dialog->colorbutton_foreground, bvalue);
+ gtk_color_button_set_color
+- (GTK_COLOR_BUTTON(context.colorbutton_foreground),
+- &foreground);
+- g_signal_connect (context.colorbutton_foreground, "color-set",
+- G_CALLBACK(on_foreground_color_set), &context);
++ (GTK_COLOR_BUTTON (dialog->colorbutton_foreground),
++ &cvalue);
+
+-
+ /* background color of pre-edit buffer */
+- is_background_set = FALSE;
+- color_to_gdk (PREEDIT_BACKGROUND, &background);
+- if (ibus_m17n_config_get_string (config,
+- context.section,
++ bvalue = FALSE;
++ _gdk_color_from_uint (PREEDIT_BACKGROUND, &cvalue);
++ if (ibus_m17n_config_get_string (dialog->config,
++ dialog->section,
+ "preedit_background",
+ &color)) {
+- if (g_strcmp0 (color, "none") != 0 &&
+- gdk_color_parse (color, &background))
+- is_background_set = TRUE;
+- g_debug ("preedit_background %d", is_background_set);
++ if (g_strcmp0 (color, "none") != 0 && gdk_color_parse (color, &cvalue))
++ bvalue = TRUE;
+ g_free (color);
+ }
+- gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(checkbutton_background),
+- is_background_set);
+- g_signal_connect (checkbutton_background, "toggled",
+- G_CALLBACK(on_background_toggled),
+- &context);
+- gtk_widget_set_sensitive (context.colorbutton_background,
+- is_background_set);
++ gtk_toggle_button_set_active
++ (GTK_TOGGLE_BUTTON (dialog->checkbutton_background),
++ bvalue);
++ g_signal_connect (dialog->checkbutton_background, "toggled",
++ G_CALLBACK (on_background_toggled), dialog);
++ gtk_widget_set_sensitive (dialog->colorbutton_background, bvalue);
+ gtk_color_button_set_color
+- (GTK_COLOR_BUTTON(context.colorbutton_background),
+- &background);
+- g_signal_connect (context.colorbutton_background, "color-set",
+- G_CALLBACK(on_background_color_set), &context);
++ (GTK_COLOR_BUTTON (dialog->colorbutton_background),
++ &cvalue);
+
+ /* underline of pre-edit buffer */
+ renderer = gtk_cell_renderer_text_new ();
+- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combobox_underline),
++ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (dialog->combobox_underline),
+ renderer, TRUE);
+- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(combobox_underline),
+- renderer, "text", 0, NULL);
+- if (!ibus_m17n_config_get_int (config,
+- context.section,
++ gtk_cell_layout_set_attributes
++ (GTK_CELL_LAYOUT (dialog->combobox_underline),
++ renderer, "text", 0, NULL);
++ if (!ibus_m17n_config_get_int (dialog->config,
++ dialog->section,
+ "preedit_underline",
+- &underline))
+- underline = IBUS_ATTR_UNDERLINE_NONE;
++ &ivalue))
++ ivalue = IBUS_ATTR_UNDERLINE_NONE;
+
+- index = get_combo_box_index_by_value (GTK_COMBO_BOX(combobox_underline),
+- underline);
+- gtk_combo_box_set_active (GTK_COMBO_BOX(combobox_underline), index);
+- g_signal_connect (combobox_underline, "changed",
+- G_CALLBACK(on_underline_changed), &context);
++ index = get_combo_box_index_by_value
++ (GTK_COMBO_BOX (dialog->combobox_underline),
++ ivalue);
++ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combobox_underline),
++ index);
+
+ /* General -> Other */
++ /* lookup table orientation */
+ renderer = gtk_cell_renderer_text_new ();
+- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT(combobox_orientation),
++ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (dialog->combobox_orientation),
+ renderer, TRUE);
+- gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(combobox_orientation),
+- renderer, "text", 0, NULL);
+- if (!ibus_m17n_config_get_int (config,
+- context.section,
++ gtk_cell_layout_set_attributes
++ (GTK_CELL_LAYOUT (dialog->combobox_orientation),
++ renderer, "text", 0, NULL);
++ if (!ibus_m17n_config_get_int (dialog->config,
++ dialog->section,
+ "lookup_table_orientation",
+- &orientation))
+- orientation = IBUS_ORIENTATION_SYSTEM;
++ &ivalue))
++ ivalue = IBUS_ORIENTATION_SYSTEM;
+
+- index = get_combo_box_index_by_value (GTK_COMBO_BOX(combobox_orientation),
+- orientation);
+- gtk_combo_box_set_active (GTK_COMBO_BOX(combobox_orientation), index);
+- g_signal_connect (combobox_orientation, "changed",
+- G_CALLBACK(on_orientation_changed), &context);
++ index = get_combo_box_index_by_value
++ (GTK_COMBO_BOX (dialog->combobox_orientation),
++ ivalue);
++ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combobox_orientation),
++ index);
+
+ /* Advanced -> m17n-lib configuration */
+- store = gtk_list_store_new (NUM_COLS,
+- G_TYPE_STRING,
+- G_TYPE_STRING,
+- G_TYPE_STRING);
+- insert_items (store, msymbol (lang), msymbol (name));
+-
+- gtk_tree_view_set_model (GTK_TREE_VIEW(treeview), GTK_TREE_MODEL (store));
+- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1,
+- "Key",
+- gtk_cell_renderer_text_new (),
+- "text", COLUMN_KEY, NULL);
+- g_object_set (treeview, "has-tooltip", TRUE, NULL);
+- g_signal_connect (treeview, "query-tooltip", G_CALLBACK(on_query_tooltip),
+- NULL);
+-
+- context.language = msymbol (lang);
+- context.name = msymbol (name);
+- context.store = store;
++ dialog->store = gtk_list_store_new (NUM_COLS,
++ G_TYPE_STRING,
++ G_TYPE_STRING,
++ G_TYPE_STRING);
++ insert_m17n_items (dialog->store, dialog->lang, dialog->name);
++
++ gtk_tree_view_set_model (GTK_TREE_VIEW (dialog->treeview),
++ GTK_TREE_MODEL (dialog->store));
++
++ renderer = gtk_cell_renderer_text_new ();
++ gtk_tree_view_insert_column_with_attributes
++ (GTK_TREE_VIEW (dialog->treeview), -1,
++ "Key",
++ renderer,
++ "text", COLUMN_KEY,
++ NULL);
+ renderer = gtk_cell_renderer_text_new ();
+- gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (treeview), -1,
+- "Value",
+- renderer,
+- "text", COLUMN_VALUE, NULL);
++ gtk_tree_view_insert_column_with_attributes
++ (GTK_TREE_VIEW (dialog->treeview), -1,
++ "Value",
++ renderer,
++ "text", COLUMN_VALUE,
++ NULL);
+ g_object_set (renderer, "editable", TRUE, NULL);
+- g_signal_connect (renderer, "edited", G_CALLBACK(on_edited), &context);
++ g_signal_connect (renderer, "edited", G_CALLBACK (on_edited), dialog);
++
++ g_signal_connect (dialog->treeview, "query-tooltip",
++ G_CALLBACK (on_query_tooltip), NULL);
++}
++
++static gchar *
++_gdk_color_to_string (GdkColor *color)
++{
++ g_strdup_printf ("#%02X%02X%02X",
++ (color->red & 0xFF00) >> 8,
++ (color->green & 0xFF00) >> 8,
++ (color->blue & 0xFF00) >> 8);
++}
++
++static void
++save_color (SetupDialog *dialog,
++ GtkToggleButton *togglebutton,
++ GtkColorButton *colorbutton,
++ const gchar *name)
++{
++ if (gtk_toggle_button_get_active (togglebutton)) {
++ GdkColor color;
++ gchar *svalue;
++
++ gtk_color_button_get_color (colorbutton, &color);
++ svalue = _gdk_color_to_string (&color);
++ ibus_m17n_config_set_string (dialog->config,
++ dialog->section,
++ name,
++ svalue);
++ g_free (svalue);
++ } else {
++ ibus_m17n_config_set_string (dialog->config,
++ dialog->section,
++ name,
++ "none");
++ }
++}
++
++static void
++save_choice (SetupDialog *dialog,
++ GtkComboBox *combo,
++ const gchar *name)
++{
++ GtkTreeModel *model;
++ GtkTreeIter iter;
++ gint active;
++
++ model = gtk_combo_box_get_model (combo);
++ gtk_combo_box_get_active_iter (combo, &iter);
++ gtk_tree_model_get (model, &iter, COLUMN_VALUE, &active, -1);
++
++ ibus_m17n_config_set_int (dialog->config, dialog->section, name, active);
++}
++
++static gboolean
++save_m17n_options (SetupDialog *dialog)
++{
++ GtkTreeModel *model = GTK_TREE_MODEL (dialog->store);
++ GtkTreeIter iter;
++ MPlist *plist, *p, *mvalue = NULL;
++ gchar *key = NULL, *value = NULL;
++ gboolean retval = TRUE;
++
++ if (!gtk_tree_model_get_iter_first (model, &iter))
++ return;
++
++ do {
++ gtk_tree_model_get (model, &iter,
++ COLUMN_KEY, &key,
++ COLUMN_VALUE, &value,
++ -1);
++
++ plist = minput_get_variable (dialog->lang, dialog->name, msymbol (key));
++ if (!plist) {
++ retval = FALSE;
++ break;
++ }
++
++ p = mplist_next (mplist_next (mplist_next (mplist_value (plist))));
++ if (!p) {
++ retval = FALSE;
++ break;
++ }
++
++ mvalue = parse_m17n_value (p, value);
++ if (!mvalue) {
++ retval = FALSE;
++ break;
++ }
++
++ if (minput_config_variable (dialog->lang,
++ dialog->name,
++ msymbol (key),
++ mvalue) != 0) {
++ retval = FALSE;
++ break;
++ }
++
++ if (mvalue)
++ m17n_object_unref (mvalue);
++ g_free (key);
++ g_free (value);
++ mvalue = NULL;
++ key = NULL;
++ value = NULL;
++ } while (gtk_tree_model_iter_next (model, &iter));
++
++ if (retval && minput_save_config () != 1)
++ retval = FALSE;
++
++ if (mvalue)
++ m17n_object_unref (mvalue);
++ g_free (key);
++ g_free (value);
++
++ return retval;
++}
++
++static void
++setup_dialog_save_config (SetupDialog *dialog)
++{
++ save_color (dialog,
++ GTK_TOGGLE_BUTTON (dialog->checkbutton_foreground),
++ GTK_COLOR_BUTTON (dialog->colorbutton_foreground),
++ "preedit_foreground");
++ save_color (dialog,
++ GTK_TOGGLE_BUTTON (dialog->checkbutton_background),
++ GTK_COLOR_BUTTON (dialog->colorbutton_background),
++ "preedit_background");
++ save_choice (dialog,
++ GTK_COMBO_BOX (dialog->combobox_underline),
++ "preedit_underline");
++ save_choice (dialog,
++ GTK_COMBO_BOX (dialog->combobox_orientation),
++ "lookup_table_orientation");
++ save_m17n_options (dialog);
++}
++
++static SetupDialog *
++setup_dialog_new (IBusConfig *config,
++ MSymbol lang,
++ MSymbol name)
++{
++ GtkBuilder *builder;
++ SetupDialog *dialog;
++ GObject *object;
++ GError *error;
++
++ dialog = g_slice_new0 (SetupDialog);
++ dialog->config = config;
++ dialog->lang = lang;
++ dialog->name = name;
++ dialog->section = g_strdup_printf ("engine/M17N/%s/%s",
++ msymbol_name (lang),
++ msymbol_name (name));
++
++ builder = gtk_builder_new ();
++ gtk_builder_set_translation_domain (builder, "ibus-m17n");
++
++ error = NULL;
++ if (gtk_builder_add_from_file (builder,
++ SETUPDIR "/ibus-m17n-preferences.ui",
++ &error) == 0) {
++ g_error_free (error);
++ g_return_val_if_reached (NULL);
++ }
++
++ object = gtk_builder_get_object (builder, "dialog");
++ dialog->dialog = GTK_WIDGET (object);
++ object = gtk_builder_get_object (builder, "checkbutton_foreground");
++ dialog->checkbutton_foreground = GTK_WIDGET (object);
++ object = gtk_builder_get_object (builder, "colorbutton_foreground");
++ dialog->colorbutton_foreground = GTK_WIDGET (object);
++ object = gtk_builder_get_object (builder, "checkbutton_background");
++ dialog->checkbutton_background = GTK_WIDGET (object);
++ object = gtk_builder_get_object (builder, "colorbutton_background");
++ dialog->colorbutton_background = GTK_WIDGET (object);
++ object = gtk_builder_get_object (builder, "combobox_underline");
++ dialog->combobox_underline = GTK_WIDGET (object);
++ object = gtk_builder_get_object (builder, "combobox_orientation");
++ dialog->combobox_orientation = GTK_WIDGET (object);
++ object = gtk_builder_get_object (builder, "treeview_mim_config");
++ dialog->treeview = GTK_WIDGET (object);
++
++ return dialog;
++}
++
++static void
++setup_dialog_free (SetupDialog *dialog)
++{
++ gtk_widget_destroy (dialog->dialog);
++ g_free (dialog->section);
++ g_object_unref (dialog->store);
++ g_slice_free (SetupDialog, dialog);
++}
++
++static void
++start (const gchar *engine_name)
++{
++ IBusBus *bus;
++ IBusConfig *config;
++ gchar **strv, *section;
++ SetupDialog *dialog;
++ GObject *object;
++
++ ibus_init ();
++ ibus_m17n_init_common ();
++
++ strv = g_strsplit (engine_name, ":", 3);
++ g_assert (g_strv_length (strv) == 3);
++ g_assert (g_strcmp0 (strv[0], "m17n") == 0);
++
++ bus = ibus_bus_new ();
++ //g_signal_connect (bus, "disconnected", G_CALLBACK (ibus_disconnected_cb), NULL);
++ config = ibus_bus_get_config (bus);
++
++ /* strv == {"m17n", lang, name, NULL} */
++ dialog = setup_dialog_new (config, msymbol (strv[1]), msymbol (strv[2]));
++ g_strfreev (strv);
++
++ setup_dialog_load_config (dialog);
++
++ gtk_window_present (GTK_WINDOW (dialog->dialog));
++ gtk_dialog_run (GTK_DIALOG (dialog->dialog));
++
++ setup_dialog_save_config (dialog);
++ setup_dialog_free (dialog);
++
++ g_object_unref (bus);
+
+- gtk_widget_show_all (dialog);
+- gtk_dialog_run (GTK_DIALOG(dialog));
++ M17N_FINI ();
+ }
+
+ int
+--
+1.7.7.6
+
+
+From 11730d65d6d62711d7f8a2ce415d1229a86dd16e Mon Sep 17 00:00:00 2001
+From: Peng Huang <shawn.p.huang at gmail.com>
+Date: Sun, 18 Sep 2011 22:08:00 -0400
+Subject: [PATCH 03/10] Fix a crash and add some warning log message.
+
+BUG=Crash in Chrome OS
+TEST=Linux desktop
+
+Review URL: http://codereview.appspot.com/5050041
+---
+ src/engine.c | 19 ++++++++++++++++---
+ 1 files changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/src/engine.c b/src/engine.c
+index dcff0c7..db14607 100644
+--- a/src/engine.c
++++ b/src/engine.c
+@@ -816,8 +816,15 @@ ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n)
+ ibus_lookup_table_set_page_size (m17n->table, mtext_len (mt));
+
+ buf = ibus_m17n_mtext_to_ucs4 (mt, &nchars);
+- for (i = 0; i < nchars; i++) {
+- ibus_lookup_table_append_candidate (m17n->table, ibus_text_new_from_unichar (buf[i]));
++ g_warn_if_fail (buf != NULL);
++
++ for (i = 0; buf != NULL && i < nchars; i++) {
++ IBusText *text = ibus_text_new_from_unichar (buf[i]);
++ if (text == NULL) {
++ text = ibus_text_new_from_printf ("INVCODE=U+08X%", buf[i]);
++ g_warn_if_reached ();
++ }
++ ibus_lookup_table_append_candidate (m17n->table, text);
+ }
+ g_free (buf);
+ }
+@@ -834,9 +841,15 @@ ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n)
+ mtext = (MText *) mplist_value (p);
+ buf = ibus_m17n_mtext_to_utf8 (mtext);
+ if (buf) {
+- ibus_lookup_table_append_candidate (m17n->table, ibus_text_new_from_string (buf));
++ ibus_lookup_table_append_candidate (m17n->table,
++ ibus_text_new_from_string (buf));
+ g_free (buf);
+ }
++ else {
++ ibus_lookup_table_append_candidate (m17n->table,
++ ibus_text_new_from_static_string ("NULL"));
++ g_warn_if_reached();
++ }
+ }
+ }
+
+--
+1.7.7.6
+
+
+From f53d61029aac81559b82fa235216748e42e4850a Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Tue, 27 Dec 2011 09:48:04 +0900
+Subject: [PATCH 04/10] Supply custom setup element in EngineDesc.
+
+BUG=RHBZ#760427
+TEST=manually
+
+Review URL: http://codereview.appspot.com/5500079
+---
+ src/m17nutil.c | 5 +++++
+ 1 files changed, 5 insertions(+), 0 deletions(-)
+
+diff --git a/src/m17nutil.c b/src/m17nutil.c
+index 54561f2..bc9155a 100644
+--- a/src/m17nutil.c
++++ b/src/m17nutil.c
+@@ -114,6 +114,7 @@ ibus_m17n_engine_new (MSymbol lang,
+ gchar *engine_title;
+ gchar *engine_icon;
+ gchar *engine_desc;
++ gchar *engine_setup;
+
+ engine_name = g_strdup_printf ("m17n:%s:%s", msymbol_name (lang), msymbol_name (name));
+
+@@ -121,6 +122,8 @@ ibus_m17n_engine_new (MSymbol lang,
+ engine_title = ibus_m17n_mtext_to_utf8 (title);
+ engine_icon = ibus_m17n_mtext_to_utf8 (icon);
+ engine_desc = ibus_m17n_mtext_to_utf8 (desc);
++ engine_setup = g_strdup_printf ("%s/ibus-setup-m17n --name %s",
++ LIBEXECDIR, engine_name);
+
+ #if IBUS_CHECK_VERSION(1,3,99)
+ engine = ibus_engine_desc_new_varargs ("name", engine_name,
+@@ -131,6 +134,7 @@ ibus_m17n_engine_new (MSymbol lang,
+ "icon", engine_icon ? engine_icon : "",
+ "layout", "us",
+ "rank", config->rank,
++ "setup", engine_setup,
+ NULL);
+ #else
+ engine = ibus_engine_desc_new (engine_name,
+@@ -149,6 +153,7 @@ ibus_m17n_engine_new (MSymbol lang,
+ g_free (engine_title);
+ g_free (engine_icon);
+ g_free (engine_desc);
++ g_free (engine_setup);
+
+ return engine;
+ }
+--
+1.7.7.6
+
+
+From 6c517a7c18254297cee745f16b96deb1033c55c5 Mon Sep 17 00:00:00 2001
+From: Peng Huang <shawn.p.huang at gmail.com>
+Date: Fri, 6 Jan 2012 10:21:19 -0500
+Subject: [PATCH 05/10] Fix a typo.
+
+BUG=None
+TEST=Manually
+
+Review URL: http://codereview.appspot.com/5524043
+---
+ src/engine.c | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/src/engine.c b/src/engine.c
+index db14607..c2b30e1 100644
+--- a/src/engine.c
++++ b/src/engine.c
+@@ -821,7 +821,7 @@ ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n)
+ for (i = 0; buf != NULL && i < nchars; i++) {
+ IBusText *text = ibus_text_new_from_unichar (buf[i]);
+ if (text == NULL) {
+- text = ibus_text_new_from_printf ("INVCODE=U+08X%", buf[i]);
++ text = ibus_text_new_from_printf ("INVCODE=U+%04"G_GINT32_FORMAT"X", buf[i]);
+ g_warn_if_reached ();
+ }
+ ibus_lookup_table_append_candidate (m17n->table, text);
+--
+1.7.7.6
+
+
+From e2902f6c6efc5bf2b55019140ea8ed82fc977369 Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Tue, 14 Feb 2012 11:54:07 +0900
+Subject: [PATCH 06/10] Require ibus-1.4 or later and use
+ ibus_config_get_values.
+
+BUG=none
+TEST=manually
+
+Review URL: https://codereview.appspot.com/5654073
+---
+ configure.ac | 11 +---
+ src/engine.c | 109 +++++++++++++++++-----------------
+ src/m17nutil.c | 98 ------------------------------
+ src/m17nutil.h | 16 -----
+ src/setup.c | 179 ++++++++++++++++++++++++++++++--------------------------
+ 5 files changed, 150 insertions(+), 263 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index 927d382..be9728d 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -52,7 +52,7 @@ AM_PROG_LIBTOOL
+
+ # check ibus
+ PKG_CHECK_MODULES(IBUS, [
+- ibus-1.0 >= 1.3
++ ibus-1.0 >= 1.4
+ ])
+
+ # check m17n
+@@ -97,15 +97,6 @@ AC_REPLACE_FUNCS([minput_list])
+ CFLAGS="$save_CFLAGS"
+ LIBS="$save_LIBS"
+
+-# check if ibus_engine_get_surrounding_text, which is available in ibus-1.3.99+ (git master)
+-save_CFLAGS="$CFLAGS"
+-save_LIBS="$LIBS"
+-CFLAGS="$CFLAGS $IBUS_CFLAGS"
+-LIBS="$LIBS $IBUS_LIBS"
+-AC_CHECK_FUNCS([ibus_engine_get_surrounding_text])
+-CFLAGS="$save_CFLAGS"
+-LIBS="$save_LIBS"
+-
+ # define GETTEXT_* variables
+ GETTEXT_PACKAGE=ibus-m17n
+ AC_SUBST(GETTEXT_PACKAGE)
+diff --git a/src/engine.c b/src/engine.c
+index c2b30e1..051b63c 100644
+--- a/src/engine.c
++++ b/src/engine.c
+@@ -43,11 +43,7 @@ static void ibus_m17n_engine_class_init (IBusM17NEngineClass *klass);
+ static void ibus_m17n_config_value_changed (IBusConfig *config,
+ const gchar *section,
+ const gchar *name,
+-#if IBUS_CHECK_VERSION(1,3,99)
+ GVariant *value,
+-#else
+- GValue *value,
+-#endif /* !IBUS_CHECK_VERSION(1,3,99) */
+ IBusM17NEngineClass *klass);
+
+ static GObject*
+@@ -215,7 +211,7 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ IBusEngineClass *engine_class = IBUS_ENGINE_CLASS (klass);
+ gchar *engine_name, *lang = NULL, *name = NULL;
+ IBusM17NEngineConfig *engine_config;
+- gchar *hex;
++ GVariant *values;
+
+ if (parent_class == NULL)
+ parent_class = (IBusEngineClass *) g_type_class_peek_parent (klass);
+@@ -251,46 +247,61 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ g_free (lang);
+ g_free (name);
+
++ engine_config = ibus_m17n_get_engine_config (engine_name);
++ g_free (engine_name);
++
+ /* configurations are per class */
+- klass->preedit_foreground = INVALID_COLOR;
+- klass->preedit_background = INVALID_COLOR;
++ klass->preedit_foreground = engine_config->preedit_highlight ?
++ PREEDIT_FOREGROUND :
++ INVALID_COLOR;
++ klass->preedit_background = engine_config->preedit_highlight ?
++ PREEDIT_BACKGROUND :
++ INVALID_COLOR;
+ klass->preedit_underline = IBUS_ATTR_UNDERLINE_NONE;
+ klass->lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
+
+- engine_config = ibus_m17n_get_engine_config (engine_name);
+- g_free (engine_name);
++ ibus_m17n_engine_config_free (engine_config);
++
++ values = ibus_config_get_values (config,
++ klass->config_section);
++ if (values != NULL) {
++ GVariant *value;
++
++ value = g_variant_lookup_value (values,
++ "preedit_foreground",
++ G_VARIANT_TYPE_STRING);
++ if (value != NULL) {
++ const gchar *hex = g_variant_get_string (value, NULL);
++ klass->preedit_foreground = ibus_m17n_parse_color (hex);
++ }
++ g_variant_unref (value);
++
++ value = g_variant_lookup_value (values,
++ "preedit_background",
++ G_VARIANT_TYPE_STRING);
++ if (value != NULL) {
++ const gchar *hex = g_variant_get_string (value, NULL);
++ klass->preedit_background = ibus_m17n_parse_color (hex);
++ }
++ g_variant_unref (value);
+
+- if (ibus_m17n_config_get_string (config,
+- klass->config_section,
+- "preedit_foreground",
+- &hex)) {
+- klass->preedit_foreground = ibus_m17n_parse_color (hex);
+- g_free (hex);
+- } else if (engine_config->preedit_highlight)
+- klass->preedit_foreground = PREEDIT_FOREGROUND;
+-
+- if (ibus_m17n_config_get_string (config,
+- klass->config_section,
+- "preedit_background",
+- &hex)) {
+- klass->preedit_background = ibus_m17n_parse_color (hex);
+- g_free (hex);
+- } else if (engine_config->preedit_highlight)
+- klass->preedit_background = PREEDIT_BACKGROUND;
+-
+- if (!ibus_m17n_config_get_int (config,
+- klass->config_section,
+- "preedit_underline",
+- &klass->preedit_underline))
+- klass->preedit_underline = IBUS_ATTR_UNDERLINE_NONE;
+-
+- if (!ibus_m17n_config_get_int (config,
+- klass->config_section,
+- "lookup_table_orientation",
+- &klass->lookup_table_orientation))
+- klass->lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
++ value = g_variant_lookup_value (values,
++ "preedit_underline",
++ G_VARIANT_TYPE_INT32);
++ if (value != NULL) {
++ klass->preedit_background = g_variant_get_int32 (value);
++ }
++ g_variant_unref (value);
+
+- ibus_m17n_engine_config_free (engine_config);
++ value = g_variant_lookup_value (values,
++ "lookup_table_orientation",
++ G_VARIANT_TYPE_INT32);
++ if (value != NULL) {
++ klass->lookup_table_orientation = g_variant_get_int32 (value);
++ }
++ g_variant_unref (value);
++ g_variant_unref (values);
++ }
+
+ g_signal_connect (config, "value-changed",
+ G_CALLBACK(ibus_m17n_config_value_changed),
+@@ -299,44 +310,32 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ klass->im = NULL;
+ }
+
+-#if IBUS_CHECK_VERSION(1,3,99)
+-#define _g_variant_get_string g_variant_get_string
+-#define _g_variant_get_int32 g_variant_get_int32
+-#else
+-#define _g_variant_get_string(value, length) g_value_get_string(value)
+-#define _g_variant_get_int32 g_value_get_int
+-#endif /* !IBUS_CHECK_VERSION(1,3,99) */
+-
+ static void
+ ibus_m17n_config_value_changed (IBusConfig *config,
+ const gchar *section,
+ const gchar *name,
+-#if IBUS_CHECK_VERSION(1,3,99)
+ GVariant *value,
+-#else
+- GValue *value,
+-#endif /* !IBUS_CHECK_VERSION(1,3,99) */
+ IBusM17NEngineClass *klass)
+ {
+ if (g_strcmp0 (section, klass->config_section) == 0) {
+ if (g_strcmp0 (name, "preedit_foreground") == 0) {
+- const gchar *hex = _g_variant_get_string (value, NULL);
++ const gchar *hex = g_variant_get_string (value, NULL);
+ guint color;
+ color = ibus_m17n_parse_color (hex);
+ if (color != INVALID_COLOR) {
+ klass->preedit_foreground = color;
+ }
+ } else if (g_strcmp0 (name, "preedit_background") == 0) {
+- const gchar *hex = _g_variant_get_string (value, NULL);
++ const gchar *hex = g_variant_get_string (value, NULL);
+ guint color;
+ color = ibus_m17n_parse_color (hex);
+ if (color != INVALID_COLOR) {
+ klass->preedit_background = color;
+ }
+ } else if (g_strcmp0 (name, "preedit_underline") == 0) {
+- klass->preedit_underline = _g_variant_get_int32 (value);
++ klass->preedit_underline = g_variant_get_int32 (value);
+ } else if (g_strcmp0 (name, "lookup_table_orientation") == 0) {
+- klass->lookup_table_orientation = _g_variant_get_int32 (value);
++ klass->lookup_table_orientation = g_variant_get_int32 (value);
+ }
+ }
+ }
+diff --git a/src/m17nutil.c b/src/m17nutil.c
+index bc9155a..9fa5517 100644
+--- a/src/m17nutil.c
++++ b/src/m17nutil.c
+@@ -373,101 +373,3 @@ ibus_m17n_get_component (void)
+
+ return component;
+ }
+-
+-void
+-ibus_m17n_config_set_string (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- const gchar *value)
+-{
+-#if IBUS_CHECK_VERSION(1,3,99)
+- ibus_config_set_value (config, section, name, g_variant_new_string (value));
+-#else
+- GValue v = { 0 };
+-
+- g_value_init (&v, G_TYPE_STRING);
+- g_value_set_string (&v, value);
+- ibus_config_set_value (config, section, name, &v);
+-#endif /* !IBUS_CHECK_VERSION(1,3,99) */
+-}
+-
+-gboolean
+-ibus_m17n_config_get_string (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- gchar **result)
+-{
+-#if IBUS_CHECK_VERSION(1,3,99)
+- GVariant *value = NULL;
+-
+- g_return_val_if_fail (result != NULL, FALSE);
+-
+- value = ibus_config_get_value (config, section, name);
+- if (value) {
+- *result = g_strdup (g_variant_get_string (value, NULL));
+- g_variant_unref (value);
+- return TRUE;
+- }
+- return FALSE;
+-#else
+- GValue value = { 0 };
+-
+- g_return_val_if_fail (result != NULL, FALSE);
+-
+- if (ibus_config_get_value (config, section, name, &value)) {
+- *result = g_strdup (g_value_get_string (&value));
+- g_value_unset (&value);
+- return TRUE;
+- }
+- return FALSE;
+-#endif /* !IBUS_CHECK_VERSION(1,3,99) */
+-}
+-
+-void
+-ibus_m17n_config_set_int (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- gint value)
+-{
+-#if IBUS_CHECK_VERSION(1,3,99)
+- ibus_config_set_value (config, section, name, g_variant_new_int32 (value));
+-#else
+- GValue v = { 0 };
+-
+- g_value_init (&v, G_TYPE_INT);
+- g_value_set_int (&v, value);
+- ibus_config_set_value (config, section, name, &v);
+-#endif /* !IBUS_CHECK_VERSION(1,3,99) */
+-}
+-
+-gboolean
+-ibus_m17n_config_get_int (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- gint *result)
+-{
+-#if IBUS_CHECK_VERSION(1,3,99)
+- GVariant *value = NULL;
+-
+- g_return_val_if_fail (result != NULL, FALSE);
+-
+- value = ibus_config_get_value (config, section, name);
+- if (value) {
+- *result = g_variant_get_int32 (value);
+- g_variant_unref (value);
+- return TRUE;
+- }
+- return FALSE;
+-#else
+- GValue value = { 0 };
+-
+- g_return_val_if_fail (result != NULL, FALSE);
+-
+- if (ibus_config_get_value (config, section, name, &value)) {
+- *result = g_value_get_int (&value);
+- g_value_unset (&value);
+- return TRUE;
+- }
+- return FALSE;
+-#endif /* !IBUS_CHECK_VERSION(1,3,99) */
+-}
+diff --git a/src/m17nutil.h b/src/m17nutil.h
+index 313e7bc..b21244c 100644
+--- a/src/m17nutil.h
++++ b/src/m17nutil.h
+@@ -31,20 +31,4 @@ guint ibus_m17n_parse_color (const gchar *hex);
+ IBusM17NEngineConfig
+ *ibus_m17n_get_engine_config (const gchar *engine_name);
+ void ibus_m17n_engine_config_free (IBusM17NEngineConfig *config);
+-void ibus_m17n_config_set_string (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- const gchar *value);
+-gboolean ibus_m17n_config_get_string (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- gchar **result);
+-void ibus_m17n_config_set_int (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- gint value);
+-gboolean ibus_m17n_config_get_int (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- gint *result);
+ #endif
+diff --git a/src/setup.c b/src/setup.c
+index 02db691..7b9609b 100644
+--- a/src/setup.c
++++ b/src/setup.c
+@@ -234,97 +234,107 @@ _gdk_color_from_uint (guint color,
+ }
+
+ static void
+-setup_dialog_load_config (SetupDialog *dialog)
++load_color (GVariant *values,
++ GtkToggleButton *togglebutton,
++ GtkColorButton *colorbutton,
++ const gchar *name,
++ GdkColor *defval)
+ {
+- gchar *color;
++ GVariant *value;
+ gboolean bvalue;
+- gint ivalue;
+ GdkColor cvalue;
+- GtkCellRenderer *renderer;
+- gint index;
+
+- /* General -> Pre-edit Appearance */
+- /* foreground color of pre-edit buffer */
++ memcpy (&cvalue, defval, sizeof (GdkColor));
++
+ bvalue = FALSE;
+- _gdk_color_from_uint (PREEDIT_FOREGROUND, &cvalue);
+- if (ibus_m17n_config_get_string (dialog->config,
+- dialog->section,
+- "preedit_foreground",
+- &color)) {
+- if (g_strcmp0 (color, "none") != 0 && gdk_color_parse (color, &cvalue))
++ value = g_variant_lookup_value (values, name, G_VARIANT_TYPE_STRING);
++ if (value != NULL) {
++ const gchar *color = g_variant_get_string (value, NULL);
++ if (g_strcmp0 (color, "none") != 0 &&
++ gdk_color_parse (color, &cvalue))
+ bvalue = TRUE;
+- g_free (color);
++ g_variant_unref (value);
+ }
+
+- gtk_toggle_button_set_active
+- (GTK_TOGGLE_BUTTON (dialog->checkbutton_foreground),
+- bvalue);
++ gtk_toggle_button_set_active (togglebutton, bvalue);
++ gtk_widget_set_sensitive (GTK_WIDGET (colorbutton), bvalue);
++ gtk_color_button_set_color (GTK_COLOR_BUTTON (colorbutton), &cvalue);
++}
++
++static void
++load_choice (GVariant *values,
++ GtkComboBox *combo,
++ const gchar *name,
++ gint defval)
++{
++ GVariant *value;
++ gint ivalue, index;
++ GtkCellRenderer *renderer;
++
++ renderer = gtk_cell_renderer_text_new ();
++ gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
++ gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo),
++ renderer, "text", 0, NULL);
++
++ ivalue = defval;
++ value = g_variant_lookup_value (values, name, G_VARIANT_TYPE_INT32);
++ if (value != NULL) {
++ ivalue = g_variant_get_int32 (value);
++ g_variant_unref (value);
++ }
++
++ index = get_combo_box_index_by_value (GTK_COMBO_BOX (combo), ivalue);
++ gtk_combo_box_set_active (GTK_COMBO_BOX (combo), index);
++}
++
++static void
++setup_dialog_load_config (SetupDialog *dialog)
++{
++ GVariant *values;
++ GdkColor defcol;
++ GtkCellRenderer *renderer;
++
++ values = ibus_config_get_values (dialog->config, dialog->section);
++ /* ibus_config_get_values may return NULL on failure */
++ if (values == NULL) {
++ GVariantType *child_type = g_variant_type_new ("{sv}");
++ values = g_variant_new_array (child_type, NULL, 0);
++ g_variant_type_free (child_type);
++ }
++
++ /* General -> Pre-edit Appearance */
++ /* foreground color of pre-edit buffer */
++ _gdk_color_from_uint (PREEDIT_FOREGROUND, &defcol);
++ load_color (values,
++ GTK_TOGGLE_BUTTON (dialog->checkbutton_foreground),
++ GTK_COLOR_BUTTON (dialog->colorbutton_foreground),
++ "preedit_foreground",
++ &defcol);
+ g_signal_connect (dialog->checkbutton_foreground, "toggled",
+ G_CALLBACK (on_foreground_toggled), dialog);
+- gtk_widget_set_sensitive (dialog->colorbutton_foreground, bvalue);
+- gtk_color_button_set_color
+- (GTK_COLOR_BUTTON (dialog->colorbutton_foreground),
+- &cvalue);
+
+ /* background color of pre-edit buffer */
+- bvalue = FALSE;
+- _gdk_color_from_uint (PREEDIT_BACKGROUND, &cvalue);
+- if (ibus_m17n_config_get_string (dialog->config,
+- dialog->section,
+- "preedit_background",
+- &color)) {
+- if (g_strcmp0 (color, "none") != 0 && gdk_color_parse (color, &cvalue))
+- bvalue = TRUE;
+- g_free (color);
+- }
+- gtk_toggle_button_set_active
+- (GTK_TOGGLE_BUTTON (dialog->checkbutton_background),
+- bvalue);
++ _gdk_color_from_uint (PREEDIT_BACKGROUND, &defcol);
++ load_color (values,
++ GTK_TOGGLE_BUTTON (dialog->checkbutton_background),
++ GTK_COLOR_BUTTON (dialog->colorbutton_background),
++ "preedit_background",
++ &defcol);
+ g_signal_connect (dialog->checkbutton_background, "toggled",
+ G_CALLBACK (on_background_toggled), dialog);
+- gtk_widget_set_sensitive (dialog->colorbutton_background, bvalue);
+- gtk_color_button_set_color
+- (GTK_COLOR_BUTTON (dialog->colorbutton_background),
+- &cvalue);
+
+ /* underline of pre-edit buffer */
+- renderer = gtk_cell_renderer_text_new ();
+- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (dialog->combobox_underline),
+- renderer, TRUE);
+- gtk_cell_layout_set_attributes
+- (GTK_CELL_LAYOUT (dialog->combobox_underline),
+- renderer, "text", 0, NULL);
+- if (!ibus_m17n_config_get_int (dialog->config,
+- dialog->section,
+- "preedit_underline",
+- &ivalue))
+- ivalue = IBUS_ATTR_UNDERLINE_NONE;
+-
+- index = get_combo_box_index_by_value
+- (GTK_COMBO_BOX (dialog->combobox_underline),
+- ivalue);
+- gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combobox_underline),
+- index);
++ load_choice (values,
++ GTK_COMBO_BOX (dialog->combobox_underline),
++ "preedit_underline",
++ IBUS_ATTR_UNDERLINE_NONE);
+
+ /* General -> Other */
+ /* lookup table orientation */
+- renderer = gtk_cell_renderer_text_new ();
+- gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (dialog->combobox_orientation),
+- renderer, TRUE);
+- gtk_cell_layout_set_attributes
+- (GTK_CELL_LAYOUT (dialog->combobox_orientation),
+- renderer, "text", 0, NULL);
+- if (!ibus_m17n_config_get_int (dialog->config,
+- dialog->section,
+- "lookup_table_orientation",
+- &ivalue))
+- ivalue = IBUS_ORIENTATION_SYSTEM;
+-
+- index = get_combo_box_index_by_value
+- (GTK_COMBO_BOX (dialog->combobox_orientation),
+- ivalue);
+- gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->combobox_orientation),
+- index);
++ load_choice (values,
++ GTK_COMBO_BOX (dialog->combobox_orientation),
++ "lookup_table_orientation",
++ IBUS_ORIENTATION_SYSTEM);
+
+ /* Advanced -> m17n-lib configuration */
+ dialog->store = gtk_list_store_new (NUM_COLS,
+@@ -355,6 +365,8 @@ setup_dialog_load_config (SetupDialog *dialog)
+
+ g_signal_connect (dialog->treeview, "query-tooltip",
+ G_CALLBACK (on_query_tooltip), NULL);
++
++ g_variant_unref (values);
+ }
+
+ static gchar *
+@@ -372,23 +384,20 @@ save_color (SetupDialog *dialog,
+ GtkColorButton *colorbutton,
+ const gchar *name)
+ {
++ GVariant *value;
++
+ if (gtk_toggle_button_get_active (togglebutton)) {
+ GdkColor color;
+- gchar *svalue;
+
+ gtk_color_button_get_color (colorbutton, &color);
+- svalue = _gdk_color_to_string (&color);
+- ibus_m17n_config_set_string (dialog->config,
+- dialog->section,
+- name,
+- svalue);
+- g_free (svalue);
++ value = g_variant_new_string (_gdk_color_to_string (&color));
+ } else {
+- ibus_m17n_config_set_string (dialog->config,
+- dialog->section,
+- name,
+- "none");
++ value = g_variant_new_string ("none");
+ }
++ ibus_config_set_value (dialog->config,
++ dialog->section,
++ name,
++ value);
+ }
+
+ static void
+@@ -399,12 +408,14 @@ save_choice (SetupDialog *dialog,
+ GtkTreeModel *model;
+ GtkTreeIter iter;
+ gint active;
++ GVariant *value;
+
+ model = gtk_combo_box_get_model (combo);
+ gtk_combo_box_get_active_iter (combo, &iter);
+ gtk_tree_model_get (model, &iter, COLUMN_VALUE, &active, -1);
+
+- ibus_m17n_config_set_int (dialog->config, dialog->section, name, active);
++ value = g_variant_new_int32 (active);
++ ibus_config_set_value (dialog->config, dialog->section, name, value);
+ }
+
+ static gboolean
+--
+1.7.7.6
+
+
+From 74f230fac8be43fa65380ff133ed4ef24bf55a57 Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Wed, 15 Feb 2012 09:50:59 +0900
+Subject: [PATCH 07/10] Define "symbol" in each IBusEngineDesc.
+
+BUG=none
+TEST=manually on Fedora 16
+
+Review URL: https://codereview.appspot.com/5647062
+---
+ src/default.xml.in.in | 206 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/m17nutil.c | 23 +++---
+ src/m17nutil.h | 3 +
+ 3 files changed, 219 insertions(+), 13 deletions(-)
+
+diff --git a/src/default.xml.in.in b/src/default.xml.in.in
+index dc93fd3..1248d48 100644
+--- a/src/default.xml.in.in
++++ b/src/default.xml.in.in
+@@ -10,6 +10,7 @@
+ <name>m17n:*</name>
+ <rank>0</rank>
+ <preedit-highlight>FALSE</preedit-highlight>
++ <symbol></symbol>
+ </engine>
+ <!-- Indic engines should be selected by default:
+ https://bugzilla.redhat.com/show_bug.cgi?id=640896 -->
+@@ -194,4 +195,209 @@
+ <name>m17n:ja:anthy</name>
+ <preedit-highlight>TRUE</preedit-highlight>
+ </engine>
++ <!-- Set IME symbols. -->
++ <engine>
++ <name>m17n:as:*</name>
++ <symbol>অ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:bn:*</name>
++ <symbol>বা</symbol>
++ </engine>
++ <engine>
++ <name>m17n:gu:*</name>
++ <symbol>ગુ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:hi:*</name>
++ <symbol>हिं</symbol>
++ </engine>
++ <engine>
++ <name>m17n:kn:*</name>
++ <symbol>ಕ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:ks:*</name>
++ <symbol>क</symbol>
++ </engine>
++ <engine>
++ <name>m17n:mai:*</name>
++ <symbol>मै</symbol>
++ </engine>
++ <engine>
++ <name>m17n:ml:*</name>
++ <symbol>മ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:mr:*</name>
++ <symbol>म</symbol>
++ </engine>
++ <engine>
++ <name>m17n:ne:*</name>
++ <symbol>ने</symbol>
++ </engine>
++ <engine>
++ <name>m17n:or:*</name>
++ <symbol>ଓ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:pa:*</name>
++ <symbol>ਪੰ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:sa:*</name>
++ <symbol>सं</symbol>
++ </engine>
++ <engine>
++ <name>m17n:sd:*</name>
++ <symbol>सिं</symbol>
++ </engine>
++ <engine>
++ <name>m17n:si:*</name>
++ <symbol>සි</symbol>
++ </engine>
++ <engine>
++ <name>m17n:ta:*</name>
++ <symbol>த</symbol>
++ </engine>
++ <engine>
++ <name>m17n:te:*</name>
++ <symbol>తె</symbol>
++ </engine>
++ <engine>
++ <name>m17n:*:kbd</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:*:pre</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:*:post</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:am:sera</name>
++ <symbol>አ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:bo:*</name>
++ <symbol>ཀ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:cr:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:dv:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:eo:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:fa:*</name>
++ <symbol>ف</symbol>
++ </engine>
++ <engine>
++ <name>m17n:fr:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:ii:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:iu:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:ja:anthy</name>
++ <symbol>あ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:kk:*</name>
++ <symbol>قا</symbol>
++ </engine>
++ <engine>
++ <name>m17n:km:*</name>
++ <symbol>ក</symbol>
++ </engine>
++ <engine>
++ <name>m17n:lo:*</name>
++ <symbol>ກ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:nsk:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:oj:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:ps:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:ru:*</name>
++ <symbol>Я</symbol>
++ </engine>
++ <engine>
++ <name>m17n:sv:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:syrc:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:tai:*</name>
++ <symbol>꫞</symbol>
++ </engine>
++ <engine>
++ <name>m17n:th:*</name>
++ <symbol>ท</symbol>
++ </engine>
++ <engine>
++ <name>m17n:ur:*</name>
++ <symbol>خ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:vi:han</name>
++ <symbol>越</symbol>
++ </engine>
++ <engine>
++ <name>m17n:vi:nom*</name>
++ <symbol>喃</symbol>
++ </engine>
++ <engine>
++ <name>m17n:vi:*</name>
++ <symbol>Ắ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:yi:*</name>
++ <symbol></symbol>
++ </engine>
++ <engine>
++ <name>m17n:zh:bopomofo</name>
++ <symbol>ㄅ</symbol>
++ </engine>
++ <engine>
++ <name>m17n:zh:cangjie</name>
++ <symbol>倉</symbol>
++ </engine>
++ <engine>
++ <name>m17n:zh:py*</name>
++ <symbol>拼</symbol>
++ </engine>
++ <engine>
++ <name>m17n:zh:quick</name>
++ <symbol>簡</symbol>
++ </engine>
++ <engine>
++ <name>m17n:zh:tonepy*</name>
++ <symbol>调</symbol>
++ </engine>
+ </engines>
+diff --git a/src/m17nutil.c b/src/m17nutil.c
+index 9fa5517..975214d 100644
+--- a/src/m17nutil.c
++++ b/src/m17nutil.c
+@@ -15,7 +15,8 @@ static MConverter *utf8_converter = NULL;
+
+ typedef enum {
+ ENGINE_CONFIG_RANK_MASK = 1 << 0,
+- ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 1
++ ENGINE_CONFIG_SYMBOL_MASK = 1 << 1,
++ ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 2
+ } EngineConfigMask;
+
+ struct _EngineConfigNode {
+@@ -125,7 +126,6 @@ ibus_m17n_engine_new (MSymbol lang,
+ engine_setup = g_strdup_printf ("%s/ibus-setup-m17n --name %s",
+ LIBEXECDIR, engine_name);
+
+-#if IBUS_CHECK_VERSION(1,3,99)
+ engine = ibus_engine_desc_new_varargs ("name", engine_name,
+ "longname", engine_longname,
+ "description", engine_desc ? engine_desc : "",
+@@ -134,19 +134,9 @@ ibus_m17n_engine_new (MSymbol lang,
+ "icon", engine_icon ? engine_icon : "",
+ "layout", "us",
+ "rank", config->rank,
++ "symbol", config->symbol ? config->symbol : "",
+ "setup", engine_setup,
+ NULL);
+-#else
+- engine = ibus_engine_desc_new (engine_name,
+- engine_longname,
+- engine_desc ? engine_desc : "",
+- msymbol_name (lang),
+- "GPL",
+- "",
+- engine_icon ? engine_icon : "",
+- "us");
+- engine->rank = config->rank;
+-#endif /* !IBUS_CHECK_VERSION(1,3,99) */
+
+ g_free (engine_name);
+ g_free (engine_longname);
+@@ -276,6 +266,8 @@ ibus_m17n_get_engine_config (const gchar *engine_name)
+ if (g_pattern_match_simple (cnode->name, engine_name)) {
+ if (cnode->mask & ENGINE_CONFIG_RANK_MASK)
+ config->rank = cnode->config.rank;
++ if (cnode->mask & ENGINE_CONFIG_SYMBOL_MASK)
++ config->symbol = cnode->config.symbol;
+ if (cnode->mask & ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK)
+ config->preedit_highlight = cnode->config.preedit_highlight;
+ }
+@@ -308,6 +300,11 @@ ibus_m17n_engine_config_parse_xml_node (EngineConfigNode *cnode,
+ cnode->mask |= ENGINE_CONFIG_RANK_MASK;
+ continue;
+ }
++ if (g_strcmp0 (sub_node->name , "symbol") == 0) {
++ cnode->config.symbol = g_strdup (sub_node->text);
++ cnode->mask |= ENGINE_CONFIG_SYMBOL_MASK;
++ continue;
++ }
+ if (g_strcmp0 (sub_node->name , "preedit-highlight") == 0) {
+ if (g_ascii_strcasecmp ("TRUE", sub_node->text) == 0)
+ cnode->config.preedit_highlight = TRUE;
+diff --git a/src/m17nutil.h b/src/m17nutil.h
+index b21244c..c77b6eb 100644
+--- a/src/m17nutil.h
++++ b/src/m17nutil.h
+@@ -14,6 +14,9 @@ struct _IBusM17NEngineConfig {
+ /* engine rank */
+ gint rank;
+
++ /* symbol */
++ gchar *symbol;
++
+ /* whether to highlight preedit */
+ gboolean preedit_highlight;
+ };
+--
+1.7.7.6
+
+
+From 3a94b20091d898345440cd5b734528ea35927c7e Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Tue, 6 Mar 2012 10:02:18 +0900
+Subject: [PATCH 08/10] Silence warnings when engine is skipped.
+
+Also, fix some mistakes.
+
+BUG=none
+TEST=manually with Fedora's default.xml
+
+Review URL: https://codereview.appspot.com/5730054
+---
+ src/Makefile.am | 12 ++++++------
+ src/engine.c | 16 +++++-----------
+ src/m17nutil.c | 6 ++++--
+ src/main.c | 5 +++--
+ src/setup.c | 2 ++
+ 5 files changed, 20 insertions(+), 21 deletions(-)
+
+diff --git a/src/Makefile.am b/src/Makefile.am
+index e354149..39d6523 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -1,6 +1,6 @@
+ # vim:set noet ts=4:
+ #
+-# ibus-anthy - The Anthy engine for IBus
++# ibus-m17n - The m17n engine for IBus
+ #
+ # Copyright (c) 2007-2008 Huang Peng <shawn.p.huang at gmail.com>
+ #
+@@ -52,13 +52,13 @@ test_m17n_LDADD = \
+
+ libexec_PROGRAMS = ibus-engine-m17n
+
+-noinst_LIBRARIES = libm17ncommon.a
++noinst_LTLIBRARIES = libm17ncommon.la
+
+-libm17ncommon_a_SOURCES = \
++libm17ncommon_la_SOURCES = \
+ m17nutil.c \
+ m17nutil.h \
+ $(NULL)
+-libm17ncommon_a_LIBADD = $(LIBOBJS)
++libm17ncommon_la_LIBADD = $(LTLIBOBJS)
+
+ ibus_engine_m17n_SOURCES = \
+ main.c \
+@@ -66,7 +66,7 @@ ibus_engine_m17n_SOURCES = \
+ engine.h \
+ $(NULL)
+ ibus_engine_m17n_LDADD = \
+- libm17ncommon.a \
++ libm17ncommon.la \
+ @IBUS_LIBS@ \
+ @M17N_LIBS@ \
+ $(NULL)
+@@ -82,7 +82,7 @@ ibus_setup_m17n_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(NULL)
+ ibus_setup_m17n_LDADD = \
+- libm17ncommon.a \
++ libm17ncommon.la \
+ @IBUS_LIBS@ \
+ @M17N_LIBS@ \
+ @GTK_LIBS@ \
+diff --git a/src/engine.c b/src/engine.c
+index 051b63c..9dc61d0 100644
+--- a/src/engine.c
++++ b/src/engine.c
+@@ -273,8 +273,8 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ if (value != NULL) {
+ const gchar *hex = g_variant_get_string (value, NULL);
+ klass->preedit_foreground = ibus_m17n_parse_color (hex);
++ g_variant_unref (value);
+ }
+- g_variant_unref (value);
+
+ value = g_variant_lookup_value (values,
+ "preedit_background",
+@@ -282,24 +282,24 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ if (value != NULL) {
+ const gchar *hex = g_variant_get_string (value, NULL);
+ klass->preedit_background = ibus_m17n_parse_color (hex);
++ g_variant_unref (value);
+ }
+- g_variant_unref (value);
+
+ value = g_variant_lookup_value (values,
+ "preedit_underline",
+ G_VARIANT_TYPE_INT32);
+ if (value != NULL) {
+ klass->preedit_background = g_variant_get_int32 (value);
++ g_variant_unref (value);
+ }
+- g_variant_unref (value);
+
+ value = g_variant_lookup_value (values,
+ "lookup_table_orientation",
+ G_VARIANT_TYPE_INT32);
+ if (value != NULL) {
+ klass->lookup_table_orientation = g_variant_get_int32 (value);
++ g_variant_unref (value);
+ }
+- g_variant_unref (value);
+ g_variant_unref (values);
+ }
+
+@@ -525,7 +525,7 @@ ibus_m17n_engine_commit_string (IBusM17NEngine *m17n,
+
+ Since IBus engines are supposed to be cross-platform, the code
+ should go into IBus core, instead of ibus-m17n. */
+-MSymbol
++static MSymbol
+ ibus_m17n_key_event_to_symbol (guint keycode,
+ guint keyval,
+ guint modifiers)
+@@ -699,11 +699,9 @@ ibus_m17n_engine_enable (IBusEngine *engine)
+
+ parent_class->enable (engine);
+
+-#ifdef HAVE_IBUS_ENGINE_GET_SURROUNDING_TEXT
+ /* Issue a dummy ibus_engine_get_surrounding_text() call to tell
+ input context that we will use surrounding-text. */
+ ibus_engine_get_surrounding_text (engine, NULL, NULL, NULL);
+-#endif /* HAVE_IBUS_ENGINE_GET_SURROUNDING_TEXT */
+ }
+
+ static void
+@@ -930,9 +928,6 @@ ibus_m17n_engine_callback (MInputContext *context,
+ }
+ else if (command == Minput_reset) {
+ }
+- /* ibus_engine_get_surrounding_text is only available in the current
+- git master (1.3.99+) */
+-#ifdef HAVE_IBUS_ENGINE_GET_SURROUNDING_TEXT
+ else if (command == Minput_get_surrounding_text &&
+ (((IBusEngine *) m17n)->client_capabilities &
+ IBUS_CAP_SURROUNDING_TEXT) != 0) {
+@@ -970,7 +965,6 @@ ibus_m17n_engine_callback (MInputContext *context,
+ mplist_set (m17n->context->plist, Mtext, surround);
+ m17n_object_unref (surround);
+ }
+-#endif /* !HAVE_IBUS_ENGINE_GET_SURROUNDING_TEXT */
+ else if (command == Minput_delete_surrounding_text &&
+ (((IBusEngine *) m17n)->client_capabilities &
+ IBUS_CAP_SURROUNDING_TEXT) != 0) {
+diff --git a/src/m17nutil.c b/src/m17nutil.c
+index 975214d..1c2b251 100644
+--- a/src/m17nutil.c
++++ b/src/m17nutil.c
+@@ -188,8 +188,10 @@ ibus_m17n_list_engines (void)
+ continue;
+ }
+ if (config->rank < 0) {
+- g_warning ("skipped %s since its rank is lower than 0",
+- engine_name);
++ g_log ("ibus-m17n",
++ G_LOG_LEVEL_MESSAGE,
++ "skipped %s since its rank is lower than 0",
++ engine_name);
+ g_free (engine_name);
+ continue;
+ }
+diff --git a/src/main.c b/src/main.c
+index f03e504..0a51491 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -115,12 +115,13 @@ main (gint argc, gchar **argv)
+
+ if (!g_option_context_parse (context, &argc, &argv, &error)) {
+ g_print ("Option parsing failed: %s\n", error->message);
+- exit (-1);
++ g_error_free (error);
++ exit (EXIT_FAILURE);
+ }
+
+ if (xml) {
+ print_engines_xml ();
+- exit (0);
++ exit (EXIT_SUCCESS);
+ }
+
+ start_component ();
+diff --git a/src/setup.c b/src/setup.c
+index 7b9609b..cc5cb09 100644
+--- a/src/setup.c
++++ b/src/setup.c
+@@ -527,6 +527,8 @@ setup_dialog_new (IBusConfig *config,
+ if (gtk_builder_add_from_file (builder,
+ SETUPDIR "/ibus-m17n-preferences.ui",
+ &error) == 0) {
++ g_warning ("can't read ibus-m17n-preferences.ui: %s",
++ error->message);
+ g_error_free (error);
+ g_return_val_if_reached (NULL);
+ }
+--
+1.7.7.6
+
+
+From b5493a0267283c63f1bf74f697afd8d9a3290ebc Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Tue, 27 Mar 2012 15:28:01 +0900
+Subject: [PATCH 09/10] Fix handling unknown keyval.
+
+BUG=none
+TEST=manually
+
+Review URL: https://codereview.appspot.com/5929043
+---
+ src/engine.c | 7 ++++---
+ 1 files changed, 4 insertions(+), 3 deletions(-)
+
+diff --git a/src/engine.c b/src/engine.c
+index 9dc61d0..4c7411c 100644
+--- a/src/engine.c
++++ b/src/engine.c
+@@ -567,12 +567,13 @@ ibus_m17n_key_event_to_symbol (guint keycode,
+ g_string_append_c (keysym, c);
+ }
+ else {
+- mask |= modifiers & (IBUS_CONTROL_MASK | IBUS_SHIFT_MASK);
+- g_string_append (keysym, ibus_keyval_name (keyval));
+- if (keysym->len == 0) {
++ const gchar *name = ibus_keyval_name (keyval);
++ if (name == NULL) {
+ g_string_free (keysym, TRUE);
+ return Mnil;
+ }
++ mask |= modifiers & (IBUS_CONTROL_MASK | IBUS_SHIFT_MASK);
++ g_string_append (keysym, name);
+ }
+
+ mask |= modifiers & (IBUS_MOD1_MASK |
+--
+1.7.7.6
+
+
+From 4928f9b8634de05aed125d825471211a0a2c8a07 Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Wed, 28 Mar 2012 09:50:12 +0900
+Subject: [PATCH 10/10] Add longname to engine config.
+
+BUG=none
+TEST=manually
+
+Review URL: https://codereview.appspot.com/5927046
+---
+ src/default.xml.in.in | 5 +++++
+ src/m17nutil.c | 12 ++++++++++--
+ src/m17nutil.h | 3 +++
+ 3 files changed, 18 insertions(+), 2 deletions(-)
+
+diff --git a/src/default.xml.in.in b/src/default.xml.in.in
+index 1248d48..9f5a01e 100644
+--- a/src/default.xml.in.in
++++ b/src/default.xml.in.in
+@@ -389,6 +389,11 @@
+ <symbol>倉</symbol>
+ </engine>
+ <engine>
++ <name>m17n:zh:pinyin</name>
++ <symbol>PY</symbol>
++ <longname>hanyu pinyin (m17n)</longname>
++ </engine>
++ <engine>
+ <name>m17n:zh:py*</name>
+ <symbol>拼</symbol>
+ </engine>
+diff --git a/src/m17nutil.c b/src/m17nutil.c
+index 1c2b251..51026b2 100644
+--- a/src/m17nutil.c
++++ b/src/m17nutil.c
+@@ -16,7 +16,8 @@ static MConverter *utf8_converter = NULL;
+ typedef enum {
+ ENGINE_CONFIG_RANK_MASK = 1 << 0,
+ ENGINE_CONFIG_SYMBOL_MASK = 1 << 1,
+- ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 2
++ ENGINE_CONFIG_LONGNAME_MASK = 1 << 2,
++ ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 3
+ } EngineConfigMask;
+
+ struct _EngineConfigNode {
+@@ -127,7 +128,7 @@ ibus_m17n_engine_new (MSymbol lang,
+ LIBEXECDIR, engine_name);
+
+ engine = ibus_engine_desc_new_varargs ("name", engine_name,
+- "longname", engine_longname,
++ "longname", config->longname ? config->longname : engine_longname,
+ "description", engine_desc ? engine_desc : "",
+ "language", msymbol_name (lang),
+ "license", "GPL",
+@@ -270,6 +271,8 @@ ibus_m17n_get_engine_config (const gchar *engine_name)
+ config->rank = cnode->config.rank;
+ if (cnode->mask & ENGINE_CONFIG_SYMBOL_MASK)
+ config->symbol = cnode->config.symbol;
++ if (cnode->mask & ENGINE_CONFIG_LONGNAME_MASK)
++ config->longname = cnode->config.longname;
+ if (cnode->mask & ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK)
+ config->preedit_highlight = cnode->config.preedit_highlight;
+ }
+@@ -307,6 +310,11 @@ ibus_m17n_engine_config_parse_xml_node (EngineConfigNode *cnode,
+ cnode->mask |= ENGINE_CONFIG_SYMBOL_MASK;
+ continue;
+ }
++ if (g_strcmp0 (sub_node->name , "longname") == 0) {
++ cnode->config.longname = g_strdup (sub_node->text);
++ cnode->mask |= ENGINE_CONFIG_LONGNAME_MASK;
++ continue;
++ }
+ if (g_strcmp0 (sub_node->name , "preedit-highlight") == 0) {
+ if (g_ascii_strcasecmp ("TRUE", sub_node->text) == 0)
+ cnode->config.preedit_highlight = TRUE;
+diff --git a/src/m17nutil.h b/src/m17nutil.h
+index c77b6eb..d790cf8 100644
+--- a/src/m17nutil.h
++++ b/src/m17nutil.h
+@@ -17,6 +17,9 @@ struct _IBusM17NEngineConfig {
+ /* symbol */
+ gchar *symbol;
+
++ /* overridding longname shown on panel */
++ gchar *longname;
++
+ /* whether to highlight preedit */
+ gboolean preedit_highlight;
+ };
+--
+1.7.7.6
+
diff --git a/ibus-m17n-blacklist-engines.patch b/ibus-m17n-blacklist-engines.patch
index cfa3a92..80c5425 100644
--- a/ibus-m17n-blacklist-engines.patch
+++ b/ibus-m17n-blacklist-engines.patch
@@ -1,19 +1,19 @@
-From 4a2f3279fb4fbeb8be66ff7bf40cce57e616d45b Mon Sep 17 00:00:00 2001
+From 5978feeb0d96d633417318daf29c3d4974e17b2d Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno at unixuser.org>
Date: Tue, 25 Oct 2011 14:26:41 +0900
-Subject: [PATCH] Blacklist some engines useless under ibus environment.
+Subject: [PATCH 3/4] Blacklist some engines useless under ibus environment.
---
- src/default.xml.in.in | 32 ++++++++++++++++++++++++++++++++
- 1 files changed, 32 insertions(+), 0 deletions(-)
+ src/default.xml.in.in | 26 ++++++++++++++++++++++++++
+ 1 files changed, 26 insertions(+), 0 deletions(-)
-Index: ibus-m17n-1.3.3/src/default.xml.in.in
-===================================================================
---- ibus-m17n-1.3.3.orig/src/default.xml.in.in
-+++ ibus-m17n-1.3.3/src/default.xml.in.in
-@@ -14,6 +14,38 @@
- @IBUS_HOTKEYS_XML@
- <virtual-keyboard>us</virtual-keyboard>
+diff --git a/src/default.xml.in.in b/src/default.xml.in.in
+index beae494..fda4f30 100644
+--- a/src/default.xml.in.in
++++ b/src/default.xml.in.in
+@@ -12,6 +12,32 @@
+ <preedit-highlight>FALSE</preedit-highlight>
+ <symbol></symbol>
</engine>
+ <!-- Blacklist some engines -->
+ <!-- kbd engines are duplicate of xkb engines -->
@@ -21,12 +21,6 @@ Index: ibus-m17n-1.3.3/src/default.xml.in.in
+ <name>m17n:*:kbd</name>
+ <rank>-1</rank>
+ </engine>
-+ <!-- zh:pinyin is considered as a toy, since it does not
-+ support Han characters -->
-+ <engine>
-+ <name>m17n:zh:pinyin</name>
-+ <rank>-1</rank>
-+ </engine>
+ <!-- zh:py is superseded by ibus-pinyin etc -->
+ <engine>
+ <name>m17n:zh:py</name>
@@ -50,3 +44,6 @@ Index: ibus-m17n-1.3.3/src/default.xml.in.in
<!-- Indic engines should be selected by default:
https://bugzilla.redhat.com/show_bug.cgi?id=640896 -->
<engine>
+--
+1.7.7.6
+
diff --git a/ibus-m17n-hide-title-status.patch b/ibus-m17n-hide-title-status.patch
index 0d52c54..7d24576 100644
--- a/ibus-m17n-hide-title-status.patch
+++ b/ibus-m17n-hide-title-status.patch
@@ -1,25 +1,25 @@
-From d4a1cb9c6bd852da73ba6520fc5c14edbe84ec14 Mon Sep 17 00:00:00 2001
+From 02022c17212357afb5cec727edd8f095aa40d98d Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno at unixuser.org>
Date: Thu, 29 Sep 2011 10:17:28 +0900
-Subject: [PATCH] Hide status from the panel if status == title.
+Subject: [PATCH 2/4] Hide status from the panel if status == title.
---
src/engine.c | 8 +++++++-
1 files changed, 7 insertions(+), 1 deletions(-)
diff --git a/src/engine.c b/src/engine.c
-index f23d982..a0dcc70 100644
+index 4c7411c..efbce66 100644
--- a/src/engine.c
+++ b/src/engine.c
-@@ -43,6 +43,7 @@ struct _IBusM17NEngineClass {
- gboolean virtual_keyboard_enabled;
- gboolean use_iok;
+@@ -35,6 +35,7 @@ struct _IBusM17NEngineClass {
+ gint preedit_underline;
+ gint lookup_table_orientation;
+ gchar *title;
MInputMethod *im;
};
-@@ -256,6 +257,10 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+@@ -244,6 +245,10 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
}
engine_name = g_strdup_printf ("m17n:%s:%s", lang, name);
klass->config_section = g_strdup_printf ("engine/M17N/%s/%s", lang, name);
@@ -27,10 +27,10 @@ index f23d982..a0dcc70 100644
+ if (l && mplist_key (l) == Mtext) {
+ klass->title = ibus_m17n_mtext_to_utf8 (mplist_value (l));
+ }
- /* whether to use iok - maybe good to move this to default.xml */
- klass->use_iok = g_strcmp0 (name, "inscript") == 0 ||
- g_strcmp0 (name, "inscript2") == 0;
-@@ -994,8 +999,9 @@ ibus_m17n_engine_callback (MInputContext *context,
+ g_free (lang);
+ g_free (name);
+
+@@ -895,8 +900,9 @@ ibus_m17n_engine_callback (MInputContext *context,
else if (command == Minput_status_draw) {
gchar *status;
status = ibus_m17n_mtext_to_utf8 (m17n->context->status);
@@ -42,5 +42,5 @@ index f23d982..a0dcc70 100644
text = ibus_text_new_from_string (status);
ibus_property_set_label (m17n->status_prop, text);
--
-1.7.6.4
+1.7.7.6
diff --git a/ibus-m17n-virtkbd.patch b/ibus-m17n-virtkbd.patch
index 2ceb043..8c02494 100644
--- a/ibus-m17n-virtkbd.patch
+++ b/ibus-m17n-virtkbd.patch
@@ -1,25 +1,19 @@
-From 49d2f16638aaa9160b87936cb89fea92186e5171 Mon Sep 17 00:00:00 2001
+From 98ae1c6dbd279e17ef3c20493a37c959f1b1e61f Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno at unixuser.org>
-Date: Wed, 31 Aug 2011 18:28:48 +0900
-Subject: [PATCH 5/6] Support virtual keyboard.
+Date: Fri, 30 Mar 2012 12:36:08 +0900
+Subject: [PATCH 4/4] Add virtual keyboard support.
---
- configure.ac | 17 +++
- src/Makefile.am | 7 ++
- src/default.xml.in.in | 111 ++++++++++++++++++++
- src/engine.c | 66 ++++++++++++
- src/ibus-m17n-preferences.ui | 16 +++
- src/m17nutil.c | 59 +++++++++++-
- src/m17nutil.h | 11 ++
- src/setup.c | 26 +++++
- src/virtkbd.c | 233 ++++++++++++++++++++++++++++++++++++++++++
- src/virtkbd.h | 31 ++++++
- 10 files changed, 576 insertions(+), 1 deletions(-)
- create mode 100644 src/virtkbd.c
- create mode 100644 src/virtkbd.h
+ configure.ac | 17 +++
+ src/Makefile.am | 5 +
+ src/default.xml.in.in | 111 +++++++++++++++++++
+ src/engine.c | 289 +++++++++++++++++++++++++++++++++++++++++++++++++
+ src/m17nutil.c | 10 ++-
+ src/m17nutil.h | 3 +
+ 6 files changed, 434 insertions(+), 1 deletions(-)
diff --git a/configure.ac b/configure.ac
-index 23102c4..13e42f8 100644
+index be9728d..3daf917 100644
--- a/configure.ac
+++ b/configure.ac
@@ -88,6 +88,23 @@ fi
@@ -47,22 +41,19 @@ index 23102c4..13e42f8 100644
save_CFLAGS="$CFLAGS"
save_LIBS="$LIBS"
diff --git a/src/Makefile.am b/src/Makefile.am
-index e354149..eac6629 100644
+index 39d6523..93e7dfd 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
-@@ -64,11 +64,18 @@ ibus_engine_m17n_SOURCES = \
- main.c \
+@@ -65,10 +65,15 @@ ibus_engine_m17n_SOURCES = \
engine.c \
engine.h \
-+ virtkbd.c \
-+ virtkbd.h \
-+ $(NULL)
+ $(NULL)
+ibus_engine_m17n_CFLAGS = \
+ @EEKBOARD_CFLAGS@ \
+ $(AM_CFLAGS) \
- $(NULL)
++ $(NULL)
ibus_engine_m17n_LDADD = \
- libm17ncommon.a \
+ libm17ncommon.la \
@IBUS_LIBS@ \
@M17N_LIBS@ \
+ @EEKBOARD_LIBS@ \
@@ -70,18 +61,18 @@ index e354149..eac6629 100644
if HAVE_GTK
diff --git a/src/default.xml.in.in b/src/default.xml.in.in
-index b1c77c5..dfcd978 100644
+index fda4f30..cbc29af 100644
--- a/src/default.xml.in.in
+++ b/src/default.xml.in.in
-@@ -12,6 +12,7 @@
+@@ -11,6 +11,7 @@
+ <rank>0</rank>
<preedit-highlight>FALSE</preedit-highlight>
<symbol></symbol>
- @IBUS_HOTKEYS_XML@
+ <virtual-keyboard>us</virtual-keyboard>
</engine>
- <!-- Indic engines should be selected by default:
- https://bugzilla.redhat.com/show_bug.cgi?id=640896 -->
-@@ -410,4 +411,114 @@
+ <!-- Blacklist some engines -->
+ <!-- kbd engines are duplicate of xkb engines -->
+@@ -440,4 +441,114 @@
<name>m17n:zh:tonepy*</name>
<symbol>调</symbol>
</engine>
@@ -197,22 +188,23 @@ index b1c77c5..dfcd978 100644
+ </engine>
</engines>
diff --git a/src/engine.c b/src/engine.c
-index dcff0c7..1e6bd1b 100644
+index efbce66..cd18e76 100644
--- a/src/engine.c
+++ b/src/engine.c
-@@ -7,6 +7,7 @@
+@@ -7,6 +7,9 @@
#include <m17n.h>
#include <string.h>
#include "m17nutil.h"
-+#include "virtkbd.h"
++#ifdef HAVE_EEKBOARD
++#include <eekboard/eekboard-client.h>
++#endif /* HAVE_EEKBOARD */
#include "engine.h"
typedef struct _IBusM17NEngine IBusM17NEngine;
-@@ -18,10 +19,13 @@ struct _IBusM17NEngine {
+@@ -18,10 +21,12 @@ struct _IBusM17NEngine {
/* members */
MInputContext *context;
IBusLookupTable *table;
-+ IBusM17NVirtualKeyboard *virtkbd;
+
IBusProperty *status_prop;
#ifdef HAVE_SETUP
@@ -222,39 +214,229 @@ index dcff0c7..1e6bd1b 100644
IBusPropList *prop_list;
};
-@@ -34,6 +38,8 @@ struct _IBusM17NEngineClass {
+@@ -34,9 +39,16 @@ struct _IBusM17NEngineClass {
guint preedit_background;
gint preedit_underline;
gint lookup_table_orientation;
+ gchar *virtual_keyboard;
-+ gboolean virtual_keyboard_enabled;
+ gchar *title;
MInputMethod *im;
++
++#ifdef HAVE_EEKBOARD
++ EekboardContext *econtext;
++ GSList *keyboards;
++ GSList *keyboards_head;
++#endif /* HAVE_EEKBOARD */
};
-@@ -256,6 +262,7 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
- klass->preedit_background = INVALID_COLOR;
- klass->preedit_underline = IBUS_ATTR_UNDERLINE_NONE;
- klass->lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
-+ klass->virtual_keyboard_enabled = FALSE;
- engine_config = ibus_m17n_get_engine_config (engine_name);
- g_free (engine_name);
-@@ -290,6 +297,14 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
- &klass->lookup_table_orientation))
- klass->lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
+ /* functions prototype */
+@@ -100,13 +112,184 @@ static IBusEngineClass *parent_class = NULL;
-+ if (!ibus_m17n_config_get_boolean (config,
-+ klass->config_section,
-+ "virtual_keyboard_enabled",
-+ &klass->virtual_keyboard_enabled))
-+ klass->virtual_keyboard_enabled = FALSE;
+ static IBusConfig *config = NULL;
+
++#ifdef HAVE_EEKBOARD
++static EekboardClient *eekboard = NULL;
+
-+ klass->virtual_keyboard = engine_config->virtual_keyboard;
++static void
++client_destroyed_cb (EekboardClient *client,
++ gpointer user_data)
++{
++ if (eekboard) {
++ g_object_unref (eekboard);
++ eekboard = NULL;
++ }
++}
++
++static void
++context_destroyed_cb (EekboardContext *context,
++ IBusM17NEngineClass *klass)
++{
++ if (klass->econtext) {
++ g_object_unref (klass->econtext);
++ klass->econtext = NULL;
++ }
++}
++
++static EekboardContext *
++create_context (IBusM17NEngineClass *klass)
++{
++ EekboardContext *context = eekboard_client_create_context (eekboard,
++ "ibus-m17n",
++ NULL);
++ g_signal_connect (context, "destroyed",
++ G_CALLBACK (context_destroyed_cb), klass);
++
++ g_slist_free (klass->keyboards);
++ klass->keyboards = NULL;
++
++ gchar **keyboards = g_strsplit (klass->virtual_keyboard, ",", -1);
++ gchar **p;
++
++ for (p = keyboards; *p; p++) {
++ guint keyboard = eekboard_context_add_keyboard (context,
++ g_strstrip (*p),
++ NULL);
++ klass->keyboards = g_slist_prepend (klass->keyboards,
++ GUINT_TO_POINTER (keyboard));
++ }
++ g_strfreev (keyboards);
++
++ klass->keyboards = g_slist_reverse (klass->keyboards);
++ klass->keyboards_head = klass->keyboards;
++
++ eekboard_context_set_keyboard (context,
++ GPOINTER_TO_UINT (klass->keyboards_head->data),
++ NULL);
++ return context;
++}
++
++static void
++key_activated_cb (EekboardContext *context,
++ guint keycode,
++ EekSymbol *symbol,
++ guint modifiers,
++ IBusM17NEngine *m17n)
++{
++ IBusM17NEngineClass *klass = (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n);
++ IBusEngine *engine = IBUS_ENGINE (m17n);
++
++ if (EEK_IS_TEXT (symbol)) {
++ const gchar *string;
++ IBusText *text;
++
++ string = eek_text_get_text (EEK_TEXT (symbol));
++ text = ibus_text_new_from_static_string (string);
++ ibus_engine_commit_text (engine, text);
++ } else if (EEK_IS_KEYSYM (symbol)) {
++ guint keyval = eek_keysym_get_xkeysym (EEK_KEYSYM (symbol));
++ ibus_engine_forward_key_event (engine,
++ keyval,
++ 0,
++ modifiers);
++ ibus_engine_forward_key_event (engine,
++ keyval,
++ 0,
++ modifiers | IBUS_RELEASE_MASK);
++ } else if (g_strcmp0 (eek_symbol_get_name (symbol),
++ "cycle-keyboard") == 0) {
++ klass->keyboards_head = g_slist_next (klass->keyboards_head);
++ if (klass->keyboards_head == NULL)
++ klass->keyboards_head = klass->keyboards;
++ eekboard_context_set_keyboard (klass->econtext,
++ GPOINTER_TO_UINT (klass->keyboards_head->data),
++ NULL);
++ }
++}
+
++static void
++init_eekboard ()
++{
++ GDBusConnection *connection;
++ GError *error;
++
++ error = NULL;
++ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
++ if (connection == NULL) {
++ g_printerr ("Can't connect to the session bus: %s\n",
++ error->message);
++ g_error_free (error);
++ return;
++ }
++
++ eek_init ();
++
++ eekboard = eekboard_client_new (connection, NULL);
++ g_object_unref (connection);
++
++ g_signal_connect (eekboard, "destroyed",
++ G_CALLBACK (client_destroyed_cb), NULL);
++}
++#endif /* HAVE_EEKBOARD */
++
++static GType ibus_m17n_virtual_keyboard_implementation_type = 0;
++
++typedef enum {
++ IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_EEKBOARD,
++ IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_IOK
++} IBusM17NVirtualKeyboardImplementation;
++
++#ifdef HAVE_EEKBOARD
++static IBusM17NVirtualKeyboardImplementation virtual_keyboard_implementation =
++ IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_EEKBOARD;
++#else
++static IBusM17NVirtualKeyboardImplementation virtual_keyboard_implementation =
++ IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_IOK;
++#endif
++
+ void
+ ibus_m17n_init (IBusBus *bus)
+ {
++ static const GEnumValue evalues[] = {
++ { IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_EEKBOARD,
++ "IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_EEKBOARD",
++ "eekboard" },
++ { IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_IOK,
++ "IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_IOK",
++ "iok" }
++ };
++
++ GVariant *values;
++
+ config = ibus_bus_get_config (bus);
+ if (config)
+ g_object_ref_sink (config);
+ ibus_m17n_init_common ();
++
++ ibus_m17n_virtual_keyboard_implementation_type =
++ g_enum_register_static ("IBusM17NVirtualKeyboardImplementation",
++ evalues);
++ values = ibus_config_get_values (config, "engine/M17N");
++ if (values != NULL) {
++ GVariant *value =
++ g_variant_lookup_value (values,
++ "virtual_keyboard_implementation",
++ G_VARIANT_TYPE_STRING);
++ if (value != NULL) {
++ GEnumClass *eclass = G_ENUM_CLASS (g_type_class_peek (ibus_m17n_virtual_keyboard_implementation_type));
++ GEnumValue *evalue = g_enum_get_value_by_nick (eclass, g_variant_get_string (value, NULL));
++ if (evalue != NULL) {
++ virtual_keyboard_implementation = evalue->value;
++ }
++ }
++ }
++
++ if (virtual_keyboard_implementation == IBUS_M17N_VIRTUAL_KEYBOARD_IMPLEMENTATION_EEKBOARD) {
++#ifdef HAVE_EEKBOARD
++ init_eekboard ();
++#else
++ g_warning ("eekboard is not supported");
++#endif /* HAVE_EEKBOARD */
++ }
+ }
+
+ static gboolean
+@@ -264,6 +447,7 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ INVALID_COLOR;
+ klass->preedit_underline = IBUS_ATTR_UNDERLINE_NONE;
+ klass->lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
++ klass->virtual_keyboard = engine_config->virtual_keyboard;
+
ibus_m17n_engine_config_free (engine_config);
- g_signal_connect (config, "value-changed",
-@@ -346,6 +361,7 @@ ibus_m17n_engine_init (IBusM17NEngine *m17n)
+@@ -313,6 +497,11 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ klass);
+
+ klass->im = NULL;
++
++#if HAVE_EEKBOARD
++ if (eekboard)
++ klass->econtext = create_context (klass);
++#endif /* HAVE_EEKBOARD */
+ }
+
+ static void
+@@ -350,6 +539,7 @@ ibus_m17n_engine_init (IBusM17NEngine *m17n)
{
IBusText* label;
IBusText* tooltip;
@@ -262,12 +444,12 @@ index dcff0c7..1e6bd1b 100644
m17n->prop_list = ibus_prop_list_new ();
g_object_ref_sink (m17n->prop_list);
-@@ -378,6 +394,24 @@ ibus_m17n_engine_init (IBusM17NEngine *m17n)
+@@ -382,6 +572,36 @@ ibus_m17n_engine_init (IBusM17NEngine *m17n)
ibus_prop_list_append (m17n->prop_list, m17n->setup_prop);
#endif /* HAVE_SETUP */
-+ label = ibus_text_new_from_string ("On-screen Keyboard");
-+ tooltip = ibus_text_new_from_string ("Show on-screen keyboard");
++ label = ibus_text_new_from_string ("Screen Keyboard");
++ tooltip = ibus_text_new_from_string ("Show screen keyboard");
+ m17n->virtkbd_prop = ibus_property_new ("virtual-keyboard",
+ PROP_TYPE_NORMAL,
+ label,
@@ -280,14 +462,26 @@ index dcff0c7..1e6bd1b 100644
+ g_object_ref_sink (m17n->virtkbd_prop);
+ ibus_prop_list_append (m17n->prop_list, m17n->virtkbd_prop);
+
-+ if (klass->virtual_keyboard_enabled &&
-+ klass->virtual_keyboard != NULL)
++#ifdef HAVE_EEKBOARD
++ if (eekboard != NULL)
+ ibus_property_set_visible (m17n->virtkbd_prop, TRUE);
++ else
++#endif /* HAVE_EEKBOARD */
++ {
++ gchar *lang = NULL, *name = NULL;
++ if (ibus_m17n_scan_class_name (G_OBJECT_CLASS_NAME (klass),
++ &lang,
++ &name) &&
++ g_str_has_prefix (name, "inscript"))
++ ibus_property_set_visible (m17n->virtkbd_prop, TRUE);
++ g_free (lang);
++ g_free (name);
++ }
+
m17n->table = ibus_lookup_table_new (9, 0, TRUE, TRUE);
g_object_ref_sink (m17n->table);
m17n->context = NULL;
-@@ -463,6 +497,11 @@ ibus_m17n_engine_destroy (IBusM17NEngine *m17n)
+@@ -467,6 +687,11 @@ ibus_m17n_engine_destroy (IBusM17NEngine *m17n)
}
#endif /* HAVE_SETUP */
@@ -299,119 +493,122 @@ index dcff0c7..1e6bd1b 100644
if (m17n->table) {
g_object_unref (m17n->table);
m17n->table = NULL;
-@@ -473,6 +512,11 @@ ibus_m17n_engine_destroy (IBusM17NEngine *m17n)
- m17n->context = NULL;
- }
-
-+ if (m17n->virtkbd) {
-+ g_object_unref (m17n->virtkbd);
-+ m17n->virtkbd = NULL;
-+ }
-+
- IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)m17n);
- }
-
-@@ -705,6 +749,9 @@ ibus_m17n_engine_enable (IBusEngine *engine)
+@@ -708,6 +933,14 @@ ibus_m17n_engine_enable (IBusEngine *engine)
+ /* Issue a dummy ibus_engine_get_surrounding_text() call to tell
input context that we will use surrounding-text. */
ibus_engine_get_surrounding_text (engine, NULL, NULL, NULL);
- #endif /* HAVE_IBUS_ENGINE_GET_SURROUNDING_TEXT */
+
-+ if (m17n->virtkbd)
-+ ibus_m17n_virtual_keyboard_enable (m17n->virtkbd);
++#ifdef HAVE_EEKBOARD
++ if (eekboard) {
++ IBusM17NEngineClass *klass = (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n);
++ if (klass->econtext)
++ eekboard_client_push_context (eekboard, klass->econtext, NULL);
++ }
++#endif /* HAVE_EEKBOARD */
}
static void
-@@ -714,6 +761,9 @@ ibus_m17n_engine_disable (IBusEngine *engine)
+@@ -717,6 +950,14 @@ ibus_m17n_engine_disable (IBusEngine *engine)
ibus_m17n_engine_focus_out (engine);
parent_class->disable (engine);
+
-+ if (m17n->virtkbd)
-+ ibus_m17n_virtual_keyboard_disable (m17n->virtkbd);
++#ifdef HAVE_EEKBOARD
++ if (eekboard) {
++ IBusM17NEngineClass *klass = (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n);
++ if (klass->econtext)
++ eekboard_client_pop_context (eekboard, NULL);
++ }
++#endif /* HAVE_EEKBOARD */
}
static void
-@@ -776,6 +826,22 @@ ibus_m17n_engine_property_activate (IBusEngine *engine,
+@@ -764,6 +1005,7 @@ ibus_m17n_engine_property_activate (IBusEngine *engine,
+ guint prop_state)
+ {
+ IBusM17NEngine *m17n = (IBusM17NEngine *) engine;
++ IBusM17NEngineClass *klass = (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n);
+
+ #ifdef HAVE_SETUP
+ if (g_strcmp0 (prop_name, "setup") == 0) {
+@@ -779,6 +1021,53 @@ ibus_m17n_engine_property_activate (IBusEngine *engine,
}
#endif /* HAVE_SETUP */
-+#ifdef HAVE_EEKBOARD
+ if (g_strcmp0 (prop_name, "virtual-keyboard") == 0) {
-+ /* virtual keyboard is not initialized until a user activates
-+ the "virtual-keyboard" prop for the first time */
-+ if (m17n->virtkbd == NULL) {
-+ IBusM17NEngineClass *klass =
-+ (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n);
-+
-+ m17n->virtkbd =
-+ ibus_m17n_virtual_keyboard_new ((IBusEngine *)m17n,
-+ klass->virtual_keyboard);
++#ifdef HAVE_EEKBOARD
++ if (eekboard) {
++ if (klass->econtext == NULL) {
++ klass->econtext = create_context (klass);
++ eekboard_client_push_context (eekboard, klass->econtext, NULL);
++ }
++ g_signal_handlers_disconnect_by_func (klass->econtext,
++ G_CALLBACK (key_activated_cb),
++ m17n);
++ g_signal_connect (klass->econtext, "key-activated",
++ G_CALLBACK (key_activated_cb), m17n);
++ eekboard_context_show_keyboard (klass->econtext, NULL);
++ } else
++#endif /* HAVE_EEKBOARD */
++ {
++ gchar *lang = NULL, *name = NULL;
++
++ if (ibus_m17n_scan_class_name (G_OBJECT_CLASS_NAME (klass),
++ &lang,
++ &name) &&
++ g_str_has_prefix (name, "inscript")) {
++ gchar *argv[4];
++ GError *error;
++
++ argv[0] = "iok";
++ argv[1] = "-n";
++ argv[2] = lang;
++ argv[3] = NULL;
++ error = NULL;
++ if (!g_spawn_async (NULL,
++ argv,
++ NULL,
++ G_SPAWN_SEARCH_PATH,
++ NULL,
++ NULL,
++ NULL,
++ &error)) {
++ g_warning ("can't spawn iok: %s", error->message);
++ g_error_free (error);
++ }
++ }
++ g_free (lang);
++ g_free (name);
+ }
-+ ibus_m17n_virtual_keyboard_toggle_display (m17n->virtkbd);
+ }
-+#endif /* HAVE_EEKBOARD */
+
parent_class->property_activate (engine, prop_name, prop_state);
}
-diff --git a/src/ibus-m17n-preferences.ui b/src/ibus-m17n-preferences.ui
-index a46ab49..bca034d 100644
---- a/src/ibus-m17n-preferences.ui
-+++ b/src/ibus-m17n-preferences.ui
-@@ -192,6 +192,7 @@
- <child>
- <object class="GtkTable" id="table2">
- <property name="visible">True</property>
-+ <property name="n_rows">2</property>
- <property name="n_columns">2</property>
- <child>
- <object class="GtkLabel" id="label9">
-@@ -210,6 +211,21 @@
- <property name="right_attach">2</property>
- </packing>
- </child>
-+ <child>
-+ <object class="GtkCheckButton" id="checkbutton_virtkbd">
-+ <property name="label" translatable="yes">Enable Virtual Keyboard</property>
-+ <property name="visible">True</property>
-+ <property name="can_focus">True</property>
-+ <property name="receives_default">False</property>
-+ <property name="draw_indicator">True</property>
-+ </object>
-+ <packing>
-+ <property name="left_attach">0</property>
-+ <property name="right_attach">2</property>
-+ <property name="top_attach">1</property>
-+ <property name="bottom_attach">2</property>
-+ </packing>
-+ </child>
- </object>
- </child>
- </object>
diff --git a/src/m17nutil.c b/src/m17nutil.c
-index 94a6891..2143e54 100644
+index 0b46531..adf7044 100644
--- a/src/m17nutil.c
+++ b/src/m17nutil.c
@@ -18,7 +18,8 @@ typedef enum {
- ENGINE_CONFIG_LAYOUT_MASK = 1 << 1,
- ENGINE_CONFIG_HOTKEYS_MASK = 1 << 2,
- ENGINE_CONFIG_SYMBOL_MASK = 1 << 3,
+ ENGINE_CONFIG_SYMBOL_MASK = 1 << 1,
+ ENGINE_CONFIG_LONGNAME_MASK = 1 << 2,
+ ENGINE_CONFIG_LAYOUT_MASK = 1 << 3,
- ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 4
+ ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 4,
+ ENGINE_CONFIG_VIRTUAL_KEYBOARD_MASK = 1 << 5
} EngineConfigMask;
struct _EngineConfigNode {
-@@ -285,6 +286,8 @@ ibus_m17n_get_engine_config (const gchar *engine_name)
- config->symbol = cnode->config.symbol;
+@@ -276,6 +277,8 @@ ibus_m17n_get_engine_config (const gchar *engine_name)
+ config->longname = cnode->config.longname;
if (cnode->mask & ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK)
config->preedit_highlight = cnode->config.preedit_highlight;
+ if (cnode->mask & ENGINE_CONFIG_VIRTUAL_KEYBOARD_MASK)
+ config->virtual_keyboard = cnode->config.virtual_keyboard;
+ if (cnode->mask & ENGINE_CONFIG_LAYOUT_MASK)
+ config->layout = cnode->config.layout;
}
- }
- return config;
-@@ -340,6 +343,11 @@ ibus_m17n_engine_config_parse_xml_node (EngineConfigNode *cnode,
+@@ -333,6 +336,11 @@ ibus_m17n_engine_config_parse_xml_node (EngineConfigNode *cnode,
cnode->mask |= ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK;
continue;
}
@@ -423,61 +620,8 @@ index 94a6891..2143e54 100644
g_warning ("<engine> element contains invalid element <%s>",
sub_node->name);
}
-@@ -494,3 +502,52 @@ ibus_m17n_config_get_int (IBusConfig *config,
- return FALSE;
- #endif /* !IBUS_CHECK_VERSION(1,3,99) */
- }
-+
-+void
-+ibus_m17n_config_set_boolean (IBusConfig *config,
-+ const gchar *section,
-+ const gchar *name,
-+ gboolean value)
-+{
-+#if IBUS_CHECK_VERSION(1,3,99)
-+ ibus_config_set_value (config, section, name, g_variant_new_boolean (value));
-+#else
-+ GValue v = { 0 };
-+
-+ g_value_init (&v, G_TYPE_BOOLEAN);
-+ g_value_set_boolean (&v, value);
-+ ibus_config_set_value (config, section, name, &v);
-+#endif /* !IBUS_CHECK_VERSION(1,3,99) */
-+}
-+
-+gboolean
-+ibus_m17n_config_get_boolean (IBusConfig *config,
-+ const gchar *section,
-+ const gchar *name,
-+ gboolean *result)
-+{
-+#if IBUS_CHECK_VERSION(1,3,99)
-+ GVariant *value = NULL;
-+
-+ g_return_val_if_fail (result != NULL, FALSE);
-+
-+ value = ibus_config_get_value (config, section, name);
-+ if (value) {
-+ *result = g_variant_get_boolean (value);
-+ g_variant_unref (value);
-+ return TRUE;
-+ }
-+ return FALSE;
-+#else
-+ GValue value = { 0 };
-+
-+ g_return_val_if_fail (result != NULL, FALSE);
-+
-+ if (ibus_config_get_value (config, section, name, &value)) {
-+ *result = g_value_get_boolean (&value);
-+ g_value_unset (&value);
-+ return TRUE;
-+ }
-+ return FALSE;
-+#endif /* !IBUS_CHECK_VERSION(1,3,99) */
-+}
diff --git a/src/m17nutil.h b/src/m17nutil.h
-index 21b1bb9..9c3fca8 100644
+index 93faad4..3c2944a 100644
--- a/src/m17nutil.h
+++ b/src/m17nutil.h
@@ -25,6 +25,9 @@ struct _IBusM17NEngineConfig {
@@ -490,360 +634,6 @@ index 21b1bb9..9c3fca8 100644
};
typedef struct _IBusM17NEngineConfig IBusM17NEngineConfig;
-@@ -56,4 +59,12 @@ gboolean ibus_m17n_config_get_int (IBusConfig *config,
- const gchar *section,
- const gchar *name,
- gint *result);
-+void ibus_m17n_config_set_boolean (IBusConfig *config,
-+ const gchar *section,
-+ const gchar *name,
-+ gboolean value);
-+gboolean ibus_m17n_config_get_boolean (IBusConfig *config,
-+ const gchar *section,
-+ const gchar *name,
-+ gboolean *result);
- #endif
-diff --git a/src/setup.c b/src/setup.c
-index 30386df..1c534d6 100644
---- a/src/setup.c
-+++ b/src/setup.c
-@@ -25,6 +25,7 @@ struct _SetupDialog {
- GtkWidget *colorbutton_foreground;
- GtkWidget *checkbutton_background;
- GtkWidget *colorbutton_background;
-+ GtkWidget *checkbutton_virtkbd;
- GtkWidget *treeview;
- GtkListStore *store;
-
-@@ -322,6 +323,15 @@ setup_dialog_load_config (SetupDialog *dialog)
- gtk_combo_box_set_active (GTK_COMBO_BOX(dialog->combobox_orientation),
- index);
-
-+ if (!ibus_m17n_config_get_boolean (dialog->config,
-+ dialog->section,
-+ "virtual_keyboard_enabled",
-+ &bvalue))
-+ bvalue = FALSE;
-+
-+ gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(dialog->checkbutton_virtkbd),
-+ bvalue);
-+
- /* Advanced -> m17n-lib configuration */
- dialog->store = gtk_list_store_new (NUM_COLS,
- G_TYPE_STRING,
-@@ -404,6 +414,17 @@ save_choice (SetupDialog *dialog,
- ibus_m17n_config_set_int (dialog->config, dialog->section, name, active);
- }
-
-+static void
-+save_toggle (SetupDialog *dialog,
-+ GtkToggleButton *togglebutton,
-+ const gchar *name)
-+{
-+ ibus_m17n_config_set_boolean (dialog->config,
-+ dialog->section,
-+ name,
-+ gtk_toggle_button_get_active (togglebutton));
-+}
-+
- static gboolean
- save_m17n_options (SetupDialog *dialog)
- {
-@@ -486,6 +507,9 @@ setup_dialog_save_config (SetupDialog *dialog)
- save_choice (dialog,
- GTK_COMBO_BOX(dialog->combobox_orientation),
- "lookup_table_orientation");
-+ save_toggle (dialog,
-+ GTK_TOGGLE_BUTTON(dialog->checkbutton_virtkbd),
-+ "virtual_keyboard_enabled");
- save_m17n_options (dialog);
- }
-
-@@ -528,6 +552,8 @@ setup_dialog_new (IBusConfig *config,
- dialog->combobox_underline = GTK_WIDGET(object);
- object = gtk_builder_get_object (builder, "combobox_orientation");
- dialog->combobox_orientation = GTK_WIDGET(object);
-+ object = gtk_builder_get_object (builder, "checkbutton_virtkbd");
-+ dialog->checkbutton_virtkbd = GTK_WIDGET(object);
- object = gtk_builder_get_object (builder, "treeview_mim_config");
- dialog->treeview = GTK_WIDGET(object);
-
-diff --git a/src/virtkbd.c b/src/virtkbd.c
-new file mode 100644
-index 0000000..9baf971
---- /dev/null
-+++ b/src/virtkbd.c
-@@ -0,0 +1,233 @@
-+/* vim:set et sts=4: */
-+#ifdef HAVE_CONFIG_H
-+#include <config.h>
-+#endif
-+
-+#ifdef HAVE_EEKBOARD
-+#include <eekboard/eekboard-client.h>
-+#endif /* HAVE_EEKBOARD */
-+
-+#include "virtkbd.h"
-+
-+struct _IBusM17NVirtualKeyboard {
-+ GObject parent;
-+ IBusEngine *engine;
-+ gchar *keyboard_type;
-+ GSList *keyboards;
-+
-+#ifdef HAVE_EEKBOARD
-+ EekboardClient *client;
-+ EekboardContext *context;
-+#endif /* HAVE_EEKBOARD */
-+};
-+
-+struct _IBusM17NVirtualKeyboardClass {
-+ GObjectClass parent_class;
-+};
-+
-+typedef struct _IBusM17NVirtualKeyboardClass IBusM17NVirtualKeyboardClass;
-+
-+#ifdef HAVE_EEKBOARD
-+#define _EEK_INIT() eek_init ()
-+#else
-+#define _EEK_INIT()
-+#endif /* HAVE_EEKBOARD */
-+
-+G_DEFINE_TYPE_WITH_CODE (IBusM17NVirtualKeyboard, ibus_m17n_virtual_keyboard,
-+ G_TYPE_OBJECT, _EEK_INIT());
-+
-+static void
-+ibus_m17n_virtual_keyboard_dispose (GObject *object)
-+{
-+ IBusM17NVirtualKeyboard *virtkbd = IBUS_M17N_VIRTUAL_KEYBOARD (object);
-+
-+ if (virtkbd->engine) {
-+ g_object_unref (virtkbd->engine);
-+ virtkbd->engine = NULL;
-+ }
-+ if (virtkbd->keyboards) {
-+ GSList *next = virtkbd->keyboards->next;
-+ /* virtkbd->keyboards is a ring; break it before free */
-+ virtkbd->keyboards->next = NULL;
-+ g_slist_free (next);
-+ }
-+
-+#ifdef HAVE_EEKBOARD
-+ if (virtkbd->context) {
-+ g_object_unref (virtkbd->context);
-+ virtkbd->context = NULL;
-+ }
-+ if (virtkbd->client) {
-+ g_object_unref (virtkbd->client);
-+ virtkbd->client = NULL;
-+ }
-+#endif /* HAVE_EEKBOARD */
-+
-+ G_OBJECT_CLASS (ibus_m17n_virtual_keyboard_parent_class)->dispose (object);
-+}
-+
-+static void
-+ibus_m17n_virtual_keyboard_finalize (GObject *object)
-+{
-+ IBusM17NVirtualKeyboard *virtkbd = IBUS_M17N_VIRTUAL_KEYBOARD (object);
-+
-+ g_free (virtkbd->keyboard_type);
-+
-+ G_OBJECT_CLASS (ibus_m17n_virtual_keyboard_parent_class)->finalize (object);
-+}
-+
-+static void
-+ibus_m17n_virtual_keyboard_class_init (IBusM17NVirtualKeyboardClass *klass)
-+{
-+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
-+ gobject_class->dispose = ibus_m17n_virtual_keyboard_dispose;
-+ gobject_class->finalize = ibus_m17n_virtual_keyboard_finalize;
-+}
-+
-+static void
-+ibus_m17n_virtual_keyboard_init (IBusM17NVirtualKeyboard *self)
-+{
-+}
-+
-+#ifdef HAVE_EEKBOARD
-+static void
-+destroyed_cb (EekboardClient *client,
-+ IBusM17NVirtualKeyboard *virtkbd)
-+{
-+ if (virtkbd->context) {
-+ g_object_unref (virtkbd->context);
-+ virtkbd->context = NULL;
-+ }
-+ if (virtkbd->client) {
-+ g_object_unref (virtkbd->client);
-+ virtkbd->client = NULL;
-+ }
-+}
-+
-+static void
-+key_pressed_cb (EekboardContext *context,
-+ gchar *keyname,
-+ EekSymbol *symbol,
-+ guint modifiers,
-+ IBusM17NVirtualKeyboard *virtkbd)
-+{
-+ if (EEK_IS_TEXT (symbol)) {
-+ const gchar *string;
-+ IBusText *text;
-+
-+ string = eek_text_get_text (EEK_TEXT (symbol));
-+ text = ibus_text_new_from_static_string (string);
-+ ibus_engine_commit_text (virtkbd->engine, text);
-+ } else if (EEK_IS_KEYSYM (symbol)) {
-+ guint keyval = eek_keysym_get_xkeysym (EEK_KEYSYM (symbol));
-+ ibus_engine_forward_key_event (virtkbd->engine,
-+ keyval,
-+ 0,
-+ modifiers);
-+ ibus_engine_forward_key_event (virtkbd->engine,
-+ keyval,
-+ 0,
-+ modifiers | IBUS_RELEASE_MASK);
-+ } else if (g_strcmp0 (eek_symbol_get_name (symbol),
-+ "cycle-keyboard") == 0) {
-+ virtkbd->keyboards = g_slist_next (virtkbd->keyboards);
-+ eekboard_context_set_keyboard (virtkbd->context,
-+ GPOINTER_TO_UINT (virtkbd->keyboards->data),
-+ NULL);
-+ }
-+}
-+
-+static void
-+init_client (IBusM17NVirtualKeyboard *virtkbd)
-+{
-+ GDBusConnection *connection;
-+ GError *error;
-+ gchar **strv, **p;
-+
-+ error = NULL;
-+ connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
-+ if (connection == NULL) {
-+ g_printerr ("Can't connect to the session bus: %s\n",
-+ error->message);
-+ return;
-+ }
-+
-+ virtkbd->client = eekboard_client_new (connection, NULL);
-+ g_object_unref (connection);
-+ g_signal_connect (virtkbd->client, "destroyed",
-+ G_CALLBACK (destroyed_cb), virtkbd);
-+
-+ virtkbd->context = eekboard_client_create_context (virtkbd->client,
-+ "ibus-m17n",
-+ NULL);
-+ g_signal_connect (virtkbd->context, "key-pressed",
-+ G_CALLBACK (key_pressed_cb), virtkbd);
-+
-+ strv = g_strsplit (virtkbd->keyboard_type, ",", -1);
-+ for (p = strv; *p; p++) {
-+ guint keyboard;
-+
-+ keyboard = eekboard_context_add_keyboard (virtkbd->context,
-+ g_strstrip (*p),
-+ NULL);
-+ virtkbd->keyboards = g_slist_prepend (virtkbd->keyboards,
-+ GUINT_TO_POINTER (keyboard));
-+ }
-+ virtkbd->keyboards = g_slist_reverse (virtkbd->keyboards);
-+ g_strfreev (strv);
-+
-+ /* make a cycle */
-+ g_slist_last (virtkbd->keyboards)->next = virtkbd->keyboards;
-+
-+ eekboard_context_set_keyboard (virtkbd->context,
-+ GPOINTER_TO_UINT (virtkbd->keyboards->data),
-+ NULL);
-+}
-+#endif /* HAVE_EEKBOARD */
-+
-+void
-+ibus_m17n_virtual_keyboard_toggle_display (IBusM17NVirtualKeyboard *virtkbd)
-+{
-+#ifdef HAVE_EEKBOARD
-+ if (virtkbd->client == NULL)
-+ ibus_m17n_virtual_keyboard_enable (virtkbd);
-+
-+ if (virtkbd->client != NULL) {
-+ if (eekboard_context_is_visible (virtkbd->context))
-+ eekboard_context_hide_keyboard (virtkbd->context, NULL);
-+ else
-+ eekboard_context_show_keyboard (virtkbd->context, NULL);
-+ }
-+#endif /* HAVE_EEKBOARD */
-+}
-+
-+void
-+ibus_m17n_virtual_keyboard_enable (IBusM17NVirtualKeyboard *virtkbd)
-+{
-+#ifdef HAVE_EEKBOARD
-+ if (virtkbd->client == NULL)
-+ init_client (virtkbd);
-+
-+ if (virtkbd->client != NULL)
-+ eekboard_client_push_context (virtkbd->client, virtkbd->context, NULL);
-+#endif /* HAVE_EEKBOARD */
-+}
-+
-+void
-+ibus_m17n_virtual_keyboard_disable (IBusM17NVirtualKeyboard *virtkbd)
-+{
-+#ifdef HAVE_EEKBOARD
-+ if (virtkbd->client != NULL)
-+ eekboard_client_pop_context (virtkbd->client, NULL);
-+#endif /* HAVE_EEKBOARD */
-+}
-+
-+IBusM17NVirtualKeyboard *
-+ibus_m17n_virtual_keyboard_new (IBusEngine *engine,
-+ const gchar *keyboard_type)
-+{
-+ IBusM17NVirtualKeyboard *virtkbd = g_object_new (IBUS_M17N_TYPE_VIRTUAL_KEYBOARD, NULL);
-+ virtkbd->engine = g_object_ref (engine);
-+ virtkbd->keyboard_type = g_strdup (keyboard_type);
-+ return virtkbd;
-+}
-diff --git a/src/virtkbd.h b/src/virtkbd.h
-new file mode 100644
-index 0000000..c28953a
---- /dev/null
-+++ b/src/virtkbd.h
-@@ -0,0 +1,31 @@
-+#ifndef __VIRTKBD_H__
-+#define __VIRTKBD_H__ 1
-+
-+#include <ibus.h>
-+
-+G_BEGIN_DECLS
-+
-+#define IBUS_M17N_TYPE_VIRTUAL_KEYBOARD (ibus_m17n_virtual_keyboard_get_type())
-+#define IBUS_M17N_VIRTUAL_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), IBUS_M17N_TYPE_VIRTUAL_KEYBOARD, IBusM17NVirtualKeyboard))
-+#define IBUS_M17N_VIRTUAL_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), IBUS_M17N_TYPE_VIRTUAL_KEYBOARD, IBusM17NVirtualKeyboardClass))
-+#define IBUS_M17N_IS_VIRTUAL_KEYBOARD(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), IBUS_M17N_TYPE_VIRTUAL_KEYBOARD))
-+#define IBUS_M17N_IS_VIRTUAL_KEYBOARD_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), IBUS_M17N_TYPE_VIRTUAL_KEYBOARD))
-+#define IBUS_M17N_VIRTUAL_KEYBOARD_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), IBUS_M17N_TYPE_VIRTUAL_KEYBOARD, IBusM17NVirtualKeyboardClass))
-+
-+typedef struct _IBusM17NVirtualKeyboard IBusM17NVirtualKeyboard;
-+
-+GType ibus_m17n_virtual_keyboard_get_type
-+ (void);
-+IBusM17NVirtualKeyboard *ibus_m17n_virtual_keyboard_new
-+ (IBusEngine *engine,
-+ const gchar *keyboard_type);
-+void ibus_m17n_virtual_keyboard_toggle_display
-+ (IBusM17NVirtualKeyboard *virtkbd);
-+void ibus_m17n_virtual_keyboard_enable
-+ (IBusM17NVirtualKeyboard *virtkbd);
-+void ibus_m17n_virtual_keyboard_disable
-+ (IBusM17NVirtualKeyboard *virtkbd);
-+
-+G_END_DECLS
-+
-+#endif /* __VIRTKBD_H__ */
--
-1.7.6.2
+1.7.7.6
diff --git a/ibus-m17n-xkb-options.patch b/ibus-m17n-xkb-options.patch
index b8f5dd7..a4179ed 100644
--- a/ibus-m17n-xkb-options.patch
+++ b/ibus-m17n-xkb-options.patch
@@ -1,7 +1,7 @@
-From 0cc2abaab50e6668e525da093ef12ed0277d5c21 Mon Sep 17 00:00:00 2001
+From ab9d608fdb6054b4b135f891ad5fa1fa7ce27c7b Mon Sep 17 00:00:00 2001
From: Daiki Ueno <ueno at unixuser.org>
Date: Mon, 8 Aug 2011 09:59:28 +0900
-Subject: [PATCH 3/6] Set XKB layout option via default.xml.
+Subject: [PATCH 1/4] Set XKB layout option via default.xml.
---
src/default.xml.in.in | 9 +++++++++
@@ -10,10 +10,10 @@ Subject: [PATCH 3/6] Set XKB layout option via default.xml.
3 files changed, 23 insertions(+), 2 deletions(-)
diff --git a/src/default.xml.in.in b/src/default.xml.in.in
-index dc93fd3..785ab05 100644
+index 9f5a01e..beae494 100644
--- a/src/default.xml.in.in
+++ b/src/default.xml.in.in
-@@ -157,6 +157,15 @@
+@@ -158,6 +158,15 @@
<name>m17n:si:samanala</name>
<rank>0</rank>
</engine>
@@ -30,39 +30,39 @@ index dc93fd3..785ab05 100644
<engine>
<name>m17n:zh:cangjie</name>
diff --git a/src/m17nutil.c b/src/m17nutil.c
-index b06f71d..201c8b4 100644
+index 51026b2..0b46531 100644
--- a/src/m17nutil.c
+++ b/src/m17nutil.c
-@@ -15,7 +15,8 @@ static MConverter *utf8_converter = NULL;
-
- typedef enum {
+@@ -17,7 +17,8 @@ typedef enum {
ENGINE_CONFIG_RANK_MASK = 1 << 0,
-- ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 1
-+ ENGINE_CONFIG_LAYOUT_MASK = 1 << 1,
-+ ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 2
+ ENGINE_CONFIG_SYMBOL_MASK = 1 << 1,
+ ENGINE_CONFIG_LONGNAME_MASK = 1 << 2,
+- ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 3
++ ENGINE_CONFIG_LAYOUT_MASK = 1 << 3,
++ ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK = 1 << 4
} EngineConfigMask;
struct _EngineConfigNode {
-@@ -130,7 +131,7 @@ ibus_m17n_engine_new (MSymbol lang,
+@@ -133,7 +134,7 @@ ibus_m17n_engine_new (MSymbol lang,
"language", msymbol_name (lang),
"license", "GPL",
"icon", engine_icon ? engine_icon : "",
- "layout", "us",
+ "layout", config->layout ? config->layout : "us",
"rank", config->rank,
- NULL);
- #else
-@@ -272,6 +273,8 @@ ibus_m17n_get_engine_config (const gchar *engine_name)
- if (g_pattern_match_simple (cnode->name, engine_name)) {
- if (cnode->mask & ENGINE_CONFIG_RANK_MASK)
- config->rank = cnode->config.rank;
-+ if (cnode->mask & ENGINE_CONFIG_LAYOUT_MASK)
-+ config->layout = cnode->config.layout;
+ "symbol", config->symbol ? config->symbol : "",
+ "setup", engine_setup,
+@@ -275,6 +276,8 @@ ibus_m17n_get_engine_config (const gchar *engine_name)
+ config->longname = cnode->config.longname;
if (cnode->mask & ENGINE_CONFIG_PREEDIT_HIGHLIGHT_MASK)
config->preedit_highlight = cnode->config.preedit_highlight;
++ if (cnode->mask & ENGINE_CONFIG_LAYOUT_MASK)
++ config->layout = cnode->config.layout;
}
-@@ -304,6 +307,12 @@ ibus_m17n_engine_config_parse_xml_node (EngineConfigNode *cnode,
- cnode->mask |= ENGINE_CONFIG_RANK_MASK;
+ }
+ return config;
+@@ -315,6 +318,12 @@ ibus_m17n_engine_config_parse_xml_node (EngineConfigNode *cnode,
+ cnode->mask |= ENGINE_CONFIG_LONGNAME_MASK;
continue;
}
+ if (g_strcmp0 (sub_node->name , "layout") == 0) {
@@ -75,12 +75,12 @@ index b06f71d..201c8b4 100644
if (g_ascii_strcasecmp ("TRUE", sub_node->text) == 0)
cnode->config.preedit_highlight = TRUE;
diff --git a/src/m17nutil.h b/src/m17nutil.h
-index 313e7bc..c7b283e 100644
+index d790cf8..93faad4 100644
--- a/src/m17nutil.h
+++ b/src/m17nutil.h
-@@ -14,6 +14,9 @@ struct _IBusM17NEngineConfig {
- /* engine rank */
- gint rank;
+@@ -20,6 +20,9 @@ struct _IBusM17NEngineConfig {
+ /* overridding longname shown on panel */
+ gchar *longname;
+ /* keyboard layout */
+ gchar *layout;
@@ -89,5 +89,5 @@ index 313e7bc..c7b283e 100644
gboolean preedit_highlight;
};
--
-1.7.6.2
+1.7.7.6
diff --git a/ibus-m17n.spec b/ibus-m17n.spec
index 37cbf97..e88461b 100644
--- a/ibus-m17n.spec
+++ b/ibus-m17n.spec
@@ -13,33 +13,24 @@
%global _with_gtk --with-gtk=2.0
%endif
-%if %have_bridge_hotkey
-%global _with_hotkeys --with-hotkeys
-%endif
-
%if (0%{?fedora} > 16)
%global _enable_eekboard --enable-eekboard
%endif
Name: ibus-m17n
Version: 1.3.3
-Release: 9%{?dist}
+Release: 11%{?dist}
Summary: The M17N engine for IBus platform
License: GPLv2+
Group: System Environment/Libraries
URL: http://code.google.com/p/ibus/
Source0: http://ibus.googlecode.com/files/%{name}-%{version}.tar.gz
-#Patch0: ibus-m17n-HEAD.patch
-Patch1: ibus-m17n-default-xml-override.patch
-Patch2: ibus-m17n-setup-refactor.patch
-Patch3: ibus-m17n-xkb-options.patch
-Patch4: ibus-m17n-xx-icon-symbol.patch
-Patch5: ibus-m17n-virtkbd.patch
-Patch6: ibus-m17n-iok.patch
-Patch7: ibus-m17n-hide-title-status.patch
-Patch8: ibus-m17n-blacklist-engines.patch
-Patch9: ibus-m17n-custom-setup-element.patch
+Patch0: ibus-m17n-HEAD.patch
+Patch1: ibus-m17n-xkb-options.patch
+Patch2: ibus-m17n-hide-title-status.patch
+Patch3: ibus-m17n-blacklist-engines.patch
+Patch4: ibus-m17n-virtkbd.patch
# The following BR is for autogen and not necessary when packging
# released tarballs.
@@ -68,18 +59,13 @@ the input table maps from m17n-db.
%prep
%setup -q
-#patch0 -p1 -b .HEAD
-%patch1 -p1 -b .default-xml-override
-%patch2 -p1 -b .setup-refactor
-%patch3 -p1 -b .xkb-options
-# do not apply patch to m4/.gitignore
-sed -i 's!^[-+][-+][-+] .*/m4/\.gitignore!#\0!' %PATCH4
-%patch4 -p1 -b .xx-icon-symbol
-%patch5 -p1 -b .virtkbd
-%patch6 -p1 -b .iok
-%patch7 -p1 -b .hide-title-status
-%patch8 -p1 -b .blacklist-engines
-%patch9 -p1 -b .custom-setup-element
+
+%patch0 -p1 -b .HEAD
+%patch1 -p1 -b .xkb-options
+%patch2 -p1 -b .hide-title-status
+%patch3 -p1 -b .blacklist-engines
+%patch4 -p1 -b .virtkbd
+
NOCONFIGURE=1 ./autogen.sh
%build
@@ -101,6 +87,10 @@ make DESTDIR=${RPM_BUILD_ROOT} install
%{_datadir}/ibus/component/*
%changelog
+* Fri Mar 30 2012 Daiki Ueno <dueno at redhat.com> - 1.3.3-11
+- Revive m17n:zh:pinyin with a different label ("hanyu pinyin (m17n)")
+- Rebase ibus-m17n-virtkbd.patch.
+
* Tue Mar 6 2012 Takao Fujiwara <tfujiwar at redhat.com> - 1.3.3-9
- Rebuild for ibus 1.4.99.20120304
More information about the scm-commits
mailing list