summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2018-02-23 14:59:49 -0500
committerMatthias Clasen <mclasen@redhat.com>2018-02-24 21:34:40 -0500
commit15cc20e7b5d46656b83a39f086650555e369aa1b (patch)
treecf7a33557fcd456d606439fe1aa5e9efd729d591 /modules
parent29bcc38ae62e73b76f0f663e2ecc5e85bfe4ca46 (diff)
downloadgtk+-15cc20e7b5d46656b83a39f086650555e369aa1b.tar.gz
Always include platform immodules
No need to load these as gio modules, we just include them in libgtk.
Diffstat (limited to 'modules')
-rw-r--r--modules/input/gtk-text-input.xml302
-rw-r--r--modules/input/gtkimcontextime.c1221
-rw-r--r--modules/input/gtkimcontextime.h58
-rw-r--r--modules/input/gtkimcontextxim.c1804
-rw-r--r--modules/input/gtkimcontextxim.h48
-rw-r--r--modules/input/imbroadway.c130
-rw-r--r--modules/input/imm-extra.h63
-rw-r--r--modules/input/imquartz.c417
-rw-r--r--modules/input/imwayland.c655
-rw-r--r--modules/input/meson.build118
-rw-r--r--modules/meson.build2
11 files changed, 0 insertions, 4818 deletions
diff --git a/modules/input/gtk-text-input.xml b/modules/input/gtk-text-input.xml
deleted file mode 100644
index a134a19f61..0000000000
--- a/modules/input/gtk-text-input.xml
+++ /dev/null
@@ -1,302 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-
-<protocol name="gtk_text_input">
- <copyright>
- Copyright © 2012, 2013 Intel Corporation
- Copyright © 2015, 2016 Jan Arne Petersen
-
- Permission to use, copy, modify, distribute, and sell this
- software and its documentation for any purpose is hereby granted
- without fee, provided that the above copyright notice appear in
- all copies and that both that copyright notice and this permission
- notice appear in supporting documentation, and that the name of
- the copyright holders not be used in advertising or publicity
- pertaining to distribution of the software without specific,
- written prior permission. The copyright holders make no
- representations about the suitability of this software for any
- purpose. It is provided "as is" without express or implied
- warranty.
-
- THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY
- SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
- AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
- ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
- THIS SOFTWARE.
- </copyright>
-
- <interface name="gtk_text_input" version="1">
- <description summary="text input">
- The gtk_text_input interface represents text input and input methods
- associated with a seat. It provides enter/leave events to follow the
- text input focus for a seat.
-
- Requests are used to enable/disable the text-input object and set
- state information like surrounding and selected text or the content type.
- The information about the entered text is sent to the text-input object
- via the pre-edit and commit_string events. Using this interface removes
- the need for applications to directly process hardware key events and
- compose text out of them.
-
- Text is valid UTF-8 encoded, indices and lengths are in bytes. Indices
- have to always point to the first byte of an UTF-8 encoded code point.
- Lengths are not allowed to contain just a part of an UTF-8 encoded code
- point.
-
- Focus moving throughout surfaces will result in the emission of
- gtk_text_input.enter and gtk_text_input.leave events. The focused
- surface must perform gtk_text_input.enable and
- gtk_text_input.disable requests as the keyboard focus moves across
- editable and non-editable elements of the UI. Those two requests are not
- expected to be paired with each other, the compositor must be able to
- handle consecutive series of the same request.
-
- State is sent by the state requests (set_surrounding_text,
- set_content_type and set_cursor_rectangle) and a commit request.
- After an enter event or disable request all state information is
- invalidated and needs to be resent by the client.
-
- This protocol defines requests and events necessary for regular clients
- to communicate with an input method. The gtk_input_method protocol
- defines the interfaces necessary to implement standalone input methods.
- If a compositor implements both interfaces, it will be the arbiter of the
- communication between both.
-
- Warning! The protocol described in this file is experimental and
- backward incompatible changes may be made. Backward compatible changes
- may be added together with the corresponding interface version bump.
- Backward incompatible changes are done by bumping the version number in
- the protocol and interface names and resetting the interface version.
- Once the protocol is to be declared stable, the 'z' prefix and the
- version number in the protocol and interface names are removed and the
- interface version number is reset.
- </description>
-
- <request name="destroy" type="destructor">
- <description summary="Destroy the wp_text_input">
- Destroy the wp_text_input object. Also disables all surfaces enabled
- through this wp_text_input object
- </description>
- </request>
-
- <enum name="enable_flags" bitfield="true">
- <description summary="enable flags">
- Content hint is a bitmask to allow to modify the behavior of the text
- input.
- </description>
- <entry name="none" value="0x0" summary="no special behaviour"/>
- <entry name="can_show_preedit" value="0x1" summary="hints that the UI is capable of showing pre-edit text"/>
- <entry name="toggle_input_panel" value="0x2" summary="requests toggling input panel (eg. on-screen keyboard)"/>
- </enum>
-
- <request name="enable">
- <description summary="Request text input to be enabled">
- Requests text input on a surface. The serial provided must be the one
- received on gtk_text_input.enter.
- </description>
- <arg name="serial" type="uint" summary="serial of enter event"/>
- <arg name="show_input_panel" type="uint" summary="details of the enable request"/>
- </request>
-
- <request name="disable">
- <description summary="Disable text input on a surface">
- Explicitly disable text input in a surface (typically when there is no
- focus on any text entry inside the surface).
- </description>
- </request>
-
- <request name="set_surrounding_text">
- <description summary="sets the surrounding text">
- Sets the plain surrounding text around the input position. Text is
- UTF-8 encoded. Cursor is the byte offset within the surrounding text.
- Anchor is the byte offset of the selection anchor within the
- surrounding text. If there is no selected text, anchor is the same as
- cursor.
-
- Make sure to always send some text before and after the cursor
- except when the cursor is at the beginning or end of text.
-
- When there was a configure_surrounding_text event take the
- before_cursor and after_cursor arguments into account for picking how
- much surrounding text to send.
-
- There is a maximum length of wayland messages so text can not be
- longer than 4000 bytes.
- </description>
- <arg name="text" type="string"/>
- <arg name="cursor" type="int"/>
- <arg name="anchor" type="int"/>
- </request>
-
- <enum name="content_hint" bitfield="true">
- <description summary="content hint">
- Content hint is a bitmask to allow to modify the behavior of the text
- input.
- </description>
- <entry name="none" value="0x0" summary="no special behaviour"/>
- <entry name="completion" value="0x1" summary="suggest word completions"/>
- <entry name="spellcheck" value="0x2" summary="suggest word corrections"/>
- <entry name="auto_capitalization" value="0x4" summary="switch to uppercase letters at the start of a sentence"/>
- <entry name="lowercase" value="0x8" summary="prefer lowercase letters"/>
- <entry name="uppercase" value="0x10" summary="prefer uppercase letters"/>
- <entry name="titlecase" value="0x20" summary="prefer casing for titles and headings (can be language dependent)"/>
- <entry name="hidden_text" value="0x40" summary="characters should be hidden"/>
- <entry name="sensitive_data" value="0x80" summary="typed text should not be stored"/>
- <entry name="latin" value="0x100" summary="just latin characters should be entered"/>
- <entry name="multiline" value="0x200" summary="the text input is multiline"/>
- </enum>
-
- <enum name="content_purpose">
- <description summary="content purpose">
- The content purpose allows to specify the primary purpose of a text
- input.
-
- This allows an input method to show special purpose input panels with
- extra characters or to disallow some characters.
- </description>
- <entry name="normal" value="0" summary="default input, allowing all characters"/>
- <entry name="alpha" value="1" summary="allow only alphabetic characters"/>
- <entry name="digits" value="2" summary="allow only digits"/>
- <entry name="number" value="3" summary="input a number (including decimal separator and sign)"/>
- <entry name="phone" value="4" summary="input a phone number"/>
- <entry name="url" value="5" summary="input an URL"/>
- <entry name="email" value="6" summary="input an email address"/>
- <entry name="name" value="7" summary="input a name of a person"/>
- <entry name="password" value="8" summary="input a password (combine with password or sensitive_data hint)"/>
- <entry name="pin" value="9" summary="input is a numeric password (combine with password or sensitive_data hint)"/>
- <entry name="date" value="10" summary="input a date"/>
- <entry name="time" value="11" summary="input a time"/>
- <entry name="datetime" value="12" summary="input a date and time"/>
- <entry name="terminal" value="13" summary="input for a terminal"/>
- </enum>
-
- <request name="set_content_type">
- <description summary="set content purpose and hint">
- Sets the content purpose and content hint. While the purpose is the
- basic purpose of an input field, the hint flags allow to modify some
- of the behavior.
-
- When no content type is explicitly set, a normal content purpose with
- none hint should be assumed.
- </description>
- <arg name="hint" type="uint" enum="content_hint"/>
- <arg name="purpose" type="uint" enum="content_purpose"/>
- </request>
-
- <request name="set_cursor_rectangle">
- <description summary="set cursor position">
- Sets the cursor outline as a x, y, width, height rectangle in surface
- local coordinates.
-
- Allows the compositor to put a window with word suggestions near the
- cursor.
- </description>
- <arg name="x" type="int"/>
- <arg name="y" type="int"/>
- <arg name="width" type="int"/>
- <arg name="height" type="int"/>
- </request>
-
- <request name="commit">
- <description summary="commit state">
- Allows to atomically send state updates from client. The previous
- set_surrounding_text, set_content_type and set_cursor_rectangle
- become effective after this call.
-
- Serial should be set to the serial from the last wp_text_input.enter
- event.
-
- To make sure to not receive outdated input method events after a
- state update, wl_display_sync() should be called after making this
- request.
- </description>
- </request>
-
- <event name="enter">
- <description summary="enter event">
- Notification that this seat's text-input focus is on a certain surface.
-
- When the seat has the keyboard capability the text-input focus follows
- the keyboard focus.
- </description>
- <arg name="serial" type="uint" summary="serial"/>
- <arg name="surface" type="object" interface="wl_surface"/>
- </event>
-
- <event name="leave">
- <description summary="leave event">
- Notification that this seat's text-input focus is no longer on
- a certain surface. The client should reset any preedit string previously
- set.
-
- The leave notification is sent before the enter notification
- for the new focus.
-
- When the seat has the keyboard capability the text-input focus follows
- the keyboard focus.
- </description>
- <arg name="serial" type="uint"/>
- <arg name="surface" type="object" interface="wl_surface"/>
- </event>
-
- <event name="preedit_string">
- <description summary="pre-edit">
- Notify when a new composing text (pre-edit) should be set around the
- current cursor position. Any previously set composing text should
- be removed.
- </description>
- <arg name="text" type="string" allow-null="true"/>
- <arg name="cursor" type="uint"/>
- </event>
-
- <event name="commit_string">
- <description summary="text commit">
- Notify when text should be inserted into the editor widget. The text to
- commit could be either just a single character after a key press or the
- result of some composing (pre-edit).
-
- The text argument could be also null if some text is removed (see
- gtk_text_input.delete_surrounding_text).
-
- Any previously set composing text should be removed.
- </description>
- <arg name="text" type="string" allow-null="true"/>
- </event>
-
- <event name="delete_surrounding_text">
- <description summary="delete surrounding text">
- Notify when the text around the current cursor position should be
- deleted. Before_length and after_length is the length (in bytes) of text
- before and after the current cursor position (excluding the selection)
- to delete.
-
- This event should be handled as part of a following commit_string or
- preedit_string event.
- </description>
- <arg name="before_length" type="uint" summary="length of text before current cursor position"/>
- <arg name="after_length" type="uint" summary="length of text after current cursor position"/>
- </event>
- </interface>
-
- <interface name="gtk_text_input_manager" version="1">
- <description summary="text input manager">
- A factory for text-input objects. This object is a global singleton.
- </description>
-
- <request name="destroy" type="destructor">
- <description summary="Destroy the wp_text_input_manager">
- Destroy the wp_text_input_manager object.
- </description>
- </request>
-
- <request name="get_text_input">
- <description summary="create a new text input object">
- Creates a new text-input object for a given seat.
- </description>
- <arg name="id" type="new_id" interface="gtk_text_input"/>
- <arg name="seat" type="object" interface="wl_seat"/>
- </request>
- </interface>
-</protocol>
diff --git a/modules/input/gtkimcontextime.c b/modules/input/gtkimcontextime.c
deleted file mode 100644
index 212a17b669..0000000000
--- a/modules/input/gtkimcontextime.c
+++ /dev/null
@@ -1,1221 +0,0 @@
-/*
- * gtkimcontextime.c
- * Copyright (C) 2003 Takuro Ashie
- * Copyright (C) 2003-2004 Kazuki IWAMOTO
- *
- * 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/>.
- *
- */
-
-/*
- * Please see the following site for the detail of Windows IME API.
- * http://msdn.microsoft.com/library/default.asp?url=/library/en-us/appendix/hh/appendix/imeimes2_35ph.asp
- */
-
-#ifdef GTK_DISABLE_DEPRECATED
-#undef GTK_DISABLE_DEPRECATED
-#endif
-
-#include "gtkimcontextime.h"
-
-#include "imm-extra.h"
-
-#include "gdk/gdkkeysyms.h"
-#include "gdk/win32/gdkwin32.h"
-#include "gdk/gdkkeysyms.h"
-
-#include <pango/pango.h>
-
-/* avoid warning */
-#ifdef STRICT
-# undef STRICT
-# include <pango/pangowin32.h>
-# ifndef STRICT
-# define STRICT 1
-# endif
-#else /* STRICT */
-# include <pango/pangowin32.h>
-#endif /* STRICT */
-
-/* #define BUFSIZE 4096 */
-
-#define IS_DEAD_KEY(k) \
- ((k) >= GDK_KEY_dead_grave && (k) <= (GDK_KEY_dead_dasia+1))
-
-#define FREE_PREEDIT_BUFFER(ctx) \
-{ \
- g_free((ctx)->priv->comp_str); \
- g_free((ctx)->priv->read_str); \
- (ctx)->priv->comp_str = NULL; \
- (ctx)->priv->read_str = NULL; \
- (ctx)->priv->comp_str_len = 0; \
- (ctx)->priv->read_str_len = 0; \
-}
-
-
-struct _GtkIMContextIMEPrivate
-{
- /* save IME context when the client window is focused out */
- DWORD conversion_mode;
- DWORD sentence_mode;
-
- LPVOID comp_str;
- DWORD comp_str_len;
- LPVOID read_str;
- DWORD read_str_len;
-
- guint32 dead_key_keyval;
-};
-
-
-/* GObject class methods */
-static void gtk_im_context_ime_class_init (GtkIMContextIMEClass *class);
-static void gtk_im_context_ime_init (GtkIMContextIME *context_ime);
-static void gtk_im_context_ime_dispose (GObject *obj);
-static void gtk_im_context_ime_finalize (GObject *obj);
-
-static void gtk_im_context_ime_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec);
-static void gtk_im_context_ime_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec);
-
-/* GtkIMContext's virtual functions */
-static void gtk_im_context_ime_set_client_widget (GtkIMContext *context,
- GtkWidget *widget);
-static gboolean gtk_im_context_ime_filter_keypress (GtkIMContext *context,
- GdkEventKey *event);
-static void gtk_im_context_ime_reset (GtkIMContext *context);
-static void gtk_im_context_ime_get_preedit_string (GtkIMContext *context,
- gchar **str,
- PangoAttrList **attrs,
- gint *cursor_pos);
-static void gtk_im_context_ime_focus_in (GtkIMContext *context);
-static void gtk_im_context_ime_focus_out (GtkIMContext *context);
-static void gtk_im_context_ime_set_cursor_location (GtkIMContext *context,
- GdkRectangle *area);
-static void gtk_im_context_ime_set_use_preedit (GtkIMContext *context,
- gboolean use_preedit);
-
-/* GtkIMContextIME's private functions */
-static void gtk_im_context_ime_set_preedit_font (GtkIMContext *context);
-
-static GdkFilterReturn
-gtk_im_context_ime_message_filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data);
-static void get_window_position (GdkWindow *win,
- gint *x,
- gint *y);
-static void cb_client_widget_hierarchy_changed (GtkWidget *widget,
- GtkWidget *widget2,
- GtkIMContextIME *context_ime);
-
-#define GTK_TYPE_IM_CONTEXT_IME (gtk_im_context_ime_get_type ())
-#define GTK_IM_CONTEXT_IME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_IME, GtkIMContextIME))
-
-G_DEFINE_DYNAMIC_TYPE (GtkIMContextIME, gtk_im_context_ime, GTK_TYPE_IM_CONTEXT)
-
-void
-g_io_module_load (GIOModule *module)
-{
- g_type_module_use (G_TYPE_MODULE (module));
-
- gtk_im_context_ime_register_type (G_TYPE_MODULE (module));
-
- g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
- GTK_TYPE_IM_CONTEXT_IME,
- "ime",
- 10);
-}
-
-void
-g_io_module_unload (GIOModule *module)
-{
-}
-
-char **
-g_io_module_query (void)
-{
- char *eps[] = {
- GTK_IM_MODULE_EXTENSION_POINT_NAME,
- NULL
- };
-
- return g_strdupv (eps);
-}
-
-static void
-gtk_im_context_ime_class_init (GtkIMContextIMEClass *class)
-{
- GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-
- gobject_class->finalize = gtk_im_context_ime_finalize;
- gobject_class->dispose = gtk_im_context_ime_dispose;
- gobject_class->set_property = gtk_im_context_ime_set_property;
- gobject_class->get_property = gtk_im_context_ime_get_property;
-
- im_context_class->set_client_widget = gtk_im_context_ime_set_client_widget;
- im_context_class->filter_keypress = gtk_im_context_ime_filter_keypress;
- im_context_class->reset = gtk_im_context_ime_reset;
- im_context_class->get_preedit_string = gtk_im_context_ime_get_preedit_string;
- im_context_class->focus_in = gtk_im_context_ime_focus_in;
- im_context_class->focus_out = gtk_im_context_ime_focus_out;
- im_context_class->set_cursor_location = gtk_im_context_ime_set_cursor_location;
- im_context_class->set_use_preedit = gtk_im_context_ime_set_use_preedit;
-}
-
-static void
-gtk_im_context_ime_class_finalize (GtkIMContextIMEClass *class)
-{
-}
-
-static void
-gtk_im_context_ime_init (GtkIMContextIME *context_ime)
-{
- context_ime->client_window = NULL;
- context_ime->toplevel = NULL;
- context_ime->use_preedit = TRUE;
- context_ime->preediting = FALSE;
- context_ime->opened = FALSE;
- context_ime->focus = FALSE;
- context_ime->cursor_location.x = 0;
- context_ime->cursor_location.y = 0;
- context_ime->cursor_location.width = 0;
- context_ime->cursor_location.height = 0;
- context_ime->commit_string = NULL;
-
- context_ime->priv = g_malloc0 (sizeof (GtkIMContextIMEPrivate));
- context_ime->priv->conversion_mode = 0;
- context_ime->priv->sentence_mode = 0;
- context_ime->priv->comp_str = NULL;
- context_ime->priv->comp_str_len = 0;
- context_ime->priv->read_str = NULL;
- context_ime->priv->read_str_len = 0;
-}
-
-
-static void
-gtk_im_context_ime_dispose (GObject *obj)
-{
- GtkIMContext *context = GTK_IM_CONTEXT (obj);
- GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (obj);
-
- if (context_ime->client_window)
- gtk_im_context_ime_set_client_widget (context, NULL);
-
- FREE_PREEDIT_BUFFER (context_ime);
-
- if (G_OBJECT_CLASS (parent_class)->dispose)
- G_OBJECT_CLASS (parent_class)->dispose (obj);
-}
-
-
-static void
-gtk_im_context_ime_finalize (GObject *obj)
-{
- /* GtkIMContext *context = GTK_IM_CONTEXT (obj); */
- GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (obj);
-
- g_free (context_ime->priv);
- context_ime->priv = NULL;
-
- if (G_OBJECT_CLASS (parent_class)->finalize)
- G_OBJECT_CLASS (parent_class)->finalize (obj);
-}
-
-
-static void
-gtk_im_context_ime_set_property (GObject *object,
- guint prop_id,
- const GValue *value,
- GParamSpec *pspec)
-{
- GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (object);
-
- g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context_ime));
-
- switch (prop_id)
- {
- default:
- break;
- }
-}
-
-
-static void
-gtk_im_context_ime_get_property (GObject *object,
- guint prop_id,
- GValue *value,
- GParamSpec *pspec)
-{
- GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (object);
-
- g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context_ime));
-
- switch (prop_id)
- {
- default:
- break;
- }
-}
-
-
-GtkIMContext *
-gtk_im_context_ime_new (void)
-{
- return g_object_new (GTK_TYPE_IM_CONTEXT_IME, NULL);
-}
-
-
-static void
-gtk_im_context_ime_set_client_widget (GtkIMContext *context,
- GtkWidget *widget)
-{
- GtkIMContextIME *context_ime;
- GtkWidget *toplevel;
- GdkWindow *client_window;
-
- g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context));
- context_ime = GTK_IM_CONTEXT_IME (context);
- toplevel = gtk_widget_get_toplevel (widget);
- client_window = gtk_widget_get_window (toplevel);
-
- if (client_window)
- {
- HIMC himc;
- HWND hwnd;
-
- hwnd = gdk_win32_window_get_impl_hwnd (client_window);
- himc = ImmGetContext (hwnd);
- if (himc)
- {
- context_ime->opened = ImmGetOpenStatus (himc);
- ImmGetConversionStatus (himc,
- &context_ime->priv->conversion_mode,
- &context_ime->priv->sentence_mode);
- ImmReleaseContext (hwnd, himc);
- }
- }
- else if (context_ime->focus)
- {
- gtk_im_context_ime_focus_out (context);
- }
-
- context_ime->client_window = client_window;
-}
-
-static gunichar
-_gtk_im_context_ime_dead_key_unichar (guint keyval,
- gboolean spacing)
-{
- switch (keyval)
- {
-#define CASE(keysym, unicode, spacing_unicode) \
- case GDK_KEY_dead_##keysym: return (spacing) ? spacing_unicode : unicode;
-
- CASE (grave, 0x0300, 0x0060);
- CASE (acute, 0x0301, 0x00b4);
- CASE (circumflex, 0x0302, 0x005e);
- CASE (tilde, 0x0303, 0x007e); /* Also used with perispomeni, 0x342. */
- CASE (macron, 0x0304, 0x00af);
- CASE (breve, 0x0306, 0x02d8);
- CASE (abovedot, 0x0307, 0x02d9);
- CASE (diaeresis, 0x0308, 0x00a8);
- CASE (hook, 0x0309, 0);
- CASE (abovering, 0x030A, 0x02da);
- CASE (doubleacute, 0x030B, 0x2dd);
- CASE (caron, 0x030C, 0x02c7);
- CASE (abovecomma, 0x0313, 0); /* Equivalent to psili */
- CASE (abovereversedcomma, 0x0314, 0); /* Equivalent to dasia */
- CASE (horn, 0x031B, 0); /* Legacy use for psili, 0x313 (or 0x343). */
- CASE (belowdot, 0x0323, 0);
- CASE (cedilla, 0x0327, 0x00b8);
- CASE (ogonek, 0x0328, 0); /* Legacy use for dasia, 0x314.*/
- CASE (iota, 0x0345, 0);
-
-#undef CASE
- default:
- return 0;
- }
-}
-
-static void
-_gtk_im_context_ime_commit_unichar (GtkIMContextIME *context_ime,
- gunichar c)
-{
- gchar utf8[10];
- int len;
-
- if (context_ime->priv->dead_key_keyval != 0)
- {
- gunichar combining;
-
- combining =
- _gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval,
- FALSE);
- g_unichar_compose (c, combining, &c);
- }
-
- len = g_unichar_to_utf8 (c, utf8);
- utf8[len] = 0;
-
- g_signal_emit_by_name (context_ime, "commit", utf8);
- context_ime->priv->dead_key_keyval = 0;
-}
-
-static gboolean
-gtk_im_context_ime_filter_keypress (GtkIMContext *context,
- GdkEventKey *event)
-{
- GtkIMContextIME *context_ime;
- gboolean retval = FALSE;
- guint32 c;
- GdkModifierType state;
- guint keyval;
-
- g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (context), FALSE);
- g_return_val_if_fail (event, FALSE);
-
- if (gdk_event_get_event_type ((GdkEvent *) event) == GDK_KEY_RELEASE)
- return FALSE;
-
- gdk_event_get_state ((GdkEvent *) event, &state);
-
- if (state & GDK_CONTROL_MASK)
- return FALSE;
-
- context_ime = GTK_IM_CONTEXT_IME (context);
-
- if (!context_ime->focus)
- return FALSE;
-
- if (!GDK_IS_WINDOW (context_ime->client_window))
- return FALSE;
-
- gdk_event_get_keyval ((GdkEvent *) event, &keyval);
-
- if (keyval == GDK_KEY_space &&
- context_ime->priv->dead_key_keyval != 0)
- {
- c = _gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval, TRUE);
- context_ime->priv->dead_key_keyval = 0;
- _gtk_im_context_ime_commit_unichar (context_ime, c);
- return TRUE;
- }
-
- c = gdk_keyval_to_unicode (keyval);
-
- if (c)
- {
- _gtk_im_context_ime_commit_unichar (context_ime, c);
- retval = TRUE;
- }
- else if (IS_DEAD_KEY (keyval))
- {
- gunichar dead_key;
-
- dead_key = _gtk_im_context_ime_dead_key_unichar (keyval, FALSE);
-
- /* Emulate double input of dead keys */
- if (dead_key && keyval == context_ime->priv->dead_key_keyval)
- {
- c = _gtk_im_context_ime_dead_key_unichar (context_ime->priv->dead_key_keyval, TRUE);
- context_ime->priv->dead_key_keyval = 0;
- _gtk_im_context_ime_commit_unichar (context_ime, c);
- _gtk_im_context_ime_commit_unichar (context_ime, c);
- }
- else
- context_ime->priv->dead_key_keyval = keyval;
- }
-
- return retval;
-}
-
-
-static void
-gtk_im_context_ime_reset (GtkIMContext *context)
-{
- GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (context);
- HWND hwnd;
- HIMC himc;
-
- if (!context_ime->client_window)
- return;
-
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return;
-
- if (context_ime->preediting)
- {
- if (ImmGetOpenStatus (himc))
- ImmNotifyIME (himc, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
-
- context_ime->preediting = FALSE;
- g_signal_emit_by_name (context, "preedit-changed");
- }
-
- ImmReleaseContext (hwnd, himc);
-}
-
-
-static gchar *
-get_utf8_preedit_string (GtkIMContextIME *context_ime, gint *pos_ret)
-{
- gchar *utf8str = NULL;
- HWND hwnd;
- HIMC himc;
- gint pos = 0;
-
- if (pos_ret)
- *pos_ret = 0;
-
- if (!context_ime->client_window)
- return g_strdup ("");
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return g_strdup ("");
-
- if (context_ime->preediting)
- {
- glong len;
-
- len = ImmGetCompositionStringW (himc, GCS_COMPSTR, NULL, 0);
- if (len > 0)
- {
- GError *error = NULL;
- gpointer buf = g_alloca (len);
-
- ImmGetCompositionStringW (himc, GCS_COMPSTR, buf, len);
- len /= 2;
- utf8str = g_utf16_to_utf8 (buf, len, NULL, NULL, &error);
- if (error)
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
-
- if (pos_ret)
- {
- pos = ImmGetCompositionStringW (himc, GCS_CURSORPOS, NULL, 0);
- if (pos < 0 || len < pos)
- {
- g_warning ("ImmGetCompositionString: "
- "Invalid cursor position!");
- pos = 0;
- }
- }
- }
- }
-
- if (!utf8str)
- {
- utf8str = g_strdup ("");
- pos = 0;
- }
-
- if (pos_ret)
- *pos_ret = pos;
-
- ImmReleaseContext (hwnd, himc);
-
- return utf8str;
-}
-
-
-static PangoAttrList *
-get_pango_attr_list (GtkIMContextIME *context_ime, const gchar *utf8str)
-{
- PangoAttrList *attrs = pango_attr_list_new ();
- HWND hwnd;
- HIMC himc;
-
- if (!context_ime->client_window)
- return attrs;
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return attrs;
-
- if (context_ime->preediting)
- {
- const gchar *schr = utf8str, *echr;
- guint8 *buf;
- guint16 f_red, f_green, f_blue, b_red, b_green, b_blue;
- glong len, spos = 0, epos, sidx = 0, eidx;
- PangoAttribute *attr;
-
- /*
- * get attributes list of IME.
- */
- len = ImmGetCompositionStringW (himc, GCS_COMPATTR, NULL, 0);
- buf = g_alloca (len);
- ImmGetCompositionStringW (himc, GCS_COMPATTR, buf, len);
-
- /*
- * schr and echr are pointer in utf8str.
- */
- for (echr = g_utf8_next_char (utf8str); *schr != '\0';
- echr = g_utf8_next_char (echr))
- {
- /*
- * spos and epos are buf(attributes list of IME) position by
- * bytes.
- * Using the wide-char API, this value is same with UTF-8 offset.
- */
- epos = g_utf8_pointer_to_offset (utf8str, echr);
-
- /*
- * sidx and eidx are positions in utf8str by bytes.
- */
- eidx = echr - utf8str;
-
- /*
- * convert attributes list to PangoAttriute.
- */
- if (*echr == '\0' || buf[spos] != buf[epos])
- {
- switch (buf[spos])
- {
- case ATTR_TARGET_CONVERTED:
- attr = pango_attr_underline_new (PANGO_UNDERLINE_DOUBLE);
- attr->start_index = sidx;
- attr->end_index = eidx;
- pango_attr_list_change (attrs, attr);
- f_red = f_green = f_blue = 0;
- b_red = b_green = b_blue = 0xffff;
- break;
- case ATTR_TARGET_NOTCONVERTED:
- f_red = f_green = f_blue = 0xffff;
- b_red = b_green = b_blue = 0;
- break;
- case ATTR_INPUT_ERROR:
- f_red = f_green = f_blue = 0;
- b_red = b_green = b_blue = 0x7fff;
- break;
- default: /* ATTR_INPUT,ATTR_CONVERTED,ATTR_FIXEDCONVERTED */
- attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
- attr->start_index = sidx;
- attr->end_index = eidx;
- pango_attr_list_change (attrs, attr);
- f_red = f_green = f_blue = 0;
- b_red = b_green = b_blue = 0xffff;
- }
- attr = pango_attr_foreground_new (f_red, f_green, f_blue);
- attr->start_index = sidx;
- attr->end_index = eidx;
- pango_attr_list_change (attrs, attr);
- attr = pango_attr_background_new (b_red, b_green, b_blue);
- attr->start_index = sidx;
- attr->end_index = eidx;
- pango_attr_list_change (attrs, attr);
-
- schr = echr;
- spos = epos;
- sidx = eidx;
- }
- }
- }
-
- ImmReleaseContext (hwnd, himc);
-
- return attrs;
-}
-
-
-static void
-gtk_im_context_ime_get_preedit_string (GtkIMContext *context,
- gchar **str,
- PangoAttrList **attrs,
- gint *cursor_pos)
-{
- gchar *utf8str = NULL;
- gint pos = 0;
- GtkIMContextIME *context_ime;
-
- context_ime = GTK_IM_CONTEXT_IME (context);
-
- utf8str = get_utf8_preedit_string (context_ime, &pos);
-
- if (attrs)
- *attrs = get_pango_attr_list (context_ime, utf8str);
-
- if (str)
- {
- *str = utf8str;
- }
- else
- {
- g_free (utf8str);
- utf8str = NULL;
- }
-
- if (cursor_pos)
- *cursor_pos = pos;
-}
-
-
-static void
-gtk_im_context_ime_focus_in (GtkIMContext *context)
-{
- GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (context);
- GdkWindow *toplevel;
- GtkWidget *widget = NULL;
- HWND hwnd;
- HIMC himc;
-
- if (!GDK_IS_WINDOW (context_ime->client_window))
- return;
-
- /* swtich current context */
- context_ime->focus = TRUE;
-
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return;
-
- toplevel = gdk_window_get_toplevel (context_ime->client_window);
- if (GDK_IS_WINDOW (toplevel))
- {
- gdk_window_add_filter (toplevel,
- gtk_im_context_ime_message_filter, context_ime);
- context_ime->toplevel = toplevel;
- }
- else
- {
- g_warning ("gtk_im_context_ime_focus_in(): "
- "cannot find toplevel window.");
- return;
- }
-
- /* trace reparenting (probably no need) */
- gdk_window_get_user_data (context_ime->client_window, (gpointer) & widget);
- if (GTK_IS_WIDGET (widget))
- {
- g_signal_connect (widget, "hierarchy-changed",
- G_CALLBACK (cb_client_widget_hierarchy_changed),
- context_ime);
- }
- else
- {
- /* warning? */
- }
-
- /* restore preedit context */
- ImmSetConversionStatus (himc,
- context_ime->priv->conversion_mode,
- context_ime->priv->sentence_mode);
-
- if (context_ime->opened)
- {
- if (!ImmGetOpenStatus (himc))
- ImmSetOpenStatus (himc, TRUE);
- if (context_ime->preediting)
- {
- ImmSetCompositionStringW (himc,
- SCS_SETSTR,
- context_ime->priv->comp_str,
- context_ime->priv->comp_str_len, NULL, 0);
- FREE_PREEDIT_BUFFER (context_ime);
- }
- }
-
- /* clean */
- ImmReleaseContext (hwnd, himc);
-}
-
-
-static void
-gtk_im_context_ime_focus_out (GtkIMContext *context)
-{
- GtkIMContextIME *context_ime = GTK_IM_CONTEXT_IME (context);
- GdkWindow *toplevel;
- GtkWidget *widget = NULL;
- HWND hwnd;
- HIMC himc;
-
- if (!GDK_IS_WINDOW (context_ime->client_window))
- return;
-
- /* swtich current context */
- context_ime->focus = FALSE;
-
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return;
-
- /* save preedit context */
- ImmGetConversionStatus (himc,
- &context_ime->priv->conversion_mode,
- &context_ime->priv->sentence_mode);
-
- if (ImmGetOpenStatus (himc))
- {
- gboolean preediting = context_ime->preediting;
-
- if (preediting)
- {
- FREE_PREEDIT_BUFFER (context_ime);
-
- context_ime->priv->comp_str_len
- = ImmGetCompositionStringW (himc, GCS_COMPSTR, NULL, 0);
- context_ime->priv->comp_str
- = g_malloc (context_ime->priv->comp_str_len);
- ImmGetCompositionStringW (himc, GCS_COMPSTR,
- context_ime->priv->comp_str,
- context_ime->priv->comp_str_len);
-
- context_ime->priv->read_str_len
- = ImmGetCompositionStringW (himc, GCS_COMPREADSTR, NULL, 0);
- context_ime->priv->read_str
- = g_malloc (context_ime->priv->read_str_len);
- ImmGetCompositionStringW (himc, GCS_COMPREADSTR,
- context_ime->priv->read_str,
- context_ime->priv->read_str_len);
- }
-
- ImmSetOpenStatus (himc, FALSE);
-
- context_ime->opened = TRUE;
- context_ime->preediting = preediting;
- }
- else
- {
- context_ime->opened = FALSE;
- context_ime->preediting = FALSE;
- }
-
- /* remove signal handler */
- gdk_window_get_user_data (context_ime->client_window, (gpointer) & widget);
- if (GTK_IS_WIDGET (widget))
- {
- g_signal_handlers_disconnect_by_func
- (G_OBJECT (widget),
- G_CALLBACK (cb_client_widget_hierarchy_changed), context_ime);
- }
-
- /* remove event fileter */
- toplevel = gdk_window_get_toplevel (context_ime->client_window);
- if (GDK_IS_WINDOW (toplevel))
- {
- gdk_window_remove_filter (toplevel,
- gtk_im_context_ime_message_filter,
- context_ime);
- context_ime->toplevel = NULL;
- }
- else
- {
- g_warning ("gtk_im_context_ime_focus_out(): "
- "cannot find toplevel window.");
- }
-
- /* clean */
- ImmReleaseContext (hwnd, himc);
-}
-
-
-static void
-gtk_im_context_ime_set_cursor_location (GtkIMContext *context,
- GdkRectangle *area)
-{
- gint wx = 0, wy = 0;
- GtkIMContextIME *context_ime;
- COMPOSITIONFORM cf;
- HWND hwnd;
- HIMC himc;
-
- g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context));
-
- context_ime = GTK_IM_CONTEXT_IME (context);
- if (area)
- context_ime->cursor_location = *area;
-
- if (!context_ime->client_window)
- return;
-
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return;
-
- get_window_position (context_ime->client_window, &wx, &wy);
- cf.dwStyle = CFS_POINT;
- cf.ptCurrentPos.x = wx + context_ime->cursor_location.x;
- cf.ptCurrentPos.y = wy + context_ime->cursor_location.y;
- ImmSetCompositionWindow (himc, &cf);
-
- ImmReleaseContext (hwnd, himc);
-}
-
-
-static void
-gtk_im_context_ime_set_use_preedit (GtkIMContext *context,
- gboolean use_preedit)
-{
- GtkIMContextIME *context_ime;
-
- g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context));
- context_ime = GTK_IM_CONTEXT_IME (context);
-
- context_ime->use_preedit = use_preedit;
- if (context_ime->preediting)
- {
- HWND hwnd;
- HIMC himc;
-
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return;
-
- /* FIXME: What to do? */
-
- ImmReleaseContext (hwnd, himc);
- }
-}
-
-
-static void
-gtk_im_context_ime_set_preedit_font (GtkIMContext *context)
-{
- GtkIMContextIME *context_ime;
- GtkWidget *widget = NULL;
- HWND hwnd;
- HIMC himc;
- HKL ime = GetKeyboardLayout (0);
- const gchar *lang;
- gunichar wc;
- PangoContext *pango_context;
- PangoFont *font;
- LOGFONT *logfont;
- GtkStyleContext *style;
- PangoFontDescription *font_desc;
-
- g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context));
-
- context_ime = GTK_IM_CONTEXT_IME (context);
- if (!context_ime->client_window)
- return;
-
- gdk_window_get_user_data (context_ime->client_window, (gpointer) &widget);
- if (!GTK_IS_WIDGET (widget))
- return;
-
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return;
-
- /* set font */
- pango_context = gtk_widget_get_pango_context (widget);
- if (!pango_context)
- goto ERROR_OUT;
-
- /* Try to make sure we use a font that actually can show the
- * language in question.
- */
-
- switch (PRIMARYLANGID (LOWORD (ime)))
- {
- case LANG_JAPANESE:
- lang = "ja"; break;
- case LANG_KOREAN:
- lang = "ko"; break;
- case LANG_CHINESE:
- switch (SUBLANGID (LOWORD (ime)))
- {
- case SUBLANG_CHINESE_TRADITIONAL:
- lang = "zh_TW"; break;
- case SUBLANG_CHINESE_SIMPLIFIED:
- lang = "zh_CN"; break;
- case SUBLANG_CHINESE_HONGKONG:
- lang = "zh_HK"; break;
- case SUBLANG_CHINESE_SINGAPORE:
- lang = "zh_SG"; break;
- case SUBLANG_CHINESE_MACAU:
- lang = "zh_MO"; break;
- default:
- lang = "zh"; break;
- }
- break;
- default:
- lang = ""; break;
- }
-
- style = gtk_widget_get_style_context (widget);
- gtk_style_context_save (style);
- gtk_style_context_set_state (style, GTK_STATE_FLAG_NORMAL);
- gtk_style_context_get (style,
- "font",
- &font_desc,
- NULL);
- gtk_style_context_restore (style);
-
- if (lang[0])
- {
- /* We know what language it is. Look for a character, any
- * character, that language needs.
- */
- PangoLanguage *pango_lang = pango_language_from_string (lang);
- PangoFontset *fontset =
- pango_context_load_fontset (pango_context,
- font_desc,
- pango_lang);
- gunichar *sample =
- g_utf8_to_ucs4 (pango_language_get_sample_string (pango_lang),
- -1, NULL, NULL, NULL);
- wc = 0x4E00; /* In all CJK languages? */
- if (sample != NULL)
- {
- int i;
-
- for (i = 0; sample[i]; i++)
- if (g_unichar_iswide (sample[i]))
- {
- wc = sample[i];
- break;
- }
- g_free (sample);
- }
- font = pango_fontset_get_font (fontset, wc);
- g_object_unref (fontset);
- }
- else
- font = pango_context_load_font (pango_context, font_desc);
-
- if (!font)
- goto ERROR_OUT;
-
- logfont = pango_win32_font_logfont (font);
- if (logfont)
- ImmSetCompositionFont (himc, logfont);
-
- g_object_unref (font);
-
-ERROR_OUT:
- /* clean */
- ImmReleaseContext (hwnd, himc);
-}
-
-
-static GdkFilterReturn
-gtk_im_context_ime_message_filter (GdkXEvent *xevent,
- GdkEvent *event,
- gpointer data)
-{
- GtkIMContext *context;
- GtkIMContextIME *context_ime;
- HWND hwnd;
- HIMC himc;
- MSG *msg = (MSG *) xevent;
- GdkFilterReturn retval = GDK_FILTER_CONTINUE;
-
- g_return_val_if_fail (GTK_IS_IM_CONTEXT_IME (data), retval);
-
- context = GTK_IM_CONTEXT (data);
- context_ime = GTK_IM_CONTEXT_IME (data);
- if (!context_ime->focus)
- return retval;
-
- hwnd = gdk_win32_window_get_impl_hwnd (context_ime->client_window);
- himc = ImmGetContext (hwnd);
- if (!himc)
- return retval;
-
- switch (msg->message)
- {
- case WM_IME_COMPOSITION:
- {
- gint wx = 0, wy = 0;
- CANDIDATEFORM cf;
-
- get_window_position (context_ime->client_window, &wx, &wy);
- /* FIXME! */
- {
- HWND hwnd_top;
- POINT pt;
- RECT rc;
-
- hwnd_top =
- gdk_win32_window_get_impl_hwnd (gdk_window_get_toplevel
- (context_ime->client_window));
- GetWindowRect (hwnd_top, &rc);
- pt.x = wx;
- pt.y = wy;
- ClientToScreen (hwnd_top, &pt);
- wx = pt.x - rc.left;
- wy = pt.y - rc.top;
- }
- cf.dwIndex = 0;
- cf.dwStyle = CFS_CANDIDATEPOS;
- cf.ptCurrentPos.x = wx + context_ime->cursor_location.x;
- cf.ptCurrentPos.y = wy + context_ime->cursor_location.y
- + context_ime->cursor_location.height;
- ImmSetCandidateWindow (himc, &cf);
-
- if ((msg->lParam & GCS_COMPSTR))
- g_signal_emit_by_name (context, "preedit-changed");
-
- if (msg->lParam & GCS_RESULTSTR)
- {
- gsize len;
- gchar *utf8str = NULL;
- GError *error = NULL;
-
- len = ImmGetCompositionStringW (himc, GCS_RESULTSTR, NULL, 0);
-
- if (len > 0)
- {
- gpointer buf = g_alloca (len);
- ImmGetCompositionStringW (himc, GCS_RESULTSTR, buf, len);
- len /= 2;
- context_ime->commit_string = g_utf16_to_utf8 (buf, len, NULL, NULL, &error);
- if (error)
- {
- g_warning ("%s", error->message);
- g_error_free (error);
- }
- }
-
- if (context_ime->commit_string)
- retval = TRUE;
- }
-
- if (context_ime->use_preedit)
- retval = TRUE;
- break;
- }
-
- case WM_IME_STARTCOMPOSITION:
- context_ime->preediting = TRUE;
- gtk_im_context_ime_set_cursor_location (context, NULL);
- g_signal_emit_by_name (context, "preedit-start");
- if (context_ime->use_preedit)
- retval = TRUE;
- break;
-
- case WM_IME_ENDCOMPOSITION:
- context_ime->preediting = FALSE;
- g_signal_emit_by_name (context, "preedit-changed");
- g_signal_emit_by_name (context, "preedit-end");
-
- if (context_ime->commit_string)
- {
- g_signal_emit_by_name (context, "commit", context_ime->commit_string);
- g_free (context_ime->commit_string);
- context_ime->commit_string = NULL;
- }
-
- if (context_ime->use_preedit)
- retval = TRUE;
- break;
-
- case WM_IME_NOTIFY:
- switch (msg->wParam)
- {
- case IMN_SETOPENSTATUS:
- context_ime->opened = ImmGetOpenStatus (himc);
- gtk_im_context_ime_set_preedit_font (context);
- break;
-
- default:
- break;
- }
-
- default:
- break;
- }
-
- ImmReleaseContext (hwnd, himc);
- return retval;
-}
-
-
-/*
- * x and y must be initialized to 0.
- */
-static void
-get_window_position (GdkWindow *win, gint *x, gint *y)
-{
- GdkWindow *parent, *toplevel;
- gint wx, wy;
-
- g_return_if_fail (GDK_IS_WINDOW (win));
- g_return_if_fail (x && y);
-
- gdk_window_get_position (win, &wx, &wy);
- *x += wx;
- *y += wy;
- parent = gdk_window_get_parent (win);
- toplevel = gdk_window_get_toplevel (win);
-
- if (parent && parent != toplevel)
- get_window_position (parent, x, y);
-}
-
-
-/*
- * probably, this handler isn't needed.
- */
-static void
-cb_client_widget_hierarchy_changed (GtkWidget *widget,
- GtkWidget *widget2,
- GtkIMContextIME *context_ime)
-{
- GdkWindow *new_toplevel;
-
- g_return_if_fail (GTK_IS_WIDGET (widget));
- g_return_if_fail (GTK_IS_IM_CONTEXT_IME (context_ime));
-
- if (!context_ime->client_window)
- return;
- if (!context_ime->focus)
- return;
-
- new_toplevel = gdk_window_get_toplevel (context_ime->client_window);
- if (context_ime->toplevel == new_toplevel)
- return;
-
- /* remove filter from old toplevel */
- if (GDK_IS_WINDOW (context_ime->toplevel))
- {
- gdk_window_remove_filter (context_ime->toplevel,
- gtk_im_context_ime_message_filter,
- context_ime);
- }
- else
- {
- }
-
- /* add filter to new toplevel */
- if (GDK_IS_WINDOW (new_toplevel))
- {
- gdk_window_add_filter (new_toplevel,
- gtk_im_context_ime_message_filter, context_ime);
- }
- else
- {
- }
-
- context_ime->toplevel = new_toplevel;
-}
diff --git a/modules/input/gtkimcontextime.h b/modules/input/gtkimcontextime.h
deleted file mode 100644
index 6bb036558f..0000000000
--- a/modules/input/gtkimcontextime.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * gtkimmoduleime
- * Copyright (C) 2003 Takuro Ashie
- * Copyright (C) 2003 Kazuki IWAMOTO
- *
- * 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/>.
- *
- * $Id$
- */
-
-#include <gtk/gtk.h>
-
-#define GTK_TYPE_IM_CONTEXT_IME gtk_type_im_context_ime
-#define GTK_IM_CONTEXT_IME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_IME, GtkIMContextIME))
-#define GTK_IM_CONTEXT_IME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_IM_CONTEXT_IME, GtkIMContextIMEClass))
-#define GTK_IS_IM_CONTEXT_IME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_IM_CONTEXT_IME))
-#define GTK_IS_IM_CONTEXT_IME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_IM_CONTEXT_IME))
-#define GTK_IM_CONTEXT_IME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_IM_CONTEXT_IME, GtkIMContextIMEClass))
-
-typedef struct _GtkIMContextIME GtkIMContextIME;
-typedef struct _GtkIMContextIMEPrivate GtkIMContextIMEPrivate;
-typedef struct _GtkIMContextIMEClass GtkIMContextIMEClass;
-
-struct _GtkIMContextIME
-{
- GtkIMContext object;
-
- GdkWindow *client_window;
- GdkWindow *toplevel;
- guint use_preedit : 1;
- guint preediting : 1;
- guint opened : 1;
- guint focus : 1;
- GdkRectangle cursor_location;
- gchar *commit_string;
-
- GtkIMContextIMEPrivate *priv;
-};
-
-struct _GtkIMContextIMEClass
-{
- GtkIMContextClass parent_class;
-};
-
-
-void gtk_im_context_ime_register_type (GTypeModule * type_module);
-GtkIMContext *gtk_im_context_ime_new (void);
diff --git a/modules/input/gtkimcontextxim.c b/modules/input/gtkimcontextxim.c
deleted file mode 100644
index 03ce3e727c..0000000000
--- a/modules/input/gtkimcontextxim.c
+++ /dev/null
@@ -1,1804 +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 "gtkimmodule.h"
-#include "gtkimcontextxim.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;
-
- GdkWindow *client_window;
- Window client_window_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_class_init (GtkIMContextXIMClass *class);
-static void gtk_im_context_xim_init (GtkIMContextXIM *im_context_xim);
-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_window (GtkIMContextXIM *context_xim,
- GdkWindow *client_window);
-
-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_DYNAMIC_TYPE (GtkIMContextXIM, gtk_im_context_xim, GTK_TYPE_IM_CONTEXT)
-
-void
-g_io_module_load (GIOModule *module)
-{
- g_type_module_use (G_TYPE_MODULE (module));
-
- g_print ("load io module for x11\n");
- gtk_im_context_xim_register_type (G_TYPE_MODULE (module));
-
- g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
- GTK_TYPE_IM_CONTEXT_XIM,
- "xim",
- 10);
-}
-
-void
-g_io_module_unload (GIOModule *module)
-{
-}
-
-char **
-g_io_module_query (void)
-{
- char *eps[] = {
- GTK_IM_MODULE_EXTENSION_POINT_NAME,
- NULL
- };
-
- return g_strdupv (eps);
-}
-
-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_window (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 (GdkWindow *client_window,
- const char *locale)
-{
- GSList *tmp_list;
- GtkXIMInfo *info;
- GdkDisplay *display = gdk_window_get_display (client_window);
-
- info = NULL;
- tmp_list = open_ims;
- while (tmp_list)
- {
- GtkXIMInfo *tmp_info = tmp_list->data;
- if (tmp_info->display == display &&
- strcmp (tmp_info->locale, locale) == 0)
- {
- if (tmp_info->im)
- {
- return tmp_info;
- }
- else
- {
- tmp_info = tmp_info;
- 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_class_finalize (GtkIMContextXIMClass *class)
-{
-}
-
-static void
-gtk_im_context_xim_init (GtkIMContextXIM *im_context_xim)
-{
- 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;
-}
-
-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_window (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_window (GtkIMContextXIM *context_xim,
- GdkWindow *client_window)
-{
- reinitialize_ic (context_xim);
- if (context_xim->client_window)
- {
- context_xim->im_info->ics = g_slist_remove (context_xim->im_info->ics, context_xim);
- context_xim->im_info = NULL;
- }
-
- context_xim->client_window = client_window;
- context_xim->client_window_xid = None;
-
- if (context_xim->client_window)
- {
- GdkWindow *native;
-
- context_xim->im_info = get_im (context_xim->client_window, context_xim->locale);
- context_xim->im_info->ics = g_slist_prepend (context_xim->im_info->ics, context_xim);
-
- for (native = client_window; native; native = gdk_window_get_parent (native))
- {
- if (gdk_window_has_native (native))
- {
- context_xim->client_window_xid = gdk_x11_window_get_xid (native);
- break;
- }
- }
- }
-
- 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);
- GtkWidget *toplevel = gtk_widget_get_toplevel (widget);
-
- set_ic_client_window (context_xim, gtk_widget_get_window (toplevel));
-}
-
-GtkIMContext *
-gtk_im_context_xim_new (void)
-{
- GtkIMContextXIM *result;
- const gchar *charset;
-
- if (!GDK_IS_X11_DISPLAY(gdk_display_get_default()))
- return NULL;
- result = g_object_new (GTK_TYPE_IM_CONTEXT_XIM, NULL);
-
- result->locale = g_strdup (setlocale (LC_CTYPE, NULL));
-
- g_get_charset (&charset);
- result->mb_charset = g_strdup (charset);
-
- return GTK_IM_CONTEXT (result);
-}
-
-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;
- GdkWindow *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_window_get_toplevel (gdk_event_get_window ((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_WINDOW_XDISPLAY (window);
- xevent.window = GDK_WINDOW_XID (window);
- xevent.root = DefaultRootWindow(GDK_WINDOW_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_window_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_window_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 GdkWindow
- * hierarchy from context->client_window until we find a
- * window that is owned by some widget, and then calling
- * gtk_widget_get_toplevel() on that widget. This should
- * handle both cases where we might have GdkWindows 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_get_toplevel (context_xim->client_widget);
- if (toplevel && gtk_widget_is_toplevel (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_get_toplevel (context_xim->client_widget);
-
- context_xim->in_toplevel = (toplevel && gtk_widget_is_toplevel (toplevel));
- }
- 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,
- GtkWidget *old_toplevel,
- GtkIMContextXIM *context_xim)
-{
- update_in_toplevel (context_xim);
-}
-
-/* Finds the GtkWidget that owns the window, or if none, the
- * widget owning the nearest parent that has a widget.
- */
-static GtkWidget *
-widget_for_window (GdkWindow *window)
-{
- while (window)
- {
- gpointer user_data;
- gdk_window_get_user_data (window, &user_data);
- if (user_data)
- return user_data;
-
- window = gdk_window_get_parent (window);
- }
-
- return NULL;
-}
-
-/* Called when context_xim->client_window 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 = widget_for_window (context_xim->client_window);
-
- 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, "hierarchy-changed",
- 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)));
-}
-
-/* Called when the toplevel window is moved; updates the position of
- * the status window to follow it.
- */
-static gboolean
-on_status_toplevel_configure (GtkWidget *toplevel,
- GdkEvent *event,
- StatusWindow *status_window)
-{
- if (gdk_event_get_event_type (event) == GDK_CONFIGURE)
- {
- GdkRectangle rect;
- GtkRequisition requisition;
- gint y;
- gint height;
-
- if (status_window->window)
- {
- height = DisplayHeight(GDK_WINDOW_XDISPLAY (gtk_widget_get_window (toplevel)), 0);
-
- gdk_window_get_frame_extents (gtk_widget_get_window (toplevel), &rect);
- gtk_widget_get_preferred_size ( (status_window->window), &requisition, NULL);
-
- if (rect.y + rect.height + requisition.height < height)
- y = rect.y + rect.height;
- else
- y = height - requisition.height;
-
- gtk_window_move (GTK_WINDOW (status_window->window), rect.x, y);
- }
- }
-
- return GDK_EVENT_PROPAGATE;
-}
-
-/* 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);
- g_signal_handlers_disconnect_by_func (status_window->toplevel,
- G_CALLBACK (on_status_toplevel_configure),
- 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, "event",
- G_CALLBACK (on_status_toplevel_configure),
- 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));
-
- on_status_toplevel_configure (status_window->toplevel, NULL, status_window);
-}
-
-/* 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/modules/input/gtkimcontextxim.h b/modules/input/gtkimcontextxim.h
deleted file mode 100644
index d81a7ff2d1..0000000000
--- a/modules/input/gtkimcontextxim.h
+++ /dev/null
@@ -1,48 +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;
-};
-
-GtkIMContext *gtk_im_context_xim_new (void);
-
-void gtk_im_context_xim_shutdown (void);
-
-G_END_DECLS
-
-#endif /* __GTK_IM_CONTEXT_XIM_H__ */
diff --git a/modules/input/imbroadway.c b/modules/input/imbroadway.c
deleted file mode 100644
index 2fb40d471e..0000000000
--- a/modules/input/imbroadway.c
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * gtkimmodulebroadway
- * Copyright (C) 2013 Alexander Larsson
- *
- * 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/>.
- *
- * $Id:$
- */
-
-#include "config.h"
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include "gtk/gtkintl.h"
-#include "gtk/gtkimmodule.h"
-
-#include "gdk/broadway/gdkbroadway.h"
-
-#define GTK_TYPE_IM_CONTEXT_BROADWAY (gtk_im_context_broadway_get_type ())
-#define GTK_IM_CONTEXT_BROADWAY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_BROADWAY, GtkIMContextBroadway))
-#define GTK_IM_CONTEXT_BROADWAY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_TYPE_IM_CONTEXT_BROADWAY, GtkIMContextBroadwayClass))
-
-typedef struct _GtkIMContextBroadway
-{
- GtkIMContextSimple parent;
- GtkWidget *client_widget;
-} GtkIMContextBroadway;
-
-typedef struct _GtkIMContextBroadwayClass
-{
- GtkIMContextSimpleClass parent_class;
-} GtkIMContextBroadwayClass;
-
-G_DEFINE_DYNAMIC_TYPE (GtkIMContextBroadway, gtk_im_context_broadway, GTK_TYPE_IM_CONTEXT_SIMPLE)
-
-void
-g_io_module_load (GIOModule *module)
-{
- g_type_module_use (G_TYPE_MODULE (module));
-
- g_print ("load io module for broadway\n");
- gtk_im_context_broadway_register_type (G_TYPE_MODULE (module));
-
- g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
- GTK_TYPE_IM_CONTEXT_BROADWAY,
- "broadway",
- 10);
-}
-
-void
-g_io_module_unload (GIOModule *module)
-{
-}
-
-char **
-g_io_module_query (void)
-{
- char *eps[] = {
- GTK_IM_MODULE_EXTENSION_POINT_NAME,
- NULL
- };
-
- return g_strdupv (eps);
-}
-
-
-static void
-broadway_set_client_widget (GtkIMContext *context, GtkWidget *widget)
-{
- GtkIMContextBroadway *bw = GTK_IM_CONTEXT_BROADWAY (context);
-
- bw->client_widget = widget;
-}
-
-static void
-broadway_focus_in (GtkIMContext *context)
-{
- GtkIMContextBroadway *bw = GTK_IM_CONTEXT_BROADWAY (context);
- GdkDisplay *display;
-
- if (bw->client_widget)
- {
- display = gtk_widget_get_display (bw->client_widget);
- gdk_broadway_display_show_keyboard (GDK_BROADWAY_DISPLAY (display));
- }
-}
-
-static void
-broadway_focus_out (GtkIMContext *context)
-{
- GtkIMContextBroadway *bw = GTK_IM_CONTEXT_BROADWAY (context);
- GdkDisplay *display;
-
- if (bw->client_widget)
- {
- display = gtk_widget_get_display (bw->client_widget);
- gdk_broadway_display_hide_keyboard (GDK_BROADWAY_DISPLAY (display));
- }
-}
-
-static void
-gtk_im_context_broadway_class_init (GtkIMContextBroadwayClass *class)
-{
- GtkIMContextClass *klass = GTK_IM_CONTEXT_CLASS (class);
-
- klass->focus_in = broadway_focus_in;
- klass->focus_out = broadway_focus_out;
- klass->set_client_widget = broadway_set_client_widget;
-}
-
-static void
-gtk_im_context_broadway_class_finalize (GtkIMContextBroadwayClass *class)
-{
-}
-
-static void
-gtk_im_context_broadway_init (GtkIMContextBroadway *im_context)
-{
-}
diff --git a/modules/input/imm-extra.h b/modules/input/imm-extra.h
deleted file mode 100644
index 094dc5b17c..0000000000
--- a/modules/input/imm-extra.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2003 Takuro Ashie
- *
- * 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/>.
- *
- * $Id$
- */
-
-#include <windows.h>
-#include <imm.h>
-
-
-/* these aren't defined in Cygwin's imm.h */
-
-#ifndef WM_IME_REQUEST
-# define WM_IME_REQUEST 0x0288
-#endif /* WM_IME_REQUEST */
-
-#ifndef IMR_COMPOSITIONWINDOW
-# define IMR_COMPOSITIONWINDOW 0x0001
-#endif /* IMR_COMPOSITIONWINDOW */
-
-#ifndef IMR_CANDIDATEWINDOW
-# define IMR_CANDIDATEWINDOW 0x0002
-#endif /* IMR_CANDIDATEWINDOW */
-
-#ifndef IMR_COMPOSITIONFONT
-# define IMR_COMPOSITIONFONT 0x0003
-#endif /* IMR_COMPOSITIONFONT */
-
-#ifndef IMR_RECONVERTSTRING
-# define IMR_RECONVERTSTRING 0x0004
-#endif /* IMR_RECONVERTSTRING */
-
-#ifndef IMR_CONFIRMRECONVERTSTRING
-# define IMR_CONFIRMRECONVERTSTRING 0x0005
-#endif /* IMR_CONFIRMRECONVERTSTRING */
-
-#ifndef IMR_QUERYCHARPOSITION
-# define IMR_QUERYCHARPOSITION 0x0006
-typedef struct tagIMECHARPOSITION {
- DWORD dwSize;
- DWORD dwCharPos;
- POINT pt;
- UINT cLineHeight;
- RECT rcDocument;
-} IMECHARPOSITION, *PIMECHARPOSITION;
-#endif /* IMR_QUERYCHARPOSITION */
-
-#ifndef IMR_DOCUMENTFEED
-# define IMR_DOCUMENTFEED 0x0007
-#endif /* IMR_DOCUMENTFEED */
diff --git a/modules/input/imquartz.c b/modules/input/imquartz.c
deleted file mode 100644
index 9d1a1cc9f8..0000000000
--- a/modules/input/imquartz.c
+++ /dev/null
@@ -1,417 +0,0 @@
-/*
- * gtkimmodulequartz
- * Copyright (C) 2011 Hiroyuki Yamamoto
- *
- * 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/>.
- *
- * $Id:$
- */
-
-#include "config.h"
-#include <string.h>
-
-#include <gtk/gtk.h>
-#include "gtk/gtkintl.h"
-#include "gtk/gtkimmodule.h"
-
-#include "gdk/quartz/gdkquartz.h"
-#include "gdk/quartz/GdkQuartzView.h"
-
-#define GTK_IM_CONTEXT_TYPE_QUARTZ (type_quartz)
-#define GTK_IM_CONTEXT_QUARTZ(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_IM_CONTEXT_TYPE_QUARTZ, GtkIMContextQuartz))
-#define GTK_IM_CONTEXT_QUARTZ_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GTK_IM_CONTEXT_TYPE_QUARTZ, GtkIMContextQuartzClass))
-
-
-typedef struct _GtkIMContextQuartz
-{
- GtkIMContext parent;
- GtkIMContext *slave;
- GdkWindow *client_window;
- gchar *preedit_str;
- unsigned int cursor_index;
- unsigned int selected_len;
- GdkRectangle *cursor_rect;
- gboolean focused;
-} GtkIMContextQuartz;
-
-typedef struct _GtkIMContextQuartzClass
-{
- GtkIMContextClass parent_class;
-} GtkIMContextQuartzClass;
-
-G_DEFINE_DYNAMIC_TYPE (GtkIMContextQuartz, gtk_im_context_quartz, GTK_TYPE_IM_CONTEXT)
-
-void
-g_io_module_load (GIOModule *module)
-{
- g_type_module_use (G_TYPE_MODULE (module));
-
- g_print ("load io module for quartz\n");
- gtk_im_context_quartz_register_type (G_TYPE_MODULE (module));
-
- g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
- GTK_TYPE_IM_CONTEXT_BROADWAY,
- "quartz",
- 10);
-}
-
-void
-g_io_module_unload (GIOModule *module)
-{
-}
-
-char **
-g_io_module_query (void)
-{
- char *eps[] = {
- GTK_IM_MODULE_EXTENSION_POINT_NAME,
- NULL
- };
-
- return g_strdupv (eps);
-}
-
-
-
-
-
-static void
-quartz_get_preedit_string (GtkIMContext *context,
- gchar **str,
- PangoAttrList **attrs,
- gint *cursor_pos)
-{
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
-
- GTK_NOTE (MISC, g_print ("quartz_get_preedit_string\n"));
-
- if (str)
- *str = qc->preedit_str ? g_strdup (qc->preedit_str) : g_strdup ("");
-
- if (attrs)
- {
- *attrs = pango_attr_list_new ();
- int len = g_utf8_strlen (*str, -1);
- gchar *ch = *str;
- if (len > 0)
- {
- PangoAttribute *attr;
- int i = 0;
- for (;;)
- {
- gchar *s = ch;
- ch = g_utf8_next_char (ch);
-
- if (i >= qc->cursor_index &&
- i < qc->cursor_index + qc->selected_len)
- attr = pango_attr_underline_new (PANGO_UNDERLINE_DOUBLE);
- else
- attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
-
- attr->start_index = s - *str;
- if (!*ch)
- attr->end_index = attr->start_index + strlen (s);
- else
- attr->end_index = ch - *str;
-
- pango_attr_list_change (*attrs, attr);
-
- if (!*ch)
- break;
- i++;
- }
- }
- }
- if (cursor_pos)
- *cursor_pos = qc->cursor_index;
-}
-
-static gboolean
-output_result (GtkIMContext *context,
- GdkWindow *win)
-{
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
- gboolean retval = FALSE;
- gchar *fixed_str, *marked_str;
-
- fixed_str = g_strdup (g_object_get_data (G_OBJECT (win), TIC_INSERT_TEXT));
- marked_str = g_strdup (g_object_get_data (G_OBJECT (win), TIC_MARKED_TEXT));
- if (fixed_str)
- {
- GTK_NOTE (MISC, g_print ("tic-insert-text: %s\n", fixed_str));
- g_free (qc->preedit_str);
- qc->preedit_str = NULL;
- g_object_set_data (G_OBJECT (win), TIC_INSERT_TEXT, NULL);
- g_signal_emit_by_name (context, "commit", fixed_str);
- g_signal_emit_by_name (context, "preedit_changed");
-
- unsigned int filtered =
- GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (win),
- GIC_FILTER_KEY));
- GTK_NOTE (MISC, g_print ("filtered, %d\n", filtered));
- if (filtered)
- retval = TRUE;
- else
- retval = FALSE;
- }
- if (marked_str)
- {
- GTK_NOTE (MISC, g_print ("tic-marked-text: %s\n", marked_str));
- qc->cursor_index =
- GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (win),
- TIC_SELECTED_POS));
- qc->selected_len =
- GPOINTER_TO_UINT (g_object_get_data (G_OBJECT (win),
- TIC_SELECTED_LEN));
- g_free (qc->preedit_str);
- qc->preedit_str = g_strdup (marked_str);
- g_object_set_data (G_OBJECT (win), TIC_MARKED_TEXT, NULL);
- g_signal_emit_by_name (context, "preedit_changed");
- retval = TRUE;
- }
- if (!fixed_str && !marked_str)
- {
- if (qc->preedit_str && strlen (qc->preedit_str) > 0)
- retval = TRUE;
- }
- g_free (fixed_str);
- g_free (marked_str);
- return retval;
-}
-
-static gboolean
-quartz_filter_keypress (GtkIMContext *context,
- GdkEventKey *event)
-{
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
- gboolean retval;
- NSView *nsview;
- GdkWindow *win;
-
- GTK_NOTE (MISC, g_print ("quartz_filter_keypress\n"));
-
- if (!GDK_IS_QUARTZ_WINDOW (qc->client_window))
- return FALSE;
-
- nsview = gdk_quartz_window_get_nsview (qc->client_window);
- win = (GdkWindow *)[ (GdkQuartzView *)nsview gdkWindow];
- GTK_NOTE (MISC, g_print ("client_window: %p, win: %p, nsview: %p\n",
- qc->client_window, win, nsview));
-
- NSEvent *nsevent = gdk_quartz_event_get_nsevent ((GdkEvent *)event);
-
- if (!nsevent)
- {
- if (event->hardware_keycode == 0 && event->keyval == 0xffffff)
- /* update text input changes by mouse events */
- return output_result (context, win);
- else
- return gtk_im_context_filter_keypress (qc->slave, event);
- }
-
- if (event->type == GDK_KEY_RELEASE)
- return FALSE;
-
- if (event->hardware_keycode == 55) /* Command */
- return FALSE;
-
- NSEventType etype = [nsevent type];
- if (etype == NSKeyDown)
- {
- g_object_set_data (G_OBJECT (win), TIC_IN_KEY_DOWN,
- GUINT_TO_POINTER (TRUE));
- [nsview keyDown: nsevent];
- }
- /* JIS_Eisu || JIS_Kana */
- if (event->hardware_keycode == 102 || event->hardware_keycode == 104)
- return FALSE;
-
- retval = output_result(context, win);
- g_object_set_data (G_OBJECT (win), TIC_IN_KEY_DOWN,
- GUINT_TO_POINTER (FALSE));
- GTK_NOTE (MISC, g_print ("quartz_filter_keypress done\n"));
-
- return retval;
-}
-
-static void
-discard_preedit (GtkIMContext *context)
-{
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
-
- if (!qc->client_window)
- return;
-
- if (!GDK_IS_QUARTZ_WINDOW (qc->client_window))
- return;
-
- NSView *nsview = gdk_quartz_window_get_nsview (qc->client_window);
- if (!nsview)
- return;
-
- /* reset any partial input for this NSView */
- [(GdkQuartzView *)nsview unmarkText];
- NSInputManager *currentInputManager = [NSInputManager currentInputManager];
- [currentInputManager markedTextAbandoned:nsview];
-
- if (qc->preedit_str && strlen (qc->preedit_str) > 0)
- {
- g_signal_emit_by_name (context, "commit", qc->preedit_str);
-
- g_free (qc->preedit_str);
- qc->preedit_str = NULL;
- g_signal_emit_by_name (context, "preedit_changed");
- }
-}
-
-static void
-quartz_reset (GtkIMContext *context)
-{
- GTK_NOTE (MISC, g_print ("quartz_reset\n"));
- discard_preedit (context);
-}
-
-static void
-quartz_set_client_window (GtkIMContext *context, GtkWidget *widget)
-{
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
-
- GTK_NOTE (MISC, g_print ("quartz_set_client_window: %p\n", widget));
-
- qc->client_window = gtk_widget_get_parent_window (widget);
-}
-
-static void
-quartz_focus_in (GtkIMContext *context)
-{
- GTK_NOTE (MISC, g_print ("quartz_focus_in\n"));
-
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
- qc->focused = TRUE;
-}
-
-static void
-quartz_focus_out (GtkIMContext *context)
-{
- GTK_NOTE (MISC, g_print ("quartz_focus_out\n"));
-
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
- qc->focused = FALSE;
-
- /* Commit any partially built strings or it'll mess up other GTK+ widgets in the window */
- discard_preedit (context);
-}
-
-static void
-quartz_set_cursor_location (GtkIMContext *context, GdkRectangle *area)
-{
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (context);
- gint x, y;
- NSView *nsview;
- GdkWindow *win;
-
- GTK_NOTE (MISC, g_print ("quartz_set_cursor_location\n"));
-
- if (!qc->client_window)
- return;
-
- if (!qc->focused)
- return;
-
- qc->cursor_rect->x = area->x;
- qc->cursor_rect->y = area->y;
- qc->cursor_rect->width = area->width;
- qc->cursor_rect->height = area->height;
-
- gdk_window_get_origin (qc->client_window, &x, &y);
-
- qc->cursor_rect->x = area->x + x;
- qc->cursor_rect->y = area->y + y;
-
- if (!GDK_IS_QUARTZ_WINDOW (qc->client_window))
- return;
-
- nsview = gdk_quartz_window_get_nsview (qc->client_window);
- win = (GdkWindow *)[ (GdkQuartzView*)nsview gdkWindow];
- g_object_set_data (G_OBJECT (win), GIC_CURSOR_RECT, qc->cursor_rect);
-}
-
-static void
-quartz_set_use_preedit (GtkIMContext *context, gboolean use_preedit)
-{
- GTK_NOTE (MISC, g_print ("quartz_set_use_preedit: %d\n", use_preedit));
-}
-
-static void
-commit_cb (GtkIMContext *context, const gchar *str, GtkIMContextQuartz *qc)
-{
- g_signal_emit_by_name (qc, "commit", str);
-}
-
-static void
-imquartz_finalize (GObject *obj)
-{
- GTK_NOTE (MISC, g_print ("imquartz_finalize\n"));
-
- GtkIMContextQuartz *qc = GTK_IM_CONTEXT_QUARTZ (obj);
- g_free (qc->preedit_str);
- qc->preedit_str = NULL;
- g_free (qc->cursor_rect);
- qc->cursor_rect = NULL;
-
- g_signal_handlers_disconnect_by_func (qc->slave, (gpointer)commit_cb, qc);
- g_object_unref (qc->slave);
-
- gtk_im_context_quartz_parent_class->finalize (obj);
-}
-
-static void
-gtk_im_context_quartz_class_init (GtkIMContextQuartzClass *class)
-{
- GTK_NOTE (MISC, g_print ("gtk_im_context_quartz_class_init\n"));
-
- GtkIMContextClass *klass = GTK_IM_CONTEXT_CLASS (class);
- GObjectClass *object_class = G_OBJECT_CLASS (class);
-
- klass->get_preedit_string = quartz_get_preedit_string;
- klass->filter_keypress = quartz_filter_keypress;
- klass->reset = quartz_reset;
- klass->set_client_widget = quartz_set_client_window;
- klass->focus_in = quartz_focus_in;
- klass->focus_out = quartz_focus_out;
- klass->set_cursor_location = quartz_set_cursor_location;
- klass->set_use_preedit = quartz_set_use_preedit;
-
- object_class->finalize = imquartz_finalize;
-}
-
-static void
-gtk_im_context_quartz_class_finalize (GtkIMContextQuartzClass *class)
-{
-}
-
-static void
-gtk_im_context_quartz_init (GtkIMContextQuartz *qc)
-{
- GTK_NOTE (MISC, g_print ("gtk_im_context_quartz_init\n"));
-
- qc->preedit_str = g_strdup ("");
- qc->cursor_index = 0;
- qc->selected_len = 0;
- qc->cursor_rect = g_malloc (sizeof (GdkRectangle));
- qc->focused = FALSE;
-
- qc->slave = g_object_new (GTK_TYPE_IM_CONTEXT_SIMPLE, NULL);
- g_signal_connect (G_OBJECT (qc->slave), "commit", G_CALLBACK (commit_cb), qc);
-}
diff --git a/modules/input/imwayland.c b/modules/input/imwayland.c
deleted file mode 100644
index 24f4f397dd..0000000000
--- a/modules/input/imwayland.c
+++ /dev/null
@@ -1,655 +0,0 @@
-/* GTK - The GIMP Toolkit
- * Copyright (C) 2017 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 <string.h>
-#include <wayland-client-protocol.h>
-
-#include <gtk/gtk.h>
-#include "gtk/gtkintl.h"
-#include "gtk/gtkimmodule.h"
-
-#include "gdk/wayland/gdkwayland.h"
-#include "gtk-text-input-client-protocol.h"
-
-typedef struct _GtkIMContextWaylandGlobal GtkIMContextWaylandGlobal;
-typedef struct _GtkIMContextWayland GtkIMContextWayland;
-typedef struct _GtkIMContextWaylandClass GtkIMContextWaylandClass;
-
-struct _GtkIMContextWaylandGlobal
-{
- struct wl_display *display;
- struct wl_registry *registry;
- struct gtk_text_input_manager *text_input_manager;
- struct gtk_text_input *text_input;
- uint32_t enter_serial;
-
- GtkIMContext *current;
-};
-
-struct _GtkIMContextWaylandClass
-{
- GtkIMContextSimpleClass parent_class;
-};
-
-struct _GtkIMContextWayland
-{
- GtkIMContextSimple parent_instance;
- GtkWidget *widget;
-
- GtkGesture *gesture;
- gdouble press_x;
- gdouble press_y;
-
- struct {
- gchar *text;
- gint cursor_idx;
- } surrounding;
-
- struct {
- gchar *text;
- gint cursor_idx;
- } preedit;
-
- cairo_rectangle_int_t cursor_rect;
- guint use_preedit : 1;
-};
-
-static GtkIMContextWaylandGlobal *global = NULL;
-
-static void gtk_im_context_wayland_global_init (GdkDisplay *display);
-
-#define GTK_TYPE_IM_CONTEXT_WAYLAND (gtk_im_context_wayland_get_type ())
-#define GTK_IM_CONTEXT_WAYLAND(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_IM_CONTEXT_WAYLAND, GtkIMContextWayland))
-
-G_DEFINE_DYNAMIC_TYPE (GtkIMContextWayland, gtk_im_context_wayland, GTK_TYPE_IM_CONTEXT_SIMPLE)
-
-void
-g_io_module_load (GIOModule *module)
-{
- g_type_module_use (G_TYPE_MODULE (module));
-
- g_print ("load io module for wayland\n");
- gtk_im_context_wayland_register_type (G_TYPE_MODULE (module));
- gtk_im_context_wayland_global_init (gdk_display_get_default ());
-
- g_io_extension_point_implement (GTK_IM_MODULE_EXTENSION_POINT_NAME,
- GTK_TYPE_IM_CONTEXT_WAYLAND,
- "wayland",
- 10);
-}
-
-void
-g_io_module_unload (GIOModule *module)
-{
-}
-
-char **
-g_io_module_query (void)
-{
- char *eps[] = {
- GTK_IM_MODULE_EXTENSION_POINT_NAME,
- NULL
- };
-
- return g_strdupv (eps);
-}
-
-
-
-static void
-reset_preedit (GtkIMContextWayland *context)
-{
- g_clear_pointer (&context->preedit.text, g_free);
- context->preedit.cursor_idx = 0;
- g_signal_emit_by_name (context, "preedit-changed");
-}
-
-static void
-text_input_enter (void *data,
- struct gtk_text_input *text_input,
- uint32_t serial,
- struct wl_surface *surface)
-{
- GtkIMContextWaylandGlobal *global = data;
-
- global->enter_serial = serial;
-}
-
-static void
-text_input_leave (void *data,
- struct gtk_text_input *text_input,
- uint32_t serial,
- struct wl_surface *surface)
-{
- GtkIMContextWayland *context;
-
- if (!global->current)
- return;
-
- context = GTK_IM_CONTEXT_WAYLAND (global->current);
- reset_preedit (context);
-}
-
-static void
-text_input_preedit (void *data,
- struct gtk_text_input *text_input,
- const char *text,
- guint cursor)
-{
- GtkIMContextWayland *context;
- gboolean state_change;
-
- if (!global->current)
- return;
-
- context = GTK_IM_CONTEXT_WAYLAND (global->current);
- if (!text && !context->preedit.text)
- return;
-
- state_change = ((text == NULL) != (context->preedit.text == NULL));
-
- if (state_change && !context->preedit.text)
- g_signal_emit_by_name (context, "preedit-start");
-
- g_free (context->preedit.text);
- context->preedit.text = g_strdup (text);
- context->preedit.cursor_idx = cursor;
-
- g_signal_emit_by_name (context, "preedit-changed");
-
- if (state_change && !context->preedit.text)
- g_signal_emit_by_name (context, "preedit-end");
-}
-
-static void
-text_input_commit (void *data,
- struct gtk_text_input *text_input,
- const char *text)
-{
- GtkIMContextWaylandGlobal *global = data;
-
- if (global->current && text)
- g_signal_emit_by_name (global->current, "commit", text);
-}
-
-static void
-text_input_delete_surrounding_text (void *data,
- struct gtk_text_input *text_input,
- uint32_t offset,
- uint32_t len)
-{
- GtkIMContextWaylandGlobal *global = data;
-
- if (global->current)
- g_signal_emit_by_name (global->current, "delete-surrounding", offset, len);
-}
-
-static const struct gtk_text_input_listener text_input_listener = {
- text_input_enter,
- text_input_leave,
- text_input_preedit,
- text_input_commit,
- text_input_delete_surrounding_text
-};
-
-static void
-registry_handle_global (void *data,
- struct wl_registry *registry,
- uint32_t id,
- const char *interface,
- uint32_t version)
-{
- GtkIMContextWaylandGlobal *global = data;
- GdkSeat *seat = gdk_display_get_default_seat (gdk_display_get_default ());
-
- if (strcmp (interface, "gtk_text_input_manager") == 0)
- {
- global->text_input_manager =
- wl_registry_bind (global->registry, id,
- &gtk_text_input_manager_interface, 1);
- global->text_input =
- gtk_text_input_manager_get_text_input (global->text_input_manager,
- gdk_wayland_seat_get_wl_seat (seat));
- gtk_text_input_add_listener (global->text_input,
- &text_input_listener, global);
- }
-}
-
-static void
-registry_handle_global_remove (void *data,
- struct wl_registry *registry,
- uint32_t id)
-{
- GtkIMContextWaylandGlobal *global = data;
-
- gtk_text_input_destroy (global->text_input);
- global->text_input = NULL;
-
- gtk_text_input_manager_destroy (global->text_input_manager);
- global->text_input_manager = NULL;
-}
-
-static const struct wl_registry_listener registry_listener = {
- registry_handle_global,
- registry_handle_global_remove
-};
-
-static void
-gtk_im_context_wayland_global_init (GdkDisplay *display)
-{
- if (global)
- return;
-
- global = g_new0 (GtkIMContextWaylandGlobal, 1);
- global->display = gdk_wayland_display_get_wl_display (display);
- global->registry = wl_display_get_registry (global->display);
-
- wl_registry_add_listener (global->registry, &registry_listener, global);
-}
-
-static void
-notify_surrounding_text (GtkIMContextWayland *context)
-{
- if (!global || !global->text_input)
- return;
- if (global->current != GTK_IM_CONTEXT (context))
- return;
- if (!context->surrounding.text)
- return;
-
- gtk_text_input_set_surrounding_text (global->text_input,
- context->surrounding.text,
- context->surrounding.cursor_idx,
- context->surrounding.cursor_idx);
-}
-
-static void
-notify_cursor_location (GtkIMContextWayland *context)
-{
- cairo_rectangle_int_t rect;
-
- if (!global || !global->text_input)
- return;
- if (global->current != GTK_IM_CONTEXT (context))
- return;
- if (!context->widget)
- return;
-
- rect = context->cursor_rect;
- gtk_widget_translate_coordinates (context->widget,
- gtk_widget_get_toplevel (context->widget),
- rect.x, rect.y,
- &rect.x, &rect.y);
-
- gtk_text_input_set_cursor_rectangle (global->text_input,
- rect.x, rect.y,
- rect.width, rect.height);
-}
-
-static uint32_t
-translate_hints (GtkInputHints input_hints,
- GtkInputPurpose purpose)
-{
- uint32_t hints = 0;
-
- if (input_hints & GTK_INPUT_HINT_SPELLCHECK)
- hints |= GTK_TEXT_INPUT_CONTENT_HINT_SPELLCHECK;
- if (input_hints & GTK_INPUT_HINT_WORD_COMPLETION)
- hints |= GTK_TEXT_INPUT_CONTENT_HINT_COMPLETION;
- if (input_hints & GTK_INPUT_HINT_LOWERCASE)
- hints |= GTK_TEXT_INPUT_CONTENT_HINT_LOWERCASE;
- if (input_hints & GTK_INPUT_HINT_UPPERCASE_CHARS)
- hints |= GTK_TEXT_INPUT_CONTENT_HINT_UPPERCASE;
- if (input_hints & GTK_INPUT_HINT_UPPERCASE_WORDS)
- hints |= GTK_TEXT_INPUT_CONTENT_HINT_TITLECASE;
- if (input_hints & GTK_INPUT_HINT_UPPERCASE_SENTENCES)
- hints |= GTK_TEXT_INPUT_CONTENT_HINT_AUTO_CAPITALIZATION;
-
- if (purpose == GTK_INPUT_PURPOSE_PIN ||
- purpose == GTK_INPUT_PURPOSE_PASSWORD)
- {
- hints |= (GTK_TEXT_INPUT_CONTENT_HINT_HIDDEN_TEXT |
- GTK_TEXT_INPUT_CONTENT_HINT_SENSITIVE_DATA);
- }
-
- return hints;
-}
-
-static uint32_t
-translate_purpose (GtkInputPurpose purpose)
-{
- switch (purpose)
- {
- case GTK_INPUT_PURPOSE_FREE_FORM:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
- case GTK_INPUT_PURPOSE_ALPHA:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_ALPHA;
- case GTK_INPUT_PURPOSE_DIGITS:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_DIGITS;
- case GTK_INPUT_PURPOSE_NUMBER:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_NUMBER;
- case GTK_INPUT_PURPOSE_PHONE:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_PHONE;
- case GTK_INPUT_PURPOSE_URL:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_URL;
- case GTK_INPUT_PURPOSE_EMAIL:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_EMAIL;
- case GTK_INPUT_PURPOSE_NAME:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_NAME;
- case GTK_INPUT_PURPOSE_PASSWORD:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_PASSWORD;
- case GTK_INPUT_PURPOSE_PIN:
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_PIN;
- }
-
- return GTK_TEXT_INPUT_CONTENT_PURPOSE_NORMAL;
-}
-
-static void
-notify_content_type (GtkIMContextWayland *context)
-{
- GtkInputHints hints;
- GtkInputPurpose purpose;
-
- if (global->current != GTK_IM_CONTEXT (context))
- return;
-
- g_object_get (context,
- "input-hints", &hints,
- "input-purpose", &purpose,
- NULL);
-
- gtk_text_input_set_content_type (global->text_input,
- translate_hints (hints, purpose),
- translate_purpose (purpose));
-}
-
-static void
-commit_state (GtkIMContextWayland *context)
-{
- if (global->current != GTK_IM_CONTEXT (context))
- return;
- gtk_text_input_commit (global->text_input);
-}
-
-static void
-enable_text_input (GtkIMContextWayland *context,
- gboolean toggle_panel)
-{
- guint flags = 0;
-
- if (context->use_preedit)
- flags |= GTK_TEXT_INPUT_ENABLE_FLAGS_CAN_SHOW_PREEDIT;
- if (toggle_panel)
- flags |= GTK_TEXT_INPUT_ENABLE_FLAGS_TOGGLE_INPUT_PANEL;
-
- gtk_text_input_enable (global->text_input,
- global->enter_serial,
- flags);
-}
-
-static void
-gtk_im_context_wayland_finalize (GObject *object)
-{
- GtkIMContextWayland *context = GTK_IM_CONTEXT_WAYLAND (object);
-
- g_clear_object (&context->widget);
- g_clear_object (&context->gesture);
-
- G_OBJECT_CLASS (gtk_im_context_wayland_parent_class)->finalize (object);
-}
-
-static void
-pressed_cb (GtkGestureMultiPress *gesture,
- gint n_press,
- gdouble x,
- gdouble y,
- GtkIMContextWayland *context)
-{
- if (n_press == 1)
- {
- context->press_x = x;
- context->press_y = y;
- }
-}
-
-static void
-released_cb (GtkGestureMultiPress *gesture,
- gint n_press,
- gdouble x,
- gdouble y,
- GtkIMContextWayland *context)
-{
- GtkInputHints hints;
-
- g_object_get (context, "input-hints", &hints, NULL);
-
- if (n_press == 1 &&
- (hints & GTK_INPUT_HINT_INHIBIT_OSK) == 0 &&
- !gtk_drag_check_threshold (context->widget,
- context->press_x,
- context->press_y,
- x, y))
- {
- enable_text_input (GTK_IM_CONTEXT_WAYLAND (context), TRUE);
- }
-}
-
-static void
-gtk_im_context_wayland_set_client_widget (GtkIMContext *context,
- GtkWidget *widget)
-{
- GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
-
- if (widget == context_wayland->widget)
- return;
-
- if (context_wayland->widget && context_wayland->widget != widget)
- g_clear_object (&context_wayland->gesture);
-
- g_set_object (&context_wayland->widget, widget);
-
- if (widget)
- {
- GtkGesture *gesture;
-
- gesture = gtk_gesture_multi_press_new (widget);
- gtk_event_controller_set_propagation_phase (GTK_EVENT_CONTROLLER (gesture),
- GTK_PHASE_CAPTURE);
- g_signal_connect (gesture, "pressed",
- G_CALLBACK (pressed_cb), context);
- g_signal_connect (gesture, "released",
- G_CALLBACK (released_cb), context);
- context_wayland->gesture = gesture;
- }
-}
-
-static void
-gtk_im_context_wayland_get_preedit_string (GtkIMContext *context,
- gchar **str,
- PangoAttrList **attrs,
- gint *cursor_pos)
-{
- GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
- gchar *preedit_str;
-
- GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->get_preedit_string (context, str, attrs, cursor_pos);
-
- /* If the parent implementation returns a len>0 string, go with it */
- if (str && *str && **str)
- return;
-
- preedit_str =
- context_wayland->preedit.text ? context_wayland->preedit.text : "";
-
- if (str)
- *str = g_strdup (preedit_str);
- if (cursor_pos)
- *cursor_pos = context_wayland->preedit.cursor_idx;
-
- if (attrs)
- {
- *attrs = pango_attr_list_new ();
- pango_attr_list_insert (*attrs,
- pango_attr_underline_new (PANGO_UNDERLINE_SINGLE));
- }
-}
-
-static gboolean
-gtk_im_context_wayland_filter_keypress (GtkIMContext *context,
- GdkEventKey *key)
-{
- /* This is done by the compositor */
- return GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->filter_keypress (context, key);
-}
-
-static void
-gtk_im_context_wayland_focus_in (GtkIMContext *context)
-{
- GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
-
- if (global->current == context)
- return;
- if (!global->text_input)
- return;
-
- global->current = context;
- enable_text_input (context_wayland, FALSE);
- notify_content_type (context_wayland);
- notify_surrounding_text (context_wayland);
- notify_cursor_location (context_wayland);
- commit_state (context_wayland);
-}
-
-static void
-gtk_im_context_wayland_focus_out (GtkIMContext *context)
-{
- if (global->current != context)
- return;
-
- gtk_text_input_disable (global->text_input);
- global->current = NULL;
-}
-
-static void
-gtk_im_context_wayland_reset (GtkIMContext *context)
-{
- reset_preedit (GTK_IM_CONTEXT_WAYLAND (context));
-
- GTK_IM_CONTEXT_CLASS (gtk_im_context_wayland_parent_class)->reset (context);
-}
-
-static void
-gtk_im_context_wayland_set_cursor_location (GtkIMContext *context,
- GdkRectangle *rect)
-{
- GtkIMContextWayland *context_wayland;
-
- context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
-
- context_wayland->cursor_rect = *rect;
- notify_cursor_location (context_wayland);
- commit_state (context_wayland);
-}
-
-static void
-gtk_im_context_wayland_set_use_preedit (GtkIMContext *context,
- gboolean use_preedit)
-{
- GtkIMContextWayland *context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
-
- context_wayland->use_preedit = !!use_preedit;
-}
-
-static void
-gtk_im_context_wayland_set_surrounding (GtkIMContext *context,
- const gchar *text,
- gint len,
- gint cursor_index)
-{
- GtkIMContextWayland *context_wayland;
-
- context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
-
- g_free (context_wayland->surrounding.text);
- context_wayland->surrounding.text = g_strdup (text);
- context_wayland->surrounding.cursor_idx = cursor_index;
-
- notify_surrounding_text (context_wayland);
- commit_state (context_wayland);
-}
-
-static gboolean
-gtk_im_context_wayland_get_surrounding (GtkIMContext *context,
- gchar **text,
- gint *cursor_index)
-{
- GtkIMContextWayland *context_wayland;
-
- context_wayland = GTK_IM_CONTEXT_WAYLAND (context);
-
- if (!context_wayland->surrounding.text)
- return FALSE;
-
- *text = context_wayland->surrounding.text;
- *cursor_index = context_wayland->surrounding.cursor_idx;
- return TRUE;
-}
-
-static void
-gtk_im_context_wayland_class_init (GtkIMContextWaylandClass *klass)
-{
- GObjectClass *object_class = G_OBJECT_CLASS (klass);
- GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (klass);
-
- object_class->finalize = gtk_im_context_wayland_finalize;
-
- im_context_class->set_client_widget = gtk_im_context_wayland_set_client_widget;
- im_context_class->get_preedit_string = gtk_im_context_wayland_get_preedit_string;
- im_context_class->filter_keypress = gtk_im_context_wayland_filter_keypress;
- im_context_class->focus_in = gtk_im_context_wayland_focus_in;
- im_context_class->focus_out = gtk_im_context_wayland_focus_out;
- im_context_class->reset = gtk_im_context_wayland_reset;
- im_context_class->set_cursor_location = gtk_im_context_wayland_set_cursor_location;
- im_context_class->set_use_preedit = gtk_im_context_wayland_set_use_preedit;
- im_context_class->set_surrounding = gtk_im_context_wayland_set_surrounding;
- im_context_class->get_surrounding = gtk_im_context_wayland_get_surrounding;
-}
-
-static void
-gtk_im_context_wayland_class_finalize (GtkIMContextWaylandClass *class)
-{
-}
-
-static void
-on_content_type_changed (GtkIMContextWayland *context)
-{
- notify_content_type (context);
- commit_state (context);
-}
-
-static void
-gtk_im_context_wayland_init (GtkIMContextWayland *context)
-{
- context->use_preedit = TRUE;
- g_signal_connect_swapped (context, "notify::input-purpose",
- G_CALLBACK (on_content_type_changed), context);
- g_signal_connect_swapped (context, "notify::input-hints",
- G_CALLBACK (on_content_type_changed), context);
-}
diff --git a/modules/input/meson.build b/modules/input/meson.build
deleted file mode 100644
index ae904b8e8d..0000000000
--- a/modules/input/meson.build
+++ /dev/null
@@ -1,118 +0,0 @@
-# Note: this file is included from the top-level before gtk/meson.build.
-# The actual input modules are then built in gtk/meson.build based on the
-# defs we provide here. It has to be that way because included input methods
-# need to be built before libgtk-4.so is built, so before gtk/meson.build, but
-# all input methods also rely on gtk generated headers to be created first, so
-# there is a bit of an ordering problem which we solve by collecting all the
-# information here but moving the actual build definitions to gtk/meson.build.
-build_dynamic_modules = false
-dynamic_modules = get_option('dynamic-modules')
-if dynamic_modules
- gmodule_supported = dependency('gmodule-no-export-2.0').get_pkgconfig_variable('gmodule_supported')
- if gmodule_supported == 'true'
- build_dynamic_modules = true
- else
- message('Modules are not supported according to gmodule-no-export-2.0.pc')
- endif
-endif
-
-all_immodules = backend_immodules
-
-# Allow building some or all immodules included
-included_immodules = get_option('included-immodules').split(',')
-if included_immodules.contains('none')
- included_immodules = []
-elif included_immodules.contains('all')
- included_immodules = all_immodules
-endif
-
-have_included_immodules = included_immodules.length() > 0
-
-foreach im: included_immodules
- if not all_immodules.contains(im)
- error('The specified input method "@0@" is not available (available methods: @1@)'.format(im, ', '.join(all_immodules)))
- endif
-endforeach
-
-immodules_subdir = 'gtk-4.0/@0@/immodules'.format(gtk_binary_version)
-immodules_install_dir = join_paths(gtk_libdir, immodules_subdir)
-
-# Format:
-# - protocol name
-# - protocol stability ('stable' or 'unstable')
-# - protocol version (if stability is 'unstable')
-proto_sources = [
- ['gtk-text-input', 'stable', ],
-]
-
-im_wayland_gen_headers = []
-im_wayland_sources = files('imwayland.c')
-wayland_scanner = find_program('wayland-scanner')
-genprotocols = find_program('../../gdk/wayland/genprotocolfiles.py')
-
-foreach p: proto_sources
- proto_name = p.get(0)
- proto_stability = p.get(1)
-
- if proto_stability == 'stable'
- output_base = proto_name
- input = '@0@.xml'.format(proto_name)
- else
- proto_version = p.get(2)
- output_base = '@0@-@1@-@2@'.format(proto_name, proto_stability, proto_version)
- input = join_paths(proto_dir, '@0@/@1@/@2@.xml'.format(proto_stability, proto_name, output_base))
- endif
-
- im_wayland_sources += custom_target('@0@ client header'.format(output_base),
- input: input,
- output: '@0@-client-protocol.h'.format(output_base),
- command: [
- genprotocols,
- wayland_scanner,
- '@INPUT@', '@OUTPUT@',
- 'client-header',
- ])
-
- im_wayland_sources += custom_target('@0@ source'.format(output_base),
- input: input,
- output: '@0@-protocol.c'.format(output_base),
- command: [
- genprotocols,
- wayland_scanner,
- '@INPUT@', '@OUTPUT@',
- 'code',
- ])
-endforeach
-
-method_defs = [
- ['broadway', files('imbroadway.c')],
- ['quartz', ('imquartz.c'), [], ('-xobjective-c')],
- ['xim', files('gtkimcontextxim.c')],
- ['ime', files('gtkimcontextime.c'), ['imm32']],
- ['wayland', im_wayland_sources],
-]
-
-inc_im_method_defs = []
-dyn_im_method_defs = []
-
-foreach m: method_defs
- im = m.get(0)
- srcs = m.get(1)
- cargs = m.get(3, [])
- libs = []
-
- # only use backend-specific input methods for backends that are enabled
- if all_immodules.contains(im)
- # check for extra libs lazily
- foreach libname: m.get(2, [])
- libs += [cc.find_library(libname)]
- endforeach
-
- if included_immodules.contains(im)
- cdata.set('INCLUDE_IM_@0@'.format(im.underscorify()), true)
- inc_im_method_defs += [[im, srcs, cargs, libs]]
- elif build_dynamic_modules
- dyn_im_method_defs += [[im, srcs, cargs, libs]]
- endif
- endif
-endforeach
diff --git a/modules/meson.build b/modules/meson.build
index d0c4adc81d..cde966a094 100644
--- a/modules/meson.build
+++ b/modules/meson.build
@@ -1,5 +1,3 @@
-# Note: 'input' subdir has already been included from top-level.
-
if os_unix
subdir('printbackends')
endif