Index: gtk/gtk.symbols
===================================================================
--- gtk/gtk.symbols	(révision 19090)
+++ gtk/gtk.symbols	(copie de travail)
@@ -1978,6 +1982,7 @@ gtk_im_context_simple_new
 #if IN_HEADER(__GTK_IM_MULTICONTEXT_H__)
 #if IN_FILE(__GTK_IM_MULTICONTEXT_C__)
 gtk_im_multicontext_append_menuitems
+gtk_im_multicontext_merge_ui
 gtk_im_multicontext_get_type G_GNUC_CONST
 gtk_im_multicontext_new
 #endif
Index: gtk/gtkimmulticontext.c
===================================================================
--- gtk/gtkimmulticontext.c	(révision 19090)
+++ gtk/gtkimmulticontext.c	(copie de travail)
@@ -26,6 +26,7 @@
 #include "gtkimmodule.h"
 #include "gtkmain.h"
 #include "gtkradiomenuitem.h"
+#include "gtkradioaction.h"
 #include "gtkintl.h"
 #include "gtkprivate.h" /* To get redefinition of GTK_LOCALE_DIR on Win32 */
 #include "gtkalias.h"
@@ -484,6 +485,67 @@ pathnamecmp (const char *a,
 #endif
 }
 
+static const gchar *
+context_info_get_display_name (const GtkIMContextInfo *context)
+{
+  const gchar *translated_name;
+
+#ifdef ENABLE_NLS
+  if (context->domain && context->domain[0])
+    {
+      if (strcmp (context->domain, GETTEXT_PACKAGE) == 0)
+        {
+          /* Same translation domain as GTK+ */
+          if (!(context->domain_dirname && context->domain_dirname[0]) ||
+              pathnamecmp (context->domain_dirname, GTK_LOCALEDIR) == 0)
+            {
+              /* Empty or NULL, domain directory, or same as
+                * GTK+. Input method may have a name in the GTK+
+                * message catalog.
+                */
+              translated_name = _(context->context_name);
+            }
+          else
+            {
+              /* Separate domain directory but the same
+                * translation domain as GTK+. We can't call
+                * bindtextdomain() as that would make GTK+ forget
+                * its own messages.
+                */
+              g_warning ("Input method %s should not use GTK's translation domain %s",
+                          context->context_id, GETTEXT_PACKAGE);
+              /* Try translating the name in GTK+'s domain */
+              translated_name = _(context->context_name);
+            }
+        }
+      else if (context->domain_dirname && context->domain_dirname[0])
+        /* Input method has own translation domain and message catalog */
+        {
+          bindtextdomain (context->domain,
+                          context->domain_dirname);
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+          bind_textdomain_codeset (context->domain, "UTF-8");
+#endif
+          translated_name = dgettext (context->domain, context->context_name);
+        }
+      else
+        {
+          /* Different translation domain, but no domain directory */
+          translated_name = context->context_name;
+        }
+    }
+  else
+    /* Empty or NULL domain. We assume that input method does not
+      * want a translated name in this case.
+      */
+    translated_name = context->context_name;
+#else
+  translated_name = context->context_name;
+#endif
+
+  return translated_name;
+}
+
 /**
  * gtk_im_multicontext_append_menuitems:
  * @context: a #GtkIMMultiContext
@@ -507,58 +569,8 @@ gtk_im_multicontext_append_menuitems (Gt
     {
       GtkWidget *menuitem;
       const gchar *translated_name;
-#ifdef ENABLE_NLS
-      if (contexts[i]->domain && contexts[i]->domain[0])
-	{
-	  if (strcmp (contexts[i]->domain, GETTEXT_PACKAGE) == 0)
-	    {
-	      /* Same translation domain as GTK+ */
-	      if (!(contexts[i]->domain_dirname && contexts[i]->domain_dirname[0]) ||
-		  pathnamecmp (contexts[i]->domain_dirname, GTK_LOCALEDIR) == 0)
-		{
-		  /* Empty or NULL, domain directory, or same as
-		   * GTK+. Input method may have a name in the GTK+
-		   * message catalog.
-		   */
-		  translated_name = _(contexts[i]->context_name);
-		}
-	      else
-		{
-		  /* Separate domain directory but the same
-		   * translation domain as GTK+. We can't call
-		   * bindtextdomain() as that would make GTK+ forget
-		   * its own messages.
-		   */
-		  g_warning ("Input method %s should not use GTK's translation domain %s",
-			     contexts[i]->context_id, GETTEXT_PACKAGE);
-		  /* Try translating the name in GTK+'s domain */
-		  translated_name = _(contexts[i]->context_name);
-		}
-	    }
-	  else if (contexts[i]->domain_dirname && contexts[i]->domain_dirname[0])
-	    /* Input method has own translation domain and message catalog */
-	    {
-	      bindtextdomain (contexts[i]->domain,
-			      contexts[i]->domain_dirname);
-#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
-	      bind_textdomain_codeset (contexts[i]->domain, "UTF-8");
-#endif
-	      translated_name = dgettext (contexts[i]->domain, contexts[i]->context_name);
-	    }
-	  else
-	    {
-	      /* Different translation domain, but no domain directory */
-	      translated_name = contexts[i]->context_name;
-	    }
-	}
-      else
-	/* Empty or NULL domain. We assume that input method does not
-	 * want a translated name in this case.
-	 */
-	translated_name = contexts[i]->context_name;
-#else
-      translated_name = contexts[i]->context_name;
-#endif
+
+      translated_name = context_info_get_display_name (contexts[i]);
       menuitem = gtk_radio_menu_item_new_with_label (group,
 						     translated_name);
       
@@ -582,5 +594,101 @@ gtk_im_multicontext_append_menuitems (Gt
   g_free (contexts);
 }
 
+static void
+action_activate_cb (GtkToggleAction *action,
+                    GtkIMMulticontext *context)
+{
+  const gchar *id;
+
+  if (!gtk_toggle_action_get_active (action))
+    return;
+
+  id = g_object_get_data (G_OBJECT (action), "gtk-context-id");
+  gtk_im_context_reset (GTK_IM_CONTEXT (context));
+      
+  global_context_id = id;
+  gtk_im_multicontext_set_slave (context, NULL, FALSE);
+}
+
+/**
+ * gtk_im_multicontext_merge_ui:
+ * @context: a #GtkIMMulticontext
+ * @ui_manager: a #GtkUIManager
+ * @group_name: the name to use when creating the #GtkActionGroup
+ * @ui_path: the path where to merge the UI in @ui_manager
+ * @group: a location to return the newly created #GtkActionGroup
+ *
+ * Creates a #GtkActionGroup with name @group_name, and inserts it into
+ * @ui_manager. The UI manager will hold a reference; @group will not own
+ * a references.
+ * Adds #GtkAction s for various available input methods to the action group,
+ * and creates the menu items at the specified UI path @ui_path.
+ *
+ * Return value: the ID of the merged UI in @ui_manager
+ */
+guint
+gtk_im_multicontext_merge_ui (GtkIMMulticontext *context,
+                              GtkUIManager *ui_manager,
+                              const gchar *group_name,
+                              const gchar *ui_path,
+                              GtkActionGroup **group)
+{
+  GtkActionGroup *action_group;
+  guint ui_id;
+  const GtkIMContextInfo **contexts;
+  guint n_contexts, i;
+  GSList *radio_group = NULL;
+
+  g_return_val_if_fail (GTK_IS_IM_MULTICONTEXT (context), 0);
+  g_return_val_if_fail (GTK_IS_UI_MANAGER (ui_manager), 0);
+  g_return_val_if_fail (group_name != NULL, 0);
+  g_return_val_if_fail (ui_path != NULL, 0);
+
+  *group = action_group = gtk_action_group_new (group_name);
+  gtk_ui_manager_insert_action_group (ui_manager, action_group, -1);
+  g_object_unref (action_group);
+
+  ui_id = gtk_ui_manager_new_merge_id (ui_manager);
+
+  _gtk_im_module_list (&contexts, &n_contexts);
+  for (i = 0; i < n_contexts; i++)
+    {
+      GtkAction *action;
+      gchar action_name[32];
+      const gchar *translated_name;
+
+      g_snprintf (action_name, sizeof (action_name), "GtkIMAction%u", i);
+      translated_name = context_info_get_display_name (contexts[i]);
+      action = GTK_ACTION (gtk_radio_action_new (action_name,
+                                                 translated_name,
+                                                 NULL,
+                                                 NULL,
+                                                 i));
+      if ((global_context_id == NULL && group == NULL) ||
+          (global_context_id &&
+           strcmp (contexts[i]->context_id, global_context_id) == 0))
+        gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), TRUE);
+
+      gtk_radio_action_set_group (GTK_RADIO_ACTION (action), radio_group);
+      radio_group = gtk_radio_action_get_group (GTK_RADIO_ACTION (action));
+      
+      g_object_set_data (G_OBJECT (action), I_("gtk-context-id"),
+			 (char *) contexts[i]->context_id);
+      g_signal_connect (action, "toggled",
+			G_CALLBACK (action_activate_cb), context);
+
+      gtk_action_group_add_action_with_accel (action_group, action, "");
+      g_object_unref (action);
+
+      gtk_ui_manager_add_ui (ui_manager, ui_id, ui_path,
+                             action_name, action_name,
+                             GTK_UI_MANAGER_MENUITEM, FALSE);
+    }
+
+  g_free (contexts);
+
+  return ui_id;
+}
+
 #define __GTK_IM_MULTICONTEXT_C__
 #include "gtkaliasdef.c"
Index: gtk/gtkimmulticontext.h
===================================================================
--- gtk/gtkimmulticontext.h	(révision 19090)
+++ gtk/gtkimmulticontext.h	(copie de travail)
@@ -22,6 +22,7 @@
 
 #include <gtk/gtkimcontext.h>
 #include <gtk/gtkmenushell.h>
+#include <gtk/gtkuimanager.h>
 
 G_BEGIN_DECLS
 
@@ -65,6 +66,12 @@ GtkIMContext *gtk_im_multicontext_new   
 void          gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
 						    GtkMenuShell      *menushell);
 
+guint         gtk_im_multicontext_merge_ui (GtkIMMulticontext *context,
+                                            GtkUIManager *ui_manager,
+                                            const gchar *group_name,
+                                            const gchar *ui_path,
+                                            GtkActionGroup **group);
+
 G_END_DECLS
 
 #endif /* __GTK_IM_MULTICONTEXT_H__ */
