diff -pruN gtk+-2.12.3.orig/gdk/win32/gdkproperty-win32.c gtk+-2.12.3/gdk/win32/gdkproperty-win32.c
--- gtk+-2.12.3.orig/gdk/win32/gdkproperty-win32.c	2007-12-05 01:52:39.000000000 +0900
+++ gtk+-2.12.3/gdk/win32/gdkproperty-win32.c	2007-12-07 23:45:26.000000000 +0900
@@ -353,6 +353,7 @@ gdk_property_delete (GdkWindow *window,
   { "Gtk/ToolbarIconSize", "gtk-toolbar-icon-size" },
   { "Gtk/IMPreeditStyle", "gtk-im-preedit-style" },
   { "Gtk/IMStatusStyle", "gtk-im-status-style" },
+  { "Gtk/IMModule", "gtk-im-module" },
   { "Net/CursorBlink", "gtk-cursor-blink" },
   { "Net/CursorBlinkTime", "gtk-cursor-blink-time" },
   { "Net/ThemeName", "gtk-theme-name" },
diff -pruN gtk+-2.12.3.orig/gdk/x11/gdksettings.c gtk+-2.12.3/gdk/x11/gdksettings.c
--- gtk+-2.12.3.orig/gdk/x11/gdksettings.c	2007-12-05 01:52:39.000000000 +0900
+++ gtk+-2.12.3/gdk/x11/gdksettings.c	2007-12-07 23:46:26.000000000 +0900
@@ -65,7 +65,8 @@ static const char gdk_settings_names[] =
   "Xft/RGBA\0"                "gtk-xft-rgba\0"
   "Xft/DPI\0"                 "gtk-xft-dpi\0"
   "Net/FallbackIconTheme\0"   "gtk-fallback-icon-theme\0"
-  "Gtk/TouchscreenMode\0"     "gtk-touchscreen-mode\0";
+  "Gtk/TouchscreenMode\0"     "gtk-touchscreen-mode\0"
+  "Gtk/IMModule\0"            "gtk-im-module\0";
 
 static const struct
 {
@@ -107,5 +108,6 @@ static const struct
   { 1197, 1206 },
   { 1219, 1227 },
   { 1239, 1261 },
-  { 1285, 1305 }
+  { 1285, 1305 },
+  { 1326, 1339 }
 };
diff -pruN gtk+-2.12.3.orig/gtk/gtkimmodule.c gtk+-2.12.3/gtk/gtkimmodule.c
--- gtk+-2.12.3.orig/gtk/gtkimmodule.c	2007-12-05 01:52:09.000000000 +0900
+++ gtk+-2.12.3/gtk/gtkimmodule.c	2007-12-07 23:45:26.000000000 +0900
@@ -614,3 +614,43 @@ _gtk_im_module_get_default_context_id (c
   
   return g_strdup (context_id ? context_id : SIMPLE_ID);
 }
+
+/**
+ * _gtk_im_module_get_default_context_id_from_settings:
+ * @widget: a #GtkWidget
+ * @locale: a locale id in the form 'en_US'
+ *
+ * Return the context_id of the IM context type from XSETTINGS first
+ * if no preferrable IM is set, then pick one up for the given locale ID.
+ *
+ * Return value: the context ID (will never be %NULL)
+ *    the value is newly allocated and must be freed
+ *    with g_free().
+ **/
+const gchar *
+_gtk_im_module_get_default_context_id_from_settings(GdkWindow   *client_window,
+						    const gchar *locale)
+{
+  GtkSettings *settings;
+  const gchar *context_id = NULL;
+  GdkScreen *screen;
+
+  if (client_window == NULL)
+    g_warning("No client window is set.");
+  if (client_window == NULL ||
+      !GDK_IS_DRAWABLE (client_window))
+    return _gtk_im_module_get_default_context_id (locale);
+  screen = gdk_drawable_get_screen(GDK_DRAWABLE (client_window));
+  if (screen)
+    settings = gtk_settings_get_for_screen (screen);
+  else
+    settings = gtk_settings_get_default ();
+
+  g_object_get (G_OBJECT (settings), "gtk-im-module", &context_id, NULL);
+  if (context_id &&
+      (strcmp (context_id, SIMPLE_ID) == 0 ||
+       g_hash_table_lookup (contexts_hash, context_id)))
+    return g_strdup(context_id);
+
+  return _gtk_im_module_get_default_context_id (locale);
+}
diff -pruN gtk+-2.12.3.orig/gtk/gtkimmodule.h gtk+-2.12.3/gtk/gtkimmodule.h
--- gtk+-2.12.3.orig/gtk/gtkimmodule.h	2007-12-05 01:52:09.000000000 +0900
+++ gtk+-2.12.3/gtk/gtkimmodule.h	2007-12-07 23:45:26.000000000 +0900
@@ -42,6 +42,8 @@ void          _gtk_im_module_list       
 						    guint                    *n_contexts);
 GtkIMContext *_gtk_im_module_create                 (const gchar             *context_id);
 const gchar * _gtk_im_module_get_default_context_id (const gchar             *lang);
+const gchar * _gtk_im_module_get_default_context_id_from_settings (GdkWindow   *client_window,
+								   const gchar *locale);
 
 /* The following entry points are exported by each input method module
  */
diff -pruN gtk+-2.12.3.orig/gtk/gtkimmulticontext.c gtk+-2.12.3/gtk/gtkimmulticontext.c
--- gtk+-2.12.3.orig/gtk/gtkimmulticontext.c	2007-12-05 01:52:08.000000000 +0900
+++ gtk+-2.12.3/gtk/gtkimmulticontext.c	2007-12-07 23:45:26.000000000 +0900
@@ -34,6 +34,7 @@ struct _GtkIMMulticontextPrivate
 {
   GdkWindow *client_window;
   GdkRectangle cursor_location;
+  GtkSettings *settings;
 
   guint use_preedit : 1;
   guint have_cursor_location : 1;
@@ -120,6 +121,8 @@ gtk_im_multicontext_init (GtkIMMulticont
   multicontext->priv->use_preedit = TRUE;
   multicontext->priv->have_cursor_location = FALSE;
   multicontext->priv->focus_in = FALSE;
+  multicontext->priv->client_window = NULL;
+  multicontext->priv->settings = NULL;
 }
 
 /**
@@ -227,7 +230,7 @@ gtk_im_multicontext_get_slave (GtkIMMult
       if (!global_context_id)
 	{
 	  gchar *locale = _gtk_get_lc_ctype ();
-	  global_context_id = _gtk_im_module_get_default_context_id (locale);
+	  global_context_id = _gtk_im_module_get_default_context_id_from_settings (multicontext->priv->client_window, locale);
 	  g_free (locale);
 	}
 	
@@ -242,14 +245,52 @@ gtk_im_multicontext_get_slave (GtkIMMult
 }
 
 static void
+gtk_im_multicontext_changes_im_module (GtkIMMulticontext *multicontext)
+{
+  GtkIMContext *slave;
+
+  gtk_im_multicontext_set_slave (multicontext, NULL, TRUE);
+  g_free (global_context_id);
+  global_context_id = NULL;
+  slave = gtk_im_multicontext_get_slave (multicontext);
+}
+
+static void
 gtk_im_multicontext_set_client_window (GtkIMContext *context,
 				       GdkWindow    *window)
 {
   GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
   
-  GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
+  GtkIMContext *slave;
+
+  if (GDK_IS_DRAWABLE (window))
+    {
+      GdkScreen *screen = gdk_drawable_get_screen (GDK_DRAWABLE (window));
+
+      if (multicontext->priv->settings)
+        {
+		g_signal_handlers_disconnect_by_func (multicontext->priv->settings,
+						      G_CALLBACK (gtk_im_multicontext_changes_im_module),
+						      multicontext);
+	}
+      if (screen)
+        multicontext->priv->settings = gtk_settings_get_for_screen (screen);
+      else
+	multicontext->priv->settings = gtk_settings_get_default ();
 
+      g_signal_connect_swapped (multicontext->priv->settings, "notify::gtk-im-module",
+				G_CALLBACK (gtk_im_multicontext_changes_im_module),
+				multicontext);
+
+      /* destroy the slave and the global_context_id because it might
+       * be set the different thing from XSETTINGS
+       */
+      gtk_im_multicontext_set_slave (multicontext, NULL, TRUE);
+      g_free (global_context_id);
+      global_context_id = NULL;
+    }
   multicontext->priv->client_window = window;
+  slave = gtk_im_multicontext_get_slave (multicontext);
   
   if (slave)
     gtk_im_context_set_client_window (slave, window);
diff -pruN gtk+-2.12.3.orig/gtk/gtksettings.c gtk+-2.12.3/gtk/gtksettings.c
--- gtk+-2.12.3.orig/gtk/gtksettings.c	2007-12-05 01:52:08.000000000 +0900
+++ gtk+-2.12.3/gtk/gtksettings.c	2007-12-07 23:45:26.000000000 +0900
@@ -106,7 +106,8 @@ enum {
   PROP_PRINT_PREVIEW_COMMAND,
   PROP_ENABLE_MNEMONICS,
   PROP_ENABLE_ACCELS,
-  PROP_RECENT_FILES_LIMIT
+  PROP_RECENT_FILES_LIMIT,
+  PROP_IM_MODULE
 };
 
 
@@ -805,6 +806,20 @@ gtk_settings_class_init (GtkSettingsClas
  							       GTK_PARAM_READWRITE),
 					     NULL);
   g_assert (result == PROP_RECENT_FILES_LIMIT);
+
+  /**
+   * GtkSettings:gtk-im-module:
+   *
+   * Which IM module should be used by default.
+   */
+  result = settings_install_property_parser (class,
+					     g_param_spec_string ("gtk-im-module",
+								  P_("Default IM module"),
+								  P_("Which IM module should be used by default"),
+								  NULL,
+								  GTK_PARAM_READWRITE),
+					     NULL);
+  g_assert (result == PROP_IM_MODULE);
 }
 
 static void
