[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