Remove the XIM input method
authorEmmanuele Bassi <ebassi@gnome.org>
Sat, 16 Nov 2019 21:05:25 +0000 (21:05 +0000)
committerEmmanuele Bassi <ebassi@gnome.org>
Sat, 16 Nov 2019 21:05:25 +0000 (21:05 +0000)
It's old and busted, and mostly broken in weird ways when it comes to
extended input devices. All that XIM does, these days, is make a mess
when people enable it by mistake.

gtk/gtkimcontextxim.c [deleted file]
gtk/gtkimcontextxim.h [deleted file]
gtk/gtkimmodule.c
gtk/meson.build

diff --git a/gtk/gtkimcontextxim.c b/gtk/gtkimcontextxim.c
deleted file mode 100644 (file)
index e4b747a..0000000
+++ /dev/null
@@ -1,1696 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2000 Red Hat, Inc.
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#include "config.h"
-#include "locale.h"
-#include <string.h>
-#include <stdlib.h>
-
-#include "gtkimcontextxim.h"
-#include "gtkimmoduleprivate.h"
-#include "gtknative.h"
-
-#include "gtk/gtkintl.h"
-
-typedef struct _StatusWindow StatusWindow;
-typedef struct _GtkXIMInfo GtkXIMInfo;
-
-struct _GtkIMContextXIM
-{
-  GtkIMContext object;
-
-  GtkXIMInfo *im_info;
-
-  gchar *locale;
-  gchar *mb_charset;
-
-  GdkSurface *client_surface;
-  Window client_surface_xid;
-  GtkWidget *client_widget;
-
-  /* The status window for this input context; we claim the
-   * status window when we are focused and have created an XIC
-   */
-  StatusWindow *status_window;
-
-  gint preedit_size;
-  gint preedit_length;
-  gunichar *preedit_chars;
-  XIMFeedback *feedbacks;
-
-  gint preedit_cursor;
-
-  XIMCallback preedit_start_callback;
-  XIMCallback preedit_done_callback;
-  XIMCallback preedit_draw_callback;
-  XIMCallback preedit_caret_callback;
-
-  XIMCallback status_start_callback;
-  XIMCallback status_done_callback;
-  XIMCallback status_draw_callback;
-
-  XIMCallback string_conversion_callback;
-
-  XIC ic;
-
-  guint filter_key_release : 1;
-  guint use_preedit : 1;
-  guint finalizing : 1;
-  guint in_toplevel : 1;
-  guint has_focus : 1;
-};
-
-struct _GtkXIMInfo
-{
-  GdkDisplay *display;
-  XIM im;
-  char *locale;
-  XIMStyle preedit_style_setting;
-  XIMStyle status_style_setting;
-  XIMStyle style;
-  GtkSettings *settings;
-  gulong status_set;
-  gulong preedit_set;
-  gulong display_closed_cb;
-  XIMStyles *xim_styles;
-  GSList *ics;
-
-  guint reconnecting :1;
-  guint supports_string_conversion;
-};
-
-/* A context status window; these are kept in the status_windows list. */
-struct _StatusWindow
-{
-  GtkWidget *window;
-
-  /* Toplevel window to which the status window corresponds */
-  GtkWidget *toplevel;
-
-  /* Currently focused GtkIMContextXIM for the toplevel, if any */
-  GtkIMContextXIM *context;
-};
-
-static void     gtk_im_context_xim_finalize           (GObject               *obj);
-static void     gtk_im_context_xim_set_client_widget  (GtkIMContext          *context,
-                                                       GtkWidget             *widget);
-static gboolean gtk_im_context_xim_filter_keypress    (GtkIMContext          *context,
-                                                      GdkEventKey           *key);
-static void     gtk_im_context_xim_reset              (GtkIMContext          *context);
-static void     gtk_im_context_xim_focus_in           (GtkIMContext          *context);
-static void     gtk_im_context_xim_focus_out          (GtkIMContext          *context);
-static void     gtk_im_context_xim_set_cursor_location (GtkIMContext          *context,
-                                                      GdkRectangle             *area);
-static void     gtk_im_context_xim_set_use_preedit    (GtkIMContext          *context,
-                                                      gboolean               use_preedit);
-static void     gtk_im_context_xim_get_preedit_string (GtkIMContext          *context,
-                                                      gchar                **str,
-                                                      PangoAttrList        **attrs,
-                                                      gint                  *cursor_pos);
-
-static void reinitialize_ic      (GtkIMContextXIM *context_xim);
-static void set_ic_client_surface (GtkIMContextXIM *context_xim,
-                                 GdkSurface       *client_surface);
-
-static void setup_styles (GtkXIMInfo *info);
-
-static void update_client_widget   (GtkIMContextXIM *context_xim);
-static void update_status_window   (GtkIMContextXIM *context_xim);
-
-static StatusWindow *status_window_get      (GtkWidget    *toplevel);
-static void          status_window_free     (StatusWindow *status_window);
-static void          status_window_set_text (StatusWindow *status_window,
-                                            const gchar  *text);
-
-static void xim_destroy_callback   (XIM      xim,
-                                   XPointer client_data,
-                                   XPointer call_data);
-
-static XIC       gtk_im_context_xim_get_ic            (GtkIMContextXIM *context_xim);
-static void           xim_info_display_closed (GdkDisplay *display,
-                                              gboolean    is_error,
-                                              GtkXIMInfo *info);
-
-G_DEFINE_TYPE_WITH_CODE (GtkIMContextXIM, gtk_im_context_xim, GTK_TYPE_IM_CONTEXT,
-                        gtk_im_module_ensure_extension_point ();
-                         g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
-                                                         g_define_type_id,
-                                                         "xim",
-                                                         0))
-
-static GSList *open_ims = NULL;
-
-/* List of status windows for different toplevels */
-static GSList *status_windows = NULL;
-
-#define PREEDIT_MASK (XIMPreeditCallbacks | XIMPreeditPosition | \
-                     XIMPreeditArea | XIMPreeditNothing | XIMPreeditNone)
-#define STATUS_MASK (XIMStatusCallbacks | XIMStatusArea | \
-                     XIMStatusNothing | XIMStatusNone)
-#define ALLOWED_MASK (XIMPreeditCallbacks | XIMPreeditNothing | XIMPreeditNone | \
-                     XIMStatusCallbacks | XIMStatusNothing | XIMStatusNone)
-
-static XIMStyle
-choose_better_style (XIMStyle style1, XIMStyle style2)
-{
-  XIMStyle s1, s2, u;
-
-  if (style1 == 0) return style2;
-  if (style2 == 0) return style1;
-  if ((style1 & (PREEDIT_MASK | STATUS_MASK))
-       == (style2 & (PREEDIT_MASK | STATUS_MASK)))
-    return style1;
-
-  s1 = style1 & PREEDIT_MASK;
-  s2 = style2 & PREEDIT_MASK;
-  u = s1 | s2;
-  if (s1 != s2) {
-    if (u & XIMPreeditCallbacks)
-      return (s1 == XIMPreeditCallbacks) ? style1 : style2;
-    else if (u & XIMPreeditPosition)
-      return (s1 == XIMPreeditPosition) ? style1 :style2;
-    else if (u & XIMPreeditArea)
-      return (s1 == XIMPreeditArea) ? style1 : style2;
-    else if (u & XIMPreeditNothing)
-      return (s1 == XIMPreeditNothing) ? style1 : style2;
-    else if (u & XIMPreeditNone)
-      return (s1 == XIMPreeditNone) ? style1 : style2;
-  } else {
-    s1 = style1 & STATUS_MASK;
-    s2 = style2 & STATUS_MASK;
-    u = s1 | s2;
-    if (u & XIMStatusCallbacks)
-      return (s1 == XIMStatusCallbacks) ? style1 : style2;
-    else if (u & XIMStatusArea)
-      return (s1 == XIMStatusArea) ? style1 : style2;
-    else if (u & XIMStatusNothing)
-      return (s1 == XIMStatusNothing) ? style1 : style2;
-    else if (u & XIMStatusNone)
-      return (s1 == XIMStatusNone) ? style1 : style2;
-  }
-  return 0; /* Get rid of stupid warning */
-}
-
-static void
-reinitialize_all_ics (GtkXIMInfo *info)
-{
-  GSList *tmp_list;
-
-  for (tmp_list = info->ics; tmp_list; tmp_list = tmp_list->next)
-    reinitialize_ic (tmp_list->data);
-}
-
-static void
-setup_styles (GtkXIMInfo *info)
-{
-  int i;
-  unsigned long settings_preference;
-  XIMStyles *xim_styles = info->xim_styles;
-
-  settings_preference = info->status_style_setting|info->preedit_style_setting;
-  info->style = 0;
-  if (xim_styles)
-    {
-      for (i = 0; i < xim_styles->count_styles; i++)
-       if ((xim_styles->supported_styles[i] & ALLOWED_MASK) == xim_styles->supported_styles[i])
-         {
-           if (settings_preference == xim_styles->supported_styles[i])
-             {
-               info->style = settings_preference;
-               break;
-             }
-           info->style = choose_better_style (info->style,
-                                              xim_styles->supported_styles[i]);
-         }
-    }
-  if (info->style == 0)
-    info->style = XIMPreeditNothing | XIMStatusNothing;
-}
-
-static void
-setup_im (GtkXIMInfo *info)
-{
-  XIMValuesList *ic_values = NULL;
-  XIMCallback im_destroy_callback;
-  GdkDisplay *display;
-
-  if (info->im == NULL)
-    return;
-
-  im_destroy_callback.client_data = (XPointer)info;
-  im_destroy_callback.callback = (XIMProc)xim_destroy_callback;
-  XSetIMValues (info->im,
-               XNDestroyCallback, &im_destroy_callback,
-               NULL);
-
-  XGetIMValues (info->im,
-               XNQueryInputStyle, &info->xim_styles,
-               XNQueryICValuesList, &ic_values,
-               NULL);
-
-  info->supports_string_conversion = FALSE;
-  if (ic_values)
-    {
-      int i;
-
-      for (i = 0; i < ic_values->count_values; i++)
-       if (strcmp (ic_values->supported_values[i],
-                   XNStringConversionCallback) == 0)
-         {
-           info->supports_string_conversion = TRUE;
-           break;
-         }
-
-#if 0
-      for (i = 0; i < ic_values->count_values; i++)
-       g_print ("%s\n", ic_values->supported_values[i]);
-      for (i = 0; i < xim_styles->count_styles; i++)
-       g_print ("%#x\n", xim_styles->supported_styles[i]);
-#endif
-
-      XFree (ic_values);
-    }
-
-  info->status_style_setting = XIMStatusCallbacks;
-  info->preedit_style_setting = XIMPreeditCallbacks;
-  setup_styles (info);
-  reinitialize_all_ics (info);
-
-  display = info->display;
-  info->display_closed_cb = g_signal_connect (display, "closed",
-                                             G_CALLBACK (xim_info_display_closed), info);
-}
-
-static void
-xim_info_display_closed (GdkDisplay *display,
-                        gboolean    is_error,
-                        GtkXIMInfo *info)
-{
-  GSList *ics, *tmp_list;
-
-  open_ims = g_slist_remove (open_ims, info);
-
-  ics = info->ics;
-  info->ics = NULL;
-
-  for (tmp_list = ics; tmp_list; tmp_list = tmp_list->next)
-    set_ic_client_surface (tmp_list->data, NULL);
-
-  g_slist_free (ics);
-
-  if (info->status_set)
-    g_signal_handler_disconnect (info->settings, info->status_set);
-  if (info->preedit_set)
-    g_signal_handler_disconnect (info->settings, info->preedit_set);
-  if (info->display_closed_cb)
-    g_signal_handler_disconnect (display, info->display_closed_cb);
-
-  if (info->xim_styles)
-    XFree (info->xim_styles);
-  g_free (info->locale);
-
-  if (info->im)
-    XCloseIM (info->im);
-
-  g_free (info);
-}
-
-static void
-xim_instantiate_callback (Display *display, XPointer client_data,
-                         XPointer call_data)
-{
-  GtkXIMInfo *info = (GtkXIMInfo*)client_data;
-  XIM im = NULL;
-
-  im = XOpenIM (display, NULL, NULL, NULL);
-
-  if (!im)
-    return;
-
-  info->im = im;
-  setup_im (info);
-
-  XUnregisterIMInstantiateCallback (display, NULL, NULL, NULL,
-                                   xim_instantiate_callback,
-                                   (XPointer)info);
-  info->reconnecting = FALSE;
-}
-
-/* initialize info->im */
-static void
-xim_info_try_im (GtkXIMInfo *info)
-{
-  GdkDisplay *display = info->display;
-
-  g_assert (info->im == NULL);
-  if (info->reconnecting)
-    return;
-
-  if (XSupportsLocale ())
-    {
-      if (!XSetLocaleModifiers (""))
-       g_warning ("Unable to set locale modifiers with XSetLocaleModifiers()");
-      info->im = XOpenIM (GDK_DISPLAY_XDISPLAY (display), NULL, NULL, NULL);
-      if (!info->im)
-       {
-         XRegisterIMInstantiateCallback (GDK_DISPLAY_XDISPLAY(display),
-                                         NULL, NULL, NULL,
-                                         xim_instantiate_callback,
-                                         (XPointer)info);
-         info->reconnecting = TRUE;
-         return;
-       }
-      setup_im (info);
-    }
-}
-
-static void
-xim_destroy_callback (XIM      xim,
-                     XPointer client_data,
-                     XPointer call_data)
-{
-  GtkXIMInfo *info = (GtkXIMInfo*)client_data;
-
-  info->im = NULL;
-
-  g_signal_handler_disconnect (info->settings, info->status_set);
-  info->status_set = 0;
-  g_signal_handler_disconnect (info->settings, info->preedit_set);
-  info->preedit_set = 0;
-
-  reinitialize_all_ics (info);
-  xim_info_try_im (info);
-  return;
-}
-
-static GtkXIMInfo *
-get_im (GdkSurface *client_surface,
-       const char *locale)
-{
-  GSList *tmp_list;
-  GtkXIMInfo *info;
-  GdkDisplay *display = gdk_surface_get_display (client_surface);
-
-  info = NULL;
-  tmp_list = open_ims;
-  while (tmp_list)
-    {
-      GtkXIMInfo *tmp_info = tmp_list->data;
-      if (tmp_info->display == display &&
-         g_strcmp0 (tmp_info->locale, locale) == 0)
-       {
-         if (tmp_info->im)
-           {
-             return tmp_info;
-           }
-         else
-           {
-             break;
-           }
-       }
-      tmp_list = tmp_list->next;
-    }
-
-  if (info == NULL)
-    {
-      info = g_new (GtkXIMInfo, 1);
-      open_ims = g_slist_prepend (open_ims, info);
-
-      info->display = display;
-      info->locale = g_strdup (locale);
-      info->xim_styles = NULL;
-      info->preedit_style_setting = 0;
-      info->status_style_setting = 0;
-      info->settings = NULL;
-      info->preedit_set = 0;
-      info->status_set = 0;
-      info->display_closed_cb = 0;
-      info->ics = NULL;
-      info->reconnecting = FALSE;
-      info->im = NULL;
-    }
-
-  xim_info_try_im (info);
-  return info;
-}
-
-static void
-gtk_im_context_xim_class_init (GtkIMContextXIMClass *class)
-{
-  GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);
-  GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-
-  im_context_class->set_client_widget = gtk_im_context_xim_set_client_widget;
-  im_context_class->filter_keypress = gtk_im_context_xim_filter_keypress;
-  im_context_class->reset = gtk_im_context_xim_reset;
-  im_context_class->get_preedit_string = gtk_im_context_xim_get_preedit_string;
-  im_context_class->focus_in = gtk_im_context_xim_focus_in;
-  im_context_class->focus_out = gtk_im_context_xim_focus_out;
-  im_context_class->set_cursor_location = gtk_im_context_xim_set_cursor_location;
-  im_context_class->set_use_preedit = gtk_im_context_xim_set_use_preedit;
-  gobject_class->finalize = gtk_im_context_xim_finalize;
-}
-
-static void
-gtk_im_context_xim_init (GtkIMContextXIM *im_context_xim)
-{
-  const char *charset;
-
-  im_context_xim->use_preedit = TRUE;
-  im_context_xim->filter_key_release = FALSE;
-  im_context_xim->finalizing = FALSE;
-  im_context_xim->has_focus = FALSE;
-  im_context_xim->in_toplevel = FALSE;
-
-  im_context_xim->locale = g_strdup (setlocale (LC_CTYPE, NULL));
-
-  g_get_charset (&charset);
-  im_context_xim->mb_charset = g_strdup (charset);
-}
-
-static void
-gtk_im_context_xim_finalize (GObject *obj)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (obj);
-
-  context_xim->finalizing = TRUE;
-
-  if (context_xim->im_info && !context_xim->im_info->ics->next)
-    {
-      if (context_xim->im_info->reconnecting)
-       {
-         GdkDisplay *display;
-
-         display = context_xim->im_info->display;
-         XUnregisterIMInstantiateCallback (GDK_DISPLAY_XDISPLAY (display),
-                                           NULL, NULL, NULL,
-                                           xim_instantiate_callback,
-                                           (XPointer)context_xim->im_info);
-       }
-      else if (context_xim->im_info->im)
-       {
-         XIMCallback im_destroy_callback;
-
-         im_destroy_callback.client_data = NULL;
-         im_destroy_callback.callback = NULL;
-         XSetIMValues (context_xim->im_info->im,
-                       XNDestroyCallback, &im_destroy_callback,
-                       NULL);
-       }
-    }
-
-  set_ic_client_surface (context_xim, NULL);
-
-  g_free (context_xim->locale);
-  g_free (context_xim->mb_charset);
-
-  G_OBJECT_CLASS (gtk_im_context_xim_parent_class)->finalize (obj);
-}
-
-static void
-reinitialize_ic (GtkIMContextXIM *context_xim)
-{
-  if (context_xim->ic)
-    {
-      XDestroyIC (context_xim->ic);
-      context_xim->ic = NULL;
-      update_status_window (context_xim);
-
-      if (context_xim->preedit_length)
-       {
-         context_xim->preedit_length = 0;
-         if (!context_xim->finalizing)
-           g_signal_emit_by_name (context_xim, "preedit-changed");
-       }
-    }
-  /*
-     reset filter_key_release flag, otherwise keystrokes will be doubled
-     until reconnecting to XIM.
-  */
-  context_xim->filter_key_release = FALSE;
-}
-
-static void
-set_ic_client_surface (GtkIMContextXIM *context_xim,
-                     GdkSurface       *client_surface)
-{
-  reinitialize_ic (context_xim);
-  if (context_xim->client_surface)
-    {
-      context_xim->im_info->ics = g_slist_remove (context_xim->im_info->ics, context_xim);
-      context_xim->im_info = NULL;
-    }
-
-  context_xim->client_surface = client_surface;
-  context_xim->client_surface_xid = None;
-
-  if (context_xim->client_surface)
-    {
-      context_xim->im_info = get_im (context_xim->client_surface, context_xim->locale);
-      context_xim->im_info->ics = g_slist_prepend (context_xim->im_info->ics, context_xim);
-      context_xim->client_surface_xid = gdk_x11_surface_get_xid (client_surface);
-    }
-
-  update_client_widget (context_xim);
-}
-
-static void
-gtk_im_context_xim_set_client_widget (GtkIMContext *context,
-                                      GtkWidget    *widget)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-  GdkSurface *surface = NULL;
-
-  if (widget != NULL)
-    surface = gtk_native_get_surface (gtk_widget_get_native (widget));
-
-  set_ic_client_surface (context_xim, surface);
-}
-
-static char *
-mb_to_utf8 (GtkIMContextXIM *context_xim,
-           const char      *str)
-{
-  GError *error = NULL;
-  gchar *result;
-
-  if (strcmp (context_xim->mb_charset, "UTF-8") == 0)
-    result = g_strdup (str);
-  else
-    {
-      result = g_convert (str, -1,
-                         "UTF-8", context_xim->mb_charset,
-                         NULL, NULL, &error);
-      if (!result)
-       {
-         g_warning ("Error converting text from IM to UTF-8: %s\n", error->message);
-         g_error_free (error);
-       }
-    }
-
-  return result;
-}
-
-static gboolean
-gtk_im_context_xim_filter_keypress (GtkIMContext *context,
-                                   GdkEventKey  *event)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-  XIC ic = gtk_im_context_xim_get_ic (context_xim);
-  gchar static_buffer[256];
-  gchar *buffer = static_buffer;
-  gint buffer_size = sizeof(static_buffer) - 1;
-  gint num_bytes = 0;
-  KeySym keysym;
-  Status status;
-  gboolean result = FALSE;
-  GdkSurface *window;
-  XKeyPressedEvent xevent;
-  GdkEventType event_type;
-  guint state;
-
-  event_type = gdk_event_get_event_type ((GdkEvent *) event);
-
-  if (!gdk_event_get_state ((GdkEvent *) event, &state))
-    return GDK_EVENT_PROPAGATE;
-
-  if (event_type == GDK_KEY_RELEASE && !context_xim->filter_key_release)
-    return FALSE;
-
-  window = gdk_event_get_surface ((GdkEvent *) event);
-
-  xevent.type = (event_type == GDK_KEY_PRESS) ? KeyPress : KeyRelease;
-  xevent.serial = 0;           /* hope it doesn't matter */
-  xevent.send_event = gdk_event_is_sent ((GdkEvent *)event);
-  xevent.display = GDK_SURFACE_XDISPLAY (window);
-  xevent.window = GDK_SURFACE_XID (window);
-  xevent.root = DefaultRootWindow(GDK_SURFACE_XDISPLAY (window));
-  xevent.subwindow = xevent.window;
-  xevent.time = gdk_event_get_time ((GdkEvent *) event);
-  xevent.x = xevent.x_root = 0;
-  xevent.y = xevent.y_root = 0;
-  xevent.state = state;
-  xevent.keycode = gdk_event_get_scancode ((GdkEvent *) event);
-  xevent.same_screen = True;
-
-  if (XFilterEvent ((XEvent *)&xevent, context_xim->client_surface_xid))
-    return TRUE;
-
-  if (state &
-      (gtk_accelerator_get_default_mod_mask () & ~(GDK_SHIFT_MASK | GDK_CONTROL_MASK)))
-    return FALSE;
-
- again:
-  if (ic)
-    num_bytes = XmbLookupString (ic, &xevent, buffer, buffer_size, &keysym, &status);
-  else
-    {
-      num_bytes = XLookupString (&xevent, buffer, buffer_size, &keysym, NULL);
-      status = XLookupBoth;
-    }
-
-  if (status == XBufferOverflow)
-    {
-      buffer_size = num_bytes;
-      if (buffer != static_buffer)
-       g_free (buffer);
-      buffer = g_malloc (num_bytes + 1);
-      goto again;
-    }
-
-  /* I don't know how we should properly handle XLookupKeysym or XLookupBoth
-   * here ... do input methods actually change the keysym? we can't really
-   * feed it back to accelerator processing at this point...
-   */
-  if (status == XLookupChars || status == XLookupBoth)
-    {
-      char *result_utf8;
-
-      buffer[num_bytes] = '\0';
-
-      result_utf8 = mb_to_utf8 (context_xim, buffer);
-      if (result_utf8)
-       {
-         if ((guchar)result_utf8[0] >= 0x20 &&
-             result_utf8[0] != 0x7f) /* Some IM have a nasty habit of converting
-                                      * control characters into strings
-                                      */
-           {
-             g_signal_emit_by_name (context, "commit", result_utf8);
-             result = TRUE;
-           }
-
-         g_free (result_utf8);
-       }
-    }
-
-  if (buffer != static_buffer)
-    g_free (buffer);
-
-  return result;
-}
-
-static void
-gtk_im_context_xim_focus_in (GtkIMContext *context)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-
-  if (!context_xim->has_focus)
-    {
-      XIC ic = gtk_im_context_xim_get_ic (context_xim);
-
-      context_xim->has_focus = TRUE;
-      update_status_window (context_xim);
-
-      if (ic)
-       XSetICFocus (ic);
-    }
-
-  return;
-}
-
-static void
-gtk_im_context_xim_focus_out (GtkIMContext *context)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-
-  if (context_xim->has_focus)
-    {
-      XIC ic = gtk_im_context_xim_get_ic (context_xim);
-
-      context_xim->has_focus = FALSE;
-      update_status_window (context_xim);
-
-      if (ic)
-       XUnsetICFocus (ic);
-    }
-
-  return;
-}
-
-static void
-gtk_im_context_xim_set_cursor_location (GtkIMContext *context,
-                                       GdkRectangle *area)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-  XIC ic = gtk_im_context_xim_get_ic (context_xim);
-
-  XVaNestedList preedit_attr;
-  XPoint          spot;
-
-  if (!ic)
-    return;
-
-  spot.x = area->x;
-  spot.y = area->y + area->height;
-
-  preedit_attr = XVaCreateNestedList (0,
-                                     XNSpotLocation, &spot,
-                                     NULL);
-  XSetICValues (ic,
-               XNPreeditAttributes, preedit_attr,
-               NULL);
-  XFree(preedit_attr);
-
-  return;
-}
-
-static void
-gtk_im_context_xim_set_use_preedit (GtkIMContext *context,
-                                   gboolean      use_preedit)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-
-  use_preedit = use_preedit != FALSE;
-
-  if (context_xim->use_preedit != use_preedit)
-    {
-      context_xim->use_preedit = use_preedit;
-      reinitialize_ic (context_xim);
-    }
-
-  return;
-}
-
-static void
-gtk_im_context_xim_reset (GtkIMContext *context)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-  XIC ic = gtk_im_context_xim_get_ic (context_xim);
-  gchar *result;
-
-  /* restore conversion state after resetting ic later */
-  XIMPreeditState preedit_state = XIMPreeditUnKnown;
-  XVaNestedList preedit_attr;
-  gboolean have_preedit_state = FALSE;
-
-  if (!ic)
-    return;
-
-
-  if (context_xim->preedit_length == 0)
-    return;
-
-  preedit_attr = XVaCreateNestedList(0,
-                                     XNPreeditState, &preedit_state,
-                                     NULL);
-  if (!XGetICValues(ic,
-                    XNPreeditAttributes, preedit_attr,
-                    NULL))
-    have_preedit_state = TRUE;
-
-  XFree(preedit_attr);
-
-  result = XmbResetIC (ic);
-
-  preedit_attr = XVaCreateNestedList(0,
-                                     XNPreeditState, preedit_state,
-                                     NULL);
-  if (have_preedit_state)
-    XSetICValues(ic,
-                XNPreeditAttributes, preedit_attr,
-                NULL);
-
-  XFree(preedit_attr);
-
-  if (result)
-    {
-      char *result_utf8 = mb_to_utf8 (context_xim, result);
-      if (result_utf8)
-       {
-         g_signal_emit_by_name (context, "commit", result_utf8);
-         g_free (result_utf8);
-       }
-    }
-
-  if (context_xim->preedit_length)
-    {
-      context_xim->preedit_length = 0;
-      g_signal_emit_by_name (context, "preedit-changed");
-    }
-
-  XFree (result);
-}
-
-/* Mask of feedback bits that we render
- */
-#define FEEDBACK_MASK (XIMReverse | XIMUnderline)
-
-static void
-add_feedback_attr (PangoAttrList *attrs,
-                  const gchar   *str,
-                  XIMFeedback    feedback,
-                  gint           start_pos,
-                  gint           end_pos)
-{
-  PangoAttribute *attr;
-
-  gint start_index = g_utf8_offset_to_pointer (str, start_pos) - str;
-  gint end_index = g_utf8_offset_to_pointer (str, end_pos) - str;
-
-  if (feedback & XIMUnderline)
-    {
-      attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
-      attr->start_index = start_index;
-      attr->end_index = end_index;
-
-      pango_attr_list_change (attrs, attr);
-    }
-
-  if (feedback & XIMReverse)
-    {
-      attr = pango_attr_foreground_new (0xffff, 0xffff, 0xffff);
-      attr->start_index = start_index;
-      attr->end_index = end_index;
-
-      pango_attr_list_change (attrs, attr);
-
-      attr = pango_attr_background_new (0, 0, 0);
-      attr->start_index = start_index;
-      attr->end_index = end_index;
-
-      pango_attr_list_change (attrs, attr);
-    }
-
-  if (feedback & ~FEEDBACK_MASK)
-    g_warning ("Unrendered feedback style: %#lx", feedback & ~FEEDBACK_MASK);
-}
-
-static void
-gtk_im_context_xim_get_preedit_string (GtkIMContext   *context,
-                                      gchar         **str,
-                                      PangoAttrList **attrs,
-                                      gint           *cursor_pos)
-{
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-  gchar *utf8 = g_ucs4_to_utf8 (context_xim->preedit_chars, context_xim->preedit_length, NULL, NULL, NULL);
-
-  if (attrs)
-    {
-      int i;
-      XIMFeedback last_feedback = 0;
-      gint start = -1;
-
-      *attrs = pango_attr_list_new ();
-
-      for (i = 0; i < context_xim->preedit_length; i++)
-       {
-         XIMFeedback new_feedback = context_xim->feedbacks[i] & FEEDBACK_MASK;
-         if (new_feedback != last_feedback)
-           {
-             if (start >= 0)
-               add_feedback_attr (*attrs, utf8, last_feedback, start, i);
-
-             last_feedback = new_feedback;
-             start = i;
-           }
-       }
-
-      if (start >= 0)
-       add_feedback_attr (*attrs, utf8, last_feedback, start, i);
-    }
-
-  if (str)
-    *str = utf8;
-  else
-    g_free (utf8);
-
-  if (cursor_pos)
-    *cursor_pos = context_xim->preedit_cursor;
-}
-
-static int
-preedit_start_callback (XIC      xic,
-                       XPointer client_data,
-                       XPointer call_data)
-{
-  GtkIMContext *context = GTK_IM_CONTEXT (client_data);
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-
-  if (!context_xim->finalizing)
-    g_signal_emit_by_name (context, "preedit-start");
-
-  return -1;                   /* No length limit */
-}
-
-static void
-preedit_done_callback (XIC      xic,
-                    XPointer client_data,
-                    XPointer call_data)
-{
-  GtkIMContext *context = GTK_IM_CONTEXT (client_data);
-  GtkIMContextXIM *context_xim = GTK_IM_CONTEXT_XIM (context);
-
-  if (context_xim->preedit_length)
-    {
-      context_xim->preedit_length = 0;
-      if (!context_xim->finalizing)
-       g_signal_emit_by_name (context_xim, "preedit-changed");
-    }
-
-  if (!context_xim->finalizing)
-    g_signal_emit_by_name (context, "preedit-end");
-}
-
-static gint
-xim_text_to_utf8 (GtkIMContextXIM *context, XIMText *xim_text, gchar **text)
-{
-  gint text_length = 0;
-  GError *error = NULL;
-  gchar *result = NULL;
-
-  if (xim_text && xim_text->string.multi_byte)
-    {
-      if (xim_text->encoding_is_wchar)
-       {
-         g_warning ("Wide character return from Xlib not currently supported");
-         *text = NULL;
-         return 0;
-       }
-
-      if (strcmp (context->mb_charset, "UTF-8") == 0)
-       result = g_strdup (xim_text->string.multi_byte);
-      else
-       result = g_convert (xim_text->string.multi_byte,
-                           -1,
-                           "UTF-8",
-                           context->mb_charset,
-                           NULL, NULL, &error);
-
-      if (result)
-       {
-         text_length = g_utf8_strlen (result, -1);
-
-         if (text_length != xim_text->length)
-           {
-             g_warning ("Size mismatch when converting text from input method: supplied length = %d\n, result length = %d", xim_text->length, text_length);
-           }
-       }
-      else
-       {
-         g_warning ("Error converting text from IM to UCS-4: %s", error->message);
-         g_error_free (error);
-
-         *text = NULL;
-         return 0;
-       }
-
-      *text = result;
-      return text_length;
-    }
-  else
-    {
-      *text = NULL;
-      return 0;
-    }
-}
-
-static void
-preedit_draw_callback (XIC                           xic,
-                      XPointer                      client_data,
-                      XIMPreeditDrawCallbackStruct *call_data)
-{
-  GtkIMContextXIM *context = GTK_IM_CONTEXT_XIM (client_data);
-
-  XIMText *new_xim_text = call_data->text;
-  gint new_text_length;
-  gunichar *new_text = NULL;
-  gint i;
-  gint diff;
-  gint new_length;
-  gchar *tmp;
-
-  gint chg_first = CLAMP (call_data->chg_first, 0, context->preedit_length);
-  gint chg_length = CLAMP (call_data->chg_length, 0, context->preedit_length - chg_first);
-
-  context->preedit_cursor = call_data->caret;
-
-  if (chg_first != call_data->chg_first || chg_length != call_data->chg_length)
-    g_warning ("Invalid change to preedit string, first=%d length=%d (orig length == %d)",
-              call_data->chg_first, call_data->chg_length, context->preedit_length);
-
-  new_text_length = xim_text_to_utf8 (context, new_xim_text, &tmp);
-  if (tmp)
-    {
-      new_text = g_utf8_to_ucs4_fast (tmp, -1, NULL);
-      g_free (tmp);
-    }
-
-  diff = new_text_length - chg_length;
-  new_length = context->preedit_length + diff;
-
-  if (new_length > context->preedit_size)
-    {
-      context->preedit_size = new_length;
-      context->preedit_chars = g_renew (gunichar, context->preedit_chars, new_length);
-      context->feedbacks = g_renew (XIMFeedback, context->feedbacks, new_length);
-    }
-
-  if (diff < 0)
-    {
-      for (i = chg_first + chg_length ; i < context->preedit_length; i++)
-       {
-         context->preedit_chars[i + diff] = context->preedit_chars[i];
-         context->feedbacks[i + diff] = context->feedbacks[i];
-       }
-    }
-  else
-    {
-      for (i = context->preedit_length - 1; i >= chg_first + chg_length ; i--)
-       {
-         context->preedit_chars[i + diff] = context->preedit_chars[i];
-         context->feedbacks[i + diff] = context->feedbacks[i];
-       }
-    }
-
-  for (i = 0; i < new_text_length; i++)
-    {
-      context->preedit_chars[chg_first + i] = new_text[i];
-      context->feedbacks[chg_first + i] = new_xim_text->feedback[i];
-    }
-
-  context->preedit_length += diff;
-
-  g_free (new_text);
-
-  if (!context->finalizing)
-    g_signal_emit_by_name (context, "preedit-changed");
-}
-
-
-static void
-preedit_caret_callback (XIC                            xic,
-                       XPointer                       client_data,
-                       XIMPreeditCaretCallbackStruct *call_data)
-{
-  GtkIMContextXIM *context = GTK_IM_CONTEXT_XIM (client_data);
-
-  if (call_data->direction == XIMAbsolutePosition)
-    {
-      context->preedit_cursor = call_data->position;
-      if (!context->finalizing)
-       g_signal_emit_by_name (context, "preedit-changed");
-    }
-  else
-    {
-      g_warning ("Caret movement command: %d %d %d not supported",
-                call_data->position, call_data->direction, call_data->style);
-    }
-}
-
-static void
-status_start_callback (XIC      xic,
-                      XPointer client_data,
-                      XPointer call_data)
-{
-  return;
-}
-
-static void
-status_done_callback (XIC      xic,
-                     XPointer client_data,
-                     XPointer call_data)
-{
-  return;
-}
-
-static void
-status_draw_callback (XIC      xic,
-                     XPointer client_data,
-                     XIMStatusDrawCallbackStruct *call_data)
-{
-  GtkIMContextXIM *context = GTK_IM_CONTEXT_XIM (client_data);
-
-  if (call_data->type == XIMTextType)
-    {
-      gchar *text;
-      xim_text_to_utf8 (context, call_data->data.text, &text);
-
-      if (context->status_window)
-       status_window_set_text (context->status_window, text ? text : "");
-    }
-  else                         /* bitmap */
-    {
-      g_print ("Status drawn with bitmap - id = %#lx\n", call_data->data.bitmap);
-    }
-}
-
-static void
-string_conversion_callback (XIC xic, XPointer client_data, XPointer call_data)
-{
-  GtkIMContextXIM *context_xim;
-  XIMStringConversionCallbackStruct *conv_data;
-  gchar *surrounding;
-  gint  cursor_index;
-
-  context_xim = (GtkIMContextXIM *)client_data;
-  conv_data = (XIMStringConversionCallbackStruct *)call_data;
-
-  if (gtk_im_context_get_surrounding ((GtkIMContext *)context_xim,
-                                      &surrounding, &cursor_index))
-    {
-      gchar *text = NULL;
-      gsize text_len = 0;
-      gint  subst_offset = 0, subst_nchars = 0;
-      gint  i;
-      gchar *p = surrounding + cursor_index, *q;
-      gshort position = (gshort)conv_data->position;
-
-      if (position > 0)
-        {
-          for (i = position; i > 0 && *p; --i)
-            p = g_utf8_next_char (p);
-          if (i > 0)
-            return;
-        }
-      /* According to X11R6.4 Xlib - C Library Reference Manual
-       * section 13.5.7.3 String Conversion Callback,
-       * XIMStringConversionPosition is starting position _relative_
-       * to current client's cursor position. So it should be able
-       * to be negative, or referring to a position before the cursor
-       * would be impossible. But current X protocol defines this as
-       * unsigned short. So, compiler may warn about the value range
-       * here. We hope the X protocol is fixed soon.
-       */
-      else if (position < 0)
-        {
-          for (i = position; i < 0 && p > surrounding; ++i)
-            p = g_utf8_prev_char (p);
-          if (i < 0)
-            return;
-        }
-
-      switch (conv_data->direction)
-        {
-        case XIMForwardChar:
-          for (i = conv_data->factor, q = p; i > 0 && *q; --i)
-            q = g_utf8_next_char (q);
-          if (i > 0)
-            break;
-          text = g_locale_from_utf8 (p, q - p, NULL, &text_len, NULL);
-          subst_offset = position;
-          subst_nchars = conv_data->factor;
-          break;
-
-        case XIMBackwardChar:
-          for (i = conv_data->factor, q = p; i > 0 && q > surrounding; --i)
-            q = g_utf8_prev_char (q);
-          if (i > 0)
-            break;
-          text = g_locale_from_utf8 (q, p - q, NULL, &text_len, NULL);
-          subst_offset = position - conv_data->factor;
-          subst_nchars = conv_data->factor;
-          break;
-
-        case XIMForwardWord:
-        case XIMBackwardWord:
-        case XIMCaretUp:
-        case XIMCaretDown:
-        case XIMNextLine:
-        case XIMPreviousLine:
-        case XIMLineStart:
-        case XIMLineEnd:
-        case XIMAbsolutePosition:
-        case XIMDontChange:
-        default:
-          break;
-        }
-      /* block out any failure happenning to "text", including conversion */
-      if (text)
-        {
-          conv_data->text = (XIMStringConversionText *)
-                              malloc (sizeof (XIMStringConversionText));
-          if (conv_data->text)
-            {
-              conv_data->text->length = text_len;
-              conv_data->text->feedback = NULL;
-              conv_data->text->encoding_is_wchar = False;
-              conv_data->text->string.mbs = (char *)malloc (text_len);
-              if (conv_data->text->string.mbs)
-                memcpy (conv_data->text->string.mbs, text, text_len);
-              else
-                {
-                  free (conv_data->text);
-                  conv_data->text = NULL;
-                }
-            }
-
-          g_free (text);
-        }
-      if (conv_data->operation == XIMStringConversionSubstitution
-          && subst_nchars > 0)
-        {
-          gtk_im_context_delete_surrounding ((GtkIMContext *)context_xim,
-                                            subst_offset, subst_nchars);
-        }
-
-      g_free (surrounding);
-    }
-}
-
-
-static XVaNestedList
-set_preedit_callback (GtkIMContextXIM *context_xim)
-{
-  context_xim->preedit_start_callback.client_data = (XPointer)context_xim;
-  context_xim->preedit_start_callback.callback = (XIMProc)preedit_start_callback;
-  context_xim->preedit_done_callback.client_data = (XPointer)context_xim;
-  context_xim->preedit_done_callback.callback = (XIMProc)preedit_done_callback;
-  context_xim->preedit_draw_callback.client_data = (XPointer)context_xim;
-  context_xim->preedit_draw_callback.callback = (XIMProc)preedit_draw_callback;
-  context_xim->preedit_caret_callback.client_data = (XPointer)context_xim;
-  context_xim->preedit_caret_callback.callback = (XIMProc)preedit_caret_callback;
-  return XVaCreateNestedList (0,
-                             XNPreeditStartCallback, &context_xim->preedit_start_callback,
-                             XNPreeditDoneCallback, &context_xim->preedit_done_callback,
-                             XNPreeditDrawCallback, &context_xim->preedit_draw_callback,
-                             XNPreeditCaretCallback, &context_xim->preedit_caret_callback,
-                             NULL);
-}
-
-static XVaNestedList
-set_status_callback (GtkIMContextXIM *context_xim)
-{
-  context_xim->status_start_callback.client_data = (XPointer)context_xim;
-  context_xim->status_start_callback.callback = (XIMProc)status_start_callback;
-  context_xim->status_done_callback.client_data = (XPointer)context_xim;
-  context_xim->status_done_callback.callback = (XIMProc)status_done_callback;
-  context_xim->status_draw_callback.client_data = (XPointer)context_xim;
-  context_xim->status_draw_callback.callback = (XIMProc)status_draw_callback;
-
-  return XVaCreateNestedList (0,
-                             XNStatusStartCallback, &context_xim->status_start_callback,
-                             XNStatusDoneCallback, &context_xim->status_done_callback,
-                             XNStatusDrawCallback, &context_xim->status_draw_callback,
-                             NULL);
-}
-
-
-static void
-set_string_conversion_callback (GtkIMContextXIM *context_xim, XIC xic)
-{
-  if (!context_xim->im_info->supports_string_conversion)
-    return;
-
-  context_xim->string_conversion_callback.client_data = (XPointer)context_xim;
-  context_xim->string_conversion_callback.callback = (XIMProc)string_conversion_callback;
-
-  XSetICValues (xic,
-               XNStringConversionCallback,
-               (XPointer)&context_xim->string_conversion_callback,
-               NULL);
-}
-
-static XIC
-gtk_im_context_xim_get_ic (GtkIMContextXIM *context_xim)
-{
-  if (context_xim->im_info == NULL || context_xim->im_info->im == NULL)
-    return NULL;
-
-  if (!context_xim->ic)
-    {
-      const char *name1 = NULL;
-      XVaNestedList list1 = NULL;
-      const char *name2 = NULL;
-      XVaNestedList list2 = NULL;
-      XIMStyle im_style = 0;
-      XIC xic = NULL;
-
-      if (context_xim->use_preedit &&
-         (context_xim->im_info->style & PREEDIT_MASK) == XIMPreeditCallbacks)
-       {
-         im_style |= XIMPreeditCallbacks;
-         name1 = XNPreeditAttributes;
-         list1 = set_preedit_callback (context_xim);
-       }
-      else if ((context_xim->im_info->style & PREEDIT_MASK) == XIMPreeditNone)
-       im_style |= XIMPreeditNone;
-      else
-       im_style |= XIMPreeditNothing;
-
-      if ((context_xim->im_info->style & STATUS_MASK) == XIMStatusCallbacks)
-       {
-         im_style |= XIMStatusCallbacks;
-         if (name1 == NULL)
-           {
-             name1 = XNStatusAttributes;
-             list1 = set_status_callback (context_xim);
-           }
-         else
-           {
-             name2 = XNStatusAttributes;
-             list2 = set_status_callback (context_xim);
-           }
-       }
-      else if ((context_xim->im_info->style & STATUS_MASK) == XIMStatusNone)
-       im_style |= XIMStatusNone;
-      else
-       im_style |= XIMStatusNothing;
-
-      xic = XCreateIC (context_xim->im_info->im,
-                      XNInputStyle, im_style,
-                      XNClientWindow, context_xim->client_surface_xid,
-                      name1, list1,
-                      name2, list2,
-                      NULL);
-      if (list1)
-       XFree (list1);
-      if (list2)
-       XFree (list2);
-
-      if (xic)
-       {
-         /* Don't filter key released events with XFilterEvents unless
-          * input methods ask for. This is a workaround for Solaris input
-          * method bug in C and European locales. It doubles each key
-          * stroke if both key pressed and released events are filtered.
-          * (bugzilla #81759)
-          */
-         gulong mask = 0xaaaaaaaa;
-         XGetICValues (xic,
-                       XNFilterEvents, &mask,
-                       NULL);
-         context_xim->filter_key_release = (mask & KeyReleaseMask) != 0;
-         set_string_conversion_callback (context_xim, xic);
-       }
-
-      context_xim->ic = xic;
-
-      update_status_window (context_xim);
-
-      if (xic && context_xim->has_focus)
-       XSetICFocus (xic);
-    }
-  return context_xim->ic;
-}
-
-/*****************************************************************
- * Status Window handling
- *
- * A status window is a small window attached to the toplevel
- * that is used to display information to the user about the
- * current input operation.
- *
- * We claim the toplevel's status window for an input context if:
- *
- * A) The input context has a toplevel
- * B) The input context has the focus
- * C) The input context has an XIC associated with it
- *
- * Tracking A) and C) is pretty reliable since we
- * compute A) and create the XIC for C) ourselves.
- * For B) we basically have to depend on our callers
- * calling ::focus-in and ::focus-out at the right time.
- *
- * The toplevel is computed by walking up the GdkSurface
- * hierarchy from context->client_surface until we find a
- * window that is owned by some widget, and then calling
- * gtk_widget_get_root() on that widget. This should
- * handle both cases where we might have GdkSurfaces without widgets,
- * and cases where GtkWidgets have strange window hierarchies
- * (like a torn off GtkHandleBox.)
- *
- * The status window is visible if and only if there is text
- * for it; whenever a new GtkIMContextXIM claims the status
- * window, we blank out any existing text. We actually only
- * create a GtkWindow for the status window the first time
- * it is shown; this is an important optimization when we are
- * using XIM with something like a simple compose-key input
- * method that never needs a status window.
- *****************************************************************/
-
-/* Called when we no longer need a status window
-*/
-static void
-disclaim_status_window (GtkIMContextXIM *context_xim)
-{
-  if (context_xim->status_window)
-    {
-      g_assert (context_xim->status_window->context == context_xim);
-
-      status_window_set_text (context_xim->status_window, "");
-
-      context_xim->status_window->context = NULL;
-      context_xim->status_window = NULL;
-    }
-}
-
-/* Called when we need a status window
- */
-static void
-claim_status_window (GtkIMContextXIM *context_xim)
-{
-  if (!context_xim->status_window && context_xim->client_widget)
-    {
-      GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (context_xim->client_widget));
-      if (toplevel)
-       {
-         StatusWindow *status_window = status_window_get (toplevel);
-
-         if (status_window->context)
-           disclaim_status_window (status_window->context);
-
-         status_window->context = context_xim;
-         context_xim->status_window = status_window;
-       }
-    }
-}
-
-/* Basic call made whenever something changed that might cause
- * us to need, or not to need a status window.
- */
-static void
-update_status_window (GtkIMContextXIM *context_xim)
-{
-  if (context_xim->ic && context_xim->in_toplevel && context_xim->has_focus)
-    claim_status_window (context_xim);
-  else
-    disclaim_status_window (context_xim);
-}
-
-/* Updates the in_toplevel flag for @context_xim
- */
-static void
-update_in_toplevel (GtkIMContextXIM *context_xim)
-{
-  if (context_xim->client_widget)
-    {
-      GtkWidget *toplevel = GTK_WIDGET (gtk_widget_get_root (context_xim->client_widget));
-
-      context_xim->in_toplevel = toplevel != NULL;
-    }
-  else
-    context_xim->in_toplevel = FALSE;
-
-  /* Some paranoia, in case we don't get a focus out */
-  if (!context_xim->in_toplevel)
-    context_xim->has_focus = FALSE;
-
-  update_status_window (context_xim);
-}
-
-/* Callback when @widget's toplevel changes. It will always
- * change from NULL to a window, or a window to NULL;
- * we use that intermediate NULL state to make sure
- * that we disclaim the toplevel status window for the old
- * window.
- */
-static void
-on_client_widget_hierarchy_changed (GtkWidget       *widget,
-                                   GParamSpec      *pspec,
-                                   GtkIMContextXIM *context_xim)
-{
-  update_in_toplevel (context_xim);
-}
-
-/* Called when context_xim->client_surface changes; takes care of
- * removing and/or setting up our watches for the toplevel
- */
-static void
-update_client_widget (GtkIMContextXIM *context_xim)
-{
-  GtkWidget *new_client_widget = NULL;
-
-  if (context_xim->client_surface)
-    new_client_widget = gtk_native_get_for_surface (context_xim->client_surface);
-
-  if (new_client_widget != context_xim->client_widget)
-    {
-      if (context_xim->client_widget)
-       {
-         g_signal_handlers_disconnect_by_func (context_xim->client_widget,
-                                               G_CALLBACK (on_client_widget_hierarchy_changed),
-                                               context_xim);
-       }
-      context_xim->client_widget = new_client_widget;
-      if (context_xim->client_widget)
-       {
-         g_signal_connect (context_xim->client_widget, "notify::root",
-                           G_CALLBACK (on_client_widget_hierarchy_changed),
-                           context_xim);
-       }
-
-      update_in_toplevel (context_xim);
-    }
-}
-
-/* Called when the toplevel is destroyed; frees the status window
- */
-static void
-on_status_toplevel_destroy (GtkWidget    *toplevel,
-                           StatusWindow *status_window)
-{
-  status_window_free (status_window);
-}
-
-/* Called when the screen for the toplevel changes; updates the
- * screen for the status window to match.
- */
-static void
-on_status_toplevel_notify_display (GtkWindow    *toplevel,
-                                  GParamSpec   *pspec,
-                                  StatusWindow *status_window)
-{
-  if (status_window->window)
-    gtk_window_set_display (GTK_WINDOW (status_window->window),
-                           gtk_widget_get_display (GTK_WIDGET (toplevel)));
-}
-
-/* Frees a status window and removes its link from the status_windows list
- */
-static void
-status_window_free (StatusWindow *status_window)
-{
-  status_windows = g_slist_remove (status_windows, status_window);
-
-  if (status_window->context)
-    status_window->context->status_window = NULL;
-
-  g_signal_handlers_disconnect_by_func (status_window->toplevel,
-                                       G_CALLBACK (on_status_toplevel_destroy),
-                                       status_window);
-  g_signal_handlers_disconnect_by_func (status_window->toplevel,
-                                       G_CALLBACK (on_status_toplevel_notify_display),
-                                       status_window);
-
-  if (status_window->window)
-    gtk_widget_destroy (status_window->window);
-
-  g_object_set_data (G_OBJECT (status_window->toplevel), "gtk-im-xim-status-window", NULL);
-
-  g_free (status_window);
-}
-
-/* Finds the status window object for a toplevel, creating it if necessary.
- */
-static StatusWindow *
-status_window_get (GtkWidget *toplevel)
-{
-  StatusWindow *status_window;
-
-  status_window = g_object_get_data (G_OBJECT (toplevel), "gtk-im-xim-status-window");
-  if (status_window)
-    return status_window;
-
-  status_window = g_new0 (StatusWindow, 1);
-  status_window->toplevel = toplevel;
-
-  status_windows = g_slist_prepend (status_windows, status_window);
-
-  g_signal_connect (toplevel, "destroy",
-                   G_CALLBACK (on_status_toplevel_destroy),
-                   status_window);
-  g_signal_connect (toplevel, "notify::display",
-                   G_CALLBACK (on_status_toplevel_notify_display),
-                   status_window);
-
-  g_object_set_data (G_OBJECT (toplevel), "gtk-im-xim-status-window", status_window);
-
-  return status_window;
-}
-
-/* Creates the widgets for the status window; called when we
- * first need to show text for the status window.
- */
-static void
-status_window_make_window (StatusWindow *status_window)
-{
-  GtkWidget *window;
-  GtkWidget *status_label;
-
-  status_window->window = gtk_window_new (GTK_WINDOW_POPUP);
-  window = status_window->window;
-
-  gtk_window_set_resizable (GTK_WINDOW (window), FALSE);
-
-  status_label = gtk_label_new ("");
-  g_object_set (status_label, "margin", 1, NULL);
-  gtk_widget_show (status_label);
-
-  gtk_container_add (GTK_CONTAINER (window), status_label);
-
-  gtk_window_set_display (GTK_WINDOW (status_window->window),
-                         gtk_widget_get_display (status_window->toplevel));
-}
-
-/* Updates the text in the status window, hiding or
- * showing the window as necessary.
- */
-static void
-status_window_set_text (StatusWindow *status_window,
-                       const gchar  *text)
-{
-  if (text[0])
-    {
-      GtkWidget *label;
-
-      if (!status_window->window)
-       status_window_make_window (status_window);
-
-      label = gtk_bin_get_child (GTK_BIN (status_window->window));
-      gtk_label_set_text (GTK_LABEL (label), text);
-
-      gtk_widget_show (status_window->window);
-    }
-  else
-    {
-      if (status_window->window)
-       gtk_widget_hide (status_window->window);
-    }
-}
-
-/**
- * gtk_im_context_xim_shutdown:
- *
- * Destroys all the status windows that are kept by the XIM contexts.  This
- * function should only be called by the XIM module exit routine.
- **/
-void
-gtk_im_context_xim_shutdown (void)
-{
-  while (status_windows)
-    status_window_free (status_windows->data);
-
-  while (open_ims)
-    {
-      GtkXIMInfo *info = open_ims->data;
-      GdkDisplay *display = info->display;
-
-      xim_info_display_closed (display, FALSE, info);
-      open_ims = g_slist_remove_link (open_ims, open_ims);
-    }
-}
diff --git a/gtk/gtkimcontextxim.h b/gtk/gtkimcontextxim.h
deleted file mode 100644 (file)
index 4d31479..0000000
+++ /dev/null
@@ -1,47 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2000 Red Hat Software
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- */
-
-#ifndef __GTK_IM_CONTEXT_XIM_H__
-#define __GTK_IM_CONTEXT_XIM_H__
-
-#include <gtk/gtk.h>
-#include "x11/gdkx.h"
-
-G_BEGIN_DECLS
-
-#define GTK_TYPE_IM_CONTEXT_XIM            (gtk_im_context_xim_get_type ())
-#define GTK_IM_CONTEXT_XIM(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIM))
-#define GTK_IM_CONTEXT_XIM_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
-#define GTK_IS_IM_CONTEXT_XIM(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_IM_CONTEXT_XIM))
-#define GTK_IS_IM_CONTEXT_XIM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IM_CONTEXT_XIM))
-#define GTK_IM_CONTEXT_XIM_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_IM_CONTEXT_XIM, GtkIMContextXIMClass))
-
-
-typedef struct _GtkIMContextXIM       GtkIMContextXIM;
-typedef struct _GtkIMContextXIMClass  GtkIMContextXIMClass;
-
-struct _GtkIMContextXIMClass
-{
-  GtkIMContextClass parent_class;
-};
-
-GType         gtk_im_context_xim_get_type (void) G_GNUC_CONST;
-void          gtk_im_context_xim_shutdown (void);
-
-G_END_DECLS
-
-#endif /* __GTK_IM_CONTEXT_XIM_H__ */
index a4c90dac1327612b7aee04e5c4a59a919ff3a983..2f4127faa7f47bb337c967256cebc5a456dc4d3f 100644 (file)
@@ -42,7 +42,6 @@
 
 #ifdef GDK_WINDOWING_X11
 #include "x11/gdkx.h"
-#include "gtkimcontextxim.h"
 #endif
 
 #ifdef GDK_WINDOWING_WAYLAND
@@ -126,13 +125,6 @@ match_backend (GdkDisplay *display,
     return FALSE;
 #endif
 
-  if (g_strcmp0 (context_id, "xim") == 0)
-#ifdef GDK_WINDOWING_X11
-    return GDK_IS_X11_DISPLAY (display);
-#else
-    return FALSE;
-#endif
-
   if (g_strcmp0 (context_id, "ime") == 0)
 #ifdef GDK_WINDOWING_WIN32
     return GDK_IS_WIN32_DISPLAY (display);
@@ -270,9 +262,6 @@ gtk_im_modules_init (void)
   gtk_im_module_ensure_extension_point ();
 
   g_type_ensure (gtk_im_context_simple_get_type ());
-#ifdef GDK_WINDOWING_X11
-  g_type_ensure (gtk_im_context_xim_get_type ());
-#endif
 #ifdef GDK_WINDOWING_WAYLAND
   g_type_ensure (gtk_im_context_wayland_get_type ());
 #endif
index bdfb7294b77e2afa93ec98e5593514cde43dd0a5..c083509f47c43759f1d4eff85bfea8f64b8f8363 100644 (file)
@@ -748,7 +748,6 @@ endif
 
 if x11_enabled
   gtk_sources += ['gtkapplication-x11.c', 'gtkmountoperation-x11.c']
-  gtk_sources += ['gtkimcontextxim.c']
 endif
 
 if wayland_enabled