diff --git a/gtk/gtkimcontextxim.c b/gtk/gtkimcontextxim.c deleted file mode 100644 index e4b747af58..0000000000 --- a/gtk/gtkimcontextxim.c +++ /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 . - */ - -#include "config.h" -#include "locale.h" -#include -#include - -#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 index 4d31479d4b..0000000000 --- a/gtk/gtkimcontextxim.h +++ /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 . - */ - -#ifndef __GTK_IM_CONTEXT_XIM_H__ -#define __GTK_IM_CONTEXT_XIM_H__ - -#include -#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__ */ diff --git a/gtk/gtkimmodule.c b/gtk/gtkimmodule.c index a4c90dac13..2f4127faa7 100644 --- a/gtk/gtkimmodule.c +++ b/gtk/gtkimmodule.c @@ -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 diff --git a/gtk/meson.build b/gtk/meson.build index bdfb7294b7..c083509f47 100644 --- a/gtk/meson.build +++ b/gtk/meson.build @@ -748,7 +748,6 @@ endif if x11_enabled gtk_sources += ['gtkapplication-x11.c', 'gtkmountoperation-x11.c'] - gtk_sources += ['gtkimcontextxim.c'] endif if wayland_enabled