[Fedora-i18n-bugs] [ibus-m17n/f13/master] Update to 1.3.1-8.
Daiki Ueno
ueno at fedoraproject.org
Wed Dec 22 02:45:55 UTC 2010
commit 8814d656f90e28dcb4b8afb842f28c9d84a21676
Author: Daiki Ueno <ueno at unixuser.org>
Date: Wed Dec 22 11:50:30 2010 +0900
Update to 1.3.1-8.
ibus-m17n-HEAD.patch | 1486 ++++++++++++++++++++++++++++++++++++++
ibus-m17n-fedora.patch | 207 ------
ibus-m17n-iok.patch | 85 ++-
ibus-m17n-surrounding-text.patch | 73 --
ibus-m17n.spec | 31 +-
5 files changed, 1560 insertions(+), 322 deletions(-)
---
diff --git a/ibus-m17n-HEAD.patch b/ibus-m17n-HEAD.patch
new file mode 100644
index 0000000..e71c97e
--- /dev/null
+++ b/ibus-m17n-HEAD.patch
@@ -0,0 +1,1486 @@
+diff --git a/autogen.sh b/autogen.sh
+index 14db0b1..99be006 100755
+--- a/autogen.sh
++++ b/autogen.sh
+@@ -1,13 +1,27 @@
+ #!/bin/sh
+-set -e
+-set -x
+-
+-autopoint
+-libtoolize --automake --copy
+-aclocal -I m4
+-autoheader
+-automake --add-missing --copy
+-autoconf
++# Run this to generate all the initial makefiles, etc.
++
++srcdir=`dirname $0`
++test -z "$srcdir" && srcdir=.
++
++PKG_NAME="ibus-m17n"
++
++(test -f $srcdir/configure.ac \
++ && test -f $srcdir/README ) || {
++ echo -n "**Error**: Directory "\`$srcdir\'" does not look like the"
++ echo " top-level $PKG_NAME directory"
++ exit 1
++}
++
++which gnome-autogen.sh || {
++ echo "You need to install gnome-common from the GNOME CVS"
++ exit 1
++}
++
+ export CFLAGS="-g -O0"
+ export CXXFLAGS="$CFLAGS"
+-./configure --enable-maintainer-mode $*
++
++ACLOCAL_FLAGS="$ACLOCAL_FLAGS -I m4"
++REQUIRED_AUTOMAKE_VERSION=1.10
++
++. gnome-autogen.sh
+diff --git a/codereview.settings b/codereview.settings
+new file mode 100644
+index 0000000..71ecbee
+--- /dev/null
++++ b/codereview.settings
+@@ -0,0 +1,2 @@
++# This file is used by "git cl" to get code review information.
++CODE_REVIEW_SERVER: codereview.appspot.com
+diff --git a/configure.ac b/configure.ac
+index 4d5ecc7..d9aeb11 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -80,6 +80,7 @@ Makefile
+ ibus-m17n.spec
+ src/Makefile
+ src/m17n.xml.in
++src/default.xml.in
+ icons/Makefile
+ m4/Makefile
+ ])
+diff --git a/src/Makefile.am b/src/Makefile.am
+index 07e4432..eaa8bd8 100644
+--- a/src/Makefile.am
++++ b/src/Makefile.am
+@@ -22,6 +22,8 @@ AM_CFLAGS = \
+ @IBUS_CFLAGS@ \
+ @M17N_CFLAGS@ \
+ -DPKGDATADIR=\"$(pkgdatadir)\" \
++ -DLIBEXECDIR=\"$(libexecdir)\" \
++ -DSETUPDIR=\"$(setupdir)\" \
+ $(NULL)
+ AM_LDADD = \
+ @IBUS_LIBS@ \
+@@ -50,41 +52,38 @@ test_m17n_LDADD = \
+
+ libexec_PROGRAMS = ibus-engine-m17n ibus-setup-m17n
+
+-ibus_engine_m17n_SOURCES = \
++noinst_LIBRARIES = libm17ncommon.a
++
++libm17ncommon_a_SOURCES = \
+ m17nutil.c \
+ m17nutil.h \
++ $(NULL)
++ibus_engine_m17n_SOURCES = \
+ main.c \
+ engine.c \
+ engine.h \
+ $(NULL)
+-ibus_engine_m17n_CFLAGS = \
+- @IBUS_CFLAGS@ \
+- @M17N_CFLAGS@ \
+- -DPKGDATADIR=\"$(pkgdatadir)\" \
+- -DLIBEXECDIR=\"$(libexecdir)\" \
+- $(NULL)
+ ibus_engine_m17n_LDADD = \
++ libm17ncommon.a \
+ @IBUS_LIBS@ \
+ @M17N_LIBS@ \
+ $(NULL)
+
+ setup_DATA = \
+ ibus-m17n-preferences.ui \
++ default.xml \
+ $(NULL)
+ setupdir = $(pkgdatadir)/setup
+
+ ibus_setup_m17n_SOURCES = \
+- m17nutil.c \
+- m17nutil.h \
+ setup.c \
+ $(NULL)
+ ibus_setup_m17n_CFLAGS = \
+- @IBUS_CFLAGS@ \
+- @M17N_CFLAGS@ \
+ @GTK2_CFLAGS@ \
+- -DSETUPDIR=\"$(setupdir)\" \
++ $(AM_CFLAGS) \
+ $(NULL)
+ ibus_setup_m17n_LDADD = \
++ libm17ncommon.a \
+ @IBUS_LIBS@ \
+ @M17N_LIBS@ \
+ @GTK2_LIBS@ \
+@@ -96,19 +95,31 @@ component_DATA = \
+ componentdir = @datadir@/ibus/component
+
+ EXTRA_DIST = \
+- m17n.xml.in \
++ m17n.xml.in.in \
++ default.xml.in \
+ $(setup_DATA) \
+ $(NULL)
+
++DISTCLEANFILES = \
++ m17n.xml.in \
++ default.xml.in \
++ $(NULL)
++
+ CLEANFILES = \
+ m17n.xml \
++ default.xml \
+ $(NULL)
+
+ m17n.xml: m17n.xml.in
++default.xml: default.xml.in
++
++SUFFIXES = .xml.in .xml
++.xml.in.xml:
+ $(AM_V_GEN) \
+ ( \
+ libexecdir=${libexecdir}; \
+ pkgdatadir=${pkgdatadir}; \
++ setupdir=${setupdir}; \
+ s=`cat $<`; \
+ eval "echo \"$${s}\""; \
+ ) > $@
+diff --git a/src/default.xml.in.in b/src/default.xml.in.in
+new file mode 100644
+index 0000000..5c5d67d
+--- /dev/null
++++ b/src/default.xml.in.in
+@@ -0,0 +1,246 @@
++<?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>
++ <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. -->
++ <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>
++ <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>
++ <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 260a806..f8e7fe5 100644
+--- a/src/engine.c
++++ b/src/engine.c
+@@ -6,6 +6,23 @@
+ #include "m17nutil.h"
+ #include "engine.h"
+
++/* type module to assign different GType to each engine */
++#define IBUS_TYPE_M17N_TYPE_MODULE (ibus_m17n_type_module_get_type ())
++#define IBUS_M17N_TYPE_MODULE (module) (G_TYPE_CHECK_INSTANCE_CAST (module, IBUS_TYPE_M17N_TYPE_MODULE, IBusM17NTypeModule)
++
++typedef struct _IBusM17NTypeModule IBusM17NTypeModule;
++typedef struct _IBusM17NTypeModuleClass IBusM17NTypeModuleClass;
++
++struct _IBusM17NTypeModule
++{
++ GTypeModule parent_instance;
++};
++
++struct _IBusM17NTypeModuleClass
++{
++ GTypeModuleClass parent_class;
++};
++
+ typedef struct _IBusM17NEngine IBusM17NEngine;
+ typedef struct _IBusM17NEngineClass IBusM17NEngineClass;
+
+@@ -18,20 +35,36 @@ struct _IBusM17NEngine {
+ IBusProperty *status_prop;
+ IBusProperty *setup_prop;
+ IBusPropList *prop_list;
+- gchar *config_section;
+ };
+
+ struct _IBusM17NEngineClass {
+ IBusEngineClass parent;
++
++ /* configurations are per class */
++ gchar *config_section;
++ guint preedit_foreground;
++ guint preedit_background;
++ gint preedit_underline;
++ gint lookup_table_orientation;
++
++ MInputMethod *im;
+ };
+
+ /* functions prototype */
++static GType
++ ibus_m17n_type_module_get_type (void);
+ static void ibus_m17n_engine_class_init (IBusM17NEngineClass *klass);
+-static void ibus_m17n_engine_init (IBusM17NEngine *m17n);
++static void ibus_m17n_engine_class_finalize (IBusM17NEngineClass *klass);
++static void ibus_m17n_config_value_changed (IBusConfig *config,
++ const gchar *section,
++ const gchar *name,
++ GValue *value,
++ IBusM17NEngineClass *klass);
+ static GObject*
+ ibus_m17n_engine_constructor (GType type,
+ guint n_construct_params,
+ GObjectConstructParam *construct_params);
++static void ibus_m17n_engine_init (IBusM17NEngine *m17n);
+ static void ibus_m17n_engine_destroy (IBusM17NEngine *m17n);
+ static gboolean
+ ibus_m17n_engine_process_key_event
+@@ -77,13 +110,9 @@ static void ibus_m17n_engine_update_lookup_table
+ (IBusM17NEngine *m17n);
+
+ static IBusEngineClass *parent_class = NULL;
+-static GHashTable *im_table = NULL;
+
+ static IBusConfig *config = NULL;
+-static guint preedit_foreground = INVALID_COLOR;
+-static guint preedit_background = INVALID_COLOR;
+-static gint preedit_underline = IBUS_ATTR_UNDERLINE_NONE;
+-static gint lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
++static IBusM17NTypeModule *module = NULL;
+
+ void
+ ibus_m17n_init (IBusBus *bus)
+@@ -92,31 +121,149 @@ ibus_m17n_init (IBusBus *bus)
+ if (config)
+ g_object_ref_sink (config);
+ ibus_m17n_init_common ();
++
++ module = g_object_new (IBUS_TYPE_M17N_TYPE_MODULE, NULL);
+ }
+
+-GType
+-ibus_m17n_engine_get_type (void)
++static gboolean
++ibus_m17n_type_module_load (GTypeModule *module)
++{
++ return TRUE;
++}
++
++static void
++ibus_m17n_type_module_unload (GTypeModule *module)
++{
++}
++
++static void
++ibus_m17n_type_module_class_init (IBusM17NTypeModuleClass *klass)
++{
++ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (klass);
++
++ module_class->load = ibus_m17n_type_module_load;
++ module_class->unload = ibus_m17n_type_module_unload;
++}
++
++static GType
++ibus_m17n_type_module_get_type (void)
+ {
+ static GType type = 0;
+
+ static const GTypeInfo type_info = {
++ sizeof (IBusM17NTypeModuleClass),
++ (GBaseInitFunc) NULL,
++ (GBaseFinalizeFunc) NULL,
++ (GClassInitFunc) ibus_m17n_type_module_class_init,
++ (GClassFinalizeFunc) NULL,
++ NULL,
++ sizeof (IBusM17NTypeModule),
++ 0,
++ (GInstanceInitFunc) NULL,
++ };
++
++ if (type == 0) {
++ type = g_type_register_static (G_TYPE_TYPE_MODULE,
++ "IBusM17NTypeModule",
++ &type_info,
++ (GTypeFlags) 0);
++ }
++
++ return type;
++}
++
++static gboolean
++ibus_m17n_scan_engine_name (const gchar *engine_name,
++ gchar **lang,
++ gchar **name)
++{
++ gchar **strv;
++
++ g_return_val_if_fail (g_str_has_prefix (engine_name, "m17n:"), FALSE);
++ strv = g_strsplit (engine_name, ":", 3);
++
++ if (g_strv_length (strv) != 3) {
++ g_strfreev (strv);
++ g_return_val_if_reached (FALSE);
++ }
++
++ *lang = strv[1];
++ *name = strv[2];
++
++ g_free (strv[0]);
++ g_free (strv);
++
++ return TRUE;
++}
++
++static gboolean
++ibus_m17n_scan_class_name (const gchar *class_name,
++ gchar **lang,
++ gchar **name)
++{
++ gchar *p;
++
++ g_return_val_if_fail (g_str_has_prefix (class_name, "IBusM17N"), FALSE);
++ g_return_val_if_fail (g_str_has_suffix (class_name, "Engine"), FALSE);
++
++ /* Strip prefix and suffix */
++ p = *lang = g_strdup (class_name + 8);
++ p = g_strrstr (p, "Engine");
++ *p = '\0';
++
++ /* Find the start position of <Name> */
++ while (g_ascii_islower (*--p) && p > *lang)
++ ;
++ g_return_val_if_fail (p > *lang, FALSE);
++ *name = g_strdup (p);
++ *p = '\0';
++
++ *lang[0] = g_ascii_tolower (*lang[0]);
++ *name[0] = g_ascii_tolower (*name[0]);
++
++ return TRUE;
++}
++
++GType
++ibus_m17n_engine_get_type_for_name (const gchar *engine_name)
++{
++ GType type;
++ gchar *type_name, *lang = NULL, *name = NULL;
++
++ GTypeInfo type_info = {
+ sizeof (IBusM17NEngineClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) ibus_m17n_engine_class_init,
+- NULL,
++ (GClassFinalizeFunc)ibus_m17n_engine_class_finalize,
+ NULL,
+ sizeof (IBusM17NEngine),
+ 0,
+ (GInstanceInitFunc) ibus_m17n_engine_init,
+ };
+
++ if (!ibus_m17n_scan_engine_name (engine_name, &lang, &name)) {
++ g_free (lang);
++ g_free (name);
++ return G_TYPE_INVALID;
++ }
++ lang[0] = g_ascii_toupper (lang[0]);
++ name[0] = g_ascii_toupper (name[0]);
++ type_name = g_strdup_printf ("IBusM17N%s%sEngine", lang, name);
++ g_free (lang);
++ g_free (name);
++
++ type = g_type_from_name (type_name);
++ g_assert (type == 0 || g_type_is_a (type, IBUS_TYPE_ENGINE));
++
+ if (type == 0) {
+- type = g_type_register_static (IBUS_TYPE_ENGINE,
+- "IBusM17NEngine",
+- &type_info,
+- (GTypeFlags) 0);
++ type = g_type_module_register_type (G_TYPE_MODULE (module),
++ IBUS_TYPE_ENGINE,
++ type_name,
++ &type_info,
++ (GTypeFlags) 0);
+ }
++ g_free (type_name);
+
+ return type;
+ }
+@@ -127,8 +274,12 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ IBusObjectClass *ibus_object_class = IBUS_OBJECT_CLASS (klass);
+ IBusEngineClass *engine_class = IBUS_ENGINE_CLASS (klass);
++ GValue value = { 0 };
++ gchar *engine_name, *lang = NULL, *name = NULL;
++ IBusM17NEngineConfig *engine_config;
+
+- parent_class = (IBusEngineClass *) g_type_class_peek_parent (klass);
++ if (parent_class == NULL)
++ parent_class = (IBusEngineClass *) g_type_class_peek_parent (klass);
+
+ object_class->constructor = ibus_m17n_engine_constructor;
+ ibus_object_class->destroy = (IBusObjectDestroyFunc) ibus_m17n_engine_destroy;
+@@ -149,50 +300,117 @@ ibus_m17n_engine_class_init (IBusM17NEngineClass *klass)
+ engine_class->cursor_down = ibus_m17n_engine_cursor_down;
+
+ engine_class->property_activate = ibus_m17n_engine_property_activate;
++
++ if (!ibus_m17n_scan_class_name (G_OBJECT_CLASS_NAME (klass),
++ &lang, &name)) {
++ g_free (lang);
++ g_free (name);
++ return;
++ }
++ engine_name = g_strdup_printf ("m17n:%s:%s", lang, name);
++ klass->config_section = g_strdup_printf ("engine/M17N/%s/%s", lang, name);
++ g_free (lang);
++ g_free (name);
++
++ /* configurations are per class */
++ klass->preedit_foreground = INVALID_COLOR;
++ klass->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);
++
++ if (ibus_config_get_value (config,
++ klass->config_section,
++ "preedit_foreground",
++ &value)) {
++ const gchar *hex = g_value_get_string (&value);
++
++ klass->preedit_foreground = ibus_m17n_parse_color (hex);
++ g_value_unset (&value);
++ } else if (engine_config->preedit_highlight)
++ klass->preedit_foreground = PREEDIT_FOREGROUND;
++
++ if (ibus_config_get_value (config,
++ klass->config_section,
++ "preedit_background",
++ &value)) {
++ const gchar *hex = g_value_get_string (&value);
++
++ klass->preedit_background = ibus_m17n_parse_color (hex);
++ g_value_unset (&value);
++ } else if (engine_config->preedit_highlight)
++ klass->preedit_background = PREEDIT_BACKGROUND;
++
++ if (ibus_config_get_value (config,
++ klass->config_section,
++ "preedit_underline",
++ &value)) {
++ klass->preedit_underline = g_value_get_int (&value);
++ g_value_unset (&value);
++ } else
++ klass->preedit_underline = IBUS_ATTR_UNDERLINE_NONE;
++
++ if (ibus_config_get_value (config,
++ klass->config_section,
++ "lookup_table_orientation",
++ &value)) {
++ klass->lookup_table_orientation = g_value_get_int (&value);
++ g_value_unset (&value);
++ } else
++ klass->lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
++
++ g_signal_connect (config, "value-changed",
++ G_CALLBACK(ibus_m17n_config_value_changed),
++ klass);
++
++ klass->im = NULL;
+ }
+
+ static void
+-ibus_config_value_changed (IBusConfig *config,
+- const gchar *section,
+- const gchar *name,
+- GValue *value,
+- gpointer user_data)
++ibus_m17n_config_value_changed (IBusConfig *config,
++ const gchar *section,
++ const gchar *name,
++ GValue *value,
++ IBusM17NEngineClass *klass)
+ {
+- IBusM17NEngine *m17n = (IBusM17NEngine *) user_data;
+-
+- if (g_strcmp0 (section, m17n->config_section) == 0) {
++ if (g_strcmp0 (section, klass->config_section) == 0) {
+ if (g_strcmp0 (name, "preedit_foreground") == 0) {
+ const gchar *hex = g_value_get_string (value);
+ guint color;
+ color = ibus_m17n_parse_color (hex);
+ if (color != INVALID_COLOR) {
+- preedit_foreground = color;
+- ibus_m17n_engine_update_preedit (m17n);
++ klass->preedit_foreground = color;
+ }
+ } else if (g_strcmp0 (name, "preedit_background") == 0) {
+ const gchar *hex = g_value_get_string (value);
+ guint color;
+ color = ibus_m17n_parse_color (hex);
+ if (color != INVALID_COLOR) {
+- preedit_background = color;
+- ibus_m17n_engine_update_preedit (m17n);
++ klass->preedit_background = color;
+ }
+ } else if (g_strcmp0 (name, "preedit_underline") == 0) {
+- preedit_underline = g_value_get_int (value);
+- ibus_m17n_engine_update_preedit (m17n);
++ klass->preedit_underline = g_value_get_int (value);
+ } else if (g_strcmp0 (name, "lookup_table_orientation") == 0) {
+- lookup_table_orientation = g_value_get_int (value);
+- ibus_m17n_engine_update_lookup_table (m17n);
++ klass->lookup_table_orientation = g_value_get_int (value);
+ }
+ }
+ }
+
+ static void
++ibus_m17n_engine_class_finalize (IBusM17NEngineClass *klass)
++{
++ if (klass->im)
++ minput_close_im (klass->im);
++ g_free (klass->config_section);
++}
++
++static void
+ ibus_m17n_engine_init (IBusM17NEngine *m17n)
+ {
+ IBusText* label;
+ IBusText* tooltip;
+- const gchar *engine_name;
+
+ m17n->status_prop = ibus_property_new ("status",
+ PROP_TYPE_NORMAL,
+@@ -234,123 +452,60 @@ ibus_m17n_engine_constructor (GType type,
+ GObjectConstructParam *construct_params)
+ {
+ IBusM17NEngine *m17n;
+- MInputMethod *im;
+- const gchar *engine_name;
+- gchar *lang;
+- gchar *name;
+- gchar **strv;
+- GValue value = { 0 };
+- gboolean preedit_highlight;
++ GObjectClass *object_class;
++ IBusM17NEngineClass *klass;
+
+ m17n = (IBusM17NEngine *) G_OBJECT_CLASS (parent_class)->constructor (type,
+ n_construct_params,
+ construct_params);
+
+- engine_name = ibus_engine_get_name ((IBusEngine *) m17n);
+- g_assert (engine_name);
+-
+- strv = g_strsplit (engine_name, ":", 3);
++ object_class = G_OBJECT_GET_CLASS (m17n);
++ klass = (IBusM17NEngineClass *) object_class;
++ if (klass->im == NULL) {
++ const gchar *engine_name;
++ gchar *lang = NULL, *name = NULL;
+
+- g_assert (g_strv_length (strv) == 3);
+- g_assert (g_strcmp0 (strv[0], "m17n") == 0);
+-
+- lang = strv[1];
+- name = strv[2];
+-
+- if (im_table == NULL) {
+- im_table = g_hash_table_new_full (g_str_hash,
+- g_str_equal,
+- g_free,
+- (GDestroyNotify) minput_close_im);
+- }
+-
+- im = (MInputMethod *) g_hash_table_lookup (im_table, engine_name);
+- if (im == NULL) {
+- im = minput_open_im (msymbol (lang), msymbol (name), NULL);
+- if (im != NULL) {
+- mplist_put (im->driver.callback_list, Minput_preedit_start, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_preedit_draw, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_preedit_done, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_status_start, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_status_draw, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_status_done, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_candidates_start, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_candidates_draw, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_candidates_done, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_set_spot, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_toggle, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_reset, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_get_surrounding_text, ibus_m17n_engine_callback);
+- mplist_put (im->driver.callback_list, Minput_delete_surrounding_text, ibus_m17n_engine_callback);
+-
+- g_hash_table_insert (im_table, g_strdup (engine_name), im);
++ engine_name = ibus_engine_get_name ((IBusEngine *) m17n);
++ if (!ibus_m17n_scan_engine_name (engine_name, &lang, &name)) {
++ g_free (lang);
++ g_free (name);
++ return NULL;
+ }
+- }
+-
+- if (im == NULL) {
+- g_warning ("Can not find m17n keymap %s", engine_name);
+- g_strfreev (strv);
+- g_object_unref (m17n);
+- return NULL;
+- }
+-
+- m17n->context = minput_create_ic (im, NULL);
+- mplist_add (m17n->context->plist, msymbol ("IBusEngine"), m17n);
+-
+- m17n->config_section = g_strdup_printf ("engine/M17N/%s/%s",
+- lang, name);
+- g_strfreev (strv);
+-
+- preedit_highlight = ibus_m17n_preedit_highlight (engine_name);
+- if (ibus_config_get_value (config,
+- m17n->config_section,
+- "preedit_foreground",
+- &value)) {
+- const gchar *hex = g_value_get_string (&value);
+- guint color = ibus_m17n_parse_color (hex);
+- if (color != (guint)-1)
+- preedit_foreground = color;
+- g_value_unset (&value);
+- } else if (preedit_highlight)
+- preedit_foreground = PREEDIT_FOREGROUND;
+
+- if (ibus_config_get_value (config,
+- m17n->config_section,
+- "preedit_background",
+- &value)) {
+- const gchar *hex = g_value_get_string (&value);
+- guint color = ibus_m17n_parse_color (hex);
+- if (color != (guint)-1)
+- preedit_background = color;
+- g_value_unset (&value);
+- } else if (preedit_highlight)
+- preedit_background = PREEDIT_BACKGROUND;
++ klass->im = minput_open_im (msymbol (lang), msymbol (name), NULL);
++ g_free (lang);
++ g_free (name);
+
+- if (ibus_config_get_value (config,
+- m17n->config_section,
+- "preedit_underline",
+- &value)) {
+- preedit_underline = g_value_get_int (&value);
+- g_value_unset (&value);
+- } else
+- preedit_underline = IBUS_ATTR_UNDERLINE_NONE;
+-
+- if (ibus_config_get_value (config,
+- m17n->config_section,
+- "lookup_table_orientation",
+- &value)) {
+- lookup_table_orientation = g_value_get_int (&value);
+- g_value_unset (&value);
+- } else
+- lookup_table_orientation = IBUS_ORIENTATION_SYSTEM;
++ if (klass->im == NULL) {
++ g_warning ("Can not find m17n keymap %s", engine_name);
++ g_object_unref (m17n);
++ return NULL;
++ }
+
+- g_signal_connect (config, "value-changed",
+- G_CALLBACK(ibus_config_value_changed), m17n);
++ mplist_put (klass->im->driver.callback_list, Minput_preedit_start, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_preedit_draw, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_preedit_done, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_status_start, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_status_draw, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_status_done, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_candidates_start, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_candidates_draw, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_candidates_done, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_set_spot, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_toggle, ibus_m17n_engine_callback);
++ /*
++ Does not set reset callback, uses the default callback in m17n.
++ mplist_put (klass->im->driver.callback_list, Minput_reset, ibus_m17n_engine_callback);
++ */
++ mplist_put (klass->im->driver.callback_list, Minput_get_surrounding_text, ibus_m17n_engine_callback);
++ mplist_put (klass->im->driver.callback_list, Minput_delete_surrounding_text, ibus_m17n_engine_callback);
++ }
++
++ m17n->context = minput_create_ic (klass->im, m17n);
+
+ return (GObject *) m17n;
+ }
+
+-
+ static void
+ ibus_m17n_engine_destroy (IBusM17NEngine *m17n)
+ {
+@@ -379,11 +534,6 @@ ibus_m17n_engine_destroy (IBusM17NEngine *m17n)
+ m17n->context = NULL;
+ }
+
+- if (m17n->config_section) {
+- g_free (m17n->config_section);
+- m17n->config_section = NULL;
+- }
+-
+ IBUS_OBJECT_CLASS (parent_class)->destroy ((IBusObject *)m17n);
+ }
+
+@@ -392,18 +542,19 @@ ibus_m17n_engine_update_preedit (IBusM17NEngine *m17n)
+ {
+ IBusText *text;
+ gchar *buf;
++ IBusM17NEngineClass *klass = (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n);
+
+ buf = ibus_m17n_mtext_to_utf8 (m17n->context->preedit);
+ if (buf) {
+ text = ibus_text_new_from_static_string (buf);
+- if (preedit_foreground != INVALID_COLOR)
++ if (klass->preedit_foreground != INVALID_COLOR)
+ ibus_text_append_attribute (text, IBUS_ATTR_TYPE_FOREGROUND,
+- preedit_foreground, 0, -1);
+- if (preedit_background != INVALID_COLOR)
++ klass->preedit_foreground, 0, -1);
++ if (klass->preedit_background != INVALID_COLOR)
+ ibus_text_append_attribute (text, IBUS_ATTR_TYPE_BACKGROUND,
+- preedit_background, 0, -1);
++ klass->preedit_background, 0, -1);
+ ibus_text_append_attribute (text, IBUS_ATTR_TYPE_UNDERLINE,
+- preedit_underline, 0, -1);
++ klass->preedit_underline, 0, -1);
+ ibus_engine_update_preedit_text ((IBusEngine *) m17n,
+ text,
+ m17n->context->cursor_pos,
+@@ -421,9 +572,9 @@ ibus_m17n_engine_commit_string (IBusM17NEngine *m17n,
+ ibus_m17n_engine_update_preedit (m17n);
+ }
+
+-/* Note on AltGr handling: While currently we expect AltGr == mod5, it
+- would be better to not expect the modifier always be assigned
+- to particular modX. However, it needs some code like:
++/* Note on AltGr (Level3 Shift) handling: While currently we expect
++ AltGr == mod5, it would be better to not expect the modifier always
++ be assigned to particular modX. However, it needs some code like:
+
+ KeyCode altgr = XKeysymToKeycode (display, XK_ISO_Level3_Shift);
+ XModifierKeymap *mods = XGetModifierMapping (display);
+@@ -445,20 +596,26 @@ ibus_m17n_key_event_to_symbol (guint keycode,
+ MSymbol mkeysym = Mnil;
+ guint mask = 0;
+ IBusKeymap *keymap;
+- guint base_keyval;
+
+ if (keyval >= IBUS_Shift_L && keyval <= IBUS_Hyper_R) {
+ return Mnil;
+ }
+
+- keymap = ibus_keymap_get ("us");
+- base_keyval = ibus_keymap_lookup_keysym (keymap, keycode, 0);
+- g_object_unref (keymap);
++ /* Here, keyval is already translated by IBUS_MOD5_MASK. Obtain
++ the untranslated keyval from the underlying keymap and
++ represent the translated keyval as the form "G-<untranslated
++ keyval>", which m17n-lib accepts. */
++ if (modifiers & IBUS_MOD5_MASK) {
++ keymap = ibus_keymap_get ("us");
++ keyval = ibus_keymap_lookup_keysym (keymap, keycode,
++ modifiers & ~IBUS_MOD5_MASK);
++ g_object_unref (keymap);
++ }
+
+ keysym = g_string_new ("");
+
+- if (base_keyval >= IBUS_space && base_keyval <= IBUS_asciitilde) {
+- gint c = (modifiers & IBUS_MOD5_MASK) ? base_keyval : keyval;
++ if (keyval >= IBUS_space && keyval <= IBUS_asciitilde) {
++ gint c = keyval;
+
+ if (keyval == IBUS_space && modifiers & IBUS_SHIFT_MASK)
+ mask |= IBUS_SHIFT_MASK;
+@@ -572,7 +729,7 @@ ibus_m17n_engine_focus_in (IBusEngine *engine)
+ IBusM17NEngine *m17n = (IBusM17NEngine *) engine;
+
+ ibus_engine_register_properties (engine, m17n->prop_list);
+- ibus_m17n_engine_process_key (m17n, msymbol ("input-focus-in"));
++ ibus_m17n_engine_process_key (m17n, Minput_focus_in);
+
+ parent_class->focus_in (engine);
+ }
+@@ -582,7 +739,7 @@ ibus_m17n_engine_focus_out (IBusEngine *engine)
+ {
+ IBusM17NEngine *m17n = (IBusM17NEngine *) engine;
+
+- ibus_m17n_engine_process_key (m17n, msymbol ("input-focus-out"));
++ ibus_m17n_engine_process_key (m17n, Minput_focus_out);
+
+ parent_class->focus_out (engine);
+ }
+@@ -593,7 +750,8 @@ ibus_m17n_engine_reset (IBusEngine *engine)
+ IBusM17NEngine *m17n = (IBusM17NEngine *) engine;
+
+ parent_class->reset (engine);
+- ibus_m17n_engine_focus_in (engine);
++
++ minput_reset_ic (m17n->context);
+ }
+
+ static void
+@@ -676,7 +834,7 @@ ibus_m17n_engine_property_activate (IBusEngine *engine,
+ static void
+ ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n)
+ {
+- ibus_lookup_table_clear (m17n->table);
++ ibus_lookup_table_clear (m17n->table);
+
+ if (m17n->context->candidate_list && m17n->context->candidate_show) {
+ IBusText *text;
+@@ -684,6 +842,7 @@ ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n)
+ group = m17n->context->candidate_list;
+ gint i = 0;
+ gint page = 1;
++ IBusM17NEngineClass *klass = (IBusM17NEngineClass *) G_OBJECT_GET_CLASS (m17n);
+
+ while (1) {
+ gint len;
+@@ -734,7 +893,7 @@ ibus_m17n_engine_update_lookup_table (IBusM17NEngine *m17n)
+ }
+
+ ibus_lookup_table_set_cursor_pos (m17n->table, m17n->context->candidate_index - i);
+- ibus_lookup_table_set_orientation (m17n->table, lookup_table_orientation);
++ ibus_lookup_table_set_orientation (m17n->table, klass->lookup_table_orientation);
+
+ text = ibus_text_new_from_printf ("( %d / %d )", page, mplist_length (m17n->context->candidate_list));
+
+@@ -752,15 +911,14 @@ ibus_m17n_engine_callback (MInputContext *context,
+ MSymbol command)
+ {
+ IBusM17NEngine *m17n = NULL;
+- MPlist *p = NULL;
+
+- p = mplist_find_by_key (context->plist, msymbol ("IBusEngine"));
+- if (p) {
+- m17n = (IBusM17NEngine *) mplist_value (p);
+- }
++ m17n = context->arg;
++ g_return_if_fail (m17n != NULL);
+
+- if (m17n == NULL) {
+- return;
++ /* the callback may be called in minput_create_ic, in the time
++ * m17n->context has not be assigned, so need assign it. */
++ if (m17n->context == NULL) {
++ m17n->context = context;
+ }
+
+ if (command == Minput_preedit_start) {
+diff --git a/src/engine.h b/src/engine.h
+index 7c0b4d9..bdd6492 100644
+--- a/src/engine.h
++++ b/src/engine.h
+@@ -4,9 +4,6 @@
+
+ #include <ibus.h>
+
+-#define IBUS_TYPE_M17N_ENGINE \
+- (ibus_m17n_engine_get_type ())
+-
+-GType ibus_m17n_engine_get_type (void);
++GType ibus_m17n_engine_get_type_for_name (const gchar *name);
+
+ #endif
+diff --git a/src/m17n.xml.in.in b/src/m17n.xml.in.in
+index 3ea4394..97d72d2 100644
+--- a/src/m17n.xml.in.in
++++ b/src/m17n.xml.in.in
+@@ -11,6 +11,7 @@
+ <textdomain>ibus-m17n</textdomain>
+ <observed-paths>
+ <path>/usr/share/m17n/</path>
++ <path>${setupdir}/default.xml</path>
+ </observed-paths>
+ <engines exec=\"${libexecdir}/ibus-engine-m17n --xml\" />
+ </component>
+diff --git a/src/m17nutil.c b/src/m17nutil.c
+index ae0fe56..6d6961f 100644
+--- a/src/m17nutil.c
++++ b/src/m17nutil.c
+@@ -7,39 +7,17 @@
+
+ static MConverter *utf8_converter = NULL;
+
+-static const gchar *keymap[] = {
+- "m17n:as:phonetic",
+- "m17n:bn:inscript",
+- "m17n:gu:inscript",
+- "m17n:hi:inscript",
+- "m17n:kn:kgp",
+- "m17n:ks:kbd",
+- "m17n:mai:inscript",
+- "m17n:ml:inscript",
+- "m17n:mr:inscript",
+- "m17n:ne:rom",
+- "m17n:or:inscript",
+- "m17n:pa:inscript",
+- "m17n:sa:harvard-kyoto",
+- "m17n:sd:inscript",
+- "m17n:si:wijesekera",
+- "m17n:ta:tamil99",
+- "m17n:te:inscript"
+-};
++#define DEFAULT_XML (SETUPDIR "/default.xml")
+
+-static const gchar *preedit_highlight[] = {
+- "m17n:ja:anthy",
+- "m17n:zh:cangjie",
+- "m17n:zh:py-b5",
+- "m17n:zh:py-gb",
+- "m17n:zh:py",
+- "m17n:zh:quick",
+- "m17n:zh:tonepy-b5",
+- "m17n:zh:tonepy-gb",
+- "m17n:zh:tonepy",
+- "m17n:zh:util",
++struct _IBusM17NEngineConfigNode {
++ gchar *name;
++ IBusM17NEngineConfig config;
+ };
+
++typedef struct _IBusM17NEngineConfigNode IBusM17NEngineConfigNode;
++
++static GSList *config_list = NULL;
++
+ void
+ ibus_m17n_init_common (void)
+ {
+@@ -101,11 +79,16 @@ guint
+ ibus_m17n_parse_color (const gchar *hex)
+ {
+ guint color;
+- if (hex && *hex == '#' &&
+- ((color = strtoul (&hex[1], NULL, 16)) != ULONG_MAX ||
+- errno != ERANGE))
+- return color;
+- return (guint)-1;
++
++ if (!hex || *hex != '#')
++ return (guint)-1;
++
++ errno = 0;
++ color = strtoul (&hex[1], NULL, 16);
++ if ((errno == ERANGE && color == ULONG_MAX)
++ || (errno != 0 && color == 0))
++ return (guint)-1;
++ return color;
+ }
+
+ static IBusEngineDesc *
+@@ -113,7 +96,8 @@ ibus_m17n_engine_new (MSymbol lang,
+ MSymbol name,
+ MText *title,
+ MText *icon,
+- MText *desc)
++ MText *desc,
++ IBusM17NEngineConfig *config)
+ {
+ IBusEngineDesc *engine;
+ gchar *engine_name;
+@@ -121,7 +105,6 @@ ibus_m17n_engine_new (MSymbol lang,
+ gchar *engine_title;
+ gchar *engine_icon;
+ gchar *engine_desc;
+- gint i;
+
+ engine_name = g_strdup_printf ("m17n:%s:%s", msymbol_name (lang), msymbol_name (name));
+
+@@ -138,16 +121,7 @@ ibus_m17n_engine_new (MSymbol lang,
+ "",
+ engine_icon ? engine_icon : "",
+ "us");
+- /* set default rank to 0 */
+- engine->rank = 0;
+-
+- for (i = 0; i < G_N_ELEMENTS(keymap); i++) {
+- if (strcmp (engine_name, keymap[i]) == 0) {
+- /* set rank of default keymap to 1 */
+- engine->rank = 1;
+- break;
+- }
+- }
++ engine->rank = config->rank;
+
+ g_free (engine_name);
+ g_free (engine_longname);
+@@ -178,10 +152,28 @@ ibus_m17n_list_engines (void)
+ MText *icon = NULL;
+ MText *desc = NULL;
+ MPlist *l;
++ gchar *engine_name;
++ IBusM17NEngineConfig *config;
+
+ lang = tag[1];
+ name = tag[2];
+
++ /* ignore input-method explicitly blacklisted in default.xml */
++ engine_name = g_strdup_printf ("m17n:%s:%s", msymbol_name (lang), msymbol_name (name));
++ config = ibus_m17n_get_engine_config (engine_name);
++ if (config == NULL) {
++ g_warning ("can't load config for %s", engine_name);
++ g_free (engine_name);
++ continue;
++ }
++ if (config->rank < 0) {
++ g_warning ("skipped %s since its rank is lower than 0",
++ engine_name);
++ g_free (engine_name);
++ continue;
++ }
++ g_free (engine_name);
++
+ l = minput_get_variable (lang, name, msymbol ("candidates-charset"));
+ if (l) {
+ /* check candidates encoding */
+@@ -226,7 +218,7 @@ ibus_m17n_list_engines (void)
+ icon = mplist_value (n);
+ }
+
+- engines = g_list_append (engines, ibus_m17n_engine_new (lang, name, title, icon, desc));
++ engines = g_list_append (engines, ibus_m17n_engine_new (lang, name, title, icon, desc, config));
+
+ if (desc)
+ m17n_object_unref (desc);
+@@ -241,11 +233,58 @@ ibus_m17n_list_engines (void)
+ return engines;
+ }
+
++IBusM17NEngineConfig *
++ibus_m17n_get_engine_config (const gchar *engine_name)
++{
++ GSList *p;
++
++ for (p = config_list; p != NULL; p = p->next) {
++ IBusM17NEngineConfigNode *cnode = p->data;
++
++ if (g_pattern_match_simple (cnode->name, engine_name))
++ return &cnode->config;
++ }
++ g_return_val_if_reached (NULL);
++}
++
++static gboolean
++ibus_m17n_engine_config_parse_xml_node (IBusM17NEngineConfigNode *cnode,
++ XMLNode *node)
++{
++ GList *p;
++
++ for (p = node->sub_nodes; p != NULL; p = p->next) {
++ XMLNode *sub_node = (XMLNode *) p->data;
++
++ if (g_strcmp0 (sub_node->name, "name") == 0) {
++ g_free (cnode->name);
++ cnode->name = g_strdup (sub_node->text);
++ continue;
++ }
++ if (g_strcmp0 (sub_node->name , "rank") == 0) {
++ cnode->config.rank = atoi (sub_node->text);
++ continue;
++ }
++ if (g_strcmp0 (sub_node->name , "preedit-highlight") == 0) {
++ if (g_ascii_strcasecmp ("TRUE", sub_node->text) == 0)
++ cnode->config.preedit_highlight = TRUE;
++ 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);
++ continue;
++ }
++ g_warning ("<engine> element contains invalid element <%s>",
++ sub_node->name);
++ }
++ return TRUE;
++}
++
+ IBusComponent *
+ ibus_m17n_get_component (void)
+ {
+ GList *engines, *p;
+ IBusComponent *component;
++ XMLNode *node;
+
+ component = ibus_component_new ("org.freedesktop.IBus.M17n",
+ N_("M17N"),
+@@ -256,26 +295,39 @@ ibus_m17n_get_component (void)
+ "",
+ "ibus-m17n");
+
++ node = ibus_xml_parse_file (DEFAULT_XML);
++ 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;
++
++ if (g_strcmp0 (sub_node->name, "engine") != 0) {
++ g_warning ("<engines> element contains invalid element <%s>",
++ sub_node->name);
++ continue;
++ }
++
++ cnode = g_slice_new0 (IBusM17NEngineConfigNode);
++ if (!ibus_m17n_engine_config_parse_xml_node (cnode, sub_node)) {
++ g_slice_free (IBusM17NEngineConfigNode, cnode);
++ continue;
++ }
++ config_list = g_slist_prepend (config_list, cnode);
++ }
++ config_list = g_slist_reverse (config_list);
++ } else
++ g_warning ("failed to parse %s", DEFAULT_XML);
++ if (node)
++ ibus_xml_free (node);
++
+ engines = ibus_m17n_list_engines ();
+
+- for (p = engines; p != NULL; p = p->next) {
+- ibus_component_add_engine (component, (IBusEngineDesc *) p->data);
+- }
++ for (p = engines; p != NULL; p = p->next)
++ ibus_component_add_engine (component, p->data);
+
+ g_list_free (engines);
+- return component;
+-}
+
+-gboolean
+-ibus_m17n_preedit_highlight (const gchar *engine_name)
+-{
+- gint i;
+-
+- for (i = 0; i < G_N_ELEMENTS(preedit_highlight); i++) {
+- if (strcmp (engine_name, preedit_highlight[i]) == 0)
+- return TRUE;
+- }
+- return FALSE;
++ return component;
+ }
+
+ #ifdef DEBUG
+@@ -304,4 +356,3 @@ int main ()
+ return 0;
+ }
+ #endif
+-
+diff --git a/src/m17nutil.h b/src/m17nutil.h
+index 7561505..a9be667 100644
+--- a/src/m17nutil.h
++++ b/src/m17nutil.h
+@@ -10,6 +10,16 @@
+ #define PREEDIT_FOREGROUND 0x00000000
+ #define PREEDIT_BACKGROUND 0x00c8c8f0
+
++struct _IBusM17NEngineConfig {
++ /* engine rank */
++ gint rank;
++
++ /* whether to highlight preedit */
++ gboolean preedit_highlight;
++};
++
++typedef struct _IBusM17NEngineConfig IBusM17NEngineConfig;
++
+ void ibus_m17n_init_common (void);
+ void ibus_m17n_init (IBusBus *bus);
+ GList *ibus_m17n_list_engines (void);
+@@ -18,5 +28,6 @@ gchar *ibus_m17n_mtext_to_utf8 (MText *text);
+ gunichar *ibus_m17n_mtext_to_ucs4 (MText *text,
+ glong *nchars);
+ guint ibus_m17n_parse_color (const gchar *hex);
+-gboolean ibus_m17n_preedit_highlight (const gchar *engine_name);
++IBusM17NEngineConfig
++ *ibus_m17n_get_engine_config (const gchar *engine_name);
+ #endif
+diff --git a/src/main.c b/src/main.c
+index b8d7c72..e76898d 100644
+--- a/src/main.c
++++ b/src/main.c
+@@ -51,7 +51,13 @@ start_component (void)
+ engines = ibus_component_get_engines (component);
+ for (p = engines; p != NULL; p = p->next) {
+ IBusEngineDesc *engine = (IBusEngineDesc *)p->data;
+- ibus_factory_add_engine (factory, engine->name, IBUS_TYPE_M17N_ENGINE);
++ GType type = ibus_m17n_engine_get_type_for_name (engine->name);
++
++ if (type == G_TYPE_INVALID) {
++ g_debug ("Can not create engine type for %s", engine->name);
++ continue;
++ }
++ ibus_factory_add_engine (factory, engine->name, type);
+ }
+
+ if (ibus) {
+@@ -74,8 +80,7 @@ print_engines_xml (void)
+
+ ibus_init ();
+
+- bus = ibus_bus_new ();
+- ibus_m17n_init (bus);
++ ibus_m17n_init_common ();
+
+ component = ibus_m17n_get_component ();
+ output = g_string_new ("");
+diff --git a/src/setup.c b/src/setup.c
+index 7442159..0fe6e1b 100644
+--- a/src/setup.c
++++ b/src/setup.c
+@@ -83,6 +83,7 @@ parse_value (MPlist *plist, gchar *text)
+ if (mplist_key (plist) == Minteger) {
+ long val;
+
++ errno = 0;
+ val = strtol (text, NULL, 10);
+ if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN))
+ || (errno != 0 && val == 0))
diff --git a/ibus-m17n-iok.patch b/ibus-m17n-iok.patch
index b3c9adc..c6e4ca2 100644
--- a/ibus-m17n-iok.patch
+++ b/ibus-m17n-iok.patch
@@ -1,20 +1,46 @@
+From 17e633c3e3cbfd1a240b95352167005a8396a7b2 Mon Sep 17 00:00:00 2001
+From: Daiki Ueno <ueno at unixuser.org>
+Date: Wed, 8 Dec 2010 18:06:11 +0900
+Subject: [PATCH] Apply iok patch from fedora.
+
+---
+ src/engine.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
+ 1 files changed, 46 insertions(+), 0 deletions(-)
+
diff --git a/src/engine.c b/src/engine.c
-index 260a806..abeeeef 100644
+index f8e7fe5..ff8bbfc 100644
--- a/src/engine.c
+++ b/src/engine.c
-@@ -19,6 +19,8 @@ struct _IBusM17NEngine {
+@@ -35,6 +35,7 @@ struct _IBusM17NEngine {
+ IBusProperty *status_prop;
IBusProperty *setup_prop;
IBusPropList *prop_list;
- gchar *config_section;
+ IBusProperty *show_iok_prop;
-+ gchar *keymap_name;
};
struct _IBusM17NEngineClass {
-@@ -218,10 +220,23 @@ ibus_m17n_engine_init (IBusM17NEngine *m17n)
+@@ -411,6 +412,8 @@ ibus_m17n_engine_init (IBusM17NEngine *m17n)
+ {
+ IBusText* label;
+ IBusText* tooltip;
++ const gchar *engine_name;
++ gchar *lang = NULL, *name = NULL;
+
+ m17n->status_prop = ibus_property_new ("status",
+ PROP_TYPE_NORMAL,
+@@ -436,10 +439,32 @@ ibus_m17n_engine_init (IBusM17NEngine *m17n)
NULL);
g_object_ref_sink (m17n->setup_prop);
++ /* show iok icon for inscript - should be go in default.xml? */
++ engine_name = ibus_engine_get_name ((IBusEngine *) m17n);
++ if (ibus_m17n_scan_engine_name (engine_name, &lang, &name) &&
++ (g_strcmp0 (name, "inscript") == 0 ||
++ g_strcmp0 (name, "inscript2") == 0))
++ ibus_property_set_visible (m17n->show_iok_prop, TRUE);
++ g_free (lang);
++ g_free (name);
++
+ label = ibus_text_new_from_string ("iok");
+ m17n->show_iok_prop = ibus_property_new ("iok",
+ PROP_TYPE_NORMAL,
@@ -35,26 +61,7 @@ index 260a806..abeeeef 100644
m17n->table = ibus_lookup_table_new (9, 0, TRUE, TRUE);
g_object_ref_sink (m17n->table);
-@@ -248,6 +263,7 @@ ibus_m17n_engine_constructor (GType type,
-
- engine_name = ibus_engine_get_name ((IBusEngine *) m17n);
- g_assert (engine_name);
-+ m17n->keymap_name = g_strdup (engine_name);
-
- strv = g_strsplit (engine_name, ":", 3);
-
-@@ -257,6 +273,10 @@ ibus_m17n_engine_constructor (GType type,
- lang = strv[1];
- name = strv[2];
-
-+ /* show iok icon for inscript */
-+ if(strcmp (name, "inscript") == 0 || strcmp (name , "inscript2") == 0)
-+ ibus_property_set_visible (m17n->show_iok_prop, TRUE);
-+
- if (im_table == NULL) {
- im_table = g_hash_table_new_full (g_str_hash,
- g_str_equal,
-@@ -369,6 +389,11 @@ ibus_m17n_engine_destroy (IBusM17NEngine *m17n)
+@@ -524,6 +549,11 @@ ibus_m17n_engine_destroy (IBusM17NEngine *m17n)
m17n->setup_prop = NULL;
}
@@ -66,23 +73,29 @@ index 260a806..abeeeef 100644
if (m17n->table) {
g_object_unref (m17n->table);
m17n->table = NULL;
-@@ -669,6 +694,19 @@ ibus_m17n_engine_property_activate (IBusEngine *engine,
+@@ -827,6 +857,22 @@ ibus_m17n_engine_property_activate (IBusEngine *engine,
LIBEXECDIR, engine_name);
g_spawn_command_line_async (setup, NULL);
g_free (setup);
+ } else if (g_strcmp0 (prop_name, "iok") == 0) {
-+ gchar **strv;
-+ gchar cmd[80];
-+
-+ strv = g_strsplit (m17n->keymap_name, ":", 3);
-+ g_assert (g_strv_length (strv) == 3);
-+ g_assert (g_strcmp0 (strv[0], "m17n") == 0);
++ const gchar *engine_name;
++ gchar *lang = NULL, *name = NULL;
+
-+ sprintf (cmd, "/usr/bin/iok -n %s", strv[1]);
-+ g_debug ("keymap name = %s,prop_name=%s, prop_state=%d", m17n->keymap_name, prop_name, prop_state);
-+ g_strfreev (strv);
++ engine_name = ibus_engine_get_name ((IBusEngine *) m17n);
++ if (ibus_m17n_scan_engine_name (engine_name, &lang, &name)) {
++ gchar *iok;
+
-+ g_spawn_command_line_async(cmd, NULL);
++ iok = g_strdup_printf ("/usr/bin/iok -n %s", lang);
++ g_debug ("keymap name = %s,prop_name=%s, prop_state=%d",
++ engine_name, prop_name, prop_state);
++ g_spawn_command_line_async(iok, NULL);
++ g_free (iok);
++ }
++ g_free (lang);
++ g_free (name);
}
parent_class->property_activate (engine, prop_name, prop_state);
}
+--
+1.7.3.3
+
diff --git a/ibus-m17n.spec b/ibus-m17n.spec
index 5f0df1c..6ff4bdf 100644
--- a/ibus-m17n.spec
+++ b/ibus-m17n.spec
@@ -2,16 +2,17 @@
Name: ibus-m17n
Version: 1.3.1
-Release: 5%{?dist}
+Release: 8%{?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-iok.patch
-Patch1: ibus-m17n-surrounding-text.patch
-Patch2: ibus-m17n-fedora.patch
+Patch0: ibus-m17n-HEAD.patch
+Patch1: ibus-m17n-iok.patch
+# IBus surrounding-text support is not yet available in F-13.
+# Patch2: ibus-m17n-surrounding-text.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: gettext-devel
@@ -19,6 +20,7 @@ BuildRequires: libtool
BuildRequires: pkgconfig
BuildRequires: m17n-lib-devel
BuildRequires: gtk2-devel
+BuildRequires: gnome-common
BuildRequires: ibus-devel >= %{require_ibus_version}
Requires: ibus >= %{require_ibus_version}
@@ -32,9 +34,10 @@ the input table maps from m17n-db.
%prep
%setup -q
%patch0 -p1
+%patch1 -p1
# IBus surrounding-text support is not yet available in F-13.
-# %patch1 -p1
-%patch2 -p1
+# %patch2 -p1
+NOCONFIGURE=1 ./autogen.sh
%build
%configure --disable-static
@@ -59,6 +62,22 @@ rm -rf $RPM_BUILD_ROOT
%{_datadir}/ibus/component/*
%changelog
+* Fri Dec 10 2010 Daiki Ueno <dueno at redhat.com> - 1.3.1-8
+- Update ibus-m17n-HEAD.patch.
+- Lower si-samanala.mim rank per request from a Sinhala user.
+
+* Wed Dec 8 2010 Daiki Ueno <dueno at redhat.com> - 1.3.1-7
+- Update ibus-m17n-HEAD.patch.
+- Fix bug 658336 - ibus-m17n: define the IM ranks in a config file and
+ not in a compiled binary
+
+* Fri Nov 5 2010 Daiki Ueno <dueno at redhat.com> - 1.3.1-6
+- Rename ibus-m17n-fedora.patch to ibus-m17n-HEAD.patch since the
+ changes are merged into upstream.
+- Update ibus-m17n-HEAD.patch with upstream fix 08e06310
+- Fix bug 649230 - [si] last input character is committed late in
+ wijesekara input method
+
* Tue Oct 12 2010 Daiki Ueno <dueno at redhat.com> - 1.3.1-5
- put several Fedora patches into one.
- Fix bug 640896 - Ibus does not load all the keymaps for a language
More information about the i18n-bugs
mailing list