summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOwen Taylor <otaylor@redhat.com>2000-11-12 03:43:24 +0000
committerOwen Taylor <otaylor@src.gnome.org>2000-11-12 03:43:24 +0000
commitdfba2269083ee8b943a490d2a25c74361c8468b2 (patch)
tree5d2f3a2875fe68dd6a16882a859481b4745cd27a
parentb9d32873133cb60502b95868b8ee308d7ad20acd (diff)
downloadgtk+-dfba2269083ee8b943a490d2a25c74361c8468b2.tar.gz
Make parent_class static.
Sun Nov 5 04:24:53 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtkcellrenderertextpixbuf.c: Make parent_class static. Tue Sep 19 10:54:22 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtkimcontext*.[ch] gtk/gtkimmulticontext.[ch] gtk/gtktextlayout.[ch] gtk/gtktextview.c gtk/gtkentry.c: Add support for positioning the cursor within the preedit string. Mon Sep 18 23:56:32 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtktextview.c: Check for bindings after passing events to im context filter. Mon Sep 18 11:50:51 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtktextlayout.c (add_preedit_attrs): Handle empty attribute lists properly. Sun Sep 17 10:08:16 2000 Owen Taylor <otaylor@redhat.com> * gtk/queryimmodules.c (main): Return non-zero exit status if errors were encountered querying any modules. Sat Sep 16 14:01:52 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtk.h: include gtkmodule.h gtkoldeditable.h, don't include gtkthemes.h. * gtk/testgtk.c gtk/testtext.c: Set environment variables to point * gtk/Makefile.am: Add new .c and .h files, build gtk-query-immodules and use it to create a gtk.immodules file for use of test programs. * gtk/gtkpreview.c: remove extra blank line. Sat Sep 16 13:21:04 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtkimcontextsimple.c (gtk_im_context_simple_add_table): Add the ability to add extra tables beyond the default one, and also the ability to have compose sequences that are prefixes of other compose sequences. * gtk/gtkimcontextsimple.c: Export a preedit string which consists of possible candidates for keystrokes that have been entered but not yet committed. * gtk/gtkimcontext.[ch] gtk/immulticontext.[ch] gtk/gtkimcontextsimple.[ch]: add gtk_im_context_reset() * gtk/gtkmulticontext.[ch] (gtk_im_multicontext_append_menuitems): Add a function to add input-method switching menu items to a menu. * gtk/gtkimmulticontext.[ch]: Properly handly set_client_window when switching input methods. * gtk/gtkimcontextsimple.[ch]: Change the format of the compose table to allow compose tables of different lengths / sequence. Sat Sep 16 13:05:48 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtkimmodule.[ch]: Support routines for loading GtkIMContext implementations dynamically at runtime. * gtk/queryimmodules.c: Program to query the available input modules and write the results into a file. * gtk/gtkrc.[ch] (gtk_rc_get_im_module_file): Add extra config options "im_module_file" (cache file for input method modules), and "im_module_path" - path to look for modules when generating cache file. This doesn't scale. Sat Sep 16 13:09:06 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtkthemes.[ch] gtk/gtkmodule.[ch]: Move most of the generic code from gtkthemes into a new abstraction GtkModule which has the logic for implementing a loadable module which implements a number of GObject types. Sat Sep 16 13:07:13 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtkeditable.[ch]: Convert GtkEditable from a class into an interface * gtk/gtkoldeditable.[ch]: Move the old editable implementation into here, so legacy widgets can still rely on the implemenation. GtkOldEditable exports GtkEditable. Make selection handling code use new text conversion functions (and handle UTF-8 as a side-effect). Use GtkClipboard for CLIPBOARD. * gtk/gtktext.[ch] gtk/gtkcombo.c gtk/gtkspinbutton.c: Adopt to match above changes. * gtk/gtkentry.[ch]: Implement GtkEditable directly, avoid GtkOldEditable implementation. Restructure to reduce number of places that modify state directly. Move to GtkBindingSet. Display the preedit string. Queue recomputation of PangoLayout and scroll position to improve effiency of doing complex changes naively. Add a menu with cut/copy/paste and input method selection. Thu Sep 14 22:11:05 2000 Owen Taylor <otaylor@redhat.com> * gtk/gtktextlayout.[ch]: Add gtk_text_layout_set_preedit_string() to set preedit string and attributes; display preedit string by inserting string and attributes at cursor when creating the GtkTextLineDisplay. * gtk/gtktextlayout.c: Move all conversions between byte positions in PangoLayout and GtkTextIter into new functions line_display_iter_to_index/index_to_iter that properly handle the preedit string. * gtk/gtktextmark.[ch]: Restore gtk_text_mark_get_name, modify it to return const char * (eventually will end up as GCONST char *, most likely.) * gtk/gtktextview.[ch]: Handle the preedit string, call gtk_im_context_reset() as necessary, add a menu to switch input methods. * gtk/gtktextlayout.[ch]: Remove useless gtk_text_layout_get_log_attrs() function.
-rw-r--r--gtk/.cvsignore3
-rw-r--r--gtk/Makefile.am59
-rw-r--r--gtk/gtk.h2
-rw-r--r--gtk/gtkcellrenderertextpixbuf.c2
-rw-r--r--gtk/gtkcombo.c11
-rw-r--r--gtk/gtkeditable.c869
-rw-r--r--gtk/gtkeditable.h165
-rw-r--r--gtk/gtkentry.c2494
-rw-r--r--gtk/gtkentry.h89
-rw-r--r--gtk/gtkimcontext.c36
-rw-r--r--gtk/gtkimcontext.h10
-rw-r--r--gtk/gtkimcontextsimple.c1592
-rw-r--r--gtk/gtkimcontextsimple.h12
-rw-r--r--gtk/gtkimmodule.c527
-rw-r--r--gtk/gtkimmodule.h62
-rw-r--r--gtk/gtkimmulticontext.c113
-rw-r--r--gtk/gtkimmulticontext.h8
-rw-r--r--gtk/gtkoldeditable.c859
-rw-r--r--gtk/gtkoldeditable.h142
-rw-r--r--gtk/gtkpreview.c1
-rw-r--r--gtk/gtkrc.c123
-rw-r--r--gtk/gtkrc.h4
-rw-r--r--gtk/gtkspinbutton.c45
-rw-r--r--gtk/gtktext.c542
-rw-r--r--gtk/gtktext.h6
-rw-r--r--gtk/gtktextlayout.c414
-rw-r--r--gtk/gtktextlayout.h18
-rw-r--r--gtk/gtktextview.c153
-rw-r--r--gtk/gtktextview.h10
-rw-r--r--gtk/gtkthemes.c428
-rw-r--r--gtk/gtkthemes.h16
-rw-r--r--gtk/queryimmodules.c170
-rw-r--r--gtk/testgtk.c11
-rw-r--r--gtk/testtext.c21
-rw-r--r--tests/testgtk.c11
-rw-r--r--tests/testtext.c21
36 files changed, 5509 insertions, 3540 deletions
diff --git a/gtk/.cvsignore b/gtk/.cvsignore
index 1a313c90c2..d93b49fe11 100644
--- a/gtk/.cvsignore
+++ b/gtk/.cvsignore
@@ -19,6 +19,7 @@ testtree
gtkcompat.h
testthreads
libgtk.la
+gtkfeatures.h
gtkmarshal.h
gtktypebuiltins.h
gtkmarshal.c
@@ -30,3 +31,5 @@ testdnd
stamp-gtktypebuiltins.h
stamp-gtkmarshal.h
stamp-gtk.defs
+gtk-query-immodules-2.0
+gtk.immodules
diff --git a/gtk/Makefile.am b/gtk/Makefile.am
index e05b165c06..060d12154c 100644
--- a/gtk/Makefile.am
+++ b/gtk/Makefile.am
@@ -104,6 +104,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtkiconfactory.h \
gtkimage.h \
gtkimcontext.h \
+ gtkimmodule.h \
gtkimmulticontext.h \
gtkinputdialog.h \
gtkinvisible.h \
@@ -124,6 +125,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtkmisc.h \
gtkmodelsimple.h \
gtknotebook.h \
+ gtkoldeditable.h \
gtkobject.h \
gtkoptionmenu.h \
gtkpacker.h \
@@ -163,7 +165,6 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
gtktexttagtable.h \
gtktextview.h \
gtktext.h \
- gtkthemes.h \
gtktipsquery.h \
gtktogglebutton.h \
gtktoolbar.h \
@@ -198,6 +199,7 @@ gtk_private_h_sources = @STRIP_BEGIN@ \
gtktextiterprivate.h \
gtktextmarkprivate.h \
gtktexttagprivate.h \
+ gtkthemes.h \
gtktreeprivate.h \
@STRIP_END@
# GTK+ C sources to build the library from
@@ -257,6 +259,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
gtkimcontext.c \
gtkimcontextsimple.c \
gtkimcontextsimple.h \
+ gtkimmodule.c \
gtkimmulticontext.c \
gtkinputdialog.c \
gtkintl.h \
@@ -279,6 +282,7 @@ gtk_c_sources = @STRIP_BEGIN@ \
gtkmodelsimple.c \
gtknotebook.c \
gtkobject.c \
+ gtkoldeditable.c \
gtkoptionmenu.c \
gtkpacker.c \
gtkpaned.c \
@@ -543,11 +547,9 @@ install-data-local:
uninstall-local:
rm -f $(DESTDIR)$(datadir)/themes/Default/gtk-2.0/gtkrc
-#
-# test programs, not to be installed
-#
-noinst_PROGRAMS = testgtk testcalendar testinput testselection testrgb testdnd testtext simple treestoretest testtextbuffer # testthreads
-DEPS = @gtktargetlib@ $(top_builddir)/gdk-pixbuf/libgdk_pixbuf-1.3.la $(top_builddir)/gdk/@gdktargetlib@
+DEPS = @gtktargetlib@ $(top_builddir)/gdk-pixbuf/libgdk_pixbuf-1.3.la $(top_builddir)/gdk/@gdktargetlib@
+TEST_DEPS = $(DEPS) gtk.immodules
+
LDADDS = @STRIP_BEGIN@ \
@gtktargetlib@ \
$(top_builddir)/gdk-pixbuf/libgdk_pixbuf-1.3.la \
@@ -561,25 +563,44 @@ LDADDS = @STRIP_BEGIN@ \
-lm \
@STRIP_END@
-testgtk_DEPENDENCIES = $(DEPS)
-testcalendar_DEPENDENCIES = $(DEPS)
-testinput_DEPENDENCIES = $(DEPS)
-testselection_DEPENDENCIES = $(DEPS)
-testrgb_DEPENDENCIES = $(DEPS)
-testtext_DEPENDENCIES = $(DEPS)
-testtextbuffer_DEPENDENCIES = $(DEPS)
-treestoretest_DEPENDENCIES = $(DEPS)
-testdnd_DEPENDENCIES = $(DEPS)
-simple_DEPENDENCIES = $(DEPS)
-#testthreads_DEPENDENCIES = $(DEPS)
+#
+# Installed tools
+#
+bin_PROGRAMS = gtk-query-immodules-2.0
+
+gtk_query_immodules_2_0_DEPENDENCIES = $(DEPS)
+gtk_query_immodules_2_0_LDADD = $(LDADDS)
+
+gtk_query_immodules_2_0_SOURCES = queryimmodules.c
+
+gtk.immodules: gtk-query-immodules-2.0
+ ./gtk-query-immodules-2.0 ../modules/input/.libs/*.so > gtk.immodules
+
+#
+# test programs, not to be installed
+#
+noinst_PROGRAMS = testgtk testcalendar testinput testselection testrgb testdnd testtext simple treestoretest testtextbuffer # testthreads
+
+testcalendar_DEPENDENCIES = $(TEST_DEPS)
+testgtk_DEPENDENCIES = $(TEST_DEPS)
+testinput_DEPENDENCIES = $(TEST_DEPS)
+testrgb_DEPENDENCIES = $(TEST_DEPS)
+testselection_DEPENDENCIES = $(TEST_DEPS)
+testtext_DEPENDENCIES = $(TEST_DEPS)
+testtextbuffer_DEPENDENCIES = $(TEST_DEPS)
+treestoretest_DEPENDENCIES = $(TEST_DEPS)
+testdnd_DEPENDENCIES = $(TEST_DEPS)
+simple_DEPENDENCIES = $(TEST_DEPS)
+#testthreads_DEPENDENCIES = $(TEST_DEPS)
+
testcalendar_LDADD = $(LDADDS)
testgtk_LDADD = $(LDADDS)
testinput_LDADD = $(LDADDS)
+testrgb_LDADD = $(LDADDS)
testselection_LDADD = $(LDADDS)
testtext_LDADD = $(LDADDS)
-treestoretest_LDADD = $(LDADDS)
testtextbuffer_LDADD = $(LDADDS)
-testrgb_LDADD = $(LDADDS)
+treestoretest_LDADD = $(LDADDS)
testdnd_LDADD = $(LDADDS)
simple_LDADD = $(LDADDS)
#testthreads_LDADD = $(LDADDS)
diff --git a/gtk/gtk.h b/gtk/gtk.h
index a7b3e8818c..ecec92e466 100644
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
@@ -104,6 +104,7 @@
#include <gtk/gtkmodelsimple.h>
#include <gtk/gtknotebook.h>
#include <gtk/gtkobject.h>
+#include <gtk/gtkoldeditable.h>
#include <gtk/gtkoptionmenu.h>
#include <gtk/gtkpacker.h>
#include <gtk/gtkpaned.h>
@@ -133,7 +134,6 @@
#include <gtk/gtktext.h>
#include <gtk/gtktextbuffer.h>
#include <gtk/gtktextview.h>
-#include <gtk/gtkthemes.h>
#include <gtk/gtktipsquery.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtktoolbar.h>
diff --git a/gtk/gtkcellrenderertextpixbuf.c b/gtk/gtkcellrenderertextpixbuf.c
index d2fe42dac4..694538a2b6 100644
--- a/gtk/gtkcellrenderertextpixbuf.c
+++ b/gtk/gtkcellrenderertextpixbuf.c
@@ -60,7 +60,7 @@ static void gtk_cell_renderer_text_pixbuf_render (GtkCellRenderer
guint flags);
-GtkCellRendererTextClass *parent_class = NULL;
+static GtkCellRendererTextClass *parent_class = NULL;
GtkType
diff --git a/gtk/gtkcombo.c b/gtk/gtkcombo.c
index 03cb0faab6..dea6d8956c 100644
--- a/gtk/gtkcombo.c
+++ b/gtk/gtkcombo.c
@@ -132,6 +132,7 @@ gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * com
/* completion */
if ((event->keyval == GDK_Tab) && (event->state & GDK_MOD1_MASK))
{
+ GtkEditable *editable = GTK_EDITABLE (entry);
GCompletion * cmpl;
gchar* prefix;
gchar* nprefix = NULL;
@@ -145,16 +146,16 @@ gtk_combo_entry_key_press (GtkEntry * entry, GdkEventKey * event, GtkCombo * com
cmpl = g_completion_new ((GCompletionFunc)gtk_combo_func);
g_completion_add_items (cmpl, GTK_LIST (combo->list)->children);
- pos = GTK_EDITABLE (entry)->current_pos;
- prefix = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, pos);
+ pos = gtk_editable_get_position (editable);
+ prefix = gtk_editable_get_chars (editable, 0, pos);
g_completion_complete(cmpl, prefix, &nprefix);
if (nprefix && strlen (nprefix) > strlen (prefix))
{
- gtk_editable_insert_text (GTK_EDITABLE (entry), nprefix + pos,
- strlen (nprefix) - strlen (prefix), &pos);
- GTK_EDITABLE (entry)->current_pos = pos;
+ gtk_editable_insert_text (editable, nprefix + pos,
+ strlen (nprefix) - strlen (prefix), &pos);
+ gtk_editable_set_position (editable, pos);
}
if (nprefix)
diff --git a/gtk/gtkeditable.c b/gtk/gtkeditable.c
index 76ee618fda..b2ea905c33 100644
--- a/gtk/gtkeditable.c
+++ b/gtk/gtkeditable.c
@@ -24,91 +24,11 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <ctype.h>
#include <string.h>
-#include "gdk/gdkkeysyms.h"
-#include "gdk/gdki18n.h"
+
#include "gtkeditable.h"
-#include "gtkmain.h"
-#include "gtkselection.h"
#include "gtksignal.h"
-#define MIN_EDITABLE_WIDTH 150
-#define DRAW_TIMEOUT 20
-#define INNER_BORDER 2
-
-enum {
- CHANGED,
- INSERT_TEXT,
- DELETE_TEXT,
- /* Binding actions */
- ACTIVATE,
- SET_EDITABLE,
- MOVE_CURSOR,
- MOVE_WORD,
- MOVE_PAGE,
- MOVE_TO_ROW,
- MOVE_TO_COLUMN,
- KILL_CHAR,
- KILL_WORD,
- KILL_LINE,
- CUT_CLIPBOARD,
- COPY_CLIPBOARD,
- PASTE_CLIPBOARD,
- LAST_SIGNAL
-};
-
-enum {
- ARG_0,
- ARG_TEXT_POSITION,
- ARG_EDITABLE
-};
-
-/* values for selection info */
-
-enum {
- TARGET_STRING,
- TARGET_TEXT,
- TARGET_COMPOUND_TEXT
-};
-
-static void gtk_editable_class_init (GtkEditableClass *klass);
-static void gtk_editable_init (GtkEditable *editable);
-static void gtk_editable_set_arg (GtkObject *object,
- GtkArg *arg,
- guint arg_id);
-static void gtk_editable_get_arg (GtkObject *object,
- GtkArg *arg,
- guint arg_id);
-static void *gtk_editable_get_public_chars (GtkEditable *editable,
- gint start,
- gint end);
-static gint gtk_editable_selection_clear (GtkWidget *widget,
- GdkEventSelection *event);
-static void gtk_editable_selection_get (GtkWidget *widget,
- GtkSelectionData *selection_data,
- guint info,
- guint time);
-static void gtk_editable_selection_received (GtkWidget *widget,
- GtkSelectionData *selection_data,
- guint time);
-
-static void gtk_editable_set_selection (GtkEditable *editable,
- gint start,
- gint end);
-static guint32 gtk_editable_get_event_time (GtkEditable *editable);
-
-static void gtk_editable_real_cut_clipboard (GtkEditable *editable);
-static void gtk_editable_real_copy_clipboard (GtkEditable *editable);
-static void gtk_editable_real_paste_clipboard (GtkEditable *editable);
-static void gtk_editable_real_set_editable (GtkEditable *editable,
- gboolean is_editable);
-
-static GtkWidgetClass *parent_class = NULL;
-static guint editable_signals[LAST_SIGNAL] = { 0 };
-
-static GdkAtom clipboard_atom = GDK_NONE;
-
GtkType
gtk_editable_get_type (void)
{
@@ -116,331 +36,32 @@ gtk_editable_get_type (void)
if (!editable_type)
{
- static const GtkTypeInfo editable_info =
+ static const GTypeInfo editable_info =
{
- "GtkEditable",
- sizeof (GtkEditable),
- sizeof (GtkEditableClass),
- (GtkClassInitFunc) gtk_editable_class_init,
- (GtkObjectInitFunc) gtk_editable_init,
- /* reserved_1 */ NULL,
- /* reserved_2 */ NULL,
- (GtkClassInitFunc) NULL,
+ sizeof (GtkEditableClass), /* class_size */
+ NULL, /* base_init */
+ NULL, /* base_finalize */
};
- editable_type = gtk_type_unique (GTK_TYPE_WIDGET, &editable_info);
+ editable_type = g_type_register_static (G_TYPE_INTERFACE, "GtkEditable", &editable_info, 0);
}
return editable_type;
}
-static void
-gtk_editable_class_init (GtkEditableClass *class)
-{
- GtkObjectClass *object_class;
- GtkWidgetClass *widget_class;
-
- object_class = (GtkObjectClass*) class;
- widget_class = (GtkWidgetClass*) class;
-
- parent_class = gtk_type_class (GTK_TYPE_WIDGET);
-
- editable_signals[CHANGED] =
- gtk_signal_new ("changed",
- GTK_RUN_LAST,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, changed),
- gtk_marshal_VOID__VOID,
- GTK_TYPE_NONE, 0);
-
- editable_signals[INSERT_TEXT] =
- gtk_signal_new ("insert_text",
- GTK_RUN_LAST,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, insert_text),
- gtk_marshal_VOID__POINTER_INT_POINTER,
- GTK_TYPE_NONE,
- 3,
- GTK_TYPE_STRING,
- GTK_TYPE_INT,
- GTK_TYPE_POINTER);
-
- editable_signals[DELETE_TEXT] =
- gtk_signal_new ("delete_text",
- GTK_RUN_LAST,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, delete_text),
- gtk_marshal_VOID__INT_INT,
- GTK_TYPE_NONE,
- 2,
- GTK_TYPE_INT,
- GTK_TYPE_INT);
-
- editable_signals[ACTIVATE] =
- gtk_signal_new ("activate",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, activate),
- gtk_marshal_VOID__VOID,
- GTK_TYPE_NONE, 0);
- widget_class->activate_signal = editable_signals[ACTIVATE];
-
- editable_signals[SET_EDITABLE] =
- gtk_signal_new ("set-editable",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, set_editable),
- gtk_marshal_VOID__BOOLEAN,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_BOOL);
-
- editable_signals[MOVE_CURSOR] =
- gtk_signal_new ("move_cursor",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, move_cursor),
- gtk_marshal_VOID__INT_INT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT,
- GTK_TYPE_INT);
-
- editable_signals[MOVE_WORD] =
- gtk_signal_new ("move_word",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, move_word),
- gtk_marshal_VOID__INT,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_INT);
-
- editable_signals[MOVE_PAGE] =
- gtk_signal_new ("move_page",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, move_page),
- gtk_marshal_VOID__INT_INT,
- GTK_TYPE_NONE, 2,
- GTK_TYPE_INT,
- GTK_TYPE_INT);
-
- editable_signals[MOVE_TO_ROW] =
- gtk_signal_new ("move_to_row",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, move_to_row),
- gtk_marshal_VOID__INT,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_INT);
-
- editable_signals[MOVE_TO_COLUMN] =
- gtk_signal_new ("move_to_column",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, move_to_column),
- gtk_marshal_VOID__INT,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_INT);
-
- editable_signals[KILL_CHAR] =
- gtk_signal_new ("kill_char",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, kill_char),
- gtk_marshal_VOID__INT,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_INT);
-
- editable_signals[KILL_WORD] =
- gtk_signal_new ("kill_word",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, kill_word),
- gtk_marshal_VOID__INT,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_INT);
-
- editable_signals[KILL_LINE] =
- gtk_signal_new ("kill_line",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, kill_line),
- gtk_marshal_VOID__INT,
- GTK_TYPE_NONE, 1,
- GTK_TYPE_INT);
-
- editable_signals[CUT_CLIPBOARD] =
- gtk_signal_new ("cut_clipboard",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, cut_clipboard),
- gtk_marshal_VOID__VOID,
- GTK_TYPE_NONE, 0);
-
- editable_signals[COPY_CLIPBOARD] =
- gtk_signal_new ("copy_clipboard",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, copy_clipboard),
- gtk_marshal_VOID__VOID,
- GTK_TYPE_NONE, 0);
-
- editable_signals[PASTE_CLIPBOARD] =
- gtk_signal_new ("paste_clipboard",
- GTK_RUN_LAST | GTK_RUN_ACTION,
- GTK_CLASS_TYPE (object_class),
- GTK_SIGNAL_OFFSET (GtkEditableClass, paste_clipboard),
- gtk_marshal_VOID__VOID,
- GTK_TYPE_NONE, 0);
-
- gtk_object_class_add_signals (object_class, editable_signals, LAST_SIGNAL);
-
- gtk_object_add_arg_type ("GtkEditable::text_position", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_TEXT_POSITION);
- gtk_object_add_arg_type ("GtkEditable::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITABLE);
-
- object_class->set_arg = gtk_editable_set_arg;
- object_class->get_arg = gtk_editable_get_arg;
-
- widget_class->selection_clear_event = gtk_editable_selection_clear;
- widget_class->selection_received = gtk_editable_selection_received;
- widget_class->selection_get = gtk_editable_selection_get;
-
- class->insert_text = NULL;
- class->delete_text = NULL;
-
- class->activate = NULL;
- class->set_editable = gtk_editable_real_set_editable;
-
- class->move_cursor = NULL;
- class->move_word = NULL;
- class->move_page = NULL;
- class->move_to_row = NULL;
- class->move_to_column = NULL;
-
- class->kill_char = NULL;
- class->kill_word = NULL;
- class->kill_line = NULL;
-
- class->cut_clipboard = gtk_editable_real_cut_clipboard;
- class->copy_clipboard = gtk_editable_real_copy_clipboard;
- class->paste_clipboard = gtk_editable_real_paste_clipboard;
-
- class->update_text = NULL;
- class->get_chars = NULL;
- class->set_selection = NULL;
- class->set_position = NULL;
-}
-
-static void
-gtk_editable_set_arg (GtkObject *object,
- GtkArg *arg,
- guint arg_id)
-{
- GtkEditable *editable;
-
- editable = GTK_EDITABLE (object);
-
- switch (arg_id)
- {
- case ARG_TEXT_POSITION:
- gtk_editable_set_position (editable, GTK_VALUE_INT (*arg));
- break;
- case ARG_EDITABLE:
- gtk_editable_set_editable (editable, GTK_VALUE_BOOL (*arg));
- break;
- default:
- break;
- }
-}
-
-static void
-gtk_editable_get_arg (GtkObject *object,
- GtkArg *arg,
- guint arg_id)
-{
- GtkEditable *editable;
-
- editable = GTK_EDITABLE (object);
-
- switch (arg_id)
- {
- case ARG_TEXT_POSITION:
- GTK_VALUE_INT (*arg) = editable->current_pos;
- break;
- case ARG_EDITABLE:
- GTK_VALUE_BOOL (*arg) = editable->editable;
- break;
- default:
- arg->type = GTK_TYPE_INVALID;
- break;
- }
-}
-
-static void
-gtk_editable_init (GtkEditable *editable)
-{
- static const GtkTargetEntry targets[] = {
- { "STRING", 0, TARGET_STRING },
- { "TEXT", 0, TARGET_TEXT },
- { "COMPOUND_TEXT", 0, TARGET_COMPOUND_TEXT }
- };
- static const gint n_targets = sizeof(targets) / sizeof(targets[0]);
-
- GTK_WIDGET_SET_FLAGS (editable, GTK_CAN_FOCUS);
-
- editable->selection_start_pos = 0;
- editable->selection_end_pos = 0;
- editable->has_selection = FALSE;
- editable->editable = 1;
- editable->visible = 1;
- editable->clipboard_text = NULL;
-
-#ifdef USE_XIM
- editable->ic = NULL;
-#endif
-
- if (!clipboard_atom)
- clipboard_atom = gdk_atom_intern ("CLIPBOARD", FALSE);
-
- gtk_selection_add_targets (GTK_WIDGET (editable), GDK_SELECTION_PRIMARY,
- targets, n_targets);
- gtk_selection_add_targets (GTK_WIDGET (editable), clipboard_atom,
- targets, n_targets);
-}
-
void
gtk_editable_insert_text (GtkEditable *editable,
const gchar *new_text,
gint new_text_length,
gint *position)
{
- GtkEditableClass *klass;
- gchar buf[64];
- gchar *text;
-
- g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
-
- gtk_widget_ref (GTK_WIDGET (editable));
-
- klass = GTK_EDITABLE_GET_CLASS (editable);
+ g_return_if_fail (position != NULL);
if (new_text_length < 0)
new_text_length = strlen (new_text);
- if (new_text_length <= 64)
- text = buf;
- else
- text = g_new (gchar, new_text_length);
-
- strncpy (text, new_text, new_text_length);
-
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[INSERT_TEXT], text, new_text_length, position);
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
-
- if (new_text_length > 64)
- g_free (text);
-
- gtk_widget_unref (GTK_WIDGET (editable));
+ GTK_EDITABLE_GET_CLASS (editable)->insert_text (editable, new_text, new_text_length, position);
}
void
@@ -448,360 +69,67 @@ gtk_editable_delete_text (GtkEditable *editable,
gint start_pos,
gint end_pos)
{
- GtkEditableClass *klass;
-
- g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- gtk_widget_ref (GTK_WIDGET (editable));
-
- klass = GTK_EDITABLE_GET_CLASS (editable);
-
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[DELETE_TEXT], start_pos, end_pos);
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
-
- gtk_widget_unref (GTK_WIDGET (editable));
-}
-
-static void
-gtk_editable_update_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
-{
- GtkEditableClass *klass;
-
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (editable));
-
- klass = GTK_EDITABLE_GET_CLASS (editable);
-
- klass->update_text (editable, start_pos, end_pos);
+ GTK_EDITABLE_GET_CLASS (editable)->delete_text (editable, start_pos, end_pos);
}
gchar *
-gtk_editable_get_chars (GtkEditable *editable,
- gint start,
- gint end)
-{
- GtkEditableClass *klass;
-
- g_return_val_if_fail (editable != NULL, NULL);
- g_return_val_if_fail (GTK_IS_EDITABLE (editable), NULL);
-
- klass = GTK_EDITABLE_GET_CLASS (editable);
-
- return klass->get_chars (editable, start, end);
-}
-
-/*
- * Like gtk_editable_get_chars, but if the editable is not
- * visible, return asterisks
- */
-static void *
-gtk_editable_get_public_chars (GtkEditable *editable,
- gint start,
- gint end)
-{
- if (editable->visible)
- return gtk_editable_get_chars (editable, start, end);
- else
- {
- gint i;
- gint nchars = end - start;
- gchar *str;
-
- if (nchars < 0)
- nchars = -nchars;
-
- str = g_new (gchar, nchars + 1);
- for (i = 0; i<nchars; i++)
- str[i] = '*';
- str[i] = '\0';
-
- return str;
- }
-}
-
-static void
-gtk_editable_set_selection (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
+gtk_editable_get_chars (GtkEditable *editable,
+ gint start,
+ gint end)
{
- GtkEditableClass *klass;
-
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (editable));
+ g_return_val_if_fail (GTK_IS_EDITABLE (editable), FALSE);
- klass = GTK_EDITABLE_GET_CLASS (editable);
-
- klass->set_selection (editable, start_pos, end_pos);
+ return GTK_EDITABLE_GET_CLASS (editable)->get_chars (editable, start, end);
}
void
gtk_editable_set_position (GtkEditable *editable,
gint position)
{
- GtkEditableClass *klass;
-
- g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- klass = GTK_EDITABLE_GET_CLASS (editable);
-
- klass->set_position (editable, position);
+ GTK_EDITABLE_GET_CLASS (editable)->set_position (editable, position);
}
gint
gtk_editable_get_position (GtkEditable *editable)
{
- g_return_val_if_fail (editable != NULL, -1);
- g_return_val_if_fail (GTK_IS_EDITABLE (editable), -1);
-
- return editable->current_pos;
-}
+ g_return_val_if_fail (GTK_IS_EDITABLE (editable), 0);
-static gint
-gtk_editable_selection_clear (GtkWidget *widget,
- GdkEventSelection *event)
-{
- GtkEditable *editable;
-
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_EDITABLE (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- /* Let the selection handling code know that the selection
- * has been changed, since we've overriden the default handler */
- if (!gtk_selection_clear (widget, event))
- return FALSE;
-
- editable = GTK_EDITABLE (widget);
-
- if (event->selection == GDK_SELECTION_PRIMARY)
- {
- if (editable->has_selection)
- {
- editable->has_selection = FALSE;
- gtk_editable_update_text (editable, editable->selection_start_pos,
- editable->selection_end_pos);
- }
- }
- else if (event->selection == clipboard_atom)
- {
- g_free (editable->clipboard_text);
- editable->clipboard_text = NULL;
- }
-
- return TRUE;
+ return GTK_EDITABLE_GET_CLASS (editable)->get_position (editable);
}
-static void
-gtk_editable_selection_get (GtkWidget *widget,
- GtkSelectionData *selection_data,
- guint info,
- guint time)
+gboolean
+gtk_editable_get_selection_bounds (GtkEditable *editable,
+ gint *start_pos,
+ gint *end_pos)
{
- GtkEditable *editable;
- gint selection_start_pos;
- gint selection_end_pos;
-
- gchar *str;
- gint length;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (widget));
-
- editable = GTK_EDITABLE (widget);
-
- if (selection_data->selection == GDK_SELECTION_PRIMARY)
- {
- selection_start_pos = MIN (editable->selection_start_pos, editable->selection_end_pos);
- selection_end_pos = MAX (editable->selection_start_pos, editable->selection_end_pos);
- str = gtk_editable_get_public_chars(editable,
- selection_start_pos,
- selection_end_pos);
- if (!str)
- return; /* Refuse */
- length = strlen (str);
- }
- else /* CLIPBOARD */
- {
- if (!editable->clipboard_text)
- return; /* Refuse */
-
- str = editable->clipboard_text;
- length = strlen (editable->clipboard_text);
- }
+ gint tmp_start, tmp_end;
+ gboolean result;
- if (info == TARGET_STRING)
- {
- gtk_selection_data_set (selection_data,
- GDK_SELECTION_TYPE_STRING,
- 8*sizeof(gchar), (guchar *)str, length);
- }
- else if ((info == TARGET_TEXT) || (info == TARGET_COMPOUND_TEXT))
- {
- guchar *text;
- gchar c;
- GdkAtom encoding;
- gint format;
- gint new_length;
-
- c = str[length];
- str[length] = '\0';
- gdk_string_to_compound_text (str, &encoding, &format, &text, &new_length);
- gtk_selection_data_set (selection_data, encoding, format, text, new_length);
- gdk_free_compound_text (text);
- str[length] = c;
- }
-
- if (str != editable->clipboard_text)
- g_free (str);
-}
-
-static void
-gtk_editable_selection_received (GtkWidget *widget,
- GtkSelectionData *selection_data,
- guint time)
-{
- GtkEditable *editable;
- gint reselect;
- gint old_pos;
- gint tmp_pos;
- enum {INVALID, STRING, CTEXT} type;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (widget));
-
- editable = GTK_EDITABLE (widget);
-
- if (selection_data->type == GDK_TARGET_STRING)
- type = STRING;
- else if ((selection_data->type == gdk_atom_intern ("COMPOUND_TEXT", FALSE)) ||
- (selection_data->type == gdk_atom_intern ("TEXT", FALSE)))
- type = CTEXT;
- else
- type = INVALID;
-
- if (type == INVALID || selection_data->length < 0)
- {
- /* avoid infinite loop */
- if (selection_data->target != GDK_TARGET_STRING)
- gtk_selection_convert (widget, selection_data->selection,
- GDK_TARGET_STRING, time);
- return;
- }
-
- reselect = FALSE;
+ g_return_val_if_fail (GTK_IS_EDITABLE (editable), FALSE);
- if ((editable->selection_start_pos != editable->selection_end_pos) &&
- (!editable->has_selection ||
- (selection_data->selection == clipboard_atom)))
- {
- reselect = TRUE;
-
- /* Don't want to call gtk_editable_delete_selection here if we are going
- * to reclaim the selection to avoid extra server traffic */
- if (editable->has_selection)
- {
- gtk_editable_delete_text (editable,
- MIN (editable->selection_start_pos, editable->selection_end_pos),
- MAX (editable->selection_start_pos, editable->selection_end_pos));
- }
- else
- gtk_editable_delete_selection (editable);
- }
+ result = GTK_EDITABLE_GET_CLASS (editable)->get_selection_bounds (editable, &tmp_start, &tmp_end);
- tmp_pos = old_pos = editable->current_pos;
+ if (start_pos)
+ *start_pos = MIN (tmp_start, tmp_end);
+ if (end_pos)
+ *end_pos = MAX (tmp_start, tmp_end);
- switch (type)
- {
- case STRING:
- selection_data->data[selection_data->length] = 0;
- gtk_editable_insert_text (editable, (gchar *)selection_data->data,
- strlen ((gchar *)selection_data->data),
- &tmp_pos);
- editable->current_pos = tmp_pos;
- break;
- case CTEXT:
- {
- gchar **list;
- gint count;
- gint i;
-
- count = gdk_text_property_to_text_list (selection_data->type,
- selection_data->format,
- selection_data->data,
- selection_data->length,
- &list);
- for (i=0; i<count; i++)
- {
- gtk_editable_insert_text (editable, list[i], strlen (list[i]), &tmp_pos);
- editable->current_pos = tmp_pos;
- }
- if (count > 0)
- gdk_free_text_list (list);
- }
- break;
- case INVALID: /* quiet compiler */
- break;
- }
-
- if (reselect)
- gtk_editable_set_selection (editable, old_pos, editable->current_pos);
+ return result;
}
void
gtk_editable_delete_selection (GtkEditable *editable)
{
- guint start;
- guint end;
+ gint start, end;
- g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- if (!editable->editable)
- return;
-
- start = editable->selection_start_pos;
- end = editable->selection_end_pos;
-
- editable->selection_start_pos = 0;
- editable->selection_end_pos = 0;
-
- if (start != end)
- gtk_editable_delete_text (editable, MIN (start, end), MAX (start,end));
-
- if (editable->has_selection)
- {
- editable->has_selection = FALSE;
- if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == GTK_WIDGET (editable)->window)
- gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
- }
-}
-
-void
-gtk_editable_claim_selection (GtkEditable *editable,
- gboolean claim,
- guint32 time)
-{
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (editable));
- g_return_if_fail (GTK_WIDGET_REALIZED (editable));
-
- editable->has_selection = FALSE;
-
- if (claim)
- {
- if (gtk_selection_owner_set (GTK_WIDGET(editable), GDK_SELECTION_PRIMARY, time))
- editable->has_selection = TRUE;
- }
- else
- {
- if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) ==
- GTK_WIDGET(editable)->window)
- gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, time);
- }
+ if (gtk_editable_get_selection_bounds (editable, &start, &end))
+ gtk_editable_delete_text (editable, start, end);
}
void
@@ -809,57 +137,9 @@ gtk_editable_select_region (GtkEditable *editable,
gint start,
gint end)
{
- g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- if (GTK_WIDGET_REALIZED (editable))
- gtk_editable_claim_selection (editable, start != end, GDK_CURRENT_TIME);
-
- gtk_editable_set_selection (editable, start, end);
-}
-
-/* Get the timestamp of the current event. Actually, the only thing
- * we really care about below is the key event
- */
-static guint32
-gtk_editable_get_event_time (GtkEditable *editable)
-{
- GdkEvent *event;
- guint32 tm = GDK_CURRENT_TIME;
-
- event = gtk_get_current_event();
-
- if (event)
- switch (event->type)
- {
- case GDK_MOTION_NOTIFY:
- tm = event->motion.time; break;
- case GDK_BUTTON_PRESS:
- case GDK_2BUTTON_PRESS:
- case GDK_3BUTTON_PRESS:
- case GDK_BUTTON_RELEASE:
- tm = event->button.time; break;
- case GDK_KEY_PRESS:
- case GDK_KEY_RELEASE:
- tm = event->key.time; break;
- case GDK_ENTER_NOTIFY:
- case GDK_LEAVE_NOTIFY:
- tm = event->crossing.time; break;
- case GDK_PROPERTY_NOTIFY:
- tm = event->property.time; break;
- case GDK_SELECTION_CLEAR:
- case GDK_SELECTION_REQUEST:
- case GDK_SELECTION_NOTIFY:
- tm = event->selection.time; break;
- case GDK_PROXIMITY_IN:
- case GDK_PROXIMITY_OUT:
- tm = event->proximity.time; break;
- default: /* use current time */
- break;
- }
- gdk_event_free(event);
-
- return tm;
+ GTK_EDITABLE_GET_CLASS (editable)->set_selection_bounds (editable, start, end);
}
void
@@ -868,7 +148,7 @@ gtk_editable_cut_clipboard (GtkEditable *editable)
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CUT_CLIPBOARD]);
+ gtk_signal_emit_by_name (GTK_OBJECT (editable), "cut_clipboard");
}
void
@@ -877,7 +157,7 @@ gtk_editable_copy_clipboard (GtkEditable *editable)
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[COPY_CLIPBOARD]);
+ gtk_signal_emit_by_name (GTK_OBJECT (editable), "copy_clipboard");
}
void
@@ -886,85 +166,16 @@ gtk_editable_paste_clipboard (GtkEditable *editable)
g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[PASTE_CLIPBOARD]);
+ gtk_signal_emit_by_name (GTK_OBJECT (editable), "paste_clipboard");
}
void
gtk_editable_set_editable (GtkEditable *editable,
gboolean is_editable)
{
- g_return_if_fail (editable != NULL);
g_return_if_fail (GTK_IS_EDITABLE (editable));
-
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[SET_EDITABLE], is_editable != FALSE);
-}
-static void
-gtk_editable_real_set_editable (GtkEditable *editable,
- gboolean is_editable)
-{
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (editable));
-
- editable->editable = is_editable != FALSE;
- gtk_widget_queue_draw (GTK_WIDGET (editable));
-}
-
-static void
-gtk_editable_real_cut_clipboard (GtkEditable *editable)
-{
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (editable));
-
- gtk_editable_real_copy_clipboard (editable);
- gtk_editable_delete_selection (editable);
-}
-
-static void
-gtk_editable_real_copy_clipboard (GtkEditable *editable)
-{
- guint32 time;
- gint selection_start_pos;
- gint selection_end_pos;
-
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (editable));
-
- time = gtk_editable_get_event_time (editable);
- selection_start_pos = MIN (editable->selection_start_pos, editable->selection_end_pos);
- selection_end_pos = MAX (editable->selection_start_pos, editable->selection_end_pos);
-
- if (selection_start_pos != selection_end_pos)
- {
- if (gtk_selection_owner_set (GTK_WIDGET (editable),
- clipboard_atom,
- time))
- editable->clipboard_text = gtk_editable_get_public_chars (editable,
- selection_start_pos,
- selection_end_pos);
- }
-}
-
-static void
-gtk_editable_real_paste_clipboard (GtkEditable *editable)
-{
- guint32 time;
-
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (editable));
-
- time = gtk_editable_get_event_time (editable);
- if (editable->editable)
- gtk_selection_convert (GTK_WIDGET(editable),
- clipboard_atom,
- gdk_atom_intern ("COMPOUND_TEXT", FALSE), time);
-}
-
-void
-gtk_editable_changed (GtkEditable *editable)
-{
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_EDITABLE (editable));
-
- gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
+ gtk_object_set (GTK_OBJECT (editable),
+ "editable", is_editable != FALSE,
+ NULL);
}
diff --git a/gtk/gtkeditable.h b/gtk/gtkeditable.h
index 55c1c22e9e..9fb5ba06ad 100644
--- a/gtk/gtkeditable.h
+++ b/gtk/gtkeditable.h
@@ -31,132 +31,73 @@
#include <gdk/gdk.h>
#include <gtk/gtkwidget.h>
-
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-#define GTK_TYPE_EDITABLE (gtk_editable_get_type ())
-#define GTK_EDITABLE(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_EDITABLE, GtkEditable))
-#define GTK_EDITABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_EDITABLE, GtkEditableClass))
-#define GTK_IS_EDITABLE(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_EDITABLE))
-#define GTK_IS_EDITABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_EDITABLE))
-#define GTK_EDITABLE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_EDITABLE, GtkEditableClass))
-
+#define GTK_TYPE_EDITABLE (gtk_editable_get_type ())
+#define GTK_EDITABLE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_EDITABLE, GtkEditable))
+#define GTK_EDITABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_CAST ((vtable), GTK_TYPE_EDITABLE, GtkEditableClass))
+#define GTK_IS_EDITABLE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_EDITABLE))
+#define GTK_IS_EDITABLE_CLASS(vtable) (G_TYPE_CHECK_CLASS_TYPE ((vtable), GTK_TYPE_EDITABLE))
+#define GTK_EDITABLE_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_EDITABLE, GtkEditableClass))
-typedef struct _GtkEditable GtkEditable;
+typedef struct _GtkEditable GtkEditable; /* Dummy typedef */
typedef struct _GtkEditableClass GtkEditableClass;
-typedef void (*GtkTextFunction) (GtkEditable *editable, guint32 time);
-
-struct _GtkEditable
-{
- GtkWidget widget;
-
- /*< public >*/
- guint current_pos;
-
- guint selection_start_pos;
- guint selection_end_pos;
- guint has_selection : 1;
-
- /*< private >*/
- guint editable : 1;
- guint visible : 1;
- GdkIC *ic;
- GdkICAttr *ic_attr;
-
- gchar *clipboard_text;
-};
-
struct _GtkEditableClass
{
- GtkWidgetClass parent_class;
+ GTypeInterface base_iface;
/* Signals for notification/filtering of changes */
- void (* changed) (GtkEditable *editable);
- void (* insert_text) (GtkEditable *editable,
- const gchar *text,
- gint length,
- gint *position);
- void (* delete_text) (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-
- /* Bindings actions */
- void (* activate) (GtkEditable *editable);
- void (* set_editable) (GtkEditable *editable,
- gboolean is_editable);
- void (* move_cursor) (GtkEditable *editable,
- gint x,
- gint y);
- void (* move_word) (GtkEditable *editable,
- gint n);
- void (* move_page) (GtkEditable *editable,
- gint x,
- gint y);
- void (* move_to_row) (GtkEditable *editable,
- gint row);
- void (* move_to_column) (GtkEditable *editable,
- gint row);
- void (* kill_char) (GtkEditable *editable,
- gint direction);
- void (* kill_word) (GtkEditable *editable,
- gint direction);
- void (* kill_line) (GtkEditable *editable,
- gint direction);
- void (* cut_clipboard) (GtkEditable *editable);
- void (* copy_clipboard) (GtkEditable *editable);
- void (* paste_clipboard) (GtkEditable *editable);
-
- /* Virtual functions. get_chars is in paricular not a signal because
- * it returns malloced memory. The others are not signals because
- * they would not be particularly useful as such. (All changes to
- * selection and position do not go through these functions)
- */
- void (* update_text) (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
- gchar* (* get_chars) (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
- void (* set_selection)(GtkEditable *editable,
- gint start_pos,
- gint end_pos);
- void (* set_position) (GtkEditable *editable,
- gint position);
+ void (* insert_text) (GtkEditable *editable,
+ const gchar *text,
+ gint length,
+ gint *position);
+ void (* delete_text) (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos);
+ gchar* (* get_chars) (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos);
+ void (* set_selection_bounds) (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos);
+ gboolean (* get_selection_bounds) (GtkEditable *editable,
+ gint *start_pos,
+ gint *end_pos);
+ void (* set_position) (GtkEditable *editable,
+ gint position);
+ gint (* get_position) (GtkEditable *editable);
};
-GtkType gtk_editable_get_type (void) G_GNUC_CONST;
-void gtk_editable_select_region (GtkEditable *editable,
- gint start,
- gint end);
-void gtk_editable_insert_text (GtkEditable *editable,
- const gchar *new_text,
- gint new_text_length,
- gint *position);
-void gtk_editable_delete_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-gchar* gtk_editable_get_chars (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-void gtk_editable_cut_clipboard (GtkEditable *editable);
-void gtk_editable_copy_clipboard (GtkEditable *editable);
-void gtk_editable_paste_clipboard (GtkEditable *editable);
-void gtk_editable_claim_selection (GtkEditable *editable,
- gboolean claim,
- guint32 time);
-void gtk_editable_delete_selection (GtkEditable *editable);
-
-void gtk_editable_changed (GtkEditable *editable);
-void gtk_editable_set_position (GtkEditable *editable,
- gint position);
-gint gtk_editable_get_position (GtkEditable *editable);
-void gtk_editable_set_editable (GtkEditable *editable,
- gboolean is_editable);
-
+GtkType gtk_editable_get_type (void) G_GNUC_CONST;
+void gtk_editable_select_region (GtkEditable *editable,
+ gint start,
+ gint end);
+gboolean gtk_editable_get_selection_bounds (GtkEditable *editable,
+ gint *start,
+ gint *end);
+void gtk_editable_insert_text (GtkEditable *editable,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position);
+void gtk_editable_delete_text (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos);
+gchar* gtk_editable_get_chars (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos);
+void gtk_editable_cut_clipboard (GtkEditable *editable);
+void gtk_editable_copy_clipboard (GtkEditable *editable);
+void gtk_editable_paste_clipboard (GtkEditable *editable);
+void gtk_editable_delete_selection (GtkEditable *editable);
+void gtk_editable_set_position (GtkEditable *editable,
+ gint position);
+gint gtk_editable_get_position (GtkEditable *editable);
+void gtk_editable_set_editable (GtkEditable *editable,
+ gboolean is_editable);
#ifdef __cplusplus
}
diff --git a/gtk/gtkentry.c b/gtk/gtkentry.c
index 050709181a..fcffeedf4b 100644
--- a/gtk/gtkentry.c
+++ b/gtk/gtkentry.c
@@ -24,19 +24,21 @@
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
-#include <ctype.h>
#include <string.h>
+
+#include <pango/pango.h>
+
#include "gdk/gdkkeysyms.h"
-#include "gdk/gdki18n.h"
+#include "gtkbindings.h"
+#include "gtkclipboard.h"
#include "gtkentry.h"
#include "gtkimmulticontext.h"
+#include "gtkintl.h"
#include "gtkmain.h"
+#include "gtkmenu.h"
+#include "gtkmenuitem.h"
#include "gtkselection.h"
#include "gtksignal.h"
-#include "gtkstyle.h"
-
-#include <pango/pango.h>
-#include <glib-object.h>
#define MIN_ENTRY_WIDTH 150
#define DRAW_TIMEOUT 20
@@ -49,13 +51,34 @@
#define MAX_SIZE G_MAXUSHORT
enum {
+ INSERT_TEXT,
+ DELETE_TEXT,
+ CHANGED,
+ ACTIVATE,
+ MOVE_CURSOR,
+ INSERT_AT_CURSOR,
+ DELETE_FROM_CURSOR,
+ CUT_CLIPBOARD,
+ COPY_CLIPBOARD,
+ PASTE_CLIPBOARD,
+ TOGGLE_OVERWRITE,
+ LAST_SIGNAL
+};
+
+enum {
ARG_0,
+ ARG_TEXT_POSITION,
+ ARG_EDITABLE,
ARG_MAX_LENGTH,
ARG_VISIBILITY
};
+static guint signals[LAST_SIGNAL] = { 0 };
+/* GObject, GtkObject methods
+ */
static void gtk_entry_class_init (GtkEntryClass *klass);
+static void gtk_entry_editable_init (GtkEditableClass *iface);
static void gtk_entry_init (GtkEntry *entry);
static void gtk_entry_set_arg (GtkObject *object,
GtkArg *arg,
@@ -64,15 +87,18 @@ static void gtk_entry_get_arg (GtkObject *object,
GtkArg *arg,
guint arg_id);
static void gtk_entry_finalize (GObject *object);
+
+/* GtkWidget methods
+ */
static void gtk_entry_realize (GtkWidget *widget);
static void gtk_entry_unrealize (GtkWidget *widget);
-static void gtk_entry_draw_focus (GtkWidget *widget);
static void gtk_entry_size_request (GtkWidget *widget,
GtkRequisition *requisition);
static void gtk_entry_size_allocate (GtkWidget *widget,
GtkAllocation *allocation);
static void gtk_entry_draw (GtkWidget *widget,
GdkRectangle *area);
+static void gtk_entry_draw_focus (GtkWidget *widget);
static gint gtk_entry_expose (GtkWidget *widget,
GdkEventExpose *event);
static gint gtk_entry_button_press (GtkWidget *widget,
@@ -87,145 +113,100 @@ static gint gtk_entry_focus_in (GtkWidget *widget,
GdkEventFocus *event);
static gint gtk_entry_focus_out (GtkWidget *widget,
GdkEventFocus *event);
-static void gtk_entry_draw_text (GtkEntry *entry);
-static void gtk_entry_ensure_layout (GtkEntry *entry);
-static void gtk_entry_draw_cursor (GtkEntry *entry);
static void gtk_entry_style_set (GtkWidget *widget,
GtkStyle *previous_style);
static void gtk_entry_direction_changed (GtkWidget *widget,
GtkTextDirection previous_dir);
static void gtk_entry_state_changed (GtkWidget *widget,
GtkStateType previous_state);
-static void gtk_entry_queue_draw (GtkEntry *entry);
-static gint gtk_entry_find_position (GtkEntry *entry,
- gint x);
-static void gtk_entry_get_cursor_locations (GtkEntry *entry,
- gint *strong_x,
- gint *weak_x);
-static void entry_adjust_scroll (GtkEntry *entry);
-static void gtk_entry_insert_text (GtkEditable *editable,
- const gchar *new_text,
- gint new_text_length,
- gint *position);
-static void gtk_entry_delete_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-static void gtk_entry_update_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-static gchar *gtk_entry_get_chars (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-
-/* Binding actions */
-static void gtk_entry_move_cursor (GtkEditable *editable,
- gint x,
- gint y);
-static void gtk_entry_move_word (GtkEditable *editable,
- gint n);
-static void gtk_entry_move_to_column (GtkEditable *editable,
- gint row);
-static void gtk_entry_kill_char (GtkEditable *editable,
- gint direction);
-static void gtk_entry_kill_word (GtkEditable *editable,
- gint direction);
-static void gtk_entry_kill_line (GtkEditable *editable,
- gint direction);
-
-/* To be removed */
-static void gtk_move_forward_character (GtkEntry *entry);
-static void gtk_move_backward_character (GtkEntry *entry);
-static void gtk_move_forward_word (GtkEntry *entry);
-static void gtk_move_backward_word (GtkEntry *entry);
-static void gtk_move_beginning_of_line (GtkEntry *entry);
-static void gtk_move_end_of_line (GtkEntry *entry);
-static void gtk_delete_forward_character (GtkEntry *entry);
-static void gtk_delete_backward_character (GtkEntry *entry);
-static void gtk_delete_forward_word (GtkEntry *entry);
-static void gtk_delete_backward_word (GtkEntry *entry);
-static void gtk_delete_line (GtkEntry *entry);
-static void gtk_delete_to_line_end (GtkEntry *entry);
-static void gtk_select_word (GtkEntry *entry,
- guint32 time);
-static void gtk_select_line (GtkEntry *entry,
- guint32 time);
-
-
-static void gtk_entry_set_selection (GtkEditable *editable,
- gint start,
- gint end);
-
-static void gtk_entry_set_position_from_editable (GtkEditable *editable,
- gint position);
+/* GtkEditable method implementations
+ */
+static void gtk_entry_insert_text (GtkEditable *editable,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position);
+static void gtk_entry_delete_text (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos);
+static gchar * gtk_entry_get_chars (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos);
+static void gtk_entry_real_set_position (GtkEditable *editable,
+ gint position);
+static gint gtk_entry_get_position (GtkEditable *editable);
+static void gtk_entry_set_selection_bounds (GtkEditable *editable,
+ gint start,
+ gint end);
+static gboolean gtk_entry_get_selection_bounds (GtkEditable *editable,
+ gint *start,
+ gint *end);
+
+/* Default signal handlers
+ */
+static void gtk_entry_real_insert_text (GtkEntry *entry,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position);
+static void gtk_entry_real_delete_text (GtkEntry *entry,
+ gint start_pos,
+ gint end_pos);
+static void gtk_entry_move (GtkEntry *entry,
+ GtkMovementStep step,
+ gint count,
+ gboolean extend_selection);
+static void gtk_entry_insert (GtkEntry *entry,
+ const gchar *str);
+static void gtk_entry_delete (GtkEntry *entry,
+ GtkDeleteType type,
+ gint count);
+static void gtk_entry_cut_clipboard (GtkEntry *entry);
+static void gtk_entry_copy_clipboard (GtkEntry *entry);
+static void gtk_entry_paste_clipboard (GtkEntry *entry);
+static void gtk_entry_toggle_overwrite (GtkEntry *entry);
+
+/* IM Context Callbacks
+ */
static void gtk_entry_commit_cb (GtkIMContext *context,
const gchar *str,
GtkEntry *entry);
-
+static void gtk_entry_preedit_changed_cb (GtkIMContext *context,
+ GtkEntry *entry);
+/* Internal routines
+ */
+static void gtk_entry_draw_text (GtkEntry *entry);
+static void gtk_entry_draw_cursor (GtkEntry *entry);
+static PangoLayout *gtk_entry_get_layout (GtkEntry *entry,
+ gboolean include_preedit);
+static void gtk_entry_queue_draw (GtkEntry *entry);
+static void gtk_entry_reset_im_context (GtkEntry *entry);
+static void gtk_entry_recompute (GtkEntry *entry);
+static gint gtk_entry_find_position (GtkEntry *entry,
+ gint x);
+static void gtk_entry_get_cursor_locations (GtkEntry *entry,
+ gint *strong_x,
+ gint *weak_x);
+static void gtk_entry_adjust_scroll (GtkEntry *entry);
+static gint gtk_entry_move_visually (GtkEntry *editable,
+ gint start,
+ gint count);
+static gint gtk_entry_move_forward_word (GtkEntry *entry,
+ gint start);
+static gint gtk_entry_move_backward_word (GtkEntry *entry,
+ gint start);
+static void gtk_entry_delete_whitespace (GtkEntry *entry);
+static void gtk_entry_select_word (GtkEntry *entry);
+static void gtk_entry_select_line (GtkEntry *entry);
+static char * gtk_entry_get_public_chars (GtkEntry *entry,
+ gint start,
+ gint end);
+static void gtk_entry_paste (GtkEntry *entry,
+ GdkAtom selection);
+static void gtk_entry_update_primary_selection (GtkEntry *entry);
+static void gtk_entry_popup_menu (GtkEntry *entry,
+ GdkEventButton *event);
static GtkWidgetClass *parent_class = NULL;
-static GdkAtom ctext_atom = GDK_NONE;
-
-static const GtkTextFunction control_keys[26] =
-{
- (GtkTextFunction)gtk_move_beginning_of_line, /* a */
- (GtkTextFunction)gtk_move_backward_character, /* b */
- (GtkTextFunction)gtk_editable_copy_clipboard, /* c */
- (GtkTextFunction)gtk_delete_forward_character, /* d */
- (GtkTextFunction)gtk_move_end_of_line, /* e */
- (GtkTextFunction)gtk_move_forward_character, /* f */
- NULL, /* g */
- (GtkTextFunction)gtk_delete_backward_character, /* h */
- NULL, /* i */
- NULL, /* j */
- (GtkTextFunction)gtk_delete_to_line_end, /* k */
- NULL, /* l */
- NULL, /* m */
- NULL, /* n */
- NULL, /* o */
- NULL, /* p */
- NULL, /* q */
- NULL, /* r */
- NULL, /* s */
- NULL, /* t */
- (GtkTextFunction)gtk_delete_line, /* u */
- (GtkTextFunction)gtk_editable_paste_clipboard, /* v */
- (GtkTextFunction)gtk_delete_backward_word, /* w */
- (GtkTextFunction)gtk_editable_cut_clipboard, /* x */
- NULL, /* y */
- NULL, /* z */
-};
-
-static const GtkTextFunction alt_keys[26] =
-{
- NULL, /* a */
- (GtkTextFunction)gtk_move_backward_word, /* b */
- NULL, /* c */
- (GtkTextFunction)gtk_delete_forward_word, /* d */
- NULL, /* e */
- (GtkTextFunction)gtk_move_forward_word, /* f */
- NULL, /* g */
- NULL, /* h */
- NULL, /* i */
- NULL, /* j */
- NULL, /* k */
- NULL, /* l */
- NULL, /* m */
- NULL, /* n */
- NULL, /* o */
- NULL, /* p */
- NULL, /* q */
- NULL, /* r */
- NULL, /* s */
- NULL, /* t */
- NULL, /* u */
- NULL, /* v */
- NULL, /* w */
- NULL, /* x */
- NULL, /* y */
- NULL, /* z */
-};
-
GtkType
gtk_entry_get_type (void)
@@ -245,31 +226,291 @@ gtk_entry_get_type (void)
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
};
+
+ static const GInterfaceInfo editable_info =
+ {
+ (GInterfaceInitFunc) gtk_entry_editable_init, /* interface_init */
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
- entry_type = gtk_type_unique (GTK_TYPE_EDITABLE, &entry_info);
+ entry_type = gtk_type_unique (GTK_TYPE_WIDGET, &entry_info);
+ g_type_add_interface_static (entry_type,
+ GTK_TYPE_EDITABLE,
+ &editable_info);
}
return entry_type;
}
static void
+add_move_binding (GtkBindingSet *binding_set,
+ guint keyval,
+ guint modmask,
+ GtkMovementStep step,
+ gint count)
+{
+ g_return_if_fail ((modmask & GDK_SHIFT_MASK) == 0);
+
+ gtk_binding_entry_add_signal (binding_set, keyval, modmask,
+ "move_cursor", 3,
+ GTK_TYPE_ENUM, step,
+ G_TYPE_INT, count,
+ G_TYPE_BOOLEAN, FALSE);
+
+ /* Selection-extending version */
+ gtk_binding_entry_add_signal (binding_set, keyval, modmask | GDK_SHIFT_MASK,
+ "move_cursor", 3,
+ GTK_TYPE_ENUM, step,
+ G_TYPE_INT, count,
+ G_TYPE_BOOLEAN, TRUE);
+}
+
+static void
gtk_entry_class_init (GtkEntryClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
- GtkEditableClass *editable_class;
+
+ GtkBindingSet *binding_set;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
- editable_class = (GtkEditableClass*) class;
- parent_class = gtk_type_class (GTK_TYPE_EDITABLE);
+ parent_class = gtk_type_class (GTK_TYPE_WIDGET);
gobject_class->finalize = gtk_entry_finalize;
- gtk_object_add_arg_type ("GtkEntry::max_length", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_MAX_LENGTH);
- gtk_object_add_arg_type ("GtkEntry::visibility", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_VISIBILITY);
+ gtk_object_add_arg_type ("GtkEntry::text_position", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_TEXT_POSITION);
+ gtk_object_add_arg_type ("GtkEntry::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITABLE);
+ gtk_object_add_arg_type ("GtkEntry::max_length", GTK_TYPE_UINT, GTK_ARG_READWRITE, ARG_MAX_LENGTH);
+ gtk_object_add_arg_type ("GtkEntry::visibility", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_VISIBILITY);
+
+ signals[INSERT_TEXT] =
+ gtk_signal_new ("insert_text",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, insert_text),
+ gtk_marshal_VOID__STRING_INT_POINTER,
+ GTK_TYPE_NONE,
+ 3,
+ GTK_TYPE_STRING,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER);
+
+ signals[DELETE_TEXT] =
+ gtk_signal_new ("delete_text",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, delete_text),
+ gtk_marshal_VOID__INT_INT,
+ GTK_TYPE_NONE,
+ 2,
+ GTK_TYPE_INT,
+ GTK_TYPE_INT);
+
+ signals[CHANGED] =
+ gtk_signal_new ("changed",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, changed),
+ gtk_marshal_VOID__VOID,
+ GTK_TYPE_NONE, 0);
+
+ /* Action signals */
+
+ signals[ACTIVATE] =
+ gtk_signal_new ("activate",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, activate),
+ gtk_marshal_VOID__VOID,
+ GTK_TYPE_NONE, 0);
+
+ widget_class->activate_signal = signals[ACTIVATE];
+
+ signals[MOVE_CURSOR] =
+ gtk_signal_new ("move_cursor",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, move),
+ gtk_marshal_VOID__ENUM_INT_BOOLEAN,
+ GTK_TYPE_NONE, 3, GTK_TYPE_MOVEMENT_STEP, GTK_TYPE_INT, GTK_TYPE_BOOL);
+
+ signals[INSERT_AT_CURSOR] =
+ gtk_signal_new ("insert_at_cursor",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, insert),
+ gtk_marshal_VOID__STRING,
+ GTK_TYPE_NONE, 1, GTK_TYPE_STRING);
+
+ signals[DELETE_FROM_CURSOR] =
+ gtk_signal_new ("delete_from_cursor",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, delete),
+ gtk_marshal_VOID__ENUM_INT,
+ GTK_TYPE_NONE, 2, GTK_TYPE_DELETE_TYPE, GTK_TYPE_INT);
+
+ signals[CUT_CLIPBOARD] =
+ gtk_signal_new ("cut_clipboard",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, cut_clipboard),
+ gtk_marshal_VOID__VOID,
+ GTK_TYPE_NONE, 0);
+
+ signals[COPY_CLIPBOARD] =
+ gtk_signal_new ("copy_clipboard",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, copy_clipboard),
+ gtk_marshal_VOID__VOID,
+ GTK_TYPE_NONE, 0);
+
+ signals[PASTE_CLIPBOARD] =
+ gtk_signal_new ("paste_clipboard",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, paste_clipboard),
+ gtk_marshal_VOID__VOID,
+ GTK_TYPE_NONE, 0);
+
+ signals[TOGGLE_OVERWRITE] =
+ gtk_signal_new ("toggle_overwrite",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkEntryClass, toggle_overwrite),
+ gtk_marshal_VOID__VOID,
+ GTK_TYPE_NONE, 0);
+
+ gtk_object_class_add_signals (object_class, signals, LAST_SIGNAL);
+
+ /*
+ * Key bindings
+ */
+ binding_set = gtk_binding_set_by_class (class);
+
+ /* Moving the insertion point */
+ add_move_binding (binding_set, GDK_Right, 0,
+ GTK_MOVEMENT_POSITIONS, 1);
+
+ add_move_binding (binding_set, GDK_Left, 0,
+ GTK_MOVEMENT_POSITIONS, -1);
+
+ add_move_binding (binding_set, GDK_f, GDK_CONTROL_MASK,
+ GTK_MOVEMENT_CHARS, 1);
+
+ add_move_binding (binding_set, GDK_b, GDK_CONTROL_MASK,
+ GTK_MOVEMENT_CHARS, -1);
+
+ add_move_binding (binding_set, GDK_Right, GDK_CONTROL_MASK,
+ GTK_MOVEMENT_WORDS, 1);
+
+ add_move_binding (binding_set, GDK_Left, GDK_CONTROL_MASK,
+ GTK_MOVEMENT_WORDS, -1);
+
+ add_move_binding (binding_set, GDK_a, GDK_CONTROL_MASK,
+ GTK_MOVEMENT_PARAGRAPH_ENDS, -1);
+
+ add_move_binding (binding_set, GDK_e, GDK_CONTROL_MASK,
+ GTK_MOVEMENT_PARAGRAPH_ENDS, 1);
+
+ add_move_binding (binding_set, GDK_f, GDK_MOD1_MASK,
+ GTK_MOVEMENT_WORDS, 1);
+
+ add_move_binding (binding_set, GDK_b, GDK_MOD1_MASK,
+ GTK_MOVEMENT_WORDS, -1);
+
+ add_move_binding (binding_set, GDK_Home, 0,
+ GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
+
+ add_move_binding (binding_set, GDK_End, 0,
+ GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);
+
+ add_move_binding (binding_set, GDK_Home, GDK_CONTROL_MASK,
+ GTK_MOVEMENT_BUFFER_ENDS, -1);
+
+ add_move_binding (binding_set, GDK_End, GDK_CONTROL_MASK,
+ GTK_MOVEMENT_BUFFER_ENDS, 1);
+
+ /* Deleting text */
+ gtk_binding_entry_add_signal (binding_set, GDK_Delete, 0,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_CHARS,
+ GTK_TYPE_INT, 1);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_d, GDK_CONTROL_MASK,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_CHARS,
+ GTK_TYPE_INT, 1);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_CHARS,
+ GTK_TYPE_INT, -1);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_CONTROL_MASK,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS,
+ GTK_TYPE_INT, 1);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_d, GDK_MOD1_MASK,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS,
+ GTK_TYPE_INT, 1);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_CONTROL_MASK,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_WORD_ENDS,
+ GTK_TYPE_INT, -1);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_k, GDK_CONTROL_MASK,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_PARAGRAPH_ENDS,
+ GTK_TYPE_INT, 1);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_u, GDK_CONTROL_MASK,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_PARAGRAPHS,
+ GTK_TYPE_INT, 1);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_MOD1_MASK,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_WHITESPACE,
+ GTK_TYPE_INT, 1);
+ gtk_binding_entry_add_signal (binding_set, GDK_space, GDK_MOD1_MASK,
+ "insert_at_cursor", 1,
+ GTK_TYPE_STRING, " ");
+
+ gtk_binding_entry_add_signal (binding_set, GDK_backslash, GDK_MOD1_MASK,
+ "delete_from_cursor", 2,
+ GTK_TYPE_ENUM, GTK_DELETE_WHITESPACE,
+ GTK_TYPE_INT, 1);
+
+ /* Cut/copy/paste */
+
+ gtk_binding_entry_add_signal (binding_set, GDK_x, GDK_CONTROL_MASK,
+ "cut_clipboard", 0);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_w, GDK_CONTROL_MASK,
+ "cut_clipboard", 0);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_c, GDK_CONTROL_MASK,
+ "copy_clipboard", 0);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_v, GDK_CONTROL_MASK,
+ "paste_clipboard", 0);
+
+ gtk_binding_entry_add_signal (binding_set, GDK_y, GDK_CONTROL_MASK,
+ "paste_clipboard", 0);
+
+ /* Overwrite */
+ gtk_binding_entry_add_signal (binding_set, GDK_Insert, 0,
+ "toggle_overwrite", 0);
+
object_class->set_arg = gtk_entry_set_arg;
object_class->get_arg = gtk_entry_get_arg;
@@ -290,22 +531,27 @@ gtk_entry_class_init (GtkEntryClass *class)
widget_class->direction_changed = gtk_entry_direction_changed;
widget_class->state_changed = gtk_entry_state_changed;
- editable_class->insert_text = gtk_entry_insert_text;
- editable_class->delete_text = gtk_entry_delete_text;
- editable_class->changed = (void (*)(GtkEditable *)) entry_adjust_scroll;
-
- editable_class->move_cursor = gtk_entry_move_cursor;
- editable_class->move_word = gtk_entry_move_word;
- editable_class->move_to_column = gtk_entry_move_to_column;
-
- editable_class->kill_char = gtk_entry_kill_char;
- editable_class->kill_word = gtk_entry_kill_word;
- editable_class->kill_line = gtk_entry_kill_line;
+ class->insert_text = gtk_entry_real_insert_text;
+ class->delete_text = gtk_entry_real_delete_text;
+ class->move = gtk_entry_move;
+ class->insert = gtk_entry_insert;
+ class->delete = gtk_entry_delete;
+ class->cut_clipboard = gtk_entry_cut_clipboard;
+ class->copy_clipboard = gtk_entry_copy_clipboard;
+ class->paste_clipboard = gtk_entry_paste_clipboard;
+ class->toggle_overwrite = gtk_entry_toggle_overwrite;
+}
- editable_class->update_text = gtk_entry_update_text;
- editable_class->get_chars = gtk_entry_get_chars;
- editable_class->set_selection = gtk_entry_set_selection;
- editable_class->set_position = gtk_entry_set_position_from_editable;
+static void
+gtk_entry_editable_init (GtkEditableClass *iface)
+{
+ iface->insert_text = gtk_entry_insert_text;
+ iface->delete_text = gtk_entry_delete_text;
+ iface->get_chars = gtk_entry_get_chars;
+ iface->set_selection_bounds = gtk_entry_set_selection_bounds;
+ iface->get_selection_bounds = gtk_entry_get_selection_bounds;
+ iface->set_position = gtk_entry_real_set_position;
+ iface->get_position = gtk_entry_get_position;
}
static void
@@ -313,12 +559,23 @@ gtk_entry_set_arg (GtkObject *object,
GtkArg *arg,
guint arg_id)
{
- GtkEntry *entry;
-
- entry = GTK_ENTRY (object);
+ GtkEntry *entry = GTK_ENTRY (object);
switch (arg_id)
{
+ case ARG_TEXT_POSITION:
+ gtk_editable_set_position (GTK_EDITABLE (object), GTK_VALUE_INT (*arg));
+ break;
+ case ARG_EDITABLE:
+ {
+ gboolean new_value = GTK_VALUE_BOOL (*arg) != 0;
+ if (new_value != entry->editable)
+ {
+ entry->editable = new_value;
+ gtk_entry_queue_draw (entry);
+ }
+ }
+ break;
case ARG_MAX_LENGTH:
gtk_entry_set_max_length (entry, GTK_VALUE_UINT (*arg));
break;
@@ -341,11 +598,17 @@ gtk_entry_get_arg (GtkObject *object,
switch (arg_id)
{
+ case ARG_TEXT_POSITION:
+ GTK_VALUE_INT (*arg) = entry->current_pos;
+ break;
+ case ARG_EDITABLE:
+ GTK_VALUE_BOOL (*arg) = entry->editable;
+ break;
case ARG_MAX_LENGTH:
GTK_VALUE_UINT (*arg) = entry->text_max_length;
break;
case ARG_VISIBILITY:
- GTK_VALUE_BOOL (*arg) = GTK_EDITABLE (entry)->visible;
+ GTK_VALUE_BOOL (*arg) = entry->visible;
break;
default:
arg->type = GTK_TYPE_INVALID;
@@ -358,20 +621,12 @@ gtk_entry_init (GtkEntry *entry)
{
GTK_WIDGET_SET_FLAGS (entry, GTK_CAN_FOCUS);
- entry->text_area = NULL;
-
entry->text_size = MIN_SIZE;
entry->text = g_malloc (entry->text_size);
entry->text[0] = '\0';
-
- entry->text_length = 0;
- entry->text_max_length = 0;
- entry->n_bytes = 0;
- entry->scroll_offset = 0;
- entry->timer = 0;
- entry->button = 0;
- entry->ascent = 0;
- entry->descent = 0;
+
+ entry->editable = TRUE;
+ entry->visible = TRUE;
/* This object is completely private. No external entity can gain a reference
* to it; so we create it here and destroy it in finalize().
@@ -380,124 +635,8 @@ gtk_entry_init (GtkEntry *entry)
gtk_signal_connect (GTK_OBJECT (entry->im_context), "commit",
GTK_SIGNAL_FUNC (gtk_entry_commit_cb), entry);
-}
-
-GtkWidget*
-gtk_entry_new (void)
-{
- return GTK_WIDGET (gtk_type_new (GTK_TYPE_ENTRY));
-}
-
-GtkWidget*
-gtk_entry_new_with_max_length (guint16 max)
-{
- GtkEntry *entry;
-
- entry = gtk_type_new (GTK_TYPE_ENTRY);
- entry->text_max_length = max;
-
- return GTK_WIDGET (entry);
-}
-
-void
-gtk_entry_set_text (GtkEntry *entry,
- const gchar *text)
-{
- gint tmp_pos;
-
- GtkEditable *editable;
-
- g_return_if_fail (entry != NULL);
- g_return_if_fail (GTK_IS_ENTRY (entry));
- g_return_if_fail (text != NULL);
-
- editable = GTK_EDITABLE (entry);
-
- gtk_entry_delete_text (GTK_EDITABLE(entry), 0, entry->text_length);
-
- tmp_pos = 0;
- gtk_editable_insert_text (editable, text, strlen (text), &tmp_pos);
- editable->current_pos = tmp_pos;
-}
-
-void
-gtk_entry_append_text (GtkEntry *entry,
- const gchar *text)
-{
- gint tmp_pos;
-
- g_return_if_fail (entry != NULL);
- g_return_if_fail (GTK_IS_ENTRY (entry));
- g_return_if_fail (text != NULL);
-
- tmp_pos = entry->text_length;
- gtk_editable_insert_text (GTK_EDITABLE(entry), text, strlen (text), &tmp_pos);
-}
-
-void
-gtk_entry_prepend_text (GtkEntry *entry,
- const gchar *text)
-{
- gint tmp_pos;
-
- g_return_if_fail (entry != NULL);
- g_return_if_fail (GTK_IS_ENTRY (entry));
- g_return_if_fail (text != NULL);
-
- tmp_pos = 0;
- gtk_editable_insert_text (GTK_EDITABLE(entry), text, strlen (text), &tmp_pos);
-}
-
-void
-gtk_entry_set_position (GtkEntry *entry,
- gint position)
-{
- g_return_if_fail (entry != NULL);
- g_return_if_fail (GTK_IS_ENTRY (entry));
-
- if ((position == -1) || (position > entry->text_length))
- GTK_EDITABLE(entry)->current_pos = entry->text_length;
- else
- GTK_EDITABLE(entry)->current_pos = position;
- entry_adjust_scroll (entry);
-}
-
-static void
-gtk_entry_set_position_from_editable (GtkEditable *editable,
- gint position)
-{
- gtk_entry_set_position (GTK_ENTRY (editable), position);
-}
-
-void
-gtk_entry_set_visibility (GtkEntry *entry,
- gboolean visible)
-{
- g_return_if_fail (entry != NULL);
- g_return_if_fail (GTK_IS_ENTRY (entry));
-
- GTK_EDITABLE (entry)->visible = visible ? TRUE : FALSE;
-
- gtk_entry_queue_draw (entry);
-}
-
-void
-gtk_entry_set_editable(GtkEntry *entry,
- gboolean editable)
-{
- g_return_if_fail (entry != NULL);
- g_return_if_fail (GTK_IS_ENTRY (entry));
-
- gtk_editable_set_editable (GTK_EDITABLE (entry), editable);
-}
-
-gchar*
-gtk_entry_get_text (GtkEntry *entry)
-{
- g_return_val_if_fail (entry != NULL, NULL);
- g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
-
- return entry->text;
+ gtk_signal_connect (GTK_OBJECT (entry->im_context), "preedit_changed",
+ GTK_SIGNAL_FUNC (gtk_entry_preedit_changed_cb), entry);
}
static void
@@ -509,13 +648,16 @@ gtk_entry_finalize (GObject *object)
entry = GTK_ENTRY (object);
- if (entry->layout)
- g_object_unref (G_OBJECT (entry->layout));
+ if (entry->cached_layout)
+ g_object_unref (G_OBJECT (entry->cached_layout));
gtk_object_unref (GTK_OBJECT (entry->im_context));
if (entry->timer)
- gtk_timeout_remove (entry->timer);
+ g_source_remove (entry->timer);
+
+ if (entry->recompute_idle)
+ g_source_remove (entry->recompute_idle);
entry->text_size = 0;
@@ -559,10 +701,7 @@ gtk_entry_realize (GtkWidget *widget)
GDK_BUTTON_RELEASE_MASK |
GDK_BUTTON1_MOTION_MASK |
GDK_BUTTON3_MOTION_MASK |
- GDK_POINTER_MOTION_HINT_MASK |
- GDK_ENTER_NOTIFY_MASK |
- GDK_LEAVE_NOTIFY_MASK |
- GDK_KEY_PRESS_MASK);
+ GDK_POINTER_MOTION_HINT_MASK);
attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
widget->window = gdk_window_new (gtk_widget_get_parent_window (widget), &attributes, attributes_mask);
@@ -572,7 +711,7 @@ gtk_entry_realize (GtkWidget *widget)
attributes.y = widget->style->ythickness;
attributes.width = widget->allocation.width - attributes.x * 2;
attributes.height = requisition.height - attributes.y * 2;
- attributes.cursor = entry->cursor = gdk_cursor_new (GDK_XTERM);
+ attributes.cursor = gdk_cursor_new (GDK_XTERM);
attributes_mask |= GDK_WA_CURSOR;
entry->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
@@ -585,12 +724,9 @@ gtk_entry_realize (GtkWidget *widget)
gdk_window_show (entry->text_area);
- if (editable->selection_start_pos != editable->selection_end_pos)
- gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME);
-
gtk_im_context_set_client_window (entry->im_context, entry->text_area);
- entry_adjust_scroll (entry);
+ gtk_entry_adjust_scroll (entry);
}
static void
@@ -610,53 +746,16 @@ gtk_entry_unrealize (GtkWidget *widget)
gdk_window_set_user_data (entry->text_area, NULL);
gdk_window_destroy (entry->text_area);
entry->text_area = NULL;
- gdk_cursor_destroy (entry->cursor);
- entry->cursor = NULL;
}
+ if (entry->popup_menu)
+ gtk_widget_destroy (entry->popup_menu);
+
if (GTK_WIDGET_CLASS (parent_class)->unrealize)
(* GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
}
static void
-gtk_entry_draw_focus (GtkWidget *widget)
-{
- gint width, height;
- gint x, y;
-
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_ENTRY (widget));
-
- if (GTK_WIDGET_DRAWABLE (widget))
- {
- x = 0;
- y = 0;
- gdk_window_get_size (widget->window, &width, &height);
-
- if (GTK_WIDGET_HAS_FOCUS (widget))
- {
- x += 1;
- y += 1;
- width -= 2;
- height -= 2;
- }
-
- gtk_paint_shadow (widget->style, widget->window,
- GTK_STATE_NORMAL, GTK_SHADOW_IN,
- NULL, widget, "entry",
- x, y, width, height);
-
- if (GTK_WIDGET_HAS_FOCUS (widget))
- {
- gdk_window_get_size (widget->window, &width, &height);
- gtk_paint_focus (widget->style, widget->window,
- NULL, widget, "entry",
- 0, 0, width - 1, height - 1);
- }
- }
-}
-
-static void
gtk_entry_size_request (GtkWidget *widget,
GtkRequisition *requisition)
{
@@ -671,13 +770,11 @@ gtk_entry_size_request (GtkWidget *widget,
entry = GTK_ENTRY (widget);
- gtk_entry_ensure_layout (entry);
-
/* hackish for now, get metrics
*/
- font = pango_context_load_font (pango_layout_get_context (entry->layout),
+ font = pango_context_load_font (gtk_widget_get_pango_context (widget),
widget->style->font_desc);
- lang = pango_context_get_lang (pango_layout_get_context (entry->layout));
+ lang = pango_context_get_lang (gtk_widget_get_pango_context (widget));
pango_font_get_metrics (font, lang, &metrics);
g_free (lang);
@@ -725,8 +822,7 @@ gtk_entry_size_allocate (GtkWidget *widget,
allocation->width - widget->style->xthickness * 2,
requisition.height - widget->style->ythickness * 2);
- /* And make sure the cursor is on screen */
- entry_adjust_scroll (entry);
+ gtk_entry_recompute (entry);
}
}
@@ -757,6 +853,44 @@ gtk_entry_draw (GtkWidget *widget,
}
}
+static void
+gtk_entry_draw_focus (GtkWidget *widget)
+{
+ gint width, height;
+ gint x, y;
+
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_ENTRY (widget));
+
+ if (GTK_WIDGET_DRAWABLE (widget))
+ {
+ x = 0;
+ y = 0;
+ gdk_window_get_size (widget->window, &width, &height);
+
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ {
+ x += 1;
+ y += 1;
+ width -= 2;
+ height -= 2;
+ }
+
+ gtk_paint_shadow (widget->style, widget->window,
+ GTK_STATE_NORMAL, GTK_SHADOW_IN,
+ NULL, widget, "entry",
+ x, y, width, height);
+
+ if (GTK_WIDGET_HAS_FOCUS (widget))
+ {
+ gdk_window_get_size (widget->window, &width, &height);
+ gtk_paint_focus (widget->style, widget->window,
+ NULL, widget, "entry",
+ 0, 0, width - 1, height - 1);
+ }
+ }
+}
+
static gint
gtk_entry_expose (GtkWidget *widget,
GdkEventExpose *event)
@@ -784,49 +918,44 @@ static gint
gtk_entry_button_press (GtkWidget *widget,
GdkEventButton *event)
{
- GtkEntry *entry;
- GtkEditable *editable;
+ GtkEntry *entry = GTK_ENTRY (widget);
+ GtkEditable *editable = GTK_EDITABLE (widget);
gint tmp_pos;
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- if (ctext_atom == GDK_NONE)
- ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
-
entry = GTK_ENTRY (widget);
editable = GTK_EDITABLE (widget);
- if (entry->button && (event->button != entry->button))
+ if (event->window != entry->text_area ||
+ (entry->button && event->button != entry->button))
return FALSE;
entry->button = event->button;
if (!GTK_WIDGET_HAS_FOCUS (widget))
gtk_widget_grab_focus (widget);
-
+
+ tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
+
if (event->button == 1)
{
switch (event->type)
{
case GDK_BUTTON_PRESS:
- gtk_grab_add (widget);
-
- tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
- /* Set it now, so we display things right. We'll unset it
- * later if things don't work out */
- editable->has_selection = TRUE;
- gtk_entry_set_selection (editable, tmp_pos, tmp_pos);
- editable->current_pos = editable->selection_start_pos;
+ gtk_entry_reset_im_context (entry);
+
+ entry->current_pos = tmp_pos;
+ entry->selection_bound = tmp_pos;
+
+ gtk_entry_recompute (entry);
+
break;
case GDK_2BUTTON_PRESS:
- gtk_select_word (entry, event->time);
+ gtk_entry_select_word (entry);
break;
case GDK_3BUTTON_PRESS:
- gtk_select_line (entry, event->time);
+ gtk_entry_select_line (entry);
break;
default:
@@ -835,28 +964,17 @@ gtk_entry_button_press (GtkWidget *widget,
return TRUE;
}
- else if (event->type == GDK_BUTTON_PRESS)
+ else if (event->button == 2 && event->type == GDK_BUTTON_PRESS && entry->editable)
{
- if ((event->button == 2) && editable->editable)
- {
- if (editable->selection_start_pos == editable->selection_end_pos ||
- editable->has_selection)
- editable->current_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
- gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
- ctext_atom, event->time);
- }
- else
- {
- gtk_grab_add (widget);
-
- tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
- gtk_entry_set_selection (editable, tmp_pos, tmp_pos);
- editable->has_selection = FALSE;
- editable->current_pos = editable->selection_start_pos;
+ gtk_editable_select_region (editable, tmp_pos, tmp_pos);
+ gtk_entry_paste (entry, GDK_SELECTION_PRIMARY);
- if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
- gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, event->time);
- }
+ return TRUE;
+ }
+ else if (event->button == 3 && event->type == GDK_BUTTON_PRESS)
+ {
+ gtk_entry_popup_menu (entry, event);
+ entry->button = 0; /* Don't wait for release, since the menu will gtk_grab_add */
return TRUE;
}
@@ -868,46 +986,20 @@ static gint
gtk_entry_button_release (GtkWidget *widget,
GdkEventButton *event)
{
- GtkEntry *entry;
- GtkEditable *editable;
-
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (widget);
+ GtkEntry *entry = GTK_ENTRY (widget);
+ GtkEditable *editable = GTK_EDITABLE (widget);
- if (entry->button != event->button)
+ if (event->window != entry->text_area || entry->button != event->button)
return FALSE;
entry->button = 0;
if (event->button == 1)
{
- gtk_grab_remove (widget);
+ gint tmp_pos;
- editable->has_selection = FALSE;
- if (editable->selection_start_pos != editable->selection_end_pos)
- {
- if (gtk_selection_owner_set (widget,
- GDK_SELECTION_PRIMARY,
- event->time))
- editable->has_selection = TRUE;
- else
- gtk_entry_queue_draw (entry);
- }
- else
- {
- if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
- gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, event->time);
- }
-
- return TRUE;
- }
- else if (event->button == 3)
- {
- gtk_grab_remove (widget);
+ tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
+ gtk_editable_select_region (editable, entry->selection_bound, tmp_pos);
return TRUE;
}
@@ -919,27 +1011,23 @@ static gint
gtk_entry_motion_notify (GtkWidget *widget,
GdkEventMotion *event)
{
- GtkEntry *entry;
- gint x;
-
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
-
- entry = GTK_ENTRY (widget);
+ GtkEntry *entry = GTK_ENTRY (widget);
+ gint tmp_pos;
- if (entry->button == 0)
+ if (event->window != entry->text_area || entry->button != 1)
return FALSE;
- x = event->x;
if (event->is_hint || (entry->text_area != event->window))
- gdk_window_get_pointer (entry->text_area, &x, NULL, NULL);
+ gdk_window_get_pointer (entry->text_area, NULL, NULL, NULL);
- GTK_EDITABLE(entry)->selection_end_pos = gtk_entry_find_position (entry, x + entry->scroll_offset);
- GTK_EDITABLE(entry)->current_pos = GTK_EDITABLE(entry)->selection_end_pos;
- entry_adjust_scroll (entry);
- gtk_entry_queue_draw (entry);
+ tmp_pos = gtk_entry_find_position (entry, event->x + entry->scroll_offset);
+ if (tmp_pos != entry->current_pos)
+ {
+ entry->current_pos = tmp_pos;
+ gtk_entry_recompute (entry);
+ }
+
return TRUE;
}
@@ -947,230 +1035,644 @@ static gint
gtk_entry_key_press (GtkWidget *widget,
GdkEventKey *event)
{
- GtkEntry *entry;
- GtkEditable *editable;
+ GtkEntry *entry = GTK_ENTRY (widget);
- gint return_val;
- gint key;
- guint initial_pos;
- gint extend_selection;
- gint extend_start;
+ if (!entry->editable)
+ return FALSE;
+
+ /* Activate key bindings
+ */
+ if (GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
+ return TRUE;
+
+ /* Not bound, pass to input method
+ */
+ entry->need_im_reset = TRUE;
+ return gtk_im_context_filter_keypress (entry->im_context, event);
+}
+static gint
+gtk_entry_focus_in (GtkWidget *widget,
+ GdkEventFocus *event)
+{
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- entry = GTK_ENTRY (widget);
- editable = GTK_EDITABLE (widget);
- return_val = FALSE;
+ GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
+ gtk_widget_draw_focus (widget);
+ gtk_entry_queue_draw (GTK_ENTRY (widget));
+
+ GTK_ENTRY (widget)->need_im_reset = TRUE;
+ gtk_im_context_focus_in (GTK_ENTRY (widget)->im_context);
- if(editable->editable == FALSE)
- return FALSE;
+ return FALSE;
+}
- initial_pos = editable->current_pos;
+static gint
+gtk_entry_focus_out (GtkWidget *widget,
+ GdkEventFocus *event)
+{
+ g_return_val_if_fail (widget != NULL, FALSE);
+ g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
+ g_return_val_if_fail (event != NULL, FALSE);
- extend_selection = event->state & GDK_SHIFT_MASK;
- extend_start = FALSE;
+ GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
+ gtk_widget_draw_focus (widget);
+ gtk_entry_queue_draw (GTK_ENTRY (widget));
- if (extend_selection)
+ GTK_ENTRY (widget)->need_im_reset = TRUE;
+ gtk_im_context_focus_out (GTK_ENTRY (widget)->im_context);
+
+ return FALSE;
+}
+
+static void
+gtk_entry_direction_changed (GtkWidget *widget,
+ GtkTextDirection previous_dir)
+{
+ GtkEntry *entry = GTK_ENTRY (widget);
+
+ gtk_entry_recompute (entry);
+
+ GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
+}
+
+static void
+gtk_entry_state_changed (GtkWidget *widget,
+ GtkStateType previous_state)
+{
+ g_return_if_fail (widget != NULL);
+ g_return_if_fail (GTK_IS_ENTRY (widget));
+
+ if (GTK_WIDGET_REALIZED (widget))
{
- if (editable->selection_start_pos == editable->selection_end_pos)
+ gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+ gdk_window_set_background (GTK_ENTRY (widget)->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+ }
+
+ gtk_widget_queue_clear (widget);
+}
+
+/* GtkEditable method implementations
+ */
+static void
+gtk_entry_insert_text (GtkEditable *editable,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position)
+{
+ GtkEntry *entry = GTK_ENTRY (editable);
+ gchar buf[64];
+ gchar *text;
+
+ if (*position < 0 || *position > entry->text_length)
+ *position = entry->text_length;
+
+ g_object_ref (G_OBJECT (editable));
+
+ if (new_text_length <= 63)
+ text = buf;
+ else
+ text = g_new (gchar, new_text_length + 1);
+
+ text[new_text_length] = '\0';
+ strncpy (text, new_text, new_text_length);
+
+ gtk_signal_emit (GTK_OBJECT (editable), signals[INSERT_TEXT], text, new_text_length, position);
+ gtk_signal_emit (GTK_OBJECT (editable), signals[CHANGED]);
+
+ if (new_text_length > 63)
+ g_free (text);
+
+ g_object_unref (G_OBJECT (editable));
+}
+
+static void
+gtk_entry_delete_text (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkEntry *entry = GTK_ENTRY (editable);
+
+ if (end_pos < 0 || end_pos > entry->text_length)
+ end_pos = entry->text_length;
+ if (start_pos < 0)
+ start_pos = 0;
+ if (start_pos > end_pos)
+ start_pos = end_pos;
+
+ g_object_ref (G_OBJECT (editable));
+
+ gtk_signal_emit (GTK_OBJECT (editable), signals[DELETE_TEXT], start_pos, end_pos);
+ gtk_signal_emit (GTK_OBJECT (editable), signals[CHANGED]);
+
+ g_object_unref (G_OBJECT (editable));
+}
+
+static gchar *
+gtk_entry_get_chars (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkEntry *entry;
+ gint start_index, end_index;
+
+ g_return_val_if_fail (editable != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_ENTRY (editable), NULL);
+
+ entry = GTK_ENTRY (editable);
+
+ if (end_pos < 0)
+ end_pos = entry->text_length;
+
+ start_pos = MIN (entry->text_length, start_pos);
+ end_pos = MIN (entry->text_length, end_pos);
+
+ start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text;
+ end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text;
+
+ return g_strndup (entry->text + start_index, end_index - start_index);
+}
+
+static void
+gtk_entry_real_set_position (GtkEditable *editable,
+ gint position)
+{
+ GtkEntry *entry = GTK_ENTRY (editable);
+
+ if (position < 0 || position > entry->text_length)
+ position = entry->text_length;
+
+ if (position != entry->current_pos)
+ {
+ gtk_entry_reset_im_context (entry);
+
+ entry->current_pos = entry->selection_bound = position;
+ gtk_entry_recompute (entry);
+ }
+}
+
+static gint
+gtk_entry_get_position (GtkEditable *editable)
+{
+ return GTK_ENTRY (editable)->current_pos;
+}
+
+static void
+gtk_entry_set_selection_bounds (GtkEditable *editable,
+ gint start,
+ gint end)
+{
+ GtkEntry *entry = GTK_ENTRY (editable);
+
+ if (start < 0)
+ start = entry->text_length;
+ if (end < 0)
+ end = entry->text_length;
+
+ gtk_entry_reset_im_context (entry);
+
+ entry->selection_bound = MIN (start, entry->text_length);
+ entry->current_pos = MIN (end, entry->text_length);
+
+ gtk_entry_update_primary_selection (entry);
+
+ gtk_entry_recompute (entry);
+}
+
+static gboolean
+gtk_entry_get_selection_bounds (GtkEditable *editable,
+ gint *start,
+ gint *end)
+{
+ GtkEntry *entry = GTK_ENTRY (editable);
+
+ *start = entry->selection_bound;
+ *end = entry->current_pos;
+
+ return (entry->selection_bound != entry->current_pos);
+}
+
+static void
+gtk_entry_style_set (GtkWidget *widget,
+ GtkStyle *previous_style)
+{
+ GtkEntry *entry = GTK_ENTRY (widget);
+
+ if (previous_style && GTK_WIDGET_REALIZED (widget))
+ {
+ gtk_entry_recompute (entry);
+
+ gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+ gdk_window_set_background (entry->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);
+ }
+}
+
+/* Default signal handlers
+ */
+static void
+gtk_entry_real_insert_text (GtkEntry *entry,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position)
+{
+ gint index;
+ gint n_chars;
+
+ if (new_text_length < 0)
+ new_text_length = strlen (new_text);
+
+ n_chars = g_utf8_strlen (new_text, new_text_length);
+ if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length)
+ {
+ gdk_beep ();
+ n_chars = entry->text_max_length - entry->text_length;
+ }
+
+ if (new_text_length + entry->n_bytes + 1 > entry->text_size)
+ {
+ while (new_text_length + entry->n_bytes + 1 > entry->text_size)
{
- editable->selection_start_pos = editable->current_pos;
- editable->selection_end_pos = editable->current_pos;
+ if (entry->text_size == 0)
+ entry->text_size = MIN_SIZE;
+ else
+ {
+ if (2 * (guint)entry->text_size < MAX_SIZE &&
+ 2 * (guint)entry->text_size > entry->text_size)
+ entry->text_size *= 2;
+ else
+ {
+ entry->text_size = MAX_SIZE;
+ new_text_length = entry->text_size - new_text_length - 1;
+ break;
+ }
+ }
}
+
+ entry->text = g_realloc (entry->text, entry->text_size);
+ }
+
+ index = g_utf8_offset_to_pointer (entry->text, *position) - entry->text;
+
+ g_memmove (entry->text + index + new_text_length, entry->text + index, entry->n_bytes - index);
+ memcpy (entry->text + index, new_text, new_text_length);
+
+ entry->n_bytes += new_text_length;
+ entry->text_length += n_chars;
+
+ /* NUL terminate for safety and convenience */
+ entry->text[entry->n_bytes] = '\0';
+
+ if (entry->current_pos > *position)
+ entry->current_pos += n_chars;
+
+ if (entry->selection_bound > *position)
+ entry->selection_bound += n_chars;
+
+ *position += n_chars;
+
+ gtk_entry_recompute (entry);
+}
+
+static void
+gtk_entry_real_delete_text (GtkEntry *entry,
+ gint start_pos,
+ gint end_pos)
+{
+ if (start_pos < 0)
+ start_pos = 0;
+ if (end_pos < 0 || end_pos > entry->text_length)
+ end_pos = entry->text_length;
+
+ if (start_pos < end_pos)
+ {
+ gint start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text;
+ gint end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text;
+
+ g_memmove (entry->text + start_index, entry->text + end_index, entry->n_bytes - end_index);
+ entry->text_length -= (end_pos - start_pos);
+ entry->n_bytes -= (end_index - start_index);
- extend_start = (editable->current_pos == editable->selection_start_pos);
+ if (entry->current_pos > start_pos)
+ entry->current_pos -= MIN (entry->current_pos, end_pos) - start_pos;
+
+ if (entry->selection_bound > start_pos)
+ entry->selection_bound -= MIN (entry->selection_bound, end_pos) - start_pos;
}
- switch (event->keyval)
+ /* We might have deleted the selection
+ */
+ gtk_entry_update_primary_selection (entry);
+
+ gtk_entry_recompute (entry);
+}
+
+
+static void
+gtk_entry_move (GtkEntry *entry,
+ GtkMovementStep step,
+ gint count,
+ gboolean extend_selection)
+{
+ gint new_pos = entry->current_pos;
+
+ gtk_entry_reset_im_context (entry);
+
+ switch (step)
{
- case GDK_BackSpace:
- return_val = TRUE;
- if (event->state & GDK_CONTROL_MASK)
- gtk_delete_backward_word (entry);
- else
- gtk_delete_backward_character (entry);
+ case GTK_MOVEMENT_CHARS:
+ new_pos = CLAMP (new_pos + count, 0, entry->text_length);
break;
- case GDK_Clear:
- return_val = TRUE;
- gtk_delete_line (entry);
+ case GTK_MOVEMENT_POSITIONS:
+ new_pos = gtk_entry_move_visually (entry, new_pos, count);
break;
- case GDK_Insert:
- return_val = TRUE;
- if (event->state & GDK_SHIFT_MASK)
- {
- extend_selection = FALSE;
- gtk_editable_paste_clipboard (editable);
- }
- else if (event->state & GDK_CONTROL_MASK)
+ case GTK_MOVEMENT_WORDS:
+ while (count > 0)
{
- gtk_editable_copy_clipboard (editable);
+ new_pos = gtk_entry_move_forward_word (entry, new_pos);
+ count--;
}
- else
+ while (count < 0)
{
- /* gtk_toggle_insert(entry) -- IMPLEMENT */
- }
- break;
- case GDK_Delete:
- return_val = TRUE;
- if (event->state & GDK_CONTROL_MASK)
- gtk_delete_forward_word (entry);
- else if (event->state & GDK_SHIFT_MASK)
- {
- extend_selection = FALSE;
- gtk_editable_cut_clipboard (editable);
+ new_pos = gtk_entry_move_backward_word (entry, new_pos);
+ count++;
}
- else
- gtk_delete_forward_character (entry);
break;
- case GDK_Home:
- return_val = TRUE;
- gtk_move_beginning_of_line (entry);
+ case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
+ case GTK_MOVEMENT_PARAGRAPH_ENDS:
+ case GTK_MOVEMENT_BUFFER_ENDS:
+ new_pos = count < 0 ? 0 : entry->text_length;
break;
- case GDK_End:
- return_val = TRUE;
- gtk_move_end_of_line (entry);
+ case GTK_MOVEMENT_DISPLAY_LINES:
+ case GTK_MOVEMENT_PARAGRAPHS:
+ case GTK_MOVEMENT_PAGES:
break;
- case GDK_Left:
- return_val = TRUE;
- if (event->state & GDK_CONTROL_MASK)
- gtk_move_backward_word (entry);
- else
- gtk_move_backward_character (entry);
- break;
- case GDK_Right:
- return_val = TRUE;
- if (event->state & GDK_CONTROL_MASK)
- gtk_move_forward_word (entry);
- else
- gtk_move_forward_character (entry);
- break;
- case GDK_Return:
- return_val = TRUE;
- gtk_widget_activate (widget);
- break;
- /* The next two keys should not be inserted literally. Any others ??? */
- case GDK_Tab:
- case GDK_Escape:
- break;
- default:
- if ((event->keyval >= 0x20) && (event->keyval <= 0xFF))
- {
- key = event->keyval;
+ }
- if (event->state & GDK_CONTROL_MASK)
- {
- if ((key >= 'A') && (key <= 'Z'))
- key -= 'A' - 'a';
+ if (extend_selection)
+ gtk_editable_select_region (GTK_EDITABLE (entry), entry->selection_bound, new_pos);
+ else
+ gtk_editable_set_position (GTK_EDITABLE (entry), new_pos);
+}
- if ((key >= 'a') && (key <= 'z') && control_keys[key - 'a'])
- {
- (* control_keys[key - 'a']) (editable, event->time);
- return_val = TRUE;
- }
- break;
- }
- else if (event->state & GDK_MOD1_MASK)
- {
- if ((key >= 'A') && (key <= 'Z'))
- key -= 'A' - 'a';
+static void
+gtk_entry_insert (GtkEntry *entry,
+ const gchar *str)
+{
+ GtkEditable *editable = GTK_EDITABLE (entry);
+ gint pos = entry->current_pos;
- if ((key >= 'a') && (key <= 'z') && alt_keys[key - 'a'])
- {
- (* alt_keys[key - 'a']) (editable, event->time);
- return_val = TRUE;
- }
- break;
- }
- }
- gtk_im_context_filter_keypress (entry->im_context, event);
-
- break;
- }
+ gtk_entry_reset_im_context (entry);
- /* since we emit signals from within the above code,
- * the widget might already be destroyed or at least
- * unrealized.
- */
- if (GTK_WIDGET_REALIZED (editable) &&
- return_val && (editable->current_pos != initial_pos))
+ gtk_editable_insert_text (editable, str, -1, &pos);
+ gtk_editable_set_position (editable, pos);
+}
+
+static void
+gtk_entry_delete (GtkEntry *entry,
+ GtkDeleteType type,
+ gint count)
+{
+ GtkEditable *editable = GTK_EDITABLE (entry);
+ gint start_pos = entry->current_pos;
+ gint end_pos = entry->current_pos;
+
+ gtk_entry_reset_im_context (entry);
+
+ if (!entry->editable)
+ return;
+
+ if (entry->selection_bound != entry->current_pos)
{
- if (extend_selection)
+ gtk_editable_delete_selection (editable);
+ return;
+ }
+
+ switch (type)
+ {
+ case GTK_DELETE_CHARS:
+ end_pos = entry->current_pos + count;
+ gtk_editable_delete_text (editable, MIN (start_pos, end_pos), MAX (start_pos, end_pos));
+ break;
+ case GTK_DELETE_WORDS:
+ if (count < 0)
{
- if (editable->current_pos < editable->selection_start_pos)
- editable->selection_start_pos = editable->current_pos;
- else if (editable->current_pos > editable->selection_end_pos)
- editable->selection_end_pos = editable->current_pos;
- else
- {
- if (extend_start)
- editable->selection_start_pos = editable->current_pos;
- else
- editable->selection_end_pos = editable->current_pos;
- }
+ /* Move to end of current word, or if not on a word, end of previous word */
+ end_pos = gtk_entry_move_backward_word (entry, end_pos);
+ end_pos = gtk_entry_move_forward_word (entry, end_pos);
}
- else
+ else if (count > 0)
+ {
+ /* Move to beginning of current word, or if not on a word, begining of next word */
+ start_pos = gtk_entry_move_forward_word (entry, start_pos);
+ start_pos = gtk_entry_move_backward_word (entry, start_pos);
+ }
+
+ /* Fall through */
+ case GTK_DELETE_WORD_ENDS:
+ while (count < 0)
{
- editable->selection_start_pos = 0;
- editable->selection_end_pos = 0;
+ start_pos = gtk_entry_move_backward_word (entry, start_pos);
+ count++;
}
+ while (count > 0)
+ {
+ end_pos = gtk_entry_move_forward_word (entry, end_pos);
+ count--;
+ }
+ gtk_editable_delete_text (editable, start_pos, end_pos);
+ break;
+ case GTK_DELETE_DISPLAY_LINE_ENDS:
+ case GTK_DELETE_PARAGRAPH_ENDS:
+ if (count < 0)
+ gtk_editable_delete_text (editable, 0, entry->current_pos);
+ else
+ gtk_editable_delete_text (editable, entry->current_pos, -1);
+ break;
+ case GTK_DELETE_DISPLAY_LINES:
+ case GTK_DELETE_PARAGRAPHS:
+ gtk_editable_delete_text (editable, 0, -1);
+ break;
+ case GTK_DELETE_WHITESPACE:
+ gtk_entry_delete_whitespace (entry);
+ break;
+ }
+}
- gtk_editable_claim_selection (editable,
- editable->selection_start_pos != editable->selection_end_pos,
- event->time);
-
- entry_adjust_scroll (entry);
- gtk_entry_queue_draw (entry);
+static void
+gtk_entry_copy_clipboard (GtkEntry *entry)
+{
+ GtkEditable *editable = GTK_EDITABLE (entry);
+ gint start, end;
+
+ if (gtk_editable_get_selection_bounds (editable, &start, &end))
+ {
+ gchar *str = gtk_entry_get_public_chars (entry, start, end);
+ gtk_clipboard_set_text (gtk_clipboard_get (GDK_NONE), str, -1);
+ g_free (str);
}
+}
+
+static void
+gtk_entry_cut_clipboard (GtkEntry *entry)
+{
+ GtkEditable *editable = GTK_EDITABLE (entry);
+ gint start, end;
- return return_val;
+ gtk_entry_copy_clipboard (entry);
+ if (gtk_editable_get_selection_bounds (editable, &start, &end))
+ gtk_editable_delete_text (editable, start, end);
}
-static gint
-gtk_entry_focus_in (GtkWidget *widget,
- GdkEventFocus *event)
+static void
+gtk_entry_paste_clipboard (GtkEntry *entry)
{
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
+ gtk_entry_paste (entry, GDK_NONE);
+}
- GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
- gtk_widget_draw_focus (widget);
- gtk_entry_queue_draw (GTK_ENTRY (widget));
+static void
+gtk_entry_toggle_overwrite (GtkEntry *entry)
+{
+ entry->overwrite_mode = !entry->overwrite_mode;
+}
+
+/* IM Context Callbacks
+ */
+
+static void
+gtk_entry_commit_cb (GtkIMContext *context,
+ const gchar *str,
+ GtkEntry *entry)
+{
+ GtkEditable *editable = GTK_EDITABLE (entry);
+ gint tmp_pos = entry->current_pos;
+
+ gtk_editable_insert_text (editable, str, strlen (str), &tmp_pos);
+ gtk_editable_set_position (editable, tmp_pos);
+}
+
+static void
+gtk_entry_preedit_changed_cb (GtkIMContext *context,
+ GtkEntry *entry)
+{
+ gchar *preedit_string;
+ gint cursor_pos;
- gtk_im_context_focus_in (GTK_ENTRY (widget)->im_context);
+ gtk_im_context_get_preedit_string (entry->im_context,
+ &preedit_string, NULL,
+ &cursor_pos);
+ entry->preedit_length = strlen (preedit_string);
+ cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1));
+ cursor_pos = g_utf8_offset_to_pointer (preedit_string, cursor_pos) - preedit_string;
+ g_free (preedit_string);
- return FALSE;
+ gtk_entry_recompute (entry);
}
-static gint
-gtk_entry_focus_out (GtkWidget *widget,
- GdkEventFocus *event)
+/* Internal functions
+ */
+
+static void
+gtk_entry_reset_layout (GtkEntry *entry)
{
- g_return_val_if_fail (widget != NULL, FALSE);
- g_return_val_if_fail (GTK_IS_ENTRY (widget), FALSE);
- g_return_val_if_fail (event != NULL, FALSE);
+ if (entry->cached_layout)
+ {
+ g_object_unref (G_OBJECT (entry->cached_layout));
+ entry->cached_layout = NULL;
+ }
+}
- GTK_WIDGET_UNSET_FLAGS (widget, GTK_HAS_FOCUS);
- gtk_widget_draw_focus (widget);
- gtk_entry_queue_draw (GTK_ENTRY (widget));
+static gboolean
+recompute_idle_func (gpointer data)
+{
+ GtkEntry *entry = GTK_ENTRY (data);
- gtk_im_context_focus_out (GTK_ENTRY (widget)->im_context);
+ gtk_entry_adjust_scroll (entry);
+ gtk_entry_queue_draw (entry);
+ entry->recompute_idle = FALSE;
+
return FALSE;
}
static void
-gtk_entry_ensure_layout (GtkEntry *entry)
+gtk_entry_recompute (GtkEntry *entry)
{
- GtkWidget *widget = GTK_WIDGET (entry);
+ gtk_entry_reset_layout (entry);
+
+ if (!entry->recompute_idle)
+ {
+ entry->recompute_idle = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 15, /* between resize and redraw */
+ recompute_idle_func, entry, NULL);
+ }
+}
+
+static PangoLayout *
+gtk_entry_create_layout (GtkEntry *entry,
+ gboolean include_preedit)
+{
+ PangoLayout *layout = gtk_widget_create_pango_layout (GTK_WIDGET (entry), NULL);
+ PangoAttrList *tmp_attrs = pango_attr_list_new ();
- if (!entry->layout)
+ gchar *preedit_string = NULL;
+ gint preedit_length = 0;
+ PangoAttrList *preedit_attrs = NULL;
+
+ if (include_preedit)
+ {
+ gtk_im_context_get_preedit_string (entry->im_context,
+ &preedit_string, &preedit_attrs, NULL);
+ preedit_length = entry->preedit_length;
+ }
+
+ if (preedit_length)
{
- entry->layout = gtk_widget_create_pango_layout (widget, NULL);
- pango_layout_set_text (entry->layout, entry->text, entry->n_bytes);
+ GString *tmp_string = g_string_new (NULL);
+
+ gint cursor_index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text;
+
+ g_string_prepend_len (tmp_string, entry->text, entry->n_bytes);
+ g_string_insert (tmp_string, cursor_index, preedit_string);
+ pango_layout_set_text (layout, tmp_string->str, tmp_string->len);
+
+ pango_attr_list_splice (tmp_attrs, preedit_attrs,
+ cursor_index, entry->preedit_length);
+
+ g_string_free (tmp_string, TRUE);
+
}
+ else
+ pango_layout_set_text (layout, entry->text, entry->n_bytes);
+
+ pango_layout_set_attributes (layout, tmp_attrs);
+
+ if (preedit_string)
+ g_free (preedit_string);
+ if (preedit_attrs)
+ pango_attr_list_unref (preedit_attrs);
+
+ pango_attr_list_unref (tmp_attrs);
+
+ return layout;
+}
+
+static PangoLayout *
+gtk_entry_get_layout (GtkEntry *entry,
+ gboolean include_preedit)
+{
+ if (entry->preedit_length > 0 &&
+ !include_preedit != !entry->cache_includes_preedit)
+ gtk_entry_reset_layout (entry);
+
+ if (!entry->cached_layout)
+ {
+ entry->cached_layout = gtk_entry_create_layout (entry, include_preedit);
+ entry->cache_includes_preedit = include_preedit;
+ }
+
+ g_object_ref (G_OBJECT (entry->cached_layout));
+ return entry->cached_layout;
}
static void
@@ -1178,15 +1680,16 @@ gtk_entry_draw_text (GtkEntry *entry)
{
GtkWidget *widget;
PangoLayoutLine *line;
- GtkEditable *editable = GTK_EDITABLE (entry);
g_return_if_fail (entry != NULL);
g_return_if_fail (GTK_IS_ENTRY (entry));
if (GTK_WIDGET_DRAWABLE (entry))
{
+ PangoLayout *layout = gtk_entry_get_layout (entry, TRUE);
PangoRectangle logical_rect;
gint area_width, area_height;
+ gint start_pos, end_pos;
gint y_pos;
gdk_window_get_size (entry->text_area, &area_width, &area_height);
@@ -1199,9 +1702,7 @@ gtk_entry_draw_text (GtkEntry *entry)
NULL, widget, "entry_bg",
0, 0, area_width, area_height);
- gtk_entry_ensure_layout (entry);
-
- line = pango_layout_get_lines (entry->layout)->data;
+ line = pango_layout_get_lines (layout)->data;
pango_layout_line_get_extents (line, NULL, &logical_rect);
/* Align primarily for locale's ascent/descent */
@@ -1220,17 +1721,14 @@ gtk_entry_draw_text (GtkEntry *entry)
gdk_draw_layout (entry->text_area, widget->style->text_gc [widget->state],
INNER_BORDER - entry->scroll_offset, y_pos,
- entry->layout);
+ layout);
- if (editable->selection_start_pos != editable->selection_end_pos)
+ if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
{
gint *ranges;
gint n_ranges, i;
- gint start_index = g_utf8_offset_to_pointer (entry->text,
- MIN (editable->selection_start_pos, editable->selection_end_pos)) - entry->text;
- gint end_index = g_utf8_offset_to_pointer (entry->text,
- MAX (editable->selection_start_pos, editable->selection_end_pos)) - entry->text;
- GtkStateType selected_state = editable->has_selection ? GTK_STATE_SELECTED : GTK_STATE_ACTIVE;
+ gint start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text;
+ gint end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text;
GdkRegion *clip_region = gdk_region_new ();
pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
@@ -1244,21 +1742,23 @@ gtk_entry_draw_text (GtkEntry *entry)
rect.width = (ranges[2*i + 1] - ranges[2*i]) / PANGO_SCALE;
rect.height = logical_rect.height / PANGO_SCALE;
- gdk_draw_rectangle (entry->text_area, widget->style->bg_gc [selected_state], TRUE,
+ gdk_draw_rectangle (entry->text_area, widget->style->bg_gc [GTK_STATE_SELECTED], TRUE,
rect.x, rect.y, rect.width, rect.height);
gdk_region_union_with_rect (clip_region, &rect);
}
- gdk_gc_set_clip_region (widget->style->fg_gc [selected_state], clip_region);
- gdk_draw_layout (entry->text_area, widget->style->fg_gc [selected_state],
+ gdk_gc_set_clip_region (widget->style->fg_gc [GTK_STATE_SELECTED], clip_region);
+ gdk_draw_layout (entry->text_area, widget->style->fg_gc [GTK_STATE_SELECTED],
INNER_BORDER - entry->scroll_offset, y_pos,
- entry->layout);
- gdk_gc_set_clip_region (widget->style->fg_gc [selected_state], NULL);
+ layout);
+ gdk_gc_set_clip_region (widget->style->fg_gc [GTK_STATE_SELECTED], NULL);
gdk_region_destroy (clip_region);
g_free (ranges);
}
+
+ g_object_unref (G_OBJECT (layout));
}
}
@@ -1271,10 +1771,9 @@ gtk_entry_draw_cursor (GtkEntry *entry)
if (GTK_WIDGET_DRAWABLE (entry))
{
GtkWidget *widget = GTK_WIDGET (entry);
- GtkEditable *editable = GTK_EDITABLE (entry);
if (GTK_WIDGET_HAS_FOCUS (widget) &&
- (editable->selection_start_pos == editable->selection_end_pos))
+ (entry->selection_bound == entry->current_pos))
{
gint xoffset = INNER_BORDER - entry->scroll_offset;
gint strong_x, weak_x;
@@ -1308,40 +1807,47 @@ gtk_entry_queue_draw (GtkEntry *entry)
GdkRectangle rect = { 0 };
gdk_window_get_size (entry->text_area, &rect.width, &rect.height);
- gdk_window_invalidate_rect (entry->text_area, &rect, 0);
+ gdk_window_invalidate_rect (entry->text_area, &rect, FALSE);
}
}
-#if 0
-static gint
-gtk_entry_timer (gpointer data)
+static void
+gtk_entry_reset_im_context (GtkEntry *entry)
{
- GtkEntry *entry;
-
- GDK_THREADS_ENTER ();
+ if (entry->need_im_reset)
+ entry->need_im_reset = 0;
- entry = GTK_ENTRY (data);
- entry->timer = 0;
-
- GDK_THREADS_LEAVE ();
-
- return FALSE;
+ gtk_im_context_reset (entry->im_context);
}
-#endif
static gint
gtk_entry_find_position (GtkEntry *entry,
gint x)
{
+ PangoLayout *layout;
PangoLayoutLine *line;
gint index;
gint pos;
gboolean trailing;
+ gint cursor_index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text;
- gtk_entry_ensure_layout (entry);
-
- line = pango_layout_get_lines (entry->layout)->data;
+ layout = gtk_entry_get_layout (entry, TRUE);
+
+ line = pango_layout_get_lines (layout)->data;
pango_layout_line_x_to_index (line, x * PANGO_SCALE, &index, &trailing);
+
+ g_object_unref (G_OBJECT (layout));
+
+ if (index >= cursor_index && entry->preedit_length)
+ {
+ if (index >= cursor_index + entry->preedit_length)
+ index -= entry->preedit_length;
+ else
+ {
+ index = cursor_index;
+ trailing = 0;
+ }
+ }
pos = g_utf8_pointer_to_offset (entry->text, entry->text + index);
@@ -1356,15 +1862,14 @@ gtk_entry_get_cursor_locations (GtkEntry *entry,
gint *strong_x,
gint *weak_x)
{
- GtkEditable *editable = GTK_EDITABLE (entry);
- int index;
+ PangoLayout *layout = gtk_entry_get_layout (entry, TRUE);
+ gint index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text;
PangoRectangle strong_pos, weak_pos;
- gtk_entry_ensure_layout (entry);
-
- index = g_utf8_offset_to_pointer (entry->text, editable->current_pos) - entry->text;
- pango_layout_get_cursor_pos (entry->layout, index, &strong_pos, &weak_pos);
+ index += entry->preedit_cursor;
+ pango_layout_get_cursor_pos (layout, index, &strong_pos, &weak_pos);
+ g_object_unref (G_OBJECT (layout));
if (strong_x)
*strong_x = strong_pos.x / PANGO_SCALE;
@@ -1374,13 +1879,14 @@ gtk_entry_get_cursor_locations (GtkEntry *entry,
}
static void
-entry_adjust_scroll (GtkEntry *entry)
+gtk_entry_adjust_scroll (GtkEntry *entry)
{
GtkWidget *widget;
gint min_offset, max_offset;
gint text_area_width;
gint strong_x, weak_x;
gint strong_xoffset, weak_xoffset;
+ PangoLayout *layout;
PangoLayoutLine *line;
PangoRectangle logical_rect;
@@ -1389,17 +1895,19 @@ entry_adjust_scroll (GtkEntry *entry)
widget = GTK_WIDGET (entry);
- if (!entry->layout || !GTK_WIDGET_REALIZED (entry))
+ if (!GTK_WIDGET_REALIZED (entry))
return;
gdk_window_get_size (entry->text_area, &text_area_width, NULL);
text_area_width -= 2 * INNER_BORDER;
- line = pango_layout_get_lines (entry->layout)->data;
-
- /* Display as much text as we can */
+ layout = gtk_entry_get_layout (entry, TRUE);
+ line = pango_layout_get_lines (layout)->data;
pango_layout_line_get_extents (line, NULL, &logical_rect);
+ g_object_unref (G_OBJECT (layout));
+
+ /* Display as much text as we can */
if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
{
@@ -1454,204 +1962,17 @@ entry_adjust_scroll (GtkEntry *entry)
{
entry->scroll_offset += weak_xoffset - text_area_width;
}
-
- gtk_widget_queue_draw (GTK_WIDGET (entry));
}
-static void
-gtk_entry_insert_text (GtkEditable *editable,
- const gchar *new_text,
- gint new_text_length,
- gint *position)
-{
- gint index;
- gint n_chars;
- GtkEntry *entry;
- GtkWidget *widget;
-
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_ENTRY (editable));
- g_return_if_fail (position != NULL);
- g_return_if_fail (*position >= 0 || *position < GTK_ENTRY (editable)->text_size);
-
- entry = GTK_ENTRY (editable);
- widget = GTK_WIDGET (editable);
-
- if (new_text_length < 0)
- new_text_length = strlen (new_text);
-
- n_chars = g_utf8_strlen (new_text, new_text_length);
- if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length)
- {
- gdk_beep ();
- n_chars = entry->text_max_length - entry->text_length;
- }
-
- if (new_text_length + entry->n_bytes + 1 > entry->text_size)
- {
- while (new_text_length + entry->n_bytes + 1 > entry->text_size)
- {
- if (entry->text_size == 0)
- entry->text_size = MIN_SIZE;
- else
- {
- if (2 * (guint)entry->text_size < MAX_SIZE &&
- 2 * (guint)entry->text_size > entry->text_size)
- entry->text_size *= 2;
- else
- {
- entry->text_size = MAX_SIZE;
- new_text_length = entry->text_size - new_text_length - 1;
- break;
- }
- }
- }
-
- entry->text = g_realloc (entry->text, entry->text_size);
- }
-
- index = g_utf8_offset_to_pointer (entry->text, *position) - entry->text;
-
- g_memmove (entry->text + index + new_text_length, entry->text + index, entry->n_bytes - index);
- memcpy (entry->text + index, new_text, new_text_length);
-
- entry->n_bytes += new_text_length;
- entry->text_length += n_chars;
-
- /* NUL terminate for safety and convenience */
- entry->text[entry->n_bytes] = '\0';
-
- if (editable->current_pos > *position)
- editable->current_pos += n_chars;
-
- if (editable->selection_start_pos > *position)
- editable->selection_start_pos += n_chars;
-
- if (editable->selection_end_pos > *position)
- editable->selection_end_pos += n_chars;
-
- *position += n_chars;
-
- if (entry->layout)
- pango_layout_set_text (entry->layout, entry->text, entry->n_bytes);
-
- gtk_entry_queue_draw (entry);
-}
-
-static void
-gtk_entry_delete_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry;
-
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_ENTRY (editable));
-
- entry = GTK_ENTRY (editable);
-
- if (end_pos < 0)
- end_pos = entry->text_length;
-
- if ((start_pos < end_pos) &&
- (start_pos >= 0) &&
- (end_pos <= entry->text_length))
- {
- gint start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text;
- gint end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text;
-
- g_memmove (entry->text + start_index, entry->text + end_index, entry->n_bytes - end_index);
- entry->text_length -= (end_pos - start_pos);
- entry->n_bytes -= (end_index - start_index);
-
- if (editable->current_pos > start_pos)
- editable->current_pos -= MIN (editable->current_pos, end_pos) - start_pos;
-
- if (editable->selection_start_pos > start_pos)
- editable->selection_start_pos -= MIN (editable->selection_start_pos, end_pos) - start_pos;
-
- if (editable->selection_end_pos > start_pos)
- editable->selection_end_pos -= MIN (editable->selection_end_pos, end_pos) - start_pos;
-
- }
-
- gtk_entry_queue_draw (entry);
-
- if (entry->layout)
- pango_layout_set_text (entry->layout, entry->text, entry->n_bytes);
-}
-
-static void
-gtk_entry_update_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry = GTK_ENTRY (editable);
-
- gtk_entry_queue_draw (entry);
-}
-
-static gchar *
-gtk_entry_get_chars (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
-{
- GtkEntry *entry;
- gint start_index, end_index;
-
- g_return_val_if_fail (editable != NULL, NULL);
- g_return_val_if_fail (GTK_IS_ENTRY (editable), NULL);
-
- entry = GTK_ENTRY (editable);
-
- if (end_pos < 0)
- end_pos = entry->text_length;
-
- start_pos = MIN (entry->text_length, start_pos);
- end_pos = MIN (entry->text_length, end_pos);
-
- start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text;
- end_index = g_utf8_offset_to_pointer (entry->text, end_pos) - entry->text;
-
- return g_strndup (entry->text + start_index, end_index - start_index);
-}
-
-static void
-gtk_entry_move_cursor (GtkEditable *editable,
- gint x,
- gint y)
-{
- GtkEntry *entry;
- gint index;
-
- entry = GTK_ENTRY (editable);
-
- index = g_utf8_offset_to_pointer (entry->text, editable->current_pos) - entry->text;
-
- /* Horizontal motion */
-
- if ((gint)editable->current_pos < -x)
- editable->current_pos = 0;
- else if (editable->current_pos + x > entry->text_length)
- editable->current_pos = entry->text_length;
- else
- editable->current_pos += x;
-
- /* Ignore vertical motion */
-}
-
-static void
-gtk_entry_move_cursor_visually (GtkEditable *editable,
- gint count)
+static gint
+gtk_entry_move_visually (GtkEntry *entry,
+ gint start,
+ gint count)
{
- GtkEntry *entry;
gint index;
+ PangoLayout *layout = gtk_entry_get_layout (entry, FALSE);
- entry = GTK_ENTRY (editable);
-
- index = g_utf8_offset_to_pointer (entry->text, editable->current_pos) - entry->text;
-
- gtk_entry_ensure_layout (entry);
+ index = g_utf8_offset_to_pointer (entry->text, start) - entry->text;
while (count != 0)
{
@@ -1659,12 +1980,12 @@ gtk_entry_move_cursor_visually (GtkEditable *editable,
if (count > 0)
{
- pango_layout_move_cursor_visually (entry->layout, index, 0, 1, &new_index, &new_trailing);
+ pango_layout_move_cursor_visually (layout, index, 0, 1, &new_index, &new_trailing);
count--;
}
else
{
- pango_layout_move_cursor_visually (entry->layout, index, 0, -1, &new_index, &new_trailing);
+ pango_layout_move_cursor_visually (layout, index, 0, -1, &new_index, &new_trailing);
count++;
}
@@ -1677,289 +1998,341 @@ gtk_entry_move_cursor_visually (GtkEditable *editable,
index = new_index;
}
- editable->current_pos = g_utf8_pointer_to_offset (entry->text, entry->text + index);
-}
-
-static void
-gtk_move_forward_character (GtkEntry *entry)
-{
- gtk_entry_move_cursor_visually (GTK_EDITABLE (entry), 1);
-}
-
-static void
-gtk_move_backward_character (GtkEntry *entry)
-{
- gtk_entry_move_cursor_visually (GTK_EDITABLE (entry), -1);
-}
-
-static void
-gtk_entry_move_word (GtkEditable *editable,
- gint n)
-{
- while (n-- > 0)
- gtk_move_forward_word (GTK_ENTRY (editable));
- while (n++ < 0)
- gtk_move_backward_word (GTK_ENTRY (editable));
+ g_object_unref (G_OBJECT (layout));
+
+ return g_utf8_pointer_to_offset (entry->text, entry->text + index);
}
-static void
-gtk_move_forward_word (GtkEntry *entry)
+static gint
+gtk_entry_move_forward_word (GtkEntry *entry,
+ gint start)
{
- GtkEditable *editable;
- gint i;
-
- editable = GTK_EDITABLE (entry);
+ gint new_pos = start;
/* Prevent any leak of information */
- if (!editable->visible)
+ if (!entry->visible)
{
- editable->current_pos = entry->text_length;
- return;
+ new_pos = entry->text_length;
}
-
- if (entry->text && (editable->current_pos < entry->text_length))
+ else if (entry->text && (new_pos < entry->text_length))
{
+ PangoLayout *layout = gtk_entry_get_layout (entry, FALSE);
PangoLogAttr *log_attrs;
- gint n_attrs, old_pos;
-
- gtk_entry_ensure_layout (entry);
- pango_layout_get_log_attrs (entry->layout, &log_attrs, &n_attrs);
+ gint n_attrs;
- i = old_pos = editable->current_pos;
+ pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
/* Advance over white space */
- while (i < n_attrs && log_attrs[i].is_white)
- i++;
+ while (new_pos < n_attrs && log_attrs[new_pos].is_white)
+ new_pos++;
/* Find the next word beginning */
- i++;
- while (i < n_attrs && !log_attrs[i].is_word_stop)
- i++;
-
- editable->current_pos = MAX (entry->text_length, i);
+ new_pos++;
+ while (new_pos < n_attrs && !log_attrs[new_pos].is_word_stop)
+ new_pos++;
/* Back up over white space */
- while (i > 0 && log_attrs[i - 1].is_white)
- i--;
-
- if (i != old_pos)
- editable->current_pos = i;
+ while (new_pos > 0 && log_attrs[new_pos - 1].is_white)
+ new_pos--;
g_free (log_attrs);
+ g_object_unref (G_OBJECT (layout));
}
+
+ return new_pos;
}
-static void
-gtk_move_backward_word (GtkEntry *entry)
-{
- GtkEditable *editable;
- gint i;
- editable = GTK_EDITABLE (entry);
+static gint
+gtk_entry_move_backward_word (GtkEntry *entry,
+ gint start)
+{
+ gint new_pos = start;
/* Prevent any leak of information */
- if (!editable->visible)
+ if (!entry->visible)
{
- editable->current_pos = 0;
- return;
+ new_pos = 0;
}
-
- if (entry->text && editable->current_pos > 0)
+ else if (entry->text && start > 0)
{
+ PangoLayout *layout = gtk_entry_get_layout (entry, FALSE);
PangoLogAttr *log_attrs;
gint n_attrs;
- gtk_entry_ensure_layout (entry);
- pango_layout_get_log_attrs (entry->layout, &log_attrs, &n_attrs);
+ pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
- i = editable->current_pos - 1;
+ new_pos = start - 1;
/* Find the previous word beginning */
- while (i > 0 && !log_attrs[i].is_word_stop)
- i--;
+ while (new_pos > 0 && !log_attrs[new_pos].is_word_stop)
+ new_pos--;
g_free (log_attrs);
+ g_object_unref (G_OBJECT (layout));
}
+
+ return new_pos;
}
static void
-gtk_entry_move_to_column (GtkEditable *editable, gint column)
+gtk_entry_delete_whitespace (GtkEntry *entry)
{
- GtkEntry *entry;
+ PangoLayout *layout = gtk_entry_get_layout (entry, FALSE);
+ PangoLogAttr *log_attrs;
+ gint n_attrs;
+ gint start, end;
- entry = GTK_ENTRY (editable);
+ pango_layout_get_log_attrs (layout, &log_attrs, &n_attrs);
+
+ start = end = entry->current_pos;
- if (column < 0 || column > entry->text_length)
- editable->current_pos = entry->text_length;
- else
- editable->current_pos = column;
+ while (start > 0 && log_attrs[start-1].is_white)
+ start--;
+
+ while (end < n_attrs && log_attrs[start-1].is_white)
+ end++;
+
+ g_free (log_attrs);
+ g_object_unref (G_OBJECT (layout));
+
+ if (start != end)
+ gtk_editable_delete_text (GTK_EDITABLE (entry), start, end);
}
+
static void
-gtk_move_beginning_of_line (GtkEntry *entry)
+gtk_entry_select_word (GtkEntry *entry)
{
- gtk_entry_move_to_column (GTK_EDITABLE (entry), 0);
+ gint start_pos = gtk_entry_move_backward_word (entry, entry->current_pos);
+ gint end_pos = gtk_entry_move_forward_word (entry, entry->current_pos);
+
+ gtk_editable_select_region (GTK_EDITABLE (entry), start_pos, end_pos);
}
static void
-gtk_move_end_of_line (GtkEntry *entry)
+gtk_entry_select_line (GtkEntry *entry)
{
- gtk_entry_move_to_column (GTK_EDITABLE (entry), -1);
+ gtk_editable_select_region (GTK_EDITABLE (entry), 0, -1);
}
-static void
-gtk_entry_kill_char (GtkEditable *editable,
- gint direction)
+/*
+ * Like gtk_editable_get_chars, but if the editable is not
+ * visible, return asterisks; also convert result to UTF-8.
+ */
+static char *
+gtk_entry_get_public_chars (GtkEntry *entry,
+ gint start,
+ gint end)
{
- if (editable->selection_start_pos != editable->selection_end_pos)
- gtk_editable_delete_selection (editable);
+ if (end < 0)
+ end = entry->text_length;
+
+ if (entry->visible)
+ return gtk_editable_get_chars (GTK_EDITABLE (entry), start, end);
else
{
- gint old_pos = editable->current_pos;
- if (direction >= 0)
- {
- gtk_entry_move_cursor (editable, 1, 0);
- gtk_editable_delete_text (editable, old_pos, editable->current_pos);
- }
- else
- {
- gtk_entry_move_cursor (editable, -1, 0);
- gtk_editable_delete_text (editable, editable->current_pos, old_pos);
- }
+ gchar *str;
+ gint i;
+ gint n_chars = end - start;
+
+ str = g_malloc (n_chars + 1);
+ for (i = 0; i < n_chars; i++)
+ str[i] = '*';
+ str[i] = '\0';
+
+ return str;
}
+
}
static void
-gtk_delete_forward_character (GtkEntry *entry)
+paste_received (GtkClipboard *clipboard,
+ const gchar *text,
+ gpointer data)
{
- gtk_entry_kill_char (GTK_EDITABLE (entry), 1);
+ GtkEntry *entry = GTK_ENTRY (data);
+ GtkEditable *editable = GTK_EDITABLE (entry);
+
+ if (text)
+ {
+ gint pos = entry->current_pos;
+
+ gtk_editable_insert_text (editable, text, -1, &pos);
+ gtk_editable_set_position (editable, pos);
+ }
+
+ g_object_unref (G_OBJECT (entry));
}
static void
-gtk_delete_backward_character (GtkEntry *entry)
+gtk_entry_paste (GtkEntry *entry,
+ GdkAtom selection)
{
- gtk_entry_kill_char (GTK_EDITABLE (entry), -1);
+ g_object_ref (G_OBJECT (entry));
+ gtk_clipboard_request_text (gtk_clipboard_get (selection),
+ paste_received, entry);
}
static void
-gtk_entry_kill_word (GtkEditable *editable,
- gint direction)
+primary_get_cb (GtkClipboard *clipboard,
+ GtkSelectionData *selection_data,
+ guint info,
+ gpointer data)
{
- if (editable->selection_start_pos != editable->selection_end_pos)
- gtk_editable_delete_selection (editable);
- else
+ GtkEntry *entry = GTK_ENTRY (data);
+ gint start, end;
+
+ if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
{
- gint old_pos = editable->current_pos;
- if (direction >= 0)
- {
- gtk_entry_move_word (editable, 1);
- gtk_editable_delete_text (editable, old_pos, editable->current_pos);
- }
- else
- {
- gtk_entry_move_word (editable, -1);
- gtk_editable_delete_text (editable, editable->current_pos, old_pos);
- }
+ gchar *str = gtk_entry_get_public_chars (entry, start, end);
+ gtk_selection_data_set_text (selection_data, str);
+ g_free (str);
}
}
static void
-gtk_delete_forward_word (GtkEntry *entry)
+primary_clear_cb (GtkClipboard *clipboard,
+ gpointer data)
{
- gtk_entry_kill_word (GTK_EDITABLE (entry), 1);
-}
+ GtkEntry *entry = GTK_ENTRY (data);
-static void
-gtk_delete_backward_word (GtkEntry *entry)
-{
- gtk_entry_kill_word (GTK_EDITABLE (entry), -1);
+ gtk_editable_select_region (GTK_EDITABLE (entry), entry->current_pos, entry->current_pos);
}
static void
-gtk_entry_kill_line (GtkEditable *editable,
- gint direction)
-{
- gint old_pos = editable->current_pos;
- if (direction >= 0)
+gtk_entry_update_primary_selection (GtkEntry *entry)
+{
+ static const GtkTargetEntry targets[] = {
+ { "UTF8_STRING", 0, 0 },
+ { "STRING", 0, 0 },
+ { "TEXT", 0, 0 },
+ { "COMPOUND_TEXT", 0, 0 }
+ };
+
+ GtkClipboard *clipboard = gtk_clipboard_get (GDK_SELECTION_PRIMARY);
+ gint start, end;
+
+ if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start, &end))
{
- gtk_entry_move_to_column (editable, -1);
- gtk_editable_delete_text (editable, old_pos, editable->current_pos);
+ if (!gtk_clipboard_set_with_owner (clipboard, targets, G_N_ELEMENTS (targets),
+ primary_get_cb, primary_clear_cb, G_OBJECT (entry)))
+ primary_clear_cb (clipboard, entry);
}
else
{
- gtk_entry_move_to_column (editable, 0);
- gtk_editable_delete_text (editable, editable->current_pos, old_pos);
+ if (gtk_clipboard_get_owner (clipboard) == G_OBJECT (entry))
+ gtk_clipboard_clear (clipboard);
}
}
-static void
-gtk_delete_line (GtkEntry *entry)
+/* Public API
+ */
+
+GtkWidget*
+gtk_entry_new (void)
{
- gtk_entry_move_to_column (GTK_EDITABLE (entry), 0);
- gtk_entry_kill_line (GTK_EDITABLE (entry), 1);
+ return GTK_WIDGET (gtk_type_new (GTK_TYPE_ENTRY));
}
-static void
-gtk_delete_to_line_end (GtkEntry *entry)
+GtkWidget*
+gtk_entry_new_with_max_length (guint16 max)
{
- gtk_editable_delete_text (GTK_EDITABLE(entry), GTK_EDITABLE(entry)->current_pos, entry->text_length);
+ GtkEntry *entry;
+
+ entry = gtk_type_new (GTK_TYPE_ENTRY);
+ entry->text_max_length = max;
+
+ return GTK_WIDGET (entry);
}
-static void
-gtk_select_word (GtkEntry *entry,
- guint32 time)
+void
+gtk_entry_set_text (GtkEntry *entry,
+ const gchar *text)
{
+ gint tmp_pos;
+
GtkEditable *editable;
- gint start_pos;
- gint end_pos;
+
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+ g_return_if_fail (text != NULL);
editable = GTK_EDITABLE (entry);
+
+ gtk_editable_delete_text (GTK_EDITABLE(entry), 0, -1);
+
+ tmp_pos = 0;
+ gtk_editable_insert_text (editable, text, strlen (text), &tmp_pos);
+}
- gtk_move_backward_word (entry);
- start_pos = editable->current_pos;
+void
+gtk_entry_append_text (GtkEntry *entry,
+ const gchar *text)
+{
+ gint tmp_pos;
- gtk_move_forward_word (entry);
- end_pos = editable->current_pos;
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+ g_return_if_fail (text != NULL);
- editable->has_selection = TRUE;
- gtk_entry_set_selection (editable, start_pos, end_pos);
- gtk_editable_claim_selection (editable, start_pos != end_pos, time);
+ tmp_pos = entry->text_length;
+ gtk_editable_insert_text (GTK_EDITABLE(entry), text, -1, &tmp_pos);
}
-static void
-gtk_select_line (GtkEntry *entry,
- guint32 time)
+void
+gtk_entry_prepend_text (GtkEntry *entry,
+ const gchar *text)
{
- GtkEditable *editable;
+ gint tmp_pos;
- editable = GTK_EDITABLE (entry);
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+ g_return_if_fail (text != NULL);
- editable->has_selection = TRUE;
- gtk_entry_set_selection (editable, 0, entry->text_length);
- gtk_editable_claim_selection (editable, entry->text_length != 0, time);
+ tmp_pos = 0;
+ gtk_editable_insert_text (GTK_EDITABLE(entry), text, -1, &tmp_pos);
+}
- editable->current_pos = editable->selection_end_pos;
+void
+gtk_entry_set_position (GtkEntry *entry,
+ gint position)
+{
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+
+ gtk_editable_set_position (GTK_EDITABLE (entry), position);
}
-static void
-gtk_entry_set_selection (GtkEditable *editable,
- gint start,
- gint end)
+void
+gtk_entry_set_visibility (GtkEntry *entry,
+ gboolean visible)
{
- GtkEntry *entry;
-
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_ENTRY (editable));
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (GTK_IS_ENTRY (entry));
- entry = GTK_ENTRY (editable);
+ entry->visible = visible ? TRUE : FALSE;
- if (end < 0)
- end = GTK_ENTRY (editable)->text_length;
-
- editable->selection_start_pos = start;
- editable->selection_end_pos = end;
+ gtk_entry_recompute (entry);
+}
+
+void
+gtk_entry_set_editable(GtkEntry *entry,
+ gboolean editable)
+{
+ g_return_if_fail (entry != NULL);
+ g_return_if_fail (GTK_IS_ENTRY (entry));
+
+ gtk_editable_set_editable (GTK_EDITABLE (entry), editable);
+}
+
+gchar*
+gtk_entry_get_text (GtkEntry *entry)
+{
+ g_return_val_if_fail (entry != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
- gtk_entry_queue_draw (GTK_ENTRY (editable));
+ return entry->text;
}
void
@@ -1983,63 +2356,66 @@ gtk_entry_set_max_length (GtkEntry *entry,
entry->text_max_length = max;
}
-
-static void
-gtk_entry_style_set (GtkWidget *widget,
- GtkStyle *previous_style)
+/* Quick hack of a popup menu
+ */
+static void
+activate_cb (GtkWidget *menuitem,
+ GtkEntry *entry)
{
- GtkEntry *entry = GTK_ENTRY (widget);
-
- if (previous_style && GTK_WIDGET_REALIZED (widget))
- {
- entry_adjust_scroll (entry);
-
- gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
- gdk_window_set_background (entry->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);
- }
-
- if (entry->layout)
- pango_layout_context_changed (entry->layout);
+ const gchar *signal = gtk_object_get_data (GTK_OBJECT (menuitem), "gtk-signal");
+ gtk_signal_emit_by_name (GTK_OBJECT (entry), signal);
}
-static void
-gtk_entry_direction_changed (GtkWidget *widget,
- GtkTextDirection previous_dir)
+static void
+append_action_signal (GtkEntry *entry,
+ GtkWidget *menu,
+ const gchar *label,
+ const gchar *signal)
{
- GtkEntry *entry = GTK_ENTRY (widget);
+ GtkWidget *menuitem = gtk_menu_item_new_with_label (label);
- if (entry->layout)
- pango_layout_context_changed (entry->layout);
+ gtk_object_set_data (GTK_OBJECT (menuitem), "gtk-signal", (char *)signal);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ activate_cb, entry);
- GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
}
-
+
static void
-gtk_entry_state_changed (GtkWidget *widget,
- GtkStateType previous_state)
+popup_menu_detach (GtkWidget *attach_widget,
+ GtkMenu *menu)
{
- g_return_if_fail (widget != NULL);
- g_return_if_fail (GTK_IS_ENTRY (widget));
-
- if (GTK_WIDGET_REALIZED (widget))
- {
- gdk_window_set_background (widget->window, &widget->style->base[GTK_WIDGET_STATE (widget)]);
- gdk_window_set_background (GTK_ENTRY (widget)->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);
- }
-
- if (GTK_WIDGET_DRAWABLE (widget))
- gtk_widget_queue_clear(widget);
+ GTK_ENTRY (attach_widget)->popup_menu = NULL;
}
static void
-gtk_entry_commit_cb (GtkIMContext *context,
- const gchar *str,
- GtkEntry *entry)
+gtk_entry_popup_menu (GtkEntry *entry,
+ GdkEventButton *event)
{
- GtkEditable *editable = GTK_EDITABLE (entry);
- gint tmp_pos = editable->current_pos;
+ if (!entry->popup_menu)
+ {
+ GtkWidget *menuitem;
+
+ entry->popup_menu = gtk_menu_new ();
- gtk_editable_insert_text (editable, str, strlen (str), &tmp_pos);
- editable->current_pos = tmp_pos;
-}
+ gtk_menu_attach_to_widget (GTK_MENU (entry->popup_menu),
+ GTK_WIDGET (entry),
+ popup_menu_detach);
+
+ append_action_signal (entry, entry->popup_menu, _("Cut"), "cut_clipboard");
+ append_action_signal (entry, entry->popup_menu, _("Copy"), "copy_clipboard");
+ append_action_signal (entry, entry->popup_menu, _("Paste"), "paste_clipboard");
+ menuitem = gtk_menu_item_new (); /* Separator */
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (entry->popup_menu), menuitem);
+
+ gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (entry->im_context),
+ GTK_MENU_SHELL (entry->popup_menu));
+ }
+
+ gtk_menu_popup (GTK_MENU (entry->popup_menu), NULL, NULL,
+ NULL, NULL,
+ event->button, event->time);
+}
diff --git a/gtk/gtkentry.h b/gtk/gtkentry.h
index 9f7f38899e..765da78f03 100644
--- a/gtk/gtkentry.h
+++ b/gtk/gtkentry.h
@@ -51,57 +51,106 @@ typedef struct _GtkEntryClass GtkEntryClass;
struct _GtkEntry
{
- GtkEditable editable;
+ GtkWidget widget;
- GdkWindow *text_area;
- GdkPixmap *backing_pixmap;
- GdkCursor *cursor;
gchar *text;
- guint16 text_size; /* allocated size, in bytes */
+ guint editable : 1;
+ guint visible : 1;
+ guint overwrite_mode : 1;
guint16 text_length; /* length in use, in chars */
guint16 text_max_length;
/*< private >*/
+ GdkWindow *text_area;
+ GtkIMContext *im_context;
+ GtkWidget *popup_menu;
+
+ gint current_pos;
+ gint selection_bound;
+
+ PangoLayout *cached_layout;
+ guint cache_includes_preedit : 1;
+
+ guint need_im_reset : 1;
+
guint button;
- guint32 timer;
- guint16 n_bytes; /* length in use, in bytes */
- PangoLayout *layout;
+ guint timer;
+ guint recompute_idle;
gint scroll_offset;
gint ascent; /* font ascent, in pango units */
gint descent; /* font descent, in pango units */
- GtkIMContext *im_context;
+
+ guint16 text_size; /* allocated size, in bytes */
+ guint16 n_bytes; /* length in use, in bytes */
+
+ guint16 preedit_length; /* length of preedit string, in bytes */
+ guint16 preedit_cursor; /* offset of cursor within preedit string, in bytes */
};
struct _GtkEntryClass
{
- GtkEditableClass parent_class;
+ GtkWidgetClass parent_class;
+
+ /* Notification of changes
+ */
+ void (* changed) (GtkEntry *entry);
+ void (* insert_text) (GtkEntry *entry,
+ const gchar *text,
+ gint length,
+ gint *position);
+ void (* delete_text) (GtkEntry *entry,
+ gint start_pos,
+ gint end_pos);
+
+ /* Action signals
+ */
+ void (* activate) (GtkEntry *entry);
+ void (* move) (GtkEntry *entry,
+ GtkMovementStep step,
+ gint count,
+ gboolean extend_selection);
+ void (* insert) (GtkEntry *entry,
+ const gchar *str);
+ void (* delete) (GtkEntry *entry,
+ GtkDeleteType type,
+ gint count);
+ void (* cut_clipboard) (GtkEntry *entry);
+ void (* copy_clipboard) (GtkEntry *entry);
+ void (* paste_clipboard) (GtkEntry *entry);
+ void (* toggle_overwrite) (GtkEntry *entry);
};
GtkType gtk_entry_get_type (void) G_GNUC_CONST;
GtkWidget* gtk_entry_new (void);
-GtkWidget* gtk_entry_new_with_max_length (guint16 max);
+void gtk_entry_set_visibility (GtkEntry *entry,
+ gboolean visible);
+void gtk_entry_set_editable (GtkEntry *entry,
+ gboolean editable);
+/* text is truncated if needed */
+void gtk_entry_set_max_length (GtkEntry *entry,
+ guint16 max);
+
+/* Somewhat more convenient than the GtkEditable generic functions
+ */
void gtk_entry_set_text (GtkEntry *entry,
const gchar *text);
+/* returns a reference to the text */
+gchar* gtk_entry_get_text (GtkEntry *entry);
+
+/* Deprecated compatibility functions
+ */
+GtkWidget* gtk_entry_new_with_max_length (guint16 max);
void gtk_entry_append_text (GtkEntry *entry,
const gchar *text);
void gtk_entry_prepend_text (GtkEntry *entry,
const gchar *text);
void gtk_entry_set_position (GtkEntry *entry,
gint position);
-/* returns a reference to the text */
-gchar* gtk_entry_get_text (GtkEntry *entry);
void gtk_entry_select_region (GtkEntry *entry,
gint start,
gint end);
-void gtk_entry_set_visibility (GtkEntry *entry,
- gboolean visible);
-void gtk_entry_set_editable (GtkEntry *entry,
- gboolean editable);
-/* text is truncated if needed */
-void gtk_entry_set_max_length (GtkEntry *entry,
- guint16 max);
#ifdef __cplusplus
}
diff --git a/gtk/gtkimcontext.c b/gtk/gtkimcontext.c
index 753937f11f..3ced6d6036 100644
--- a/gtk/gtkimcontext.c
+++ b/gtk/gtkimcontext.c
@@ -35,7 +35,8 @@ static void gtk_im_context_init (GtkIMContext *im_context);
static void gtk_im_context_real_get_preedit_string (GtkIMContext *context,
gchar **str,
- PangoAttrList **attrs);
+ PangoAttrList **attrs,
+ gint *cursor_pos);
static gboolean gtk_im_context_real_filter_keypress (GtkIMContext *context,
GdkEventKey *event);
@@ -118,12 +119,15 @@ gtk_im_context_init (GtkIMContext *im_context)
static void
gtk_im_context_real_get_preedit_string (GtkIMContext *context,
gchar **str,
- PangoAttrList **attrs)
+ PangoAttrList **attrs,
+ gint *cursor_pos)
{
if (str)
*str = g_strdup ("");
if (attrs)
*attrs = pango_attr_list_new ();
+ if (cursor_pos)
+ *cursor_pos = 0;
}
static gboolean
@@ -175,7 +179,8 @@ gtk_im_context_set_client_window (GtkIMContext *context,
void
gtk_im_context_get_preedit_string (GtkIMContext *context,
gchar **str,
- PangoAttrList **attrs)
+ PangoAttrList **attrs,
+ gint *cursor_pos)
{
GtkIMContextClass *klass;
@@ -183,7 +188,7 @@ gtk_im_context_get_preedit_string (GtkIMContext *context,
g_return_if_fail (GTK_IS_IM_CONTEXT (context));
klass = GTK_IM_CONTEXT_GET_CLASS (context);
- klass->get_preedit_string (context, str, attrs);
+ klass->get_preedit_string (context, str, attrs, cursor_pos);
}
/**
@@ -235,7 +240,7 @@ gtk_im_context_focus_in (GtkIMContext *context)
}
/**
- * gtk_im_context_focus_in:
+ * gtk_im_context_focus_out:
* @context: a #GtkIMContext
*
* Notify the input method that the widget to which this
@@ -256,4 +261,25 @@ gtk_im_context_focus_out (GtkIMContext *context)
klass->focus_out (context);
}
+/**
+ * gtk_im_context_reset:
+ * @context: a #GtkIMContext
+ *
+ * Notify the input method that a change such as a change in cursor
+ * position has been made. This will typically cause the input
+ * method to clear the preedit state.
+ **/
+void
+gtk_im_context_reset (GtkIMContext *context)
+{
+ GtkIMContextClass *klass;
+
+ g_return_if_fail (context != NULL);
+ g_return_if_fail (GTK_IS_IM_CONTEXT (context));
+
+ klass = GTK_IM_CONTEXT_GET_CLASS (context);
+ if (klass->reset)
+ klass->reset (context);
+}
+
diff --git a/gtk/gtkimcontext.h b/gtk/gtkimcontext.h
index efc4ab64fe..6435c4eaf8 100644
--- a/gtk/gtkimcontext.h
+++ b/gtk/gtkimcontext.h
@@ -60,11 +60,13 @@ struct _GtkIMContextClass
GdkWindow *window);
void (*get_preedit_string) (GtkIMContext *context,
gchar **str,
- PangoAttrList **attrs);
+ PangoAttrList **attrs,
+ gint *cursor_pos);
gboolean (*filter_keypress) (GtkIMContext *context,
GdkEventKey *event);
void (*focus_in) (GtkIMContext *context);
void (*focus_out) (GtkIMContext *context);
+ void (*reset) (GtkIMContext *context);
};
GtkType gtk_im_context_get_type (void) G_GNUC_CONST;
@@ -72,12 +74,14 @@ GtkType gtk_im_context_get_type (void) G_GNUC_CONST;
void gtk_im_context_set_client_window (GtkIMContext *context,
GdkWindow *window);
void gtk_im_context_get_preedit_string (GtkIMContext *context,
- char **str,
- PangoAttrList **attrs);
+ gchar **str,
+ PangoAttrList **attrs,
+ gint *cursor_pos);
gboolean gtk_im_context_filter_keypress (GtkIMContext *context,
GdkEventKey *event);
void gtk_im_context_focus_in (GtkIMContext *context);
void gtk_im_context_focus_out (GtkIMContext *context);
+void gtk_im_context_reset (GtkIMContext *context);
#ifdef __cplusplus
}
diff --git a/gtk/gtkimcontextsimple.c b/gtk/gtkimcontextsimple.c
index edfdb57296..a01c85c3bd 100644
--- a/gtk/gtkimcontextsimple.c
+++ b/gtk/gtkimcontextsimple.c
@@ -23,12 +23,13 @@
#include "gtksignal.h"
#include "gtkimcontextsimple.h"
-typedef struct _GtkComposeSeq GtkComposeSeq;
+typedef struct _GtkComposeTable GtkComposeTable;
-struct _GtkComposeSeq
+struct _GtkComposeTable
{
- guint16 keysyms[GTK_MAX_COMPOSE_LEN];
- guint16 unicode;
+ guint16 *data;
+ gint max_seq_len;
+ gint n_seqs;
};
/* The following table was generated from the X compose tables include with
@@ -54,665 +55,671 @@ struct _GtkComposeSeq
* that depend on the locale or selected input method.
*/
-GtkComposeSeq gtk_compose_seqs[] = {
- { { GDK_dead_grave, GDK_space, 0, 0 }, 0x0060 }, /* GRAVE_ACCENT */
- { { GDK_dead_grave, GDK_A, 0, 0 }, 0x00C0 }, /* LATIN_CAPITAL_LETTER_A_WITH_GRAVE */
- { { GDK_dead_grave, GDK_E, 0, 0 }, 0x00C8 }, /* LATIN_CAPITAL_LETTER_E_WITH_GRAVE */
- { { GDK_dead_grave, GDK_I, 0, 0 }, 0x00CC }, /* LATIN_CAPITAL_LETTER_I_WITH_GRAVE */
- { { GDK_dead_grave, GDK_O, 0, 0 }, 0x00D2 }, /* LATIN_CAPITAL_LETTER_O_WITH_GRAVE */
- { { GDK_dead_grave, GDK_U, 0, 0 }, 0x00D9 }, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
- { { GDK_dead_grave, GDK_a, 0, 0 }, 0x00E0 }, /* LATIN_SMALL_LETTER_A_WITH_GRAVE */
- { { GDK_dead_grave, GDK_e, 0, 0 }, 0x00E8 }, /* LATIN_SMALL_LETTER_E_WITH_GRAVE */
- { { GDK_dead_grave, GDK_i, 0, 0 }, 0x00EC }, /* LATIN_SMALL_LETTER_I_WITH_GRAVE */
- { { GDK_dead_grave, GDK_o, 0, 0 }, 0x00F2 }, /* LATIN_SMALL_LETTER_O_WITH_GRAVE */
- { { GDK_dead_grave, GDK_u, 0, 0 }, 0x00F9 }, /* LATIN_SMALL_LETTER_U_WITH_GRAVE */
- { { GDK_dead_acute, GDK_space, 0, 0 }, 0x0027 }, /* APOSTROPHE */
- { { GDK_dead_acute, GDK_apostrophe, 0, 0 }, 0x00B4 }, /* ACUTE_ACCENT */
- { { GDK_dead_acute, GDK_A, 0, 0 }, 0x00C1 }, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
- { { GDK_dead_acute, GDK_E, 0, 0 }, 0x00C9 }, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
- { { GDK_dead_acute, GDK_I, 0, 0 }, 0x00CD }, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
- { { GDK_dead_acute, GDK_O, 0, 0 }, 0x00D3 }, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
- { { GDK_dead_acute, GDK_U, 0, 0 }, 0x00DA }, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
- { { GDK_dead_acute, GDK_Y, 0, 0 }, 0x00DD }, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
- { { GDK_dead_acute, GDK_a, 0, 0 }, 0x00E1 }, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
- { { GDK_dead_acute, GDK_e, 0, 0 }, 0x00E9 }, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
- { { GDK_dead_acute, GDK_i, 0, 0 }, 0x00ED }, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
- { { GDK_dead_acute, GDK_o, 0, 0 }, 0x00F3 }, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
- { { GDK_dead_acute, GDK_u, 0, 0 }, 0x00FA }, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
- { { GDK_dead_acute, GDK_y, 0, 0 }, 0x00FD }, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
- { { GDK_dead_acute, GDK_acute, 0, 0 }, 0x00B4 }, /* ACUTE_ACCENT */
- { { GDK_dead_acute, GDK_dead_acute, 0, 0 }, 0x00B4 }, /* ACUTE_ACCENT */
- { { GDK_dead_circumflex, GDK_space, 0, 0 }, 0x005E }, /* CIRCUMFLEX_ACCENT */
- { { GDK_dead_circumflex, GDK_minus, 0, 0 }, 0x00AF }, /* MACRON */
- { { GDK_dead_circumflex, GDK_period, 0, 0 }, 0x00B7 }, /* MIDDLE_DOT */
- { { GDK_dead_circumflex, GDK_slash, 0, 0 }, 0x007C }, /* VERTICAL_LINE */
- { { GDK_dead_circumflex, GDK_0, 0, 0 }, 0x00B0 }, /* DEGREE_SIGN */
- { { GDK_dead_circumflex, GDK_1, 0, 0 }, 0x00B9 }, /* SUPERSCRIPT_ONE */
- { { GDK_dead_circumflex, GDK_2, 0, 0 }, 0x00B2 }, /* SUPERSCRIPT_TWO */
- { { GDK_dead_circumflex, GDK_3, 0, 0 }, 0x00B3 }, /* SUPERSCRIPT_THREE */
- { { GDK_dead_circumflex, GDK_A, 0, 0 }, 0x00C2 }, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_E, 0, 0 }, 0x00CA }, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_I, 0, 0 }, 0x00CE }, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_O, 0, 0 }, 0x00D4 }, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_U, 0, 0 }, 0x00DB }, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_underscore, 0, 0 }, 0x00AF }, /* MACRON */
- { { GDK_dead_circumflex, GDK_a, 0, 0 }, 0x00E2 }, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_e, 0, 0 }, 0x00EA }, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_i, 0, 0 }, 0x00EE }, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_o, 0, 0 }, 0x00F4 }, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_dead_circumflex, GDK_u, 0, 0 }, 0x00FB }, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_dead_tilde, GDK_space, 0, 0 }, 0x007E }, /* TILDE */
- { { GDK_dead_tilde, GDK_A, 0, 0 }, 0x00C3 }, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
- { { GDK_dead_tilde, GDK_I, 0, 0 }, 0x0128 }, /* LATIN_CAPITAL_LETTER_I_WITH_TILDE */
- { { GDK_dead_tilde, GDK_N, 0, 0 }, 0x00D1 }, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
- { { GDK_dead_tilde, GDK_O, 0, 0 }, 0x00D5 }, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
- { { GDK_dead_tilde, GDK_U, 0, 0 }, 0x0168 }, /* LATIN_CAPITAL_LETTER_U_WITH_TILDE */
- { { GDK_dead_tilde, GDK_a, 0, 0 }, 0x00E3 }, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
- { { GDK_dead_tilde, GDK_i, 0, 0 }, 0x0129 }, /* LATIN_SMALL_LETTER_I_WITH_TILDE */
- { { GDK_dead_tilde, GDK_n, 0, 0 }, 0x00F1 }, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
- { { GDK_dead_tilde, GDK_o, 0, 0 }, 0x00F5 }, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
- { { GDK_dead_tilde, GDK_u, 0, 0 }, 0x0169 }, /* LATIN_SMALL_LETTER_U_WITH_TILDE */
- { { GDK_dead_tilde, GDK_asciitilde, 0, 0 }, 0x007E }, /* TILDE */
- { { GDK_dead_tilde, GDK_dead_tilde, 0, 0 }, 0x007E }, /* TILDE */
- { { GDK_dead_macron, GDK_A, 0, 0 }, 0x0100 }, /* LATIN_CAPITAL_LETTER_A_WITH_MACRON */
- { { GDK_dead_macron, GDK_E, 0, 0 }, 0x0112 }, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
- { { GDK_dead_macron, GDK_I, 0, 0 }, 0x012A }, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
- { { GDK_dead_macron, GDK_O, 0, 0 }, 0x014C }, /* LATIN_CAPITAL_LETTER_O_WITH_MACRON */
- { { GDK_dead_macron, GDK_U, 0, 0 }, 0x00D9 }, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
- { { GDK_dead_macron, GDK_a, 0, 0 }, 0x0101 }, /* LATIN_SMALL_LETTER_A_WITH_MACRON */
- { { GDK_dead_macron, GDK_e, 0, 0 }, 0x0113 }, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
- { { GDK_dead_macron, GDK_i, 0, 0 }, 0x012B }, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
- { { GDK_dead_macron, GDK_o, 0, 0 }, 0x014D }, /* LATIN_SMALL_LETTER_O_WITH_MACRON */
- { { GDK_dead_macron, GDK_u, 0, 0 }, 0x016B }, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
- { { GDK_dead_macron, GDK_macron, 0, 0 }, 0x00AF }, /* MACRON */
- { { GDK_dead_macron, GDK_dead_macron, 0, 0 }, 0x00AF }, /* MACRON */
- { { GDK_dead_breve, GDK_G, 0, 0 }, 0x011E }, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
- { { GDK_dead_breve, GDK_g, 0, 0 }, 0x011F }, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
- { { GDK_dead_abovedot, GDK_E, 0, 0 }, 0x0116 }, /* LATIN_CAPITAL_LETTER_E_WITH_DOT_ABOVE */
- { { GDK_dead_abovedot, GDK_I, 0, 0 }, 0x0130 }, /* LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE */
- { { GDK_dead_abovedot, GDK_e, 0, 0 }, 0x0117 }, /* LATIN_SMALL_LETTER_E_WITH_DOT_ABOVE */
- { { GDK_dead_abovedot, GDK_i, 0, 0 }, 0x0131 }, /* LATIN_SMALL_LETTER_DOTLESS_I */
- { { GDK_dead_abovedot, GDK_abovedot, 0, 0 }, 0x02D9 }, /* DOT_ABOVE */
- { { GDK_dead_abovedot, GDK_dead_abovedot, 0, 0 }, 0x02D9 }, /* DOT_ABOVE */
- { { GDK_dead_diaeresis, GDK_space, 0, 0 }, 0x00A8 }, /* DIAERESIS */
- { { GDK_dead_diaeresis, GDK_quotedbl, 0, 0 }, 0x00A8 }, /* DIAERESIS */
- { { GDK_dead_diaeresis, GDK_A, 0, 0 }, 0x00C4 }, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_E, 0, 0 }, 0x00CB }, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_I, 0, 0 }, 0x00CF }, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_O, 0, 0 }, 0x00D6 }, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_U, 0, 0 }, 0x00DC }, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_Y, 0, 0 }, 0x0178 }, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_a, 0, 0 }, 0x00E4 }, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_e, 0, 0 }, 0x00EB }, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_i, 0, 0 }, 0x00EF }, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_o, 0, 0 }, 0x00F6 }, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_u, 0, 0 }, 0x00FC }, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_y, 0, 0 }, 0x00FF }, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_dead_diaeresis, GDK_diaeresis, 0, 0 }, 0x00A8 }, /* DIAERESIS */
- { { GDK_dead_diaeresis, GDK_dead_diaeresis, 0, 0 }, 0x00A8 }, /* DIAERESIS */
- { { GDK_dead_abovering, GDK_A, 0, 0 }, 0x00C5 }, /* LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */
- { { GDK_dead_abovering, GDK_a, 0, 0 }, 0x00E5 }, /* LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */
- { { GDK_dead_abovering, GDK_dead_abovering, 0, 0 }, 0x02DA }, /* RING_ABOVE */
- { { GDK_dead_caron, GDK_C, 0, 0 }, 0x010C }, /* LATIN_CAPITAL_LETTER_C_WITH_CARON */
- { { GDK_dead_caron, GDK_S, 0, 0 }, 0x0160 }, /* LATIN_CAPITAL_LETTER_S_WITH_CARON */
- { { GDK_dead_caron, GDK_Z, 0, 0 }, 0x017D }, /* LATIN_CAPITAL_LETTER_Z_WITH_CARON */
- { { GDK_dead_caron, GDK_c, 0, 0 }, 0x010D }, /* LATIN_SMALL_LETTER_C_WITH_CARON */
- { { GDK_dead_caron, GDK_s, 0, 0 }, 0x0161 }, /* LATIN_SMALL_LETTER_S_WITH_CARON */
- { { GDK_dead_caron, GDK_z, 0, 0 }, 0x017E }, /* LATIN_SMALL_LETTER_Z_WITH_CARON */
- { { GDK_dead_caron, GDK_caron, 0, 0 }, 0x02C7 }, /* CARON */
- { { GDK_dead_caron, GDK_dead_caron, 0, 0 }, 0x02C7 }, /* CARON */
- { { GDK_dead_cedilla, GDK_comma, 0, 0 }, 0x00B8 }, /* CEDILLA */
- { { GDK_dead_cedilla, GDK_minus, 0, 0 }, 0x00AC }, /* NOT_SIGN */
- { { GDK_dead_cedilla, GDK_C, 0, 0 }, 0x00C7 }, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_G, 0, 0 }, 0x0122 }, /* LATIN_CAPITAL_LETTER_G_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_K, 0, 0 }, 0x0136 }, /* LATIN_CAPITAL_LETTER_K_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_L, 0, 0 }, 0x013B }, /* LATIN_CAPITAL_LETTER_L_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_N, 0, 0 }, 0x0145 }, /* LATIN_CAPITAL_LETTER_N_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_R, 0, 0 }, 0x0156 }, /* LATIN_CAPITAL_LETTER_R_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_S, 0, 0 }, 0x015E }, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_c, 0, 0 }, 0x00E7 }, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_g, 0, 0 }, 0x0123 }, /* LATIN_SMALL_LETTER_G_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_k, 0, 0 }, 0x0137 }, /* LATIN_SMALL_LETTER_K_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_l, 0, 0 }, 0x013C }, /* LATIN_SMALL_LETTER_L_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_n, 0, 0 }, 0x0146 }, /* LATIN_SMALL_LETTER_N_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_r, 0, 0 }, 0x0157 }, /* LATIN_SMALL_LETTER_R_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_s, 0, 0 }, 0x015F }, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
- { { GDK_dead_cedilla, GDK_cedilla, 0, 0 }, 0x00B8 }, /* CEDILLA */
- { { GDK_dead_cedilla, GDK_dead_cedilla, 0, 0 }, 0x00B8 }, /* CEDILLA */
- { { GDK_dead_ogonek, GDK_A, 0, 0 }, 0x0104 }, /* LATIN_CAPITAL_LETTER_A_WITH_OGONEK */
- { { GDK_dead_ogonek, GDK_E, 0, 0 }, 0x0118 }, /* LATIN_CAPITAL_LETTER_E_WITH_OGONEK */
- { { GDK_dead_ogonek, GDK_I, 0, 0 }, 0x012E }, /* LATIN_CAPITAL_LETTER_I_WITH_OGONEK */
- { { GDK_dead_ogonek, GDK_U, 0, 0 }, 0x0172 }, /* LATIN_CAPITAL_LETTER_U_WITH_OGONEK */
- { { GDK_dead_ogonek, GDK_a, 0, 0 }, 0x0105 }, /* LATIN_SMALL_LETTER_A_WITH_OGONEK */
- { { GDK_dead_ogonek, GDK_e, 0, 0 }, 0x0119 }, /* LATIN_SMALL_LETTER_E_WITH_OGONEK */
- { { GDK_dead_ogonek, GDK_i, 0, 0 }, 0x012F }, /* LATIN_SMALL_LETTER_I_WITH_OGONEK */
- { { GDK_dead_ogonek, GDK_u, 0, 0 }, 0x0173 }, /* LATIN_SMALL_LETTER_U_WITH_OGONEK */
- { { GDK_dead_ogonek, GDK_ogonek, 0, 0 }, 0x02DB }, /* OGONEK */
- { { GDK_dead_ogonek, GDK_dead_ogonek, 0, 0 }, 0x02DB }, /* OGONEK */
- { { GDK_Multi_key, GDK_space, GDK_space, 0 }, 0x00A0 }, /* NOxBREAK_SPACE */
- { { GDK_Multi_key, GDK_space, GDK_apostrophe, 0 }, 0x0027 }, /* APOSTROPHE */
- { { GDK_Multi_key, GDK_space, GDK_minus, 0 }, 0x007E }, /* TILDE */
- { { GDK_Multi_key, GDK_space, GDK_greater, 0 }, 0x005E }, /* CIRCUMFLEX_ACCENT */
- { { GDK_Multi_key, GDK_space, GDK_asciicircum, 0 }, 0x005E }, /* CIRCUMFLEX_ACCENT */
- { { GDK_Multi_key, GDK_space, GDK_grave, 0 }, 0x0060 }, /* GRAVE_ACCENT */
- { { GDK_Multi_key, GDK_space, GDK_asciitilde, 0 }, 0x007E }, /* TILDE */
- { { GDK_Multi_key, GDK_exclam, GDK_exclam, 0 }, 0x00A1 }, /* INVERTED_EXCLAMATION_MARK */
- { { GDK_Multi_key, GDK_exclam, GDK_P, 0 }, 0x00B6 }, /* PILCROW_SIGN */
- { { GDK_Multi_key, GDK_exclam, GDK_S, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_exclam, GDK_p, 0 }, 0x00B6 }, /* PILCROW_SIGN */
- { { GDK_Multi_key, GDK_exclam, GDK_s, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_quotedbl, GDK_quotedbl, 0 }, 0x00A8 }, /* DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_A, 0 }, 0x00C4 }, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_E, 0 }, 0x00CB }, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_I, 0 }, 0x00CF }, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_O, 0 }, 0x00D6 }, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_U, 0 }, 0x00DC }, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_Y, 0 }, 0x0178 }, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_a, 0 }, 0x00E4 }, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_e, 0 }, 0x00EB }, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_i, 0 }, 0x00EF }, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_o, 0 }, 0x00F6 }, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_u, 0 }, 0x00FC }, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_quotedbl, GDK_y, 0 }, 0x00FF }, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_apostrophe, GDK_space, 0 }, 0x0027 }, /* APOSTROPHE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_apostrophe, 0 }, 0x00B4 }, /* ACUTE_ACCENT */
- { { GDK_Multi_key, GDK_apostrophe, GDK_A, 0 }, 0x00C1 }, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_E, 0 }, 0x00C9 }, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_I, 0 }, 0x00CD }, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_O, 0 }, 0x00D3 }, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_U, 0 }, 0x00DA }, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_Y, 0 }, 0x00DD }, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_a, 0 }, 0x00E1 }, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_e, 0 }, 0x00E9 }, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_i, 0 }, 0x00ED }, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_o, 0 }, 0x00F3 }, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_u, 0 }, 0x00FA }, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
- { { GDK_Multi_key, GDK_apostrophe, GDK_y, 0 }, 0x00FD }, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
- { { GDK_Multi_key, GDK_parenleft, GDK_parenleft, 0 }, 0x005B }, /* LEFT_SQUARE_BRACKET */
- { { GDK_Multi_key, GDK_parenleft, GDK_minus, 0 }, 0x007B }, /* LEFT_CURLY_BRACKET */
- { { GDK_Multi_key, GDK_parenleft, GDK_G, 0 }, 0x011E }, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_parenleft, GDK_c, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_parenleft, GDK_g, 0 }, 0x011F }, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_parenleft, GDK_r, 0 }, 0x00AE }, /* REGISTERED_SIGN */
- { { GDK_Multi_key, GDK_parenright, GDK_parenright, 0 }, 0x005D }, /* RIGHT_SQUARE_BRACKET */
- { { GDK_Multi_key, GDK_parenright, GDK_minus, 0 }, 0x007D }, /* RIGHT_CURLY_BRACKET */
- { { GDK_Multi_key, GDK_asterisk, GDK_0, 0 }, 0x00B0 }, /* DEGREE_SIGN */
- { { GDK_Multi_key, GDK_asterisk, GDK_A, 0 }, 0x00C5 }, /* LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */
- { { GDK_Multi_key, GDK_asterisk, GDK_a, 0 }, 0x00E5 }, /* LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */
- { { GDK_Multi_key, GDK_plus, GDK_plus, 0 }, 0x0023 }, /* NUMBER_SIGN */
- { { GDK_Multi_key, GDK_plus, GDK_minus, 0 }, 0x00B1 }, /* PLUSxMINUS_SIGN */
- { { GDK_Multi_key, GDK_comma, GDK_comma, 0 }, 0x00B8 }, /* CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_minus, 0 }, 0x00AC }, /* NOT_SIGN */
- { { GDK_Multi_key, GDK_comma, GDK_A, 0 }, 0x0104 }, /* LATIN_CAPITAL_LETTER_A_WITH_OGONEK */
- { { GDK_Multi_key, GDK_comma, GDK_C, 0 }, 0x00C7 }, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_E, 0 }, 0x0118 }, /* LATIN_CAPITAL_LETTER_E_WITH_OGONEK */
- { { GDK_Multi_key, GDK_comma, GDK_G, 0 }, 0x0122 }, /* LATIN_CAPITAL_LETTER_G_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_I, 0 }, 0x012E }, /* LATIN_CAPITAL_LETTER_I_WITH_OGONEK */
- { { GDK_Multi_key, GDK_comma, GDK_K, 0 }, 0x0136 }, /* LATIN_CAPITAL_LETTER_K_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_L, 0 }, 0x013B }, /* LATIN_CAPITAL_LETTER_L_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_N, 0 }, 0x0145 }, /* LATIN_CAPITAL_LETTER_N_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_R, 0 }, 0x0156 }, /* LATIN_CAPITAL_LETTER_R_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_S, 0 }, 0x015E }, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_U, 0 }, 0x0172 }, /* LATIN_CAPITAL_LETTER_U_WITH_OGONEK */
- { { GDK_Multi_key, GDK_comma, GDK_a, 0 }, 0x0105 }, /* LATIN_SMALL_LETTER_A_WITH_OGONEK */
- { { GDK_Multi_key, GDK_comma, GDK_c, 0 }, 0x00E7 }, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_e, 0 }, 0x0119 }, /* LATIN_SMALL_LETTER_E_WITH_OGONEK */
- { { GDK_Multi_key, GDK_comma, GDK_g, 0 }, 0x0123 }, /* LATIN_SMALL_LETTER_G_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_i, 0 }, 0x012F }, /* LATIN_SMALL_LETTER_I_WITH_OGONEK */
- { { GDK_Multi_key, GDK_comma, GDK_k, 0 }, 0x0137 }, /* LATIN_SMALL_LETTER_K_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_l, 0 }, 0x013C }, /* LATIN_SMALL_LETTER_L_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_n, 0 }, 0x0146 }, /* LATIN_SMALL_LETTER_N_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_r, 0 }, 0x0157 }, /* LATIN_SMALL_LETTER_R_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_s, 0 }, 0x015F }, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_comma, GDK_u, 0 }, 0x0173 }, /* LATIN_SMALL_LETTER_U_WITH_OGONEK */
- { { GDK_Multi_key, GDK_minus, GDK_space, 0 }, 0x007E }, /* TILDE */
- { { GDK_Multi_key, GDK_minus, GDK_parenleft, 0 }, 0x007B }, /* LEFT_CURLY_BRACKET */
- { { GDK_Multi_key, GDK_minus, GDK_parenright, 0 }, 0x007D }, /* RIGHT_CURLY_BRACKET */
- { { GDK_Multi_key, GDK_minus, GDK_plus, 0 }, 0x00B1 }, /* PLUSxMINUS_SIGN */
- { { GDK_Multi_key, GDK_minus, GDK_comma, 0 }, 0x00AC }, /* NOT_SIGN */
- { { GDK_Multi_key, GDK_minus, GDK_minus, 0 }, 0x00AD }, /* SOFT_HYPHEN */
- { { GDK_Multi_key, GDK_minus, GDK_colon, 0 }, 0x00F7 }, /* DIVISION_SIGN */
- { { GDK_Multi_key, GDK_minus, GDK_A, 0 }, 0x00C3 }, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
- { { GDK_Multi_key, GDK_minus, GDK_D, 0 }, 0x0110 }, /* LATIN_CAPITAL_LETTER_D_WITH_STROKE */
- { { GDK_Multi_key, GDK_minus, GDK_E, 0 }, 0x0112 }, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
- { { GDK_Multi_key, GDK_minus, GDK_I, 0 }, 0x012A }, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
- { { GDK_Multi_key, GDK_minus, GDK_L, 0 }, 0x00A3 }, /* POUND_SIGN */
- { { GDK_Multi_key, GDK_minus, GDK_N, 0 }, 0x00D1 }, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
- { { GDK_Multi_key, GDK_minus, GDK_O, 0 }, 0x00D5 }, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
- { { GDK_Multi_key, GDK_minus, GDK_U, 0 }, 0x00D9 }, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
- { { GDK_Multi_key, GDK_minus, GDK_Y, 0 }, 0x00A5 }, /* YEN_SIGN */
- { { GDK_Multi_key, GDK_minus, GDK_asciicircum, 0 }, 0x00AF }, /* MACRON */
- { { GDK_Multi_key, GDK_minus, GDK_a, 0 }, 0x00E3 }, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
- { { GDK_Multi_key, GDK_minus, GDK_d, 0 }, 0x0111 }, /* LATIN_SMALL_LETTER_D_WITH_STROKE */
- { { GDK_Multi_key, GDK_minus, GDK_e, 0 }, 0x0113 }, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
- { { GDK_Multi_key, GDK_minus, GDK_i, 0 }, 0x012B }, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
- { { GDK_Multi_key, GDK_minus, GDK_l, 0 }, 0x00A3 }, /* POUND_SIGN */
- { { GDK_Multi_key, GDK_minus, GDK_n, 0 }, 0x00F1 }, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
- { { GDK_Multi_key, GDK_minus, GDK_o, 0 }, 0x00F5 }, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
- { { GDK_Multi_key, GDK_minus, GDK_u, 0 }, 0x016B }, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
- { { GDK_Multi_key, GDK_minus, GDK_y, 0 }, 0x00A5 }, /* YEN_SIGN */
- { { GDK_Multi_key, GDK_period, GDK_period, 0 }, 0x02D9 }, /* DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_B, 0 }, 0x1E02 }, /* LATIN_CAPITAL_LETTER_B_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_C, 0 }, 0x010A }, /* LATIN_CAPITAL_LETTER_C_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_D, 0 }, 0x1E0A }, /* LATIN_CAPITAL_LETTER_D_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_E, 0 }, 0x0116 }, /* LATIN_CAPITAL_LETTER_E_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_F, 0 }, 0x1E1E }, /* LATIN_CAPITAL_LETTER_F_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_G, 0 }, 0x0120 }, /* LATIN_CAPITAL_LETTER_G_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_I, 0 }, 0x0130 }, /* LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_M, 0 }, 0x1E40 }, /* LATIN_CAPITAL_LETTER_M_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_P, 0 }, 0x1E56 }, /* LATIN_CAPITAL_LETTER_P_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_S, 0 }, 0x1E60 }, /* LATIN_CAPITAL_LETTER_S_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_T, 0 }, 0x1E6A }, /* LATIN_CAPITAL_LETTER_T_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_asciicircum, 0 }, 0x00B7 }, /* MIDDLE_DOT */
- { { GDK_Multi_key, GDK_period, GDK_b, 0 }, 0x1E03 }, /* LATIN_SMALL_LETTER_B_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_c, 0 }, 0x010B }, /* LATIN_SMALL_LETTER_C_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_d, 0 }, 0x1E0B }, /* LATIN_SMALL_LETTER_D_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_e, 0 }, 0x0117 }, /* LATIN_SMALL_LETTER_E_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_f, 0 }, 0x1E1F }, /* LATIN_SMALL_LETTER_F_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_g, 0 }, 0x0121 }, /* LATIN_SMALL_LETTER_G_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_i, 0 }, 0x0131 }, /* LATIN_SMALL_LETTER_DOTLESS_I */
- { { GDK_Multi_key, GDK_period, GDK_m, 0 }, 0x1E41 }, /* LATIN_SMALL_LETTER_M_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_p, 0 }, 0x1E57 }, /* LATIN_SMALL_LETTER_P_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_s, 0 }, 0x1E61 }, /* LATIN_SMALL_LETTER_S_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_period, GDK_t, 0 }, 0x1E6B }, /* LATIN_SMALL_LETTER_T_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_slash, GDK_slash, 0 }, 0x005C }, /* REVERSE_SOLIDUS */
- { { GDK_Multi_key, GDK_slash, GDK_less, 0 }, 0x005C }, /* REVERSE_SOLIDUS */
- { { GDK_Multi_key, GDK_slash, GDK_C, 0 }, 0x00A2 }, /* CENT_SIGN */
- { { GDK_Multi_key, GDK_slash, GDK_O, 0 }, 0x00D8 }, /* LATIN_CAPITAL_LETTER_O_WITH_STROKE */
- { { GDK_Multi_key, GDK_slash, GDK_T, 0 }, 0x0166 }, /* LATIN_CAPITAL_LETTER_T_WITH_STROKE */
- { { GDK_Multi_key, GDK_slash, GDK_U, 0 }, 0x00B5 }, /* MICRO_SIGN */
- { { GDK_Multi_key, GDK_slash, GDK_asciicircum, 0 }, 0x007C }, /* VERTICAL_LINE */
- { { GDK_Multi_key, GDK_slash, GDK_c, 0 }, 0x00A2 }, /* CENT_SIGN */
- { { GDK_Multi_key, GDK_slash, GDK_o, 0 }, 0x00F8 }, /* LATIN_SMALL_LETTER_O_WITH_STROKE */
- { { GDK_Multi_key, GDK_slash, GDK_t, 0 }, 0x0167 }, /* LATIN_SMALL_LETTER_T_WITH_STROKE */
- { { GDK_Multi_key, GDK_slash, GDK_u, 0 }, 0x00B5 }, /* MICRO_SIGN */
- { { GDK_Multi_key, GDK_0, GDK_asterisk, 0 }, 0x00B0 }, /* DEGREE_SIGN */
- { { GDK_Multi_key, GDK_0, GDK_C, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_0, GDK_S, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_0, GDK_X, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_0, GDK_asciicircum, 0 }, 0x00B0 }, /* DEGREE_SIGN */
- { { GDK_Multi_key, GDK_0, GDK_c, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_0, GDK_s, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_0, GDK_x, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_1, GDK_S, 0 }, 0x00B9 }, /* SUPERSCRIPT_ONE */
- { { GDK_Multi_key, GDK_1, GDK_asciicircum, 0 }, 0x00B9 }, /* SUPERSCRIPT_ONE */
- { { GDK_Multi_key, GDK_1, GDK_s, 0 }, 0x00B9 }, /* SUPERSCRIPT_ONE */
- { { GDK_Multi_key, GDK_2, GDK_S, 0 }, 0x00B2 }, /* SUPERSCRIPT_TWO */
- { { GDK_Multi_key, GDK_2, GDK_asciicircum, 0 }, 0x00B2 }, /* SUPERSCRIPT_TWO */
- { { GDK_Multi_key, GDK_2, GDK_s, 0 }, 0x00B2 }, /* SUPERSCRIPT_TWO */
- { { GDK_Multi_key, GDK_3, GDK_S, 0 }, 0x00B3 }, /* SUPERSCRIPT_THREE */
- { { GDK_Multi_key, GDK_3, GDK_asciicircum, 0 }, 0x00B3 }, /* SUPERSCRIPT_THREE */
- { { GDK_Multi_key, GDK_3, GDK_s, 0 }, 0x00B3 }, /* SUPERSCRIPT_THREE */
- { { GDK_Multi_key, GDK_colon, GDK_minus, 0 }, 0x00F7 }, /* DIVISION_SIGN */
- { { GDK_Multi_key, GDK_less, GDK_slash, 0 }, 0x005C }, /* REVERSE_SOLIDUS */
- { { GDK_Multi_key, GDK_less, GDK_less, 0 }, 0x00AB }, /* LEFTxPOINTING_DOUBLE_ANGLE_QUOTATION_MARK */
- { { GDK_Multi_key, GDK_less, GDK_C, 0 }, 0x010C }, /* LATIN_CAPITAL_LETTER_C_WITH_CARON */
- { { GDK_Multi_key, GDK_less, GDK_S, 0 }, 0x0160 }, /* LATIN_CAPITAL_LETTER_S_WITH_CARON */
- { { GDK_Multi_key, GDK_less, GDK_Z, 0 }, 0x017D }, /* LATIN_CAPITAL_LETTER_Z_WITH_CARON */
- { { GDK_Multi_key, GDK_less, GDK_c, 0 }, 0x010D }, /* LATIN_SMALL_LETTER_C_WITH_CARON */
- { { GDK_Multi_key, GDK_less, GDK_s, 0 }, 0x0161 }, /* LATIN_SMALL_LETTER_S_WITH_CARON */
- { { GDK_Multi_key, GDK_less, GDK_z, 0 }, 0x017E }, /* LATIN_SMALL_LETTER_Z_WITH_CARON */
- { { GDK_Multi_key, GDK_equal, GDK_C, 0 }, 0x20AC }, /* EURO_SIGN */
- { { GDK_Multi_key, GDK_equal, GDK_L, 0 }, 0x00A3 }, /* POUND_SIGN */
- { { GDK_Multi_key, GDK_equal, GDK_Y, 0 }, 0x00A5 }, /* YEN_SIGN */
- { { GDK_Multi_key, GDK_equal, GDK_e, 0 }, 0x20AC }, /* EURO_SIGN */
- { { GDK_Multi_key, GDK_equal, GDK_l, 0 }, 0x00A3 }, /* POUND_SIGN */
- { { GDK_Multi_key, GDK_equal, GDK_y, 0 }, 0x00A5 }, /* YEN_SIGN */
- { { GDK_Multi_key, GDK_greater, GDK_space, 0 }, 0x005E }, /* CIRCUMFLEX_ACCENT */
- { { GDK_Multi_key, GDK_greater, GDK_greater, 0 }, 0x00BB }, /* RIGHTxPOINTING_DOUBLE_ANGLE_QUOTATION_MARK */
- { { GDK_Multi_key, GDK_greater, GDK_A, 0 }, 0x00C2 }, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_E, 0 }, 0x00CA }, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_I, 0 }, 0x00CE }, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_O, 0 }, 0x00D4 }, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_U, 0 }, 0x00DB }, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_a, 0 }, 0x00E2 }, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_e, 0 }, 0x00EA }, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_i, 0 }, 0x00EE }, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_o, 0 }, 0x00F4 }, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_greater, GDK_u, 0 }, 0x00FB }, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_question, GDK_question, 0 }, 0x00BF }, /* INVERTED_QUESTION_MARK */
- { { GDK_Multi_key, GDK_A, GDK_quotedbl, 0 }, 0x00C4 }, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_A, GDK_apostrophe, 0 }, 0x00C1 }, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
- { { GDK_Multi_key, GDK_A, GDK_asterisk, 0 }, 0x00C5 }, /* LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */
- { { GDK_Multi_key, GDK_A, GDK_comma, 0 }, 0x0104 }, /* LATIN_CAPITAL_LETTER_A_WITH_OGONEK */
- { { GDK_Multi_key, GDK_A, GDK_minus, 0 }, 0x00C3 }, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
- { { GDK_Multi_key, GDK_A, GDK_greater, 0 }, 0x00C2 }, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_A, GDK_A, 0 }, 0x00C5 }, /* LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */
- { { GDK_Multi_key, GDK_A, GDK_E, 0 }, 0x00C6 }, /* LATIN_CAPITAL_LETTER_AE */
- { { GDK_Multi_key, GDK_A, GDK_asciicircum, 0 }, 0x00C2 }, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_A, GDK_underscore, 0 }, 0x00AA }, /* FEMININE_ORDINAL_INDICATOR */
- { { GDK_Multi_key, GDK_A, GDK_grave, 0 }, 0x00C0 }, /* LATIN_CAPITAL_LETTER_A_WITH_GRAVE */
- { { GDK_Multi_key, GDK_A, GDK_asciitilde, 0 }, 0x00C3 }, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
- { { GDK_Multi_key, GDK_A, GDK_diaeresis, 0 }, 0x00C4 }, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_A, GDK_acute, 0 }, 0x00C1 }, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
- { { GDK_Multi_key, GDK_B, GDK_period, 0 }, 0x1E02 }, /* LATIN_CAPITAL_LETTER_B_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_C, GDK_comma, 0 }, 0x00C7 }, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_C, GDK_period, 0 }, 0x010A }, /* LATIN_CAPITAL_LETTER_C_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_C, GDK_slash, 0 }, 0x00A2 }, /* CENT_SIGN */
- { { GDK_Multi_key, GDK_C, GDK_0, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_C, GDK_less, 0 }, 0x010C }, /* LATIN_CAPITAL_LETTER_C_WITH_CARON */
- { { GDK_Multi_key, GDK_C, GDK_equal, 0 }, 0x20AC }, /* EURO_SIGN */
- { { GDK_Multi_key, GDK_C, GDK_O, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_C, GDK_o, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_C, GDK_bar, 0 }, 0x00A2 }, /* CENT_SIGN */
- { { GDK_Multi_key, GDK_D, GDK_minus, 0 }, 0x0110 }, /* LATIN_CAPITAL_LETTER_D_WITH_STROKE */
- { { GDK_Multi_key, GDK_D, GDK_period, 0 }, 0x1E0A }, /* LATIN_CAPITAL_LETTER_D_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_E, GDK_quotedbl, 0 }, 0x00CB }, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_E, GDK_apostrophe, 0 }, 0x00C9 }, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
- { { GDK_Multi_key, GDK_E, GDK_comma, 0 }, 0x0118 }, /* LATIN_CAPITAL_LETTER_E_WITH_OGONEK */
- { { GDK_Multi_key, GDK_E, GDK_minus, 0 }, 0x0112 }, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
- { { GDK_Multi_key, GDK_E, GDK_period, 0 }, 0x0116 }, /* LATIN_CAPITAL_LETTER_E_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_E, GDK_greater, 0 }, 0x00CA }, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_E, GDK_asciicircum, 0 }, 0x00CA }, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_E, GDK_underscore, 0 }, 0x0112 }, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
- { { GDK_Multi_key, GDK_E, GDK_grave, 0 }, 0x00C8 }, /* LATIN_CAPITAL_LETTER_E_WITH_GRAVE */
- { { GDK_Multi_key, GDK_E, GDK_diaeresis, 0 }, 0x00CB }, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_E, GDK_acute, 0 }, 0x00C9 }, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
- { { GDK_Multi_key, GDK_F, GDK_period, 0 }, 0x1E1E }, /* LATIN_CAPITAL_LETTER_F_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_G, GDK_parenleft, 0 }, 0x011E }, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_G, GDK_comma, 0 }, 0x0122 }, /* LATIN_CAPITAL_LETTER_G_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_G, GDK_period, 0 }, 0x0120 }, /* LATIN_CAPITAL_LETTER_G_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_G, GDK_U, 0 }, 0x011E }, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_G, GDK_breve, 0 }, 0x011E }, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_I, GDK_quotedbl, 0 }, 0x00CF }, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_I, GDK_apostrophe, 0 }, 0x00CD }, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
- { { GDK_Multi_key, GDK_I, GDK_comma, 0 }, 0x012E }, /* LATIN_CAPITAL_LETTER_I_WITH_OGONEK */
- { { GDK_Multi_key, GDK_I, GDK_minus, 0 }, 0x012A }, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
- { { GDK_Multi_key, GDK_I, GDK_period, 0 }, 0x0130 }, /* LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_I, GDK_greater, 0 }, 0x00CE }, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_I, GDK_asciicircum, 0 }, 0x00CE }, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_I, GDK_underscore, 0 }, 0x012A }, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
- { { GDK_Multi_key, GDK_I, GDK_grave, 0 }, 0x00CC }, /* LATIN_CAPITAL_LETTER_I_WITH_GRAVE */
- { { GDK_Multi_key, GDK_I, GDK_asciitilde, 0 }, 0x0128 }, /* LATIN_CAPITAL_LETTER_I_WITH_TILDE */
- { { GDK_Multi_key, GDK_I, GDK_diaeresis, 0 }, 0x00CF }, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_I, GDK_acute, 0 }, 0x00CD }, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
- { { GDK_Multi_key, GDK_K, GDK_comma, 0 }, 0x0136 }, /* LATIN_CAPITAL_LETTER_K_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_L, GDK_comma, 0 }, 0x013B }, /* LATIN_CAPITAL_LETTER_L_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_L, GDK_minus, 0 }, 0x00A3 }, /* POUND_SIGN */
- { { GDK_Multi_key, GDK_L, GDK_equal, 0 }, 0x00A3 }, /* POUND_SIGN */
- { { GDK_Multi_key, GDK_L, GDK_V, 0 }, 0x007C }, /* VERTICAL_LINE */
- { { GDK_Multi_key, GDK_M, GDK_period, 0 }, 0x1E40 }, /* LATIN_CAPITAL_LETTER_M_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_N, GDK_comma, 0 }, 0x0145 }, /* LATIN_CAPITAL_LETTER_N_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_N, GDK_minus, 0 }, 0x00D1 }, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
- { { GDK_Multi_key, GDK_N, GDK_G, 0 }, 0x014A }, /* LATIN_CAPITAL_LETTER_ENG */
- { { GDK_Multi_key, GDK_N, GDK_asciitilde, 0 }, 0x00D1 }, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
- { { GDK_Multi_key, GDK_O, GDK_quotedbl, 0 }, 0x00D6 }, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_O, GDK_apostrophe, 0 }, 0x00D3 }, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
- { { GDK_Multi_key, GDK_O, GDK_minus, 0 }, 0x00D5 }, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
- { { GDK_Multi_key, GDK_O, GDK_slash, 0 }, 0x00D8 }, /* LATIN_CAPITAL_LETTER_O_WITH_STROKE */
- { { GDK_Multi_key, GDK_O, GDK_greater, 0 }, 0x00D4 }, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_O, GDK_C, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_O, GDK_E, 0 }, 0x0152 }, /* LATIN_CAPITAL_LIGATURE_OE */
- { { GDK_Multi_key, GDK_O, GDK_R, 0 }, 0x00AE }, /* REGISTERED_SIGN */
- { { GDK_Multi_key, GDK_O, GDK_S, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_O, GDK_X, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_O, GDK_asciicircum, 0 }, 0x00D4 }, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_O, GDK_underscore, 0 }, 0x00BA }, /* MASCULINE_ORDINAL_INDICATOR */
- { { GDK_Multi_key, GDK_O, GDK_grave, 0 }, 0x00D2 }, /* LATIN_CAPITAL_LETTER_O_WITH_GRAVE */
- { { GDK_Multi_key, GDK_O, GDK_c, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_O, GDK_x, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_O, GDK_asciitilde, 0 }, 0x00D5 }, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
- { { GDK_Multi_key, GDK_O, GDK_diaeresis, 0 }, 0x00D6 }, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_O, GDK_acute, 0 }, 0x00D3 }, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
- { { GDK_Multi_key, GDK_P, GDK_exclam, 0 }, 0x00B6 }, /* PILCROW_SIGN */
- { { GDK_Multi_key, GDK_P, GDK_period, 0 }, 0x1E56 }, /* LATIN_CAPITAL_LETTER_P_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_R, GDK_comma, 0 }, 0x0156 }, /* LATIN_CAPITAL_LETTER_R_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_R, GDK_O, 0 }, 0x00AE }, /* REGISTERED_SIGN */
- { { GDK_Multi_key, GDK_S, GDK_exclam, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_S, GDK_comma, 0 }, 0x015E }, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_S, GDK_period, 0 }, 0x1E60 }, /* LATIN_CAPITAL_LETTER_S_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_S, GDK_0, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_S, GDK_1, 0 }, 0x00B9 }, /* SUPERSCRIPT_ONE */
- { { GDK_Multi_key, GDK_S, GDK_2, 0 }, 0x00B2 }, /* SUPERSCRIPT_TWO */
- { { GDK_Multi_key, GDK_S, GDK_3, 0 }, 0x00B3 }, /* SUPERSCRIPT_THREE */
- { { GDK_Multi_key, GDK_S, GDK_less, 0 }, 0x0160 }, /* LATIN_CAPITAL_LETTER_S_WITH_CARON */
- { { GDK_Multi_key, GDK_S, GDK_O, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_S, GDK_cedilla, 0 }, 0x015E }, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_T, GDK_minus, 0 }, 0x0166 }, /* LATIN_CAPITAL_LETTER_T_WITH_STROKE */
- { { GDK_Multi_key, GDK_T, GDK_period, 0 }, 0x1E6A }, /* LATIN_CAPITAL_LETTER_T_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_T, GDK_slash, 0 }, 0x0166 }, /* LATIN_CAPITAL_LETTER_T_WITH_STROKE */
- { { GDK_Multi_key, GDK_T, GDK_H, 0 }, 0x00DE }, /* LATIN_CAPITAL_LETTER_THORN */
- { { GDK_Multi_key, GDK_U, GDK_quotedbl, 0 }, 0x00DC }, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_U, GDK_apostrophe, 0 }, 0x00DA }, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
- { { GDK_Multi_key, GDK_U, GDK_comma, 0 }, 0x0172 }, /* LATIN_CAPITAL_LETTER_U_WITH_OGONEK */
- { { GDK_Multi_key, GDK_U, GDK_minus, 0 }, 0x00D9 }, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
- { { GDK_Multi_key, GDK_U, GDK_slash, 0 }, 0x00B5 }, /* MICRO_SIGN */
- { { GDK_Multi_key, GDK_U, GDK_greater, 0 }, 0x00DB }, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_U, GDK_asciicircum, 0 }, 0x00DB }, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_U, GDK_underscore, 0 }, 0x00D9 }, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
- { { GDK_Multi_key, GDK_U, GDK_grave, 0 }, 0x00D9 }, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
- { { GDK_Multi_key, GDK_U, GDK_asciitilde, 0 }, 0x0168 }, /* LATIN_CAPITAL_LETTER_U_WITH_TILDE */
- { { GDK_Multi_key, GDK_U, GDK_diaeresis, 0 }, 0x00DC }, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_U, GDK_acute, 0 }, 0x00DA }, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
- { { GDK_Multi_key, GDK_V, GDK_L, 0 }, 0x007C }, /* VERTICAL_LINE */
- { { GDK_Multi_key, GDK_W, GDK_asciicircum, 0 }, 0x0174 }, /* LATIN_CAPITAL_LETTER_W_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_X, GDK_0, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_X, GDK_O, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_X, GDK_o, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_Y, GDK_quotedbl, 0 }, 0x0178 }, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_Y, GDK_apostrophe, 0 }, 0x00DD }, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
- { { GDK_Multi_key, GDK_Y, GDK_minus, 0 }, 0x00A5 }, /* YEN_SIGN */
- { { GDK_Multi_key, GDK_Y, GDK_equal, 0 }, 0x00A5 }, /* YEN_SIGN */
- { { GDK_Multi_key, GDK_Y, GDK_asciicircum, 0 }, 0x0176 }, /* LATIN_CAPITAL_LETTER_Y_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_Y, GDK_diaeresis, 0 }, 0x0178 }, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_Y, GDK_acute, 0 }, 0x00DD }, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
- { { GDK_Multi_key, GDK_Z, GDK_less, 0 }, 0x017D }, /* LATIN_CAPITAL_LETTER_Z_WITH_CARON */
- { { GDK_Multi_key, GDK_asciicircum, GDK_space, 0 }, 0x005E }, /* CIRCUMFLEX_ACCENT */
- { { GDK_Multi_key, GDK_asciicircum, GDK_minus, 0 }, 0x00AF }, /* MACRON */
- { { GDK_Multi_key, GDK_asciicircum, GDK_period, 0 }, 0x00B7 }, /* MIDDLE_DOT */
- { { GDK_Multi_key, GDK_asciicircum, GDK_slash, 0 }, 0x007C }, /* VERTICAL_LINE */
- { { GDK_Multi_key, GDK_asciicircum, GDK_0, 0 }, 0x00B0 }, /* DEGREE_SIGN */
- { { GDK_Multi_key, GDK_asciicircum, GDK_1, 0 }, 0x00B9 }, /* SUPERSCRIPT_ONE */
- { { GDK_Multi_key, GDK_asciicircum, GDK_2, 0 }, 0x00B2 }, /* SUPERSCRIPT_TWO */
- { { GDK_Multi_key, GDK_asciicircum, GDK_3, 0 }, 0x00B3 }, /* SUPERSCRIPT_THREE */
- { { GDK_Multi_key, GDK_asciicircum, GDK_A, 0 }, 0x00C2 }, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_E, 0 }, 0x00CA }, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_I, 0 }, 0x00CE }, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_O, 0 }, 0x00D4 }, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_U, 0 }, 0x00DB }, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_W, 0 }, 0x0174 }, /* LATIN_CAPITAL_LETTER_W_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_Y, 0 }, 0x0176 }, /* LATIN_CAPITAL_LETTER_Y_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_underscore, 0 }, 0x00AF }, /* MACRON */
- { { GDK_Multi_key, GDK_asciicircum, GDK_a, 0 }, 0x00E2 }, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_e, 0 }, 0x00EA }, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_i, 0 }, 0x00EE }, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_o, 0 }, 0x00F4 }, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_u, 0 }, 0x00FB }, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_w, 0 }, 0x0175 }, /* LATIN_SMALL_LETTER_W_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_asciicircum, GDK_y, 0 }, 0x0177 }, /* LATIN_SMALL_LETTER_Y_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_underscore, GDK_A, 0 }, 0x00AA }, /* FEMININE_ORDINAL_INDICATOR */
- { { GDK_Multi_key, GDK_underscore, GDK_E, 0 }, 0x0112 }, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
- { { GDK_Multi_key, GDK_underscore, GDK_I, 0 }, 0x012A }, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
- { { GDK_Multi_key, GDK_underscore, GDK_O, 0 }, 0x00BA }, /* MASCULINE_ORDINAL_INDICATOR */
- { { GDK_Multi_key, GDK_underscore, GDK_U, 0 }, 0x00D9 }, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
- { { GDK_Multi_key, GDK_underscore, GDK_asciicircum, 0 }, 0x00AF }, /* MACRON */
- { { GDK_Multi_key, GDK_underscore, GDK_underscore, 0 }, 0x00AF }, /* MACRON */
- { { GDK_Multi_key, GDK_underscore, GDK_a, 0 }, 0x00AA }, /* FEMININE_ORDINAL_INDICATOR */
- { { GDK_Multi_key, GDK_underscore, GDK_e, 0 }, 0x0113 }, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
- { { GDK_Multi_key, GDK_underscore, GDK_i, 0 }, 0x012B }, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
- { { GDK_Multi_key, GDK_underscore, GDK_o, 0 }, 0x00BA }, /* MASCULINE_ORDINAL_INDICATOR */
- { { GDK_Multi_key, GDK_underscore, GDK_u, 0 }, 0x016B }, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
- { { GDK_Multi_key, GDK_grave, GDK_space, 0 }, 0x0060 }, /* GRAVE_ACCENT */
- { { GDK_Multi_key, GDK_grave, GDK_A, 0 }, 0x00C0 }, /* LATIN_CAPITAL_LETTER_A_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_E, 0 }, 0x00C8 }, /* LATIN_CAPITAL_LETTER_E_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_I, 0 }, 0x00CC }, /* LATIN_CAPITAL_LETTER_I_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_O, 0 }, 0x00D2 }, /* LATIN_CAPITAL_LETTER_O_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_U, 0 }, 0x00D9 }, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_a, 0 }, 0x00E0 }, /* LATIN_SMALL_LETTER_A_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_e, 0 }, 0x00E8 }, /* LATIN_SMALL_LETTER_E_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_i, 0 }, 0x00EC }, /* LATIN_SMALL_LETTER_I_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_o, 0 }, 0x00F2 }, /* LATIN_SMALL_LETTER_O_WITH_GRAVE */
- { { GDK_Multi_key, GDK_grave, GDK_u, 0 }, 0x00F9 }, /* LATIN_SMALL_LETTER_U_WITH_GRAVE */
- { { GDK_Multi_key, GDK_a, GDK_quotedbl, 0 }, 0x00E4 }, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_a, GDK_apostrophe, 0 }, 0x00E1 }, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
- { { GDK_Multi_key, GDK_a, GDK_asterisk, 0 }, 0x00E5 }, /* LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */
- { { GDK_Multi_key, GDK_a, GDK_comma, 0 }, 0x0105 }, /* LATIN_SMALL_LETTER_A_WITH_OGONEK */
- { { GDK_Multi_key, GDK_a, GDK_minus, 0 }, 0x00E3 }, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
- { { GDK_Multi_key, GDK_a, GDK_greater, 0 }, 0x00E2 }, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_a, GDK_asciicircum, 0 }, 0x00E2 }, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_a, GDK_underscore, 0 }, 0x00AA }, /* FEMININE_ORDINAL_INDICATOR */
- { { GDK_Multi_key, GDK_a, GDK_grave, 0 }, 0x00E0 }, /* LATIN_SMALL_LETTER_A_WITH_GRAVE */
- { { GDK_Multi_key, GDK_a, GDK_a, 0 }, 0x00E5 }, /* LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */
- { { GDK_Multi_key, GDK_a, GDK_e, 0 }, 0x00E6 }, /* LATIN_SMALL_LETTER_AE */
- { { GDK_Multi_key, GDK_a, GDK_asciitilde, 0 }, 0x00E3 }, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
- { { GDK_Multi_key, GDK_a, GDK_diaeresis, 0 }, 0x00E4 }, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_a, GDK_acute, 0 }, 0x00E1 }, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
- { { GDK_Multi_key, GDK_b, GDK_period, 0 }, 0x1E03 }, /* LATIN_SMALL_LETTER_B_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_c, GDK_comma, 0 }, 0x00E7 }, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_c, GDK_period, 0 }, 0x010B }, /* LATIN_SMALL_LETTER_C_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_c, GDK_slash, 0 }, 0x00A2 }, /* CENT_SIGN */
- { { GDK_Multi_key, GDK_c, GDK_0, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_c, GDK_less, 0 }, 0x010D }, /* LATIN_SMALL_LETTER_C_WITH_CARON */
- { { GDK_Multi_key, GDK_c, GDK_O, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_c, GDK_o, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_c, GDK_bar, 0 }, 0x00A2 }, /* CENT_SIGN */
- { { GDK_Multi_key, GDK_d, GDK_minus, 0 }, 0x0111 }, /* LATIN_SMALL_LETTER_D_WITH_STROKE */
- { { GDK_Multi_key, GDK_d, GDK_period, 0 }, 0x1E0B }, /* LATIN_SMALL_LETTER_D_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_e, GDK_quotedbl, 0 }, 0x00EB }, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_e, GDK_apostrophe, 0 }, 0x00E9 }, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
- { { GDK_Multi_key, GDK_e, GDK_comma, 0 }, 0x0119 }, /* LATIN_SMALL_LETTER_E_WITH_OGONEK */
- { { GDK_Multi_key, GDK_e, GDK_minus, 0 }, 0x0113 }, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
- { { GDK_Multi_key, GDK_e, GDK_period, 0 }, 0x0117 }, /* LATIN_SMALL_LETTER_E_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_e, GDK_equal, 0 }, 0x20AC }, /* EURO_SIGN */
- { { GDK_Multi_key, GDK_e, GDK_greater, 0 }, 0x00EA }, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_e, GDK_asciicircum, 0 }, 0x00EA }, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_e, GDK_underscore, 0 }, 0x0113 }, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
- { { GDK_Multi_key, GDK_e, GDK_grave, 0 }, 0x00E8 }, /* LATIN_SMALL_LETTER_E_WITH_GRAVE */
- { { GDK_Multi_key, GDK_e, GDK_diaeresis, 0 }, 0x00EB }, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_e, GDK_acute, 0 }, 0x00E9 }, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
- { { GDK_Multi_key, GDK_f, GDK_period, 0 }, 0x1E1F }, /* LATIN_SMALL_LETTER_F_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_g, GDK_parenleft, 0 }, 0x011F }, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_g, GDK_comma, 0 }, 0x0123 }, /* LATIN_SMALL_LETTER_G_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_g, GDK_period, 0 }, 0x0121 }, /* LATIN_SMALL_LETTER_G_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_g, GDK_U, 0 }, 0x011F }, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_g, GDK_breve, 0 }, 0x011F }, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_i, GDK_quotedbl, 0 }, 0x00EF }, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_i, GDK_apostrophe, 0 }, 0x00ED }, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
- { { GDK_Multi_key, GDK_i, GDK_comma, 0 }, 0x012F }, /* LATIN_SMALL_LETTER_I_WITH_OGONEK */
- { { GDK_Multi_key, GDK_i, GDK_minus, 0 }, 0x012B }, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
- { { GDK_Multi_key, GDK_i, GDK_period, 0 }, 0x0131 }, /* LATIN_SMALL_LETTER_DOTLESS_I */
- { { GDK_Multi_key, GDK_i, GDK_greater, 0 }, 0x00EE }, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_i, GDK_asciicircum, 0 }, 0x00EE }, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_i, GDK_underscore, 0 }, 0x012B }, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
- { { GDK_Multi_key, GDK_i, GDK_grave, 0 }, 0x00EC }, /* LATIN_SMALL_LETTER_I_WITH_GRAVE */
- { { GDK_Multi_key, GDK_i, GDK_asciitilde, 0 }, 0x0129 }, /* LATIN_SMALL_LETTER_I_WITH_TILDE */
- { { GDK_Multi_key, GDK_i, GDK_diaeresis, 0 }, 0x00EF }, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_i, GDK_acute, 0 }, 0x00ED }, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
- { { GDK_Multi_key, GDK_k, GDK_comma, 0 }, 0x0137 }, /* LATIN_SMALL_LETTER_K_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_k, GDK_k, 0 }, 0x0138 }, /* LATIN_SMALL_LETTER_KRA */
- { { GDK_Multi_key, GDK_l, GDK_comma, 0 }, 0x013C }, /* LATIN_SMALL_LETTER_L_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_l, GDK_minus, 0 }, 0x00A3 }, /* POUND_SIGN */
- { { GDK_Multi_key, GDK_l, GDK_equal, 0 }, 0x00A3 }, /* POUND_SIGN */
- { { GDK_Multi_key, GDK_l, GDK_v, 0 }, 0x007C }, /* VERTICAL_LINE */
- { { GDK_Multi_key, GDK_m, GDK_period, 0 }, 0x1E41 }, /* LATIN_SMALL_LETTER_M_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_n, GDK_comma, 0 }, 0x0146 }, /* LATIN_SMALL_LETTER_N_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_n, GDK_minus, 0 }, 0x00F1 }, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
- { { GDK_Multi_key, GDK_n, GDK_g, 0 }, 0x014B }, /* LATIN_SMALL_LETTER_ENG */
- { { GDK_Multi_key, GDK_n, GDK_asciitilde, 0 }, 0x00F1 }, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
- { { GDK_Multi_key, GDK_o, GDK_quotedbl, 0 }, 0x00F6 }, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_o, GDK_apostrophe, 0 }, 0x00F3 }, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
- { { GDK_Multi_key, GDK_o, GDK_minus, 0 }, 0x00F5 }, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
- { { GDK_Multi_key, GDK_o, GDK_slash, 0 }, 0x00F8 }, /* LATIN_SMALL_LETTER_O_WITH_STROKE */
- { { GDK_Multi_key, GDK_o, GDK_greater, 0 }, 0x00F4 }, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_o, GDK_C, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_o, GDK_X, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_o, GDK_asciicircum, 0 }, 0x00F4 }, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_o, GDK_underscore, 0 }, 0x00BA }, /* MASCULINE_ORDINAL_INDICATOR */
- { { GDK_Multi_key, GDK_o, GDK_grave, 0 }, 0x00F2 }, /* LATIN_SMALL_LETTER_O_WITH_GRAVE */
- { { GDK_Multi_key, GDK_o, GDK_c, 0 }, 0x00A9 }, /* COPYRIGHT_SIGN */
- { { GDK_Multi_key, GDK_o, GDK_e, 0 }, 0x0153 }, /* LATIN_SMALL_LIGATURE_OE */
- { { GDK_Multi_key, GDK_o, GDK_s, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_o, GDK_x, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_o, GDK_asciitilde, 0 }, 0x00F5 }, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
- { { GDK_Multi_key, GDK_o, GDK_diaeresis, 0 }, 0x00F6 }, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_o, GDK_acute, 0 }, 0x00F3 }, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
- { { GDK_Multi_key, GDK_p, GDK_exclam, 0 }, 0x00B6 }, /* PILCROW_SIGN */
- { { GDK_Multi_key, GDK_p, GDK_period, 0 }, 0x1E57 }, /* LATIN_SMALL_LETTER_P_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_r, GDK_comma, 0 }, 0x0157 }, /* LATIN_SMALL_LETTER_R_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_s, GDK_exclam, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_s, GDK_comma, 0 }, 0x015F }, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_s, GDK_period, 0 }, 0x1E61 }, /* LATIN_SMALL_LETTER_S_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_s, GDK_0, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_s, GDK_1, 0 }, 0x00B9 }, /* SUPERSCRIPT_ONE */
- { { GDK_Multi_key, GDK_s, GDK_2, 0 }, 0x00B2 }, /* SUPERSCRIPT_TWO */
- { { GDK_Multi_key, GDK_s, GDK_3, 0 }, 0x00B3 }, /* SUPERSCRIPT_THREE */
- { { GDK_Multi_key, GDK_s, GDK_less, 0 }, 0x0161 }, /* LATIN_SMALL_LETTER_S_WITH_CARON */
- { { GDK_Multi_key, GDK_s, GDK_o, 0 }, 0x00A7 }, /* SECTION_SIGN */
- { { GDK_Multi_key, GDK_s, GDK_s, 0 }, 0x00DF }, /* LATIN_SMALL_LETTER_SHARP_S */
- { { GDK_Multi_key, GDK_s, GDK_cedilla, 0 }, 0x015F }, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_t, GDK_minus, 0 }, 0x0167 }, /* LATIN_SMALL_LETTER_T_WITH_STROKE */
- { { GDK_Multi_key, GDK_t, GDK_period, 0 }, 0x1E6B }, /* LATIN_SMALL_LETTER_T_WITH_DOT_ABOVE */
- { { GDK_Multi_key, GDK_t, GDK_slash, 0 }, 0x0167 }, /* LATIN_SMALL_LETTER_T_WITH_STROKE */
- { { GDK_Multi_key, GDK_t, GDK_h, 0 }, 0x00FE }, /* LATIN_SMALL_LETTER_THORN */
- { { GDK_Multi_key, GDK_u, GDK_quotedbl, 0 }, 0x00FC }, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_u, GDK_apostrophe, 0 }, 0x00FA }, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
- { { GDK_Multi_key, GDK_u, GDK_comma, 0 }, 0x0173 }, /* LATIN_SMALL_LETTER_U_WITH_OGONEK */
- { { GDK_Multi_key, GDK_u, GDK_minus, 0 }, 0x016B }, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
- { { GDK_Multi_key, GDK_u, GDK_slash, 0 }, 0x00B5 }, /* MICRO_SIGN */
- { { GDK_Multi_key, GDK_u, GDK_greater, 0 }, 0x00FB }, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_u, GDK_asciicircum, 0 }, 0x00FB }, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_u, GDK_underscore, 0 }, 0x016B }, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
- { { GDK_Multi_key, GDK_u, GDK_grave, 0 }, 0x00F9 }, /* LATIN_SMALL_LETTER_U_WITH_GRAVE */
- { { GDK_Multi_key, GDK_u, GDK_asciitilde, 0 }, 0x0169 }, /* LATIN_SMALL_LETTER_U_WITH_TILDE */
- { { GDK_Multi_key, GDK_u, GDK_diaeresis, 0 }, 0x00FC }, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_u, GDK_acute, 0 }, 0x00FA }, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
- { { GDK_Multi_key, GDK_v, GDK_Z, 0 }, 0x017D }, /* LATIN_CAPITAL_LETTER_Z_WITH_CARON */
- { { GDK_Multi_key, GDK_v, GDK_l, 0 }, 0x007C }, /* VERTICAL_LINE */
- { { GDK_Multi_key, GDK_v, GDK_z, 0 }, 0x017E }, /* LATIN_SMALL_LETTER_Z_WITH_CARON */
- { { GDK_Multi_key, GDK_w, GDK_asciicircum, 0 }, 0x0175 }, /* LATIN_SMALL_LETTER_W_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_x, GDK_0, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_x, GDK_O, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_x, GDK_o, 0 }, 0x00A4 }, /* CURRENCY_SIGN */
- { { GDK_Multi_key, GDK_x, GDK_x, 0 }, 0x00D7 }, /* MULTIPLICATION_SIGN */
- { { GDK_Multi_key, GDK_y, GDK_quotedbl, 0 }, 0x00FF }, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_y, GDK_apostrophe, 0 }, 0x00FD }, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
- { { GDK_Multi_key, GDK_y, GDK_minus, 0 }, 0x00A5 }, /* YEN_SIGN */
- { { GDK_Multi_key, GDK_y, GDK_equal, 0 }, 0x00A5 }, /* YEN_SIGN */
- { { GDK_Multi_key, GDK_y, GDK_asciicircum, 0 }, 0x0177 }, /* LATIN_SMALL_LETTER_Y_WITH_CIRCUMFLEX */
- { { GDK_Multi_key, GDK_y, GDK_diaeresis, 0 }, 0x00FF }, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_y, GDK_acute, 0 }, 0x00FD }, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
- { { GDK_Multi_key, GDK_z, GDK_less, 0 }, 0x017E }, /* LATIN_SMALL_LETTER_Z_WITH_CARON */
- { { GDK_Multi_key, GDK_bar, GDK_C, 0 }, 0x00A2 }, /* CENT_SIGN */
- { { GDK_Multi_key, GDK_bar, GDK_c, 0 }, 0x00A2 }, /* CENT_SIGN */
- { { GDK_Multi_key, GDK_asciitilde, GDK_space, 0 }, 0x007E }, /* TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_A, 0 }, 0x00C3 }, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_I, 0 }, 0x0128 }, /* LATIN_CAPITAL_LETTER_I_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_N, 0 }, 0x00D1 }, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_O, 0 }, 0x00D5 }, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_U, 0 }, 0x0168 }, /* LATIN_CAPITAL_LETTER_U_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_a, 0 }, 0x00E3 }, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_i, 0 }, 0x0129 }, /* LATIN_SMALL_LETTER_I_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_n, 0 }, 0x00F1 }, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_o, 0 }, 0x00F5 }, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
- { { GDK_Multi_key, GDK_asciitilde, GDK_u, 0 }, 0x0169 }, /* LATIN_SMALL_LETTER_U_WITH_TILDE */
- { { GDK_Multi_key, GDK_diaeresis, GDK_A, 0 }, 0x00C4 }, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_E, 0 }, 0x00CB }, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_I, 0 }, 0x00CF }, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_O, 0 }, 0x00D6 }, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_U, 0 }, 0x00DC }, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_Y, 0 }, 0x0178 }, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_a, 0 }, 0x00E4 }, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_e, 0 }, 0x00EB }, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_i, 0 }, 0x00EF }, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_o, 0 }, 0x00F6 }, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_u, 0 }, 0x00FC }, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_diaeresis, GDK_y, 0 }, 0x00FF }, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
- { { GDK_Multi_key, GDK_acute, GDK_A, 0 }, 0x00C1 }, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_E, 0 }, 0x00C9 }, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_I, 0 }, 0x00CD }, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_O, 0 }, 0x00D3 }, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_U, 0 }, 0x00DA }, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_Y, 0 }, 0x00DD }, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_a, 0 }, 0x00E1 }, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_e, 0 }, 0x00E9 }, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_i, 0 }, 0x00ED }, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_o, 0 }, 0x00F3 }, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_u, 0 }, 0x00FA }, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
- { { GDK_Multi_key, GDK_acute, GDK_y, 0 }, 0x00FD }, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
- { { GDK_Multi_key, GDK_cedilla, GDK_S, 0 }, 0x015E }, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_cedilla, GDK_s, 0 }, 0x015F }, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
- { { GDK_Multi_key, GDK_breve, GDK_G, 0 }, 0x011E }, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
- { { GDK_Multi_key, GDK_breve, GDK_g, 0 }, 0x011F }, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
+static guint16 gtk_compose_seqs[] = {
+ GDK_dead_grave, GDK_space, 0, 0, 0, 0x0060, /* GRAVE_ACCENT */
+ GDK_dead_grave, GDK_A, 0, 0, 0, 0x00C0, /* LATIN_CAPITAL_LETTER_A_WITH_GRAVE */
+ GDK_dead_grave, GDK_E, 0, 0, 0, 0x00C8, /* LATIN_CAPITAL_LETTER_E_WITH_GRAVE */
+ GDK_dead_grave, GDK_I, 0, 0, 0, 0x00CC, /* LATIN_CAPITAL_LETTER_I_WITH_GRAVE */
+ GDK_dead_grave, GDK_O, 0, 0, 0, 0x00D2, /* LATIN_CAPITAL_LETTER_O_WITH_GRAVE */
+ GDK_dead_grave, GDK_U, 0, 0, 0, 0x00D9, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
+ GDK_dead_grave, GDK_a, 0, 0, 0, 0x00E0, /* LATIN_SMALL_LETTER_A_WITH_GRAVE */
+ GDK_dead_grave, GDK_e, 0, 0, 0, 0x00E8, /* LATIN_SMALL_LETTER_E_WITH_GRAVE */
+ GDK_dead_grave, GDK_i, 0, 0, 0, 0x00EC, /* LATIN_SMALL_LETTER_I_WITH_GRAVE */
+ GDK_dead_grave, GDK_o, 0, 0, 0, 0x00F2, /* LATIN_SMALL_LETTER_O_WITH_GRAVE */
+ GDK_dead_grave, GDK_u, 0, 0, 0, 0x00F9, /* LATIN_SMALL_LETTER_U_WITH_GRAVE */
+ GDK_dead_acute, GDK_space, 0, 0, 0, 0x0027, /* APOSTROPHE */
+ GDK_dead_acute, GDK_apostrophe, 0, 0, 0, 0x00B4, /* ACUTE_ACCENT */
+ GDK_dead_acute, GDK_A, 0, 0, 0, 0x00C1, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
+ GDK_dead_acute, GDK_E, 0, 0, 0, 0x00C9, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
+ GDK_dead_acute, GDK_I, 0, 0, 0, 0x00CD, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
+ GDK_dead_acute, GDK_O, 0, 0, 0, 0x00D3, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
+ GDK_dead_acute, GDK_U, 0, 0, 0, 0x00DA, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
+ GDK_dead_acute, GDK_Y, 0, 0, 0, 0x00DD, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
+ GDK_dead_acute, GDK_a, 0, 0, 0, 0x00E1, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
+ GDK_dead_acute, GDK_e, 0, 0, 0, 0x00E9, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
+ GDK_dead_acute, GDK_i, 0, 0, 0, 0x00ED, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
+ GDK_dead_acute, GDK_o, 0, 0, 0, 0x00F3, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
+ GDK_dead_acute, GDK_u, 0, 0, 0, 0x00FA, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
+ GDK_dead_acute, GDK_y, 0, 0, 0, 0x00FD, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
+ GDK_dead_acute, GDK_acute, 0, 0, 0, 0x00B4, /* ACUTE_ACCENT */
+ GDK_dead_acute, GDK_dead_acute, 0, 0, 0, 0x00B4, /* ACUTE_ACCENT */
+ GDK_dead_circumflex, GDK_space, 0, 0, 0, 0x005E, /* CIRCUMFLEX_ACCENT */
+ GDK_dead_circumflex, GDK_minus, 0, 0, 0, 0x00AF, /* MACRON */
+ GDK_dead_circumflex, GDK_period, 0, 0, 0, 0x00B7, /* MIDDLE_DOT */
+ GDK_dead_circumflex, GDK_slash, 0, 0, 0, 0x007C, /* VERTICAL_LINE */
+ GDK_dead_circumflex, GDK_0, 0, 0, 0, 0x00B0, /* DEGREE_SIGN */
+ GDK_dead_circumflex, GDK_1, 0, 0, 0, 0x00B9, /* SUPERSCRIPT_ONE */
+ GDK_dead_circumflex, GDK_2, 0, 0, 0, 0x00B2, /* SUPERSCRIPT_TWO */
+ GDK_dead_circumflex, GDK_3, 0, 0, 0, 0x00B3, /* SUPERSCRIPT_THREE */
+ GDK_dead_circumflex, GDK_A, 0, 0, 0, 0x00C2, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_E, 0, 0, 0, 0x00CA, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_I, 0, 0, 0, 0x00CE, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_O, 0, 0, 0, 0x00D4, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_U, 0, 0, 0, 0x00DB, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_underscore, 0, 0, 0, 0x00AF, /* MACRON */
+ GDK_dead_circumflex, GDK_a, 0, 0, 0, 0x00E2, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_e, 0, 0, 0, 0x00EA, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_i, 0, 0, 0, 0x00EE, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_o, 0, 0, 0, 0x00F4, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_dead_circumflex, GDK_u, 0, 0, 0, 0x00FB, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_dead_tilde, GDK_space, 0, 0, 0, 0x007E, /* TILDE */
+ GDK_dead_tilde, GDK_A, 0, 0, 0, 0x00C3, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
+ GDK_dead_tilde, GDK_I, 0, 0, 0, 0x0128, /* LATIN_CAPITAL_LETTER_I_WITH_TILDE */
+ GDK_dead_tilde, GDK_N, 0, 0, 0, 0x00D1, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
+ GDK_dead_tilde, GDK_O, 0, 0, 0, 0x00D5, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
+ GDK_dead_tilde, GDK_U, 0, 0, 0, 0x0168, /* LATIN_CAPITAL_LETTER_U_WITH_TILDE */
+ GDK_dead_tilde, GDK_a, 0, 0, 0, 0x00E3, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
+ GDK_dead_tilde, GDK_i, 0, 0, 0, 0x0129, /* LATIN_SMALL_LETTER_I_WITH_TILDE */
+ GDK_dead_tilde, GDK_n, 0, 0, 0, 0x00F1, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
+ GDK_dead_tilde, GDK_o, 0, 0, 0, 0x00F5, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
+ GDK_dead_tilde, GDK_u, 0, 0, 0, 0x0169, /* LATIN_SMALL_LETTER_U_WITH_TILDE */
+ GDK_dead_tilde, GDK_asciitilde, 0, 0, 0, 0x007E, /* TILDE */
+ GDK_dead_tilde, GDK_dead_tilde, 0, 0, 0, 0x007E, /* TILDE */
+ GDK_dead_macron, GDK_A, 0, 0, 0, 0x0100, /* LATIN_CAPITAL_LETTER_A_WITH_MACRON */
+ GDK_dead_macron, GDK_E, 0, 0, 0, 0x0112, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
+ GDK_dead_macron, GDK_I, 0, 0, 0, 0x012A, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
+ GDK_dead_macron, GDK_O, 0, 0, 0, 0x014C, /* LATIN_CAPITAL_LETTER_O_WITH_MACRON */
+ GDK_dead_macron, GDK_U, 0, 0, 0, 0x00D9, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
+ GDK_dead_macron, GDK_a, 0, 0, 0, 0x0101, /* LATIN_SMALL_LETTER_A_WITH_MACRON */
+ GDK_dead_macron, GDK_e, 0, 0, 0, 0x0113, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
+ GDK_dead_macron, GDK_i, 0, 0, 0, 0x012B, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
+ GDK_dead_macron, GDK_o, 0, 0, 0, 0x014D, /* LATIN_SMALL_LETTER_O_WITH_MACRON */
+ GDK_dead_macron, GDK_u, 0, 0, 0, 0x016B, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
+ GDK_dead_macron, GDK_macron, 0, 0, 0, 0x00AF, /* MACRON */
+ GDK_dead_macron, GDK_dead_macron, 0, 0, 0, 0x00AF, /* MACRON */
+ GDK_dead_breve, GDK_G, 0, 0, 0, 0x011E, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
+ GDK_dead_breve, GDK_g, 0, 0, 0, 0x011F, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
+ GDK_dead_abovedot, GDK_E, 0, 0, 0, 0x0116, /* LATIN_CAPITAL_LETTER_E_WITH_DOT_ABOVE */
+ GDK_dead_abovedot, GDK_I, 0, 0, 0, 0x0130, /* LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE */
+ GDK_dead_abovedot, GDK_e, 0, 0, 0, 0x0117, /* LATIN_SMALL_LETTER_E_WITH_DOT_ABOVE */
+ GDK_dead_abovedot, GDK_i, 0, 0, 0, 0x0131, /* LATIN_SMALL_LETTER_DOTLESS_I */
+ GDK_dead_abovedot, GDK_abovedot, 0, 0, 0, 0x02D9, /* DOT_ABOVE */
+ GDK_dead_abovedot, GDK_dead_abovedot, 0, 0, 0, 0x02D9, /* DOT_ABOVE */
+ GDK_dead_diaeresis, GDK_space, 0, 0, 0, 0x00A8, /* DIAERESIS */
+ GDK_dead_diaeresis, GDK_quotedbl, 0, 0, 0, 0x00A8, /* DIAERESIS */
+ GDK_dead_diaeresis, GDK_A, 0, 0, 0, 0x00C4, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_E, 0, 0, 0, 0x00CB, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_I, 0, 0, 0, 0x00CF, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_O, 0, 0, 0, 0x00D6, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_U, 0, 0, 0, 0x00DC, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_Y, 0, 0, 0, 0x0178, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_a, 0, 0, 0, 0x00E4, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_e, 0, 0, 0, 0x00EB, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_i, 0, 0, 0, 0x00EF, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_o, 0, 0, 0, 0x00F6, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_u, 0, 0, 0, 0x00FC, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_y, 0, 0, 0, 0x00FF, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
+ GDK_dead_diaeresis, GDK_diaeresis, 0, 0, 0, 0x00A8, /* DIAERESIS */
+ GDK_dead_diaeresis, GDK_dead_diaeresis, 0, 0, 0, 0x00A8, /* DIAERESIS */
+ GDK_dead_abovering, GDK_A, 0, 0, 0, 0x00C5, /* LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */
+ GDK_dead_abovering, GDK_a, 0, 0, 0, 0x00E5, /* LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */
+ GDK_dead_abovering, GDK_dead_abovering, 0, 0, 0, 0x02DA, /* RING_ABOVE */
+ GDK_dead_caron, GDK_C, 0, 0, 0, 0x010C, /* LATIN_CAPITAL_LETTER_C_WITH_CARON */
+ GDK_dead_caron, GDK_S, 0, 0, 0, 0x0160, /* LATIN_CAPITAL_LETTER_S_WITH_CARON */
+ GDK_dead_caron, GDK_Z, 0, 0, 0, 0x017D, /* LATIN_CAPITAL_LETTER_Z_WITH_CARON */
+ GDK_dead_caron, GDK_c, 0, 0, 0, 0x010D, /* LATIN_SMALL_LETTER_C_WITH_CARON */
+ GDK_dead_caron, GDK_s, 0, 0, 0, 0x0161, /* LATIN_SMALL_LETTER_S_WITH_CARON */
+ GDK_dead_caron, GDK_z, 0, 0, 0, 0x017E, /* LATIN_SMALL_LETTER_Z_WITH_CARON */
+ GDK_dead_caron, GDK_caron, 0, 0, 0, 0x02C7, /* CARON */
+ GDK_dead_caron, GDK_dead_caron, 0, 0, 0, 0x02C7, /* CARON */
+ GDK_dead_cedilla, GDK_comma, 0, 0, 0, 0x00B8, /* CEDILLA */
+ GDK_dead_cedilla, GDK_minus, 0, 0, 0, 0x00AC, /* NOT_SIGN */
+ GDK_dead_cedilla, GDK_C, 0, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_G, 0, 0, 0, 0x0122, /* LATIN_CAPITAL_LETTER_G_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_K, 0, 0, 0, 0x0136, /* LATIN_CAPITAL_LETTER_K_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_L, 0, 0, 0, 0x013B, /* LATIN_CAPITAL_LETTER_L_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_N, 0, 0, 0, 0x0145, /* LATIN_CAPITAL_LETTER_N_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_R, 0, 0, 0, 0x0156, /* LATIN_CAPITAL_LETTER_R_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_S, 0, 0, 0, 0x015E, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_c, 0, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_g, 0, 0, 0, 0x0123, /* LATIN_SMALL_LETTER_G_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_k, 0, 0, 0, 0x0137, /* LATIN_SMALL_LETTER_K_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_l, 0, 0, 0, 0x013C, /* LATIN_SMALL_LETTER_L_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_n, 0, 0, 0, 0x0146, /* LATIN_SMALL_LETTER_N_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_r, 0, 0, 0, 0x0157, /* LATIN_SMALL_LETTER_R_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_s, 0, 0, 0, 0x015F, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
+ GDK_dead_cedilla, GDK_cedilla, 0, 0, 0, 0x00B8, /* CEDILLA */
+ GDK_dead_cedilla, GDK_dead_cedilla, 0, 0, 0, 0x00B8, /* CEDILLA */
+ GDK_dead_ogonek, GDK_A, 0, 0, 0, 0x0104, /* LATIN_CAPITAL_LETTER_A_WITH_OGONEK */
+ GDK_dead_ogonek, GDK_E, 0, 0, 0, 0x0118, /* LATIN_CAPITAL_LETTER_E_WITH_OGONEK */
+ GDK_dead_ogonek, GDK_I, 0, 0, 0, 0x012E, /* LATIN_CAPITAL_LETTER_I_WITH_OGONEK */
+ GDK_dead_ogonek, GDK_U, 0, 0, 0, 0x0172, /* LATIN_CAPITAL_LETTER_U_WITH_OGONEK */
+ GDK_dead_ogonek, GDK_a, 0, 0, 0, 0x0105, /* LATIN_SMALL_LETTER_A_WITH_OGONEK */
+ GDK_dead_ogonek, GDK_e, 0, 0, 0, 0x0119, /* LATIN_SMALL_LETTER_E_WITH_OGONEK */
+ GDK_dead_ogonek, GDK_i, 0, 0, 0, 0x012F, /* LATIN_SMALL_LETTER_I_WITH_OGONEK */
+ GDK_dead_ogonek, GDK_u, 0, 0, 0, 0x0173, /* LATIN_SMALL_LETTER_U_WITH_OGONEK */
+ GDK_dead_ogonek, GDK_ogonek, 0, 0, 0, 0x02DB, /* OGONEK */
+ GDK_dead_ogonek, GDK_dead_ogonek, 0, 0, 0, 0x02DB, /* OGONEK */
+ GDK_Multi_key, GDK_space, GDK_space, 0, 0, 0x00A0, /* NOxBREAK_SPACE */
+ GDK_Multi_key, GDK_space, GDK_apostrophe, 0, 0, 0x0027, /* APOSTROPHE */
+ GDK_Multi_key, GDK_space, GDK_minus, 0, 0, 0x007E, /* TILDE */
+ GDK_Multi_key, GDK_space, GDK_greater, 0, 0, 0x005E, /* CIRCUMFLEX_ACCENT */
+ GDK_Multi_key, GDK_space, GDK_asciicircum, 0, 0, 0x005E, /* CIRCUMFLEX_ACCENT */
+ GDK_Multi_key, GDK_space, GDK_grave, 0, 0, 0x0060, /* GRAVE_ACCENT */
+ GDK_Multi_key, GDK_space, GDK_asciitilde, 0, 0, 0x007E, /* TILDE */
+ GDK_Multi_key, GDK_exclam, GDK_exclam, 0, 0, 0x00A1, /* INVERTED_EXCLAMATION_MARK */
+ GDK_Multi_key, GDK_exclam, GDK_P, 0, 0, 0x00B6, /* PILCROW_SIGN */
+ GDK_Multi_key, GDK_exclam, GDK_S, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_exclam, GDK_p, 0, 0, 0x00B6, /* PILCROW_SIGN */
+ GDK_Multi_key, GDK_exclam, GDK_s, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_quotedbl, GDK_quotedbl, 0, 0, 0x00A8, /* DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_A, 0, 0, 0x00C4, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_E, 0, 0, 0x00CB, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_I, 0, 0, 0x00CF, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_O, 0, 0, 0x00D6, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_U, 0, 0, 0x00DC, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_Y, 0, 0, 0x0178, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_a, 0, 0, 0x00E4, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_e, 0, 0, 0x00EB, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_i, 0, 0, 0x00EF, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_o, 0, 0, 0x00F6, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_u, 0, 0, 0x00FC, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_quotedbl, GDK_y, 0, 0, 0x00FF, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_apostrophe, GDK_space, 0, 0, 0x0027, /* APOSTROPHE */
+ GDK_Multi_key, GDK_apostrophe, GDK_apostrophe, 0, 0, 0x00B4, /* ACUTE_ACCENT */
+ GDK_Multi_key, GDK_apostrophe, GDK_A, 0, 0, 0x00C1, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_E, 0, 0, 0x00C9, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_I, 0, 0, 0x00CD, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_O, 0, 0, 0x00D3, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_U, 0, 0, 0x00DA, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_Y, 0, 0, 0x00DD, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_a, 0, 0, 0x00E1, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_e, 0, 0, 0x00E9, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_i, 0, 0, 0x00ED, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_o, 0, 0, 0x00F3, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_u, 0, 0, 0x00FA, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
+ GDK_Multi_key, GDK_apostrophe, GDK_y, 0, 0, 0x00FD, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
+ GDK_Multi_key, GDK_parenleft, GDK_parenleft, 0, 0, 0x005B, /* LEFT_SQUARE_BRACKET */
+ GDK_Multi_key, GDK_parenleft, GDK_minus, 0, 0, 0x007B, /* LEFT_CURLY_BRACKET */
+ GDK_Multi_key, GDK_parenleft, GDK_G, 0, 0, 0x011E, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_parenleft, GDK_c, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_parenleft, GDK_g, 0, 0, 0x011F, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_parenleft, GDK_r, 0, 0, 0x00AE, /* REGISTERED_SIGN */
+ GDK_Multi_key, GDK_parenright, GDK_parenright, 0, 0, 0x005D, /* RIGHT_SQUARE_BRACKET */
+ GDK_Multi_key, GDK_parenright, GDK_minus, 0, 0, 0x007D, /* RIGHT_CURLY_BRACKET */
+ GDK_Multi_key, GDK_asterisk, GDK_0, 0, 0, 0x00B0, /* DEGREE_SIGN */
+ GDK_Multi_key, GDK_asterisk, GDK_A, 0, 0, 0x00C5, /* LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */
+ GDK_Multi_key, GDK_asterisk, GDK_a, 0, 0, 0x00E5, /* LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */
+ GDK_Multi_key, GDK_plus, GDK_plus, 0, 0, 0x0023, /* NUMBER_SIGN */
+ GDK_Multi_key, GDK_plus, GDK_minus, 0, 0, 0x00B1, /* PLUSxMINUS_SIGN */
+ GDK_Multi_key, GDK_comma, GDK_comma, 0, 0, 0x00B8, /* CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_minus, 0, 0, 0x00AC, /* NOT_SIGN */
+ GDK_Multi_key, GDK_comma, GDK_A, 0, 0, 0x0104, /* LATIN_CAPITAL_LETTER_A_WITH_OGONEK */
+ GDK_Multi_key, GDK_comma, GDK_C, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_E, 0, 0, 0x0118, /* LATIN_CAPITAL_LETTER_E_WITH_OGONEK */
+ GDK_Multi_key, GDK_comma, GDK_G, 0, 0, 0x0122, /* LATIN_CAPITAL_LETTER_G_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_I, 0, 0, 0x012E, /* LATIN_CAPITAL_LETTER_I_WITH_OGONEK */
+ GDK_Multi_key, GDK_comma, GDK_K, 0, 0, 0x0136, /* LATIN_CAPITAL_LETTER_K_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_L, 0, 0, 0x013B, /* LATIN_CAPITAL_LETTER_L_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_N, 0, 0, 0x0145, /* LATIN_CAPITAL_LETTER_N_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_R, 0, 0, 0x0156, /* LATIN_CAPITAL_LETTER_R_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_S, 0, 0, 0x015E, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_U, 0, 0, 0x0172, /* LATIN_CAPITAL_LETTER_U_WITH_OGONEK */
+ GDK_Multi_key, GDK_comma, GDK_a, 0, 0, 0x0105, /* LATIN_SMALL_LETTER_A_WITH_OGONEK */
+ GDK_Multi_key, GDK_comma, GDK_c, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_e, 0, 0, 0x0119, /* LATIN_SMALL_LETTER_E_WITH_OGONEK */
+ GDK_Multi_key, GDK_comma, GDK_g, 0, 0, 0x0123, /* LATIN_SMALL_LETTER_G_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_i, 0, 0, 0x012F, /* LATIN_SMALL_LETTER_I_WITH_OGONEK */
+ GDK_Multi_key, GDK_comma, GDK_k, 0, 0, 0x0137, /* LATIN_SMALL_LETTER_K_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_l, 0, 0, 0x013C, /* LATIN_SMALL_LETTER_L_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_n, 0, 0, 0x0146, /* LATIN_SMALL_LETTER_N_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_r, 0, 0, 0x0157, /* LATIN_SMALL_LETTER_R_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_s, 0, 0, 0x015F, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
+ GDK_Multi_key, GDK_comma, GDK_u, 0, 0, 0x0173, /* LATIN_SMALL_LETTER_U_WITH_OGONEK */
+ GDK_Multi_key, GDK_minus, GDK_space, 0, 0, 0x007E, /* TILDE */
+ GDK_Multi_key, GDK_minus, GDK_parenleft, 0, 0, 0x007B, /* LEFT_CURLY_BRACKET */
+ GDK_Multi_key, GDK_minus, GDK_parenright, 0, 0, 0x007D, /* RIGHT_CURLY_BRACKET */
+ GDK_Multi_key, GDK_minus, GDK_plus, 0, 0, 0x00B1, /* PLUSxMINUS_SIGN */
+ GDK_Multi_key, GDK_minus, GDK_comma, 0, 0, 0x00AC, /* NOT_SIGN */
+ GDK_Multi_key, GDK_minus, GDK_minus, 0, 0, 0x00AD, /* SOFT_HYPHEN */
+ GDK_Multi_key, GDK_minus, GDK_colon, 0, 0, 0x00F7, /* DIVISION_SIGN */
+ GDK_Multi_key, GDK_minus, GDK_A, 0, 0, 0x00C3, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
+ GDK_Multi_key, GDK_minus, GDK_D, 0, 0, 0x0110, /* LATIN_CAPITAL_LETTER_D_WITH_STROKE */
+ GDK_Multi_key, GDK_minus, GDK_E, 0, 0, 0x0112, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
+ GDK_Multi_key, GDK_minus, GDK_I, 0, 0, 0x012A, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
+ GDK_Multi_key, GDK_minus, GDK_L, 0, 0, 0x00A3, /* POUND_SIGN */
+ GDK_Multi_key, GDK_minus, GDK_N, 0, 0, 0x00D1, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
+ GDK_Multi_key, GDK_minus, GDK_O, 0, 0, 0x00D5, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
+ GDK_Multi_key, GDK_minus, GDK_U, 0, 0, 0x00D9, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
+ GDK_Multi_key, GDK_minus, GDK_Y, 0, 0, 0x00A5, /* YEN_SIGN */
+ GDK_Multi_key, GDK_minus, GDK_asciicircum, 0, 0, 0x00AF, /* MACRON */
+ GDK_Multi_key, GDK_minus, GDK_a, 0, 0, 0x00E3, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
+ GDK_Multi_key, GDK_minus, GDK_d, 0, 0, 0x0111, /* LATIN_SMALL_LETTER_D_WITH_STROKE */
+ GDK_Multi_key, GDK_minus, GDK_e, 0, 0, 0x0113, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
+ GDK_Multi_key, GDK_minus, GDK_i, 0, 0, 0x012B, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
+ GDK_Multi_key, GDK_minus, GDK_l, 0, 0, 0x00A3, /* POUND_SIGN */
+ GDK_Multi_key, GDK_minus, GDK_n, 0, 0, 0x00F1, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
+ GDK_Multi_key, GDK_minus, GDK_o, 0, 0, 0x00F5, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
+ GDK_Multi_key, GDK_minus, GDK_u, 0, 0, 0x016B, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
+ GDK_Multi_key, GDK_minus, GDK_y, 0, 0, 0x00A5, /* YEN_SIGN */
+ GDK_Multi_key, GDK_period, GDK_period, 0, 0, 0x02D9, /* DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_B, 0, 0, 0x1E02, /* LATIN_CAPITAL_LETTER_B_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_C, 0, 0, 0x010A, /* LATIN_CAPITAL_LETTER_C_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_D, 0, 0, 0x1E0A, /* LATIN_CAPITAL_LETTER_D_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_E, 0, 0, 0x0116, /* LATIN_CAPITAL_LETTER_E_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_F, 0, 0, 0x1E1E, /* LATIN_CAPITAL_LETTER_F_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_G, 0, 0, 0x0120, /* LATIN_CAPITAL_LETTER_G_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_I, 0, 0, 0x0130, /* LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_M, 0, 0, 0x1E40, /* LATIN_CAPITAL_LETTER_M_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_P, 0, 0, 0x1E56, /* LATIN_CAPITAL_LETTER_P_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_S, 0, 0, 0x1E60, /* LATIN_CAPITAL_LETTER_S_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_T, 0, 0, 0x1E6A, /* LATIN_CAPITAL_LETTER_T_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_asciicircum, 0, 0, 0x00B7, /* MIDDLE_DOT */
+ GDK_Multi_key, GDK_period, GDK_b, 0, 0, 0x1E03, /* LATIN_SMALL_LETTER_B_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_c, 0, 0, 0x010B, /* LATIN_SMALL_LETTER_C_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_d, 0, 0, 0x1E0B, /* LATIN_SMALL_LETTER_D_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_e, 0, 0, 0x0117, /* LATIN_SMALL_LETTER_E_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_f, 0, 0, 0x1E1F, /* LATIN_SMALL_LETTER_F_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_g, 0, 0, 0x0121, /* LATIN_SMALL_LETTER_G_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_i, 0, 0, 0x0131, /* LATIN_SMALL_LETTER_DOTLESS_I */
+ GDK_Multi_key, GDK_period, GDK_m, 0, 0, 0x1E41, /* LATIN_SMALL_LETTER_M_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_p, 0, 0, 0x1E57, /* LATIN_SMALL_LETTER_P_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_s, 0, 0, 0x1E61, /* LATIN_SMALL_LETTER_S_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_period, GDK_t, 0, 0, 0x1E6B, /* LATIN_SMALL_LETTER_T_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_slash, GDK_slash, 0, 0, 0x005C, /* REVERSE_SOLIDUS */
+ GDK_Multi_key, GDK_slash, GDK_less, 0, 0, 0x005C, /* REVERSE_SOLIDUS */
+ GDK_Multi_key, GDK_slash, GDK_C, 0, 0, 0x00A2, /* CENT_SIGN */
+ GDK_Multi_key, GDK_slash, GDK_O, 0, 0, 0x00D8, /* LATIN_CAPITAL_LETTER_O_WITH_STROKE */
+ GDK_Multi_key, GDK_slash, GDK_T, 0, 0, 0x0166, /* LATIN_CAPITAL_LETTER_T_WITH_STROKE */
+ GDK_Multi_key, GDK_slash, GDK_U, 0, 0, 0x00B5, /* MICRO_SIGN */
+ GDK_Multi_key, GDK_slash, GDK_asciicircum, 0, 0, 0x007C, /* VERTICAL_LINE */
+ GDK_Multi_key, GDK_slash, GDK_c, 0, 0, 0x00A2, /* CENT_SIGN */
+ GDK_Multi_key, GDK_slash, GDK_o, 0, 0, 0x00F8, /* LATIN_SMALL_LETTER_O_WITH_STROKE */
+ GDK_Multi_key, GDK_slash, GDK_t, 0, 0, 0x0167, /* LATIN_SMALL_LETTER_T_WITH_STROKE */
+ GDK_Multi_key, GDK_slash, GDK_u, 0, 0, 0x00B5, /* MICRO_SIGN */
+ GDK_Multi_key, GDK_0, GDK_asterisk, 0, 0, 0x00B0, /* DEGREE_SIGN */
+ GDK_Multi_key, GDK_0, GDK_C, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_0, GDK_S, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_0, GDK_X, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_0, GDK_asciicircum, 0, 0, 0x00B0, /* DEGREE_SIGN */
+ GDK_Multi_key, GDK_0, GDK_c, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_0, GDK_s, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_0, GDK_x, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_1, GDK_S, 0, 0, 0x00B9, /* SUPERSCRIPT_ONE */
+ GDK_Multi_key, GDK_1, GDK_asciicircum, 0, 0, 0x00B9, /* SUPERSCRIPT_ONE */
+ GDK_Multi_key, GDK_1, GDK_s, 0, 0, 0x00B9, /* SUPERSCRIPT_ONE */
+ GDK_Multi_key, GDK_2, GDK_S, 0, 0, 0x00B2, /* SUPERSCRIPT_TWO */
+ GDK_Multi_key, GDK_2, GDK_asciicircum, 0, 0, 0x00B2, /* SUPERSCRIPT_TWO */
+ GDK_Multi_key, GDK_2, GDK_s, 0, 0, 0x00B2, /* SUPERSCRIPT_TWO */
+ GDK_Multi_key, GDK_3, GDK_S, 0, 0, 0x00B3, /* SUPERSCRIPT_THREE */
+ GDK_Multi_key, GDK_3, GDK_asciicircum, 0, 0, 0x00B3, /* SUPERSCRIPT_THREE */
+ GDK_Multi_key, GDK_3, GDK_s, 0, 0, 0x00B3, /* SUPERSCRIPT_THREE */
+ GDK_Multi_key, GDK_colon, GDK_minus, 0, 0, 0x00F7, /* DIVISION_SIGN */
+ GDK_Multi_key, GDK_less, GDK_slash, 0, 0, 0x005C, /* REVERSE_SOLIDUS */
+ GDK_Multi_key, GDK_less, GDK_less, 0, 0, 0x00AB, /* LEFTxPOINTING_DOUBLE_ANGLE_QUOTATION_MARK */
+ GDK_Multi_key, GDK_less, GDK_C, 0, 0, 0x010C, /* LATIN_CAPITAL_LETTER_C_WITH_CARON */
+ GDK_Multi_key, GDK_less, GDK_S, 0, 0, 0x0160, /* LATIN_CAPITAL_LETTER_S_WITH_CARON */
+ GDK_Multi_key, GDK_less, GDK_Z, 0, 0, 0x017D, /* LATIN_CAPITAL_LETTER_Z_WITH_CARON */
+ GDK_Multi_key, GDK_less, GDK_c, 0, 0, 0x010D, /* LATIN_SMALL_LETTER_C_WITH_CARON */
+ GDK_Multi_key, GDK_less, GDK_s, 0, 0, 0x0161, /* LATIN_SMALL_LETTER_S_WITH_CARON */
+ GDK_Multi_key, GDK_less, GDK_z, 0, 0, 0x017E, /* LATIN_SMALL_LETTER_Z_WITH_CARON */
+ GDK_Multi_key, GDK_equal, GDK_C, 0, 0, 0x20AC, /* EURO_SIGN */
+ GDK_Multi_key, GDK_equal, GDK_L, 0, 0, 0x00A3, /* POUND_SIGN */
+ GDK_Multi_key, GDK_equal, GDK_Y, 0, 0, 0x00A5, /* YEN_SIGN */
+ GDK_Multi_key, GDK_equal, GDK_e, 0, 0, 0x20AC, /* EURO_SIGN */
+ GDK_Multi_key, GDK_equal, GDK_l, 0, 0, 0x00A3, /* POUND_SIGN */
+ GDK_Multi_key, GDK_equal, GDK_y, 0, 0, 0x00A5, /* YEN_SIGN */
+ GDK_Multi_key, GDK_greater, GDK_space, 0, 0, 0x005E, /* CIRCUMFLEX_ACCENT */
+ GDK_Multi_key, GDK_greater, GDK_greater, 0, 0, 0x00BB, /* RIGHTxPOINTING_DOUBLE_ANGLE_QUOTATION_MARK */
+ GDK_Multi_key, GDK_greater, GDK_A, 0, 0, 0x00C2, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_E, 0, 0, 0x00CA, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_I, 0, 0, 0x00CE, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_O, 0, 0, 0x00D4, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_U, 0, 0, 0x00DB, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_a, 0, 0, 0x00E2, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_e, 0, 0, 0x00EA, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_i, 0, 0, 0x00EE, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_o, 0, 0, 0x00F4, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_greater, GDK_u, 0, 0, 0x00FB, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_question, GDK_question, 0, 0, 0x00BF, /* INVERTED_QUESTION_MARK */
+ GDK_Multi_key, GDK_A, GDK_quotedbl, 0, 0, 0x00C4, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_A, GDK_apostrophe, 0, 0, 0x00C1, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
+ GDK_Multi_key, GDK_A, GDK_asterisk, 0, 0, 0x00C5, /* LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */
+ GDK_Multi_key, GDK_A, GDK_comma, 0, 0, 0x0104, /* LATIN_CAPITAL_LETTER_A_WITH_OGONEK */
+ GDK_Multi_key, GDK_A, GDK_minus, 0, 0, 0x00C3, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
+ GDK_Multi_key, GDK_A, GDK_greater, 0, 0, 0x00C2, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_A, GDK_A, 0, 0, 0x00C5, /* LATIN_CAPITAL_LETTER_A_WITH_RING_ABOVE */
+ GDK_Multi_key, GDK_A, GDK_E, 0, 0, 0x00C6, /* LATIN_CAPITAL_LETTER_AE */
+ GDK_Multi_key, GDK_A, GDK_asciicircum, 0, 0, 0x00C2, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_A, GDK_underscore, 0, 0, 0x00AA, /* FEMININE_ORDINAL_INDICATOR */
+ GDK_Multi_key, GDK_A, GDK_grave, 0, 0, 0x00C0, /* LATIN_CAPITAL_LETTER_A_WITH_GRAVE */
+ GDK_Multi_key, GDK_A, GDK_asciitilde, 0, 0, 0x00C3, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
+ GDK_Multi_key, GDK_A, GDK_diaeresis, 0, 0, 0x00C4, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_A, GDK_acute, 0, 0, 0x00C1, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
+ GDK_Multi_key, GDK_B, GDK_period, 0, 0, 0x1E02, /* LATIN_CAPITAL_LETTER_B_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_C, GDK_comma, 0, 0, 0x00C7, /* LATIN_CAPITAL_LETTER_C_WITH_CEDILLA */
+ GDK_Multi_key, GDK_C, GDK_period, 0, 0, 0x010A, /* LATIN_CAPITAL_LETTER_C_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_C, GDK_slash, 0, 0, 0x00A2, /* CENT_SIGN */
+ GDK_Multi_key, GDK_C, GDK_0, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_C, GDK_less, 0, 0, 0x010C, /* LATIN_CAPITAL_LETTER_C_WITH_CARON */
+ GDK_Multi_key, GDK_C, GDK_equal, 0, 0, 0x20AC, /* EURO_SIGN */
+ GDK_Multi_key, GDK_C, GDK_O, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_C, GDK_o, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_C, GDK_bar, 0, 0, 0x00A2, /* CENT_SIGN */
+ GDK_Multi_key, GDK_D, GDK_minus, 0, 0, 0x0110, /* LATIN_CAPITAL_LETTER_D_WITH_STROKE */
+ GDK_Multi_key, GDK_D, GDK_period, 0, 0, 0x1E0A, /* LATIN_CAPITAL_LETTER_D_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_E, GDK_quotedbl, 0, 0, 0x00CB, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_E, GDK_apostrophe, 0, 0, 0x00C9, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
+ GDK_Multi_key, GDK_E, GDK_comma, 0, 0, 0x0118, /* LATIN_CAPITAL_LETTER_E_WITH_OGONEK */
+ GDK_Multi_key, GDK_E, GDK_minus, 0, 0, 0x0112, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
+ GDK_Multi_key, GDK_E, GDK_period, 0, 0, 0x0116, /* LATIN_CAPITAL_LETTER_E_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_E, GDK_greater, 0, 0, 0x00CA, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_E, GDK_asciicircum, 0, 0, 0x00CA, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_E, GDK_underscore, 0, 0, 0x0112, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
+ GDK_Multi_key, GDK_E, GDK_grave, 0, 0, 0x00C8, /* LATIN_CAPITAL_LETTER_E_WITH_GRAVE */
+ GDK_Multi_key, GDK_E, GDK_diaeresis, 0, 0, 0x00CB, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_E, GDK_acute, 0, 0, 0x00C9, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
+ GDK_Multi_key, GDK_F, GDK_period, 0, 0, 0x1E1E, /* LATIN_CAPITAL_LETTER_F_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_G, GDK_parenleft, 0, 0, 0x011E, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_G, GDK_comma, 0, 0, 0x0122, /* LATIN_CAPITAL_LETTER_G_WITH_CEDILLA */
+ GDK_Multi_key, GDK_G, GDK_period, 0, 0, 0x0120, /* LATIN_CAPITAL_LETTER_G_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_G, GDK_U, 0, 0, 0x011E, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_G, GDK_breve, 0, 0, 0x011E, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_I, GDK_quotedbl, 0, 0, 0x00CF, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_I, GDK_apostrophe, 0, 0, 0x00CD, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
+ GDK_Multi_key, GDK_I, GDK_comma, 0, 0, 0x012E, /* LATIN_CAPITAL_LETTER_I_WITH_OGONEK */
+ GDK_Multi_key, GDK_I, GDK_minus, 0, 0, 0x012A, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
+ GDK_Multi_key, GDK_I, GDK_period, 0, 0, 0x0130, /* LATIN_CAPITAL_LETTER_I_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_I, GDK_greater, 0, 0, 0x00CE, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_I, GDK_asciicircum, 0, 0, 0x00CE, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_I, GDK_underscore, 0, 0, 0x012A, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
+ GDK_Multi_key, GDK_I, GDK_grave, 0, 0, 0x00CC, /* LATIN_CAPITAL_LETTER_I_WITH_GRAVE */
+ GDK_Multi_key, GDK_I, GDK_asciitilde, 0, 0, 0x0128, /* LATIN_CAPITAL_LETTER_I_WITH_TILDE */
+ GDK_Multi_key, GDK_I, GDK_diaeresis, 0, 0, 0x00CF, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_I, GDK_acute, 0, 0, 0x00CD, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
+ GDK_Multi_key, GDK_K, GDK_comma, 0, 0, 0x0136, /* LATIN_CAPITAL_LETTER_K_WITH_CEDILLA */
+ GDK_Multi_key, GDK_L, GDK_comma, 0, 0, 0x013B, /* LATIN_CAPITAL_LETTER_L_WITH_CEDILLA */
+ GDK_Multi_key, GDK_L, GDK_minus, 0, 0, 0x00A3, /* POUND_SIGN */
+ GDK_Multi_key, GDK_L, GDK_equal, 0, 0, 0x00A3, /* POUND_SIGN */
+ GDK_Multi_key, GDK_L, GDK_V, 0, 0, 0x007C, /* VERTICAL_LINE */
+ GDK_Multi_key, GDK_M, GDK_period, 0, 0, 0x1E40, /* LATIN_CAPITAL_LETTER_M_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_N, GDK_comma, 0, 0, 0x0145, /* LATIN_CAPITAL_LETTER_N_WITH_CEDILLA */
+ GDK_Multi_key, GDK_N, GDK_minus, 0, 0, 0x00D1, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
+ GDK_Multi_key, GDK_N, GDK_G, 0, 0, 0x014A, /* LATIN_CAPITAL_LETTER_ENG */
+ GDK_Multi_key, GDK_N, GDK_asciitilde, 0, 0, 0x00D1, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
+ GDK_Multi_key, GDK_O, GDK_quotedbl, 0, 0, 0x00D6, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_O, GDK_apostrophe, 0, 0, 0x00D3, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
+ GDK_Multi_key, GDK_O, GDK_minus, 0, 0, 0x00D5, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
+ GDK_Multi_key, GDK_O, GDK_slash, 0, 0, 0x00D8, /* LATIN_CAPITAL_LETTER_O_WITH_STROKE */
+ GDK_Multi_key, GDK_O, GDK_greater, 0, 0, 0x00D4, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_O, GDK_C, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_O, GDK_E, 0, 0, 0x0152, /* LATIN_CAPITAL_LIGATURE_OE */
+ GDK_Multi_key, GDK_O, GDK_R, 0, 0, 0x00AE, /* REGISTERED_SIGN */
+ GDK_Multi_key, GDK_O, GDK_S, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_O, GDK_X, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_O, GDK_asciicircum, 0, 0, 0x00D4, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_O, GDK_underscore, 0, 0, 0x00BA, /* MASCULINE_ORDINAL_INDICATOR */
+ GDK_Multi_key, GDK_O, GDK_grave, 0, 0, 0x00D2, /* LATIN_CAPITAL_LETTER_O_WITH_GRAVE */
+ GDK_Multi_key, GDK_O, GDK_c, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_O, GDK_x, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_O, GDK_asciitilde, 0, 0, 0x00D5, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
+ GDK_Multi_key, GDK_O, GDK_diaeresis, 0, 0, 0x00D6, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_O, GDK_acute, 0, 0, 0x00D3, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
+ GDK_Multi_key, GDK_P, GDK_exclam, 0, 0, 0x00B6, /* PILCROW_SIGN */
+ GDK_Multi_key, GDK_P, GDK_period, 0, 0, 0x1E56, /* LATIN_CAPITAL_LETTER_P_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_R, GDK_comma, 0, 0, 0x0156, /* LATIN_CAPITAL_LETTER_R_WITH_CEDILLA */
+ GDK_Multi_key, GDK_R, GDK_O, 0, 0, 0x00AE, /* REGISTERED_SIGN */
+ GDK_Multi_key, GDK_S, GDK_exclam, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_S, GDK_comma, 0, 0, 0x015E, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
+ GDK_Multi_key, GDK_S, GDK_period, 0, 0, 0x1E60, /* LATIN_CAPITAL_LETTER_S_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_S, GDK_0, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_S, GDK_1, 0, 0, 0x00B9, /* SUPERSCRIPT_ONE */
+ GDK_Multi_key, GDK_S, GDK_2, 0, 0, 0x00B2, /* SUPERSCRIPT_TWO */
+ GDK_Multi_key, GDK_S, GDK_3, 0, 0, 0x00B3, /* SUPERSCRIPT_THREE */
+ GDK_Multi_key, GDK_S, GDK_less, 0, 0, 0x0160, /* LATIN_CAPITAL_LETTER_S_WITH_CARON */
+ GDK_Multi_key, GDK_S, GDK_O, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_S, GDK_cedilla, 0, 0, 0x015E, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
+ GDK_Multi_key, GDK_T, GDK_minus, 0, 0, 0x0166, /* LATIN_CAPITAL_LETTER_T_WITH_STROKE */
+ GDK_Multi_key, GDK_T, GDK_period, 0, 0, 0x1E6A, /* LATIN_CAPITAL_LETTER_T_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_T, GDK_slash, 0, 0, 0x0166, /* LATIN_CAPITAL_LETTER_T_WITH_STROKE */
+ GDK_Multi_key, GDK_T, GDK_H, 0, 0, 0x00DE, /* LATIN_CAPITAL_LETTER_THORN */
+ GDK_Multi_key, GDK_U, GDK_quotedbl, 0, 0, 0x00DC, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_U, GDK_apostrophe, 0, 0, 0x00DA, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
+ GDK_Multi_key, GDK_U, GDK_comma, 0, 0, 0x0172, /* LATIN_CAPITAL_LETTER_U_WITH_OGONEK */
+ GDK_Multi_key, GDK_U, GDK_minus, 0, 0, 0x00D9, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
+ GDK_Multi_key, GDK_U, GDK_slash, 0, 0, 0x00B5, /* MICRO_SIGN */
+ GDK_Multi_key, GDK_U, GDK_greater, 0, 0, 0x00DB, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_U, GDK_asciicircum, 0, 0, 0x00DB, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_U, GDK_underscore, 0, 0, 0x00D9, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
+ GDK_Multi_key, GDK_U, GDK_grave, 0, 0, 0x00D9, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
+ GDK_Multi_key, GDK_U, GDK_asciitilde, 0, 0, 0x0168, /* LATIN_CAPITAL_LETTER_U_WITH_TILDE */
+ GDK_Multi_key, GDK_U, GDK_diaeresis, 0, 0, 0x00DC, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_U, GDK_acute, 0, 0, 0x00DA, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
+ GDK_Multi_key, GDK_V, GDK_L, 0, 0, 0x007C, /* VERTICAL_LINE */
+ GDK_Multi_key, GDK_W, GDK_asciicircum, 0, 0, 0x0174, /* LATIN_CAPITAL_LETTER_W_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_X, GDK_0, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_X, GDK_O, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_X, GDK_o, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_Y, GDK_quotedbl, 0, 0, 0x0178, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_Y, GDK_apostrophe, 0, 0, 0x00DD, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
+ GDK_Multi_key, GDK_Y, GDK_minus, 0, 0, 0x00A5, /* YEN_SIGN */
+ GDK_Multi_key, GDK_Y, GDK_equal, 0, 0, 0x00A5, /* YEN_SIGN */
+ GDK_Multi_key, GDK_Y, GDK_asciicircum, 0, 0, 0x0176, /* LATIN_CAPITAL_LETTER_Y_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_Y, GDK_diaeresis, 0, 0, 0x0178, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_Y, GDK_acute, 0, 0, 0x00DD, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
+ GDK_Multi_key, GDK_Z, GDK_less, 0, 0, 0x017D, /* LATIN_CAPITAL_LETTER_Z_WITH_CARON */
+ GDK_Multi_key, GDK_asciicircum, GDK_space, 0, 0, 0x005E, /* CIRCUMFLEX_ACCENT */
+ GDK_Multi_key, GDK_asciicircum, GDK_minus, 0, 0, 0x00AF, /* MACRON */
+ GDK_Multi_key, GDK_asciicircum, GDK_period, 0, 0, 0x00B7, /* MIDDLE_DOT */
+ GDK_Multi_key, GDK_asciicircum, GDK_slash, 0, 0, 0x007C, /* VERTICAL_LINE */
+ GDK_Multi_key, GDK_asciicircum, GDK_0, 0, 0, 0x00B0, /* DEGREE_SIGN */
+ GDK_Multi_key, GDK_asciicircum, GDK_1, 0, 0, 0x00B9, /* SUPERSCRIPT_ONE */
+ GDK_Multi_key, GDK_asciicircum, GDK_2, 0, 0, 0x00B2, /* SUPERSCRIPT_TWO */
+ GDK_Multi_key, GDK_asciicircum, GDK_3, 0, 0, 0x00B3, /* SUPERSCRIPT_THREE */
+ GDK_Multi_key, GDK_asciicircum, GDK_A, 0, 0, 0x00C2, /* LATIN_CAPITAL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_E, 0, 0, 0x00CA, /* LATIN_CAPITAL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_I, 0, 0, 0x00CE, /* LATIN_CAPITAL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_O, 0, 0, 0x00D4, /* LATIN_CAPITAL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_U, 0, 0, 0x00DB, /* LATIN_CAPITAL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_W, 0, 0, 0x0174, /* LATIN_CAPITAL_LETTER_W_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_Y, 0, 0, 0x0176, /* LATIN_CAPITAL_LETTER_Y_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_underscore, 0, 0, 0x00AF, /* MACRON */
+ GDK_Multi_key, GDK_asciicircum, GDK_a, 0, 0, 0x00E2, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_e, 0, 0, 0x00EA, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_i, 0, 0, 0x00EE, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_o, 0, 0, 0x00F4, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_u, 0, 0, 0x00FB, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_w, 0, 0, 0x0175, /* LATIN_SMALL_LETTER_W_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_asciicircum, GDK_y, 0, 0, 0x0177, /* LATIN_SMALL_LETTER_Y_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_underscore, GDK_A, 0, 0, 0x00AA, /* FEMININE_ORDINAL_INDICATOR */
+ GDK_Multi_key, GDK_underscore, GDK_E, 0, 0, 0x0112, /* LATIN_CAPITAL_LETTER_E_WITH_MACRON */
+ GDK_Multi_key, GDK_underscore, GDK_I, 0, 0, 0x012A, /* LATIN_CAPITAL_LETTER_I_WITH_MACRON */
+ GDK_Multi_key, GDK_underscore, GDK_O, 0, 0, 0x00BA, /* MASCULINE_ORDINAL_INDICATOR */
+ GDK_Multi_key, GDK_underscore, GDK_U, 0, 0, 0x00D9, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
+ GDK_Multi_key, GDK_underscore, GDK_asciicircum, 0, 0, 0x00AF, /* MACRON */
+ GDK_Multi_key, GDK_underscore, GDK_underscore, 0, 0, 0x00AF, /* MACRON */
+ GDK_Multi_key, GDK_underscore, GDK_a, 0, 0, 0x00AA, /* FEMININE_ORDINAL_INDICATOR */
+ GDK_Multi_key, GDK_underscore, GDK_e, 0, 0, 0x0113, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
+ GDK_Multi_key, GDK_underscore, GDK_i, 0, 0, 0x012B, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
+ GDK_Multi_key, GDK_underscore, GDK_o, 0, 0, 0x00BA, /* MASCULINE_ORDINAL_INDICATOR */
+ GDK_Multi_key, GDK_underscore, GDK_u, 0, 0, 0x016B, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
+ GDK_Multi_key, GDK_grave, GDK_space, 0, 0, 0x0060, /* GRAVE_ACCENT */
+ GDK_Multi_key, GDK_grave, GDK_A, 0, 0, 0x00C0, /* LATIN_CAPITAL_LETTER_A_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_E, 0, 0, 0x00C8, /* LATIN_CAPITAL_LETTER_E_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_I, 0, 0, 0x00CC, /* LATIN_CAPITAL_LETTER_I_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_O, 0, 0, 0x00D2, /* LATIN_CAPITAL_LETTER_O_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_U, 0, 0, 0x00D9, /* LATIN_CAPITAL_LETTER_U_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_a, 0, 0, 0x00E0, /* LATIN_SMALL_LETTER_A_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_e, 0, 0, 0x00E8, /* LATIN_SMALL_LETTER_E_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_i, 0, 0, 0x00EC, /* LATIN_SMALL_LETTER_I_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_o, 0, 0, 0x00F2, /* LATIN_SMALL_LETTER_O_WITH_GRAVE */
+ GDK_Multi_key, GDK_grave, GDK_u, 0, 0, 0x00F9, /* LATIN_SMALL_LETTER_U_WITH_GRAVE */
+ GDK_Multi_key, GDK_a, GDK_quotedbl, 0, 0, 0x00E4, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_a, GDK_apostrophe, 0, 0, 0x00E1, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
+ GDK_Multi_key, GDK_a, GDK_asterisk, 0, 0, 0x00E5, /* LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */
+ GDK_Multi_key, GDK_a, GDK_comma, 0, 0, 0x0105, /* LATIN_SMALL_LETTER_A_WITH_OGONEK */
+ GDK_Multi_key, GDK_a, GDK_minus, 0, 0, 0x00E3, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
+ GDK_Multi_key, GDK_a, GDK_greater, 0, 0, 0x00E2, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_a, GDK_asciicircum, 0, 0, 0x00E2, /* LATIN_SMALL_LETTER_A_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_a, GDK_underscore, 0, 0, 0x00AA, /* FEMININE_ORDINAL_INDICATOR */
+ GDK_Multi_key, GDK_a, GDK_grave, 0, 0, 0x00E0, /* LATIN_SMALL_LETTER_A_WITH_GRAVE */
+ GDK_Multi_key, GDK_a, GDK_a, 0, 0, 0x00E5, /* LATIN_SMALL_LETTER_A_WITH_RING_ABOVE */
+ GDK_Multi_key, GDK_a, GDK_e, 0, 0, 0x00E6, /* LATIN_SMALL_LETTER_AE */
+ GDK_Multi_key, GDK_a, GDK_asciitilde, 0, 0, 0x00E3, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
+ GDK_Multi_key, GDK_a, GDK_diaeresis, 0, 0, 0x00E4, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_a, GDK_acute, 0, 0, 0x00E1, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
+ GDK_Multi_key, GDK_b, GDK_period, 0, 0, 0x1E03, /* LATIN_SMALL_LETTER_B_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_c, GDK_comma, 0, 0, 0x00E7, /* LATIN_SMALL_LETTER_C_WITH_CEDILLA */
+ GDK_Multi_key, GDK_c, GDK_period, 0, 0, 0x010B, /* LATIN_SMALL_LETTER_C_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_c, GDK_slash, 0, 0, 0x00A2, /* CENT_SIGN */
+ GDK_Multi_key, GDK_c, GDK_0, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_c, GDK_less, 0, 0, 0x010D, /* LATIN_SMALL_LETTER_C_WITH_CARON */
+ GDK_Multi_key, GDK_c, GDK_O, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_c, GDK_o, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_c, GDK_bar, 0, 0, 0x00A2, /* CENT_SIGN */
+ GDK_Multi_key, GDK_d, GDK_minus, 0, 0, 0x0111, /* LATIN_SMALL_LETTER_D_WITH_STROKE */
+ GDK_Multi_key, GDK_d, GDK_period, 0, 0, 0x1E0B, /* LATIN_SMALL_LETTER_D_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_e, GDK_quotedbl, 0, 0, 0x00EB, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_e, GDK_apostrophe, 0, 0, 0x00E9, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
+ GDK_Multi_key, GDK_e, GDK_comma, 0, 0, 0x0119, /* LATIN_SMALL_LETTER_E_WITH_OGONEK */
+ GDK_Multi_key, GDK_e, GDK_minus, 0, 0, 0x0113, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
+ GDK_Multi_key, GDK_e, GDK_period, 0, 0, 0x0117, /* LATIN_SMALL_LETTER_E_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_e, GDK_equal, 0, 0, 0x20AC, /* EURO_SIGN */
+ GDK_Multi_key, GDK_e, GDK_greater, 0, 0, 0x00EA, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_e, GDK_asciicircum, 0, 0, 0x00EA, /* LATIN_SMALL_LETTER_E_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_e, GDK_underscore, 0, 0, 0x0113, /* LATIN_SMALL_LETTER_E_WITH_MACRON */
+ GDK_Multi_key, GDK_e, GDK_grave, 0, 0, 0x00E8, /* LATIN_SMALL_LETTER_E_WITH_GRAVE */
+ GDK_Multi_key, GDK_e, GDK_diaeresis, 0, 0, 0x00EB, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_e, GDK_acute, 0, 0, 0x00E9, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
+ GDK_Multi_key, GDK_f, GDK_period, 0, 0, 0x1E1F, /* LATIN_SMALL_LETTER_F_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_g, GDK_parenleft, 0, 0, 0x011F, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_g, GDK_comma, 0, 0, 0x0123, /* LATIN_SMALL_LETTER_G_WITH_CEDILLA */
+ GDK_Multi_key, GDK_g, GDK_period, 0, 0, 0x0121, /* LATIN_SMALL_LETTER_G_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_g, GDK_U, 0, 0, 0x011F, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_g, GDK_breve, 0, 0, 0x011F, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_i, GDK_quotedbl, 0, 0, 0x00EF, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_i, GDK_apostrophe, 0, 0, 0x00ED, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
+ GDK_Multi_key, GDK_i, GDK_comma, 0, 0, 0x012F, /* LATIN_SMALL_LETTER_I_WITH_OGONEK */
+ GDK_Multi_key, GDK_i, GDK_minus, 0, 0, 0x012B, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
+ GDK_Multi_key, GDK_i, GDK_period, 0, 0, 0x0131, /* LATIN_SMALL_LETTER_DOTLESS_I */
+ GDK_Multi_key, GDK_i, GDK_greater, 0, 0, 0x00EE, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_i, GDK_asciicircum, 0, 0, 0x00EE, /* LATIN_SMALL_LETTER_I_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_i, GDK_underscore, 0, 0, 0x012B, /* LATIN_SMALL_LETTER_I_WITH_MACRON */
+ GDK_Multi_key, GDK_i, GDK_grave, 0, 0, 0x00EC, /* LATIN_SMALL_LETTER_I_WITH_GRAVE */
+ GDK_Multi_key, GDK_i, GDK_asciitilde, 0, 0, 0x0129, /* LATIN_SMALL_LETTER_I_WITH_TILDE */
+ GDK_Multi_key, GDK_i, GDK_diaeresis, 0, 0, 0x00EF, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_i, GDK_acute, 0, 0, 0x00ED, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
+ GDK_Multi_key, GDK_k, GDK_comma, 0, 0, 0x0137, /* LATIN_SMALL_LETTER_K_WITH_CEDILLA */
+ GDK_Multi_key, GDK_k, GDK_k, 0, 0, 0x0138, /* LATIN_SMALL_LETTER_KRA */
+ GDK_Multi_key, GDK_l, GDK_comma, 0, 0, 0x013C, /* LATIN_SMALL_LETTER_L_WITH_CEDILLA */
+ GDK_Multi_key, GDK_l, GDK_minus, 0, 0, 0x00A3, /* POUND_SIGN */
+ GDK_Multi_key, GDK_l, GDK_equal, 0, 0, 0x00A3, /* POUND_SIGN */
+ GDK_Multi_key, GDK_l, GDK_v, 0, 0, 0x007C, /* VERTICAL_LINE */
+ GDK_Multi_key, GDK_m, GDK_period, 0, 0, 0x1E41, /* LATIN_SMALL_LETTER_M_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_n, GDK_comma, 0, 0, 0x0146, /* LATIN_SMALL_LETTER_N_WITH_CEDILLA */
+ GDK_Multi_key, GDK_n, GDK_minus, 0, 0, 0x00F1, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
+ GDK_Multi_key, GDK_n, GDK_g, 0, 0, 0x014B, /* LATIN_SMALL_LETTER_ENG */
+ GDK_Multi_key, GDK_n, GDK_asciitilde, 0, 0, 0x00F1, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
+ GDK_Multi_key, GDK_o, GDK_quotedbl, 0, 0, 0x00F6, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_o, GDK_apostrophe, 0, 0, 0x00F3, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
+ GDK_Multi_key, GDK_o, GDK_minus, 0, 0, 0x00F5, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
+ GDK_Multi_key, GDK_o, GDK_slash, 0, 0, 0x00F8, /* LATIN_SMALL_LETTER_O_WITH_STROKE */
+ GDK_Multi_key, GDK_o, GDK_greater, 0, 0, 0x00F4, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_o, GDK_C, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_o, GDK_X, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_o, GDK_asciicircum, 0, 0, 0x00F4, /* LATIN_SMALL_LETTER_O_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_o, GDK_underscore, 0, 0, 0x00BA, /* MASCULINE_ORDINAL_INDICATOR */
+ GDK_Multi_key, GDK_o, GDK_grave, 0, 0, 0x00F2, /* LATIN_SMALL_LETTER_O_WITH_GRAVE */
+ GDK_Multi_key, GDK_o, GDK_c, 0, 0, 0x00A9, /* COPYRIGHT_SIGN */
+ GDK_Multi_key, GDK_o, GDK_e, 0, 0, 0x0153, /* LATIN_SMALL_LIGATURE_OE */
+ GDK_Multi_key, GDK_o, GDK_s, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_o, GDK_x, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_o, GDK_asciitilde, 0, 0, 0x00F5, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
+ GDK_Multi_key, GDK_o, GDK_diaeresis, 0, 0, 0x00F6, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_o, GDK_acute, 0, 0, 0x00F3, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
+ GDK_Multi_key, GDK_p, GDK_exclam, 0, 0, 0x00B6, /* PILCROW_SIGN */
+ GDK_Multi_key, GDK_p, GDK_period, 0, 0, 0x1E57, /* LATIN_SMALL_LETTER_P_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_r, GDK_comma, 0, 0, 0x0157, /* LATIN_SMALL_LETTER_R_WITH_CEDILLA */
+ GDK_Multi_key, GDK_s, GDK_exclam, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_s, GDK_comma, 0, 0, 0x015F, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
+ GDK_Multi_key, GDK_s, GDK_period, 0, 0, 0x1E61, /* LATIN_SMALL_LETTER_S_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_s, GDK_0, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_s, GDK_1, 0, 0, 0x00B9, /* SUPERSCRIPT_ONE */
+ GDK_Multi_key, GDK_s, GDK_2, 0, 0, 0x00B2, /* SUPERSCRIPT_TWO */
+ GDK_Multi_key, GDK_s, GDK_3, 0, 0, 0x00B3, /* SUPERSCRIPT_THREE */
+ GDK_Multi_key, GDK_s, GDK_less, 0, 0, 0x0161, /* LATIN_SMALL_LETTER_S_WITH_CARON */
+ GDK_Multi_key, GDK_s, GDK_o, 0, 0, 0x00A7, /* SECTION_SIGN */
+ GDK_Multi_key, GDK_s, GDK_s, 0, 0, 0x00DF, /* LATIN_SMALL_LETTER_SHARP_S */
+ GDK_Multi_key, GDK_s, GDK_cedilla, 0, 0, 0x015F, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
+ GDK_Multi_key, GDK_t, GDK_minus, 0, 0, 0x0167, /* LATIN_SMALL_LETTER_T_WITH_STROKE */
+ GDK_Multi_key, GDK_t, GDK_period, 0, 0, 0x1E6B, /* LATIN_SMALL_LETTER_T_WITH_DOT_ABOVE */
+ GDK_Multi_key, GDK_t, GDK_slash, 0, 0, 0x0167, /* LATIN_SMALL_LETTER_T_WITH_STROKE */
+ GDK_Multi_key, GDK_t, GDK_h, 0, 0, 0x00FE, /* LATIN_SMALL_LETTER_THORN */
+ GDK_Multi_key, GDK_u, GDK_quotedbl, 0, 0, 0x00FC, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_u, GDK_apostrophe, 0, 0, 0x00FA, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
+ GDK_Multi_key, GDK_u, GDK_comma, 0, 0, 0x0173, /* LATIN_SMALL_LETTER_U_WITH_OGONEK */
+ GDK_Multi_key, GDK_u, GDK_minus, 0, 0, 0x016B, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
+ GDK_Multi_key, GDK_u, GDK_slash, 0, 0, 0x00B5, /* MICRO_SIGN */
+ GDK_Multi_key, GDK_u, GDK_greater, 0, 0, 0x00FB, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_u, GDK_asciicircum, 0, 0, 0x00FB, /* LATIN_SMALL_LETTER_U_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_u, GDK_underscore, 0, 0, 0x016B, /* LATIN_SMALL_LETTER_U_WITH_MACRON */
+ GDK_Multi_key, GDK_u, GDK_grave, 0, 0, 0x00F9, /* LATIN_SMALL_LETTER_U_WITH_GRAVE */
+ GDK_Multi_key, GDK_u, GDK_asciitilde, 0, 0, 0x0169, /* LATIN_SMALL_LETTER_U_WITH_TILDE */
+ GDK_Multi_key, GDK_u, GDK_diaeresis, 0, 0, 0x00FC, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_u, GDK_acute, 0, 0, 0x00FA, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
+ GDK_Multi_key, GDK_v, GDK_Z, 0, 0, 0x017D, /* LATIN_CAPITAL_LETTER_Z_WITH_CARON */
+ GDK_Multi_key, GDK_v, GDK_l, 0, 0, 0x007C, /* VERTICAL_LINE */
+ GDK_Multi_key, GDK_v, GDK_z, 0, 0, 0x017E, /* LATIN_SMALL_LETTER_Z_WITH_CARON */
+ GDK_Multi_key, GDK_w, GDK_asciicircum, 0, 0, 0x0175, /* LATIN_SMALL_LETTER_W_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_x, GDK_0, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_x, GDK_O, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_x, GDK_o, 0, 0, 0x00A4, /* CURRENCY_SIGN */
+ GDK_Multi_key, GDK_x, GDK_x, 0, 0, 0x00D7, /* MULTIPLICATION_SIGN */
+ GDK_Multi_key, GDK_y, GDK_quotedbl, 0, 0, 0x00FF, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_y, GDK_apostrophe, 0, 0, 0x00FD, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
+ GDK_Multi_key, GDK_y, GDK_minus, 0, 0, 0x00A5, /* YEN_SIGN */
+ GDK_Multi_key, GDK_y, GDK_equal, 0, 0, 0x00A5, /* YEN_SIGN */
+ GDK_Multi_key, GDK_y, GDK_asciicircum, 0, 0, 0x0177, /* LATIN_SMALL_LETTER_Y_WITH_CIRCUMFLEX */
+ GDK_Multi_key, GDK_y, GDK_diaeresis, 0, 0, 0x00FF, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_y, GDK_acute, 0, 0, 0x00FD, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
+ GDK_Multi_key, GDK_z, GDK_less, 0, 0, 0x017E, /* LATIN_SMALL_LETTER_Z_WITH_CARON */
+ GDK_Multi_key, GDK_bar, GDK_C, 0, 0, 0x00A2, /* CENT_SIGN */
+ GDK_Multi_key, GDK_bar, GDK_c, 0, 0, 0x00A2, /* CENT_SIGN */
+ GDK_Multi_key, GDK_asciitilde, GDK_space, 0, 0, 0x007E, /* TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_A, 0, 0, 0x00C3, /* LATIN_CAPITAL_LETTER_A_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_I, 0, 0, 0x0128, /* LATIN_CAPITAL_LETTER_I_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_N, 0, 0, 0x00D1, /* LATIN_CAPITAL_LETTER_N_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_O, 0, 0, 0x00D5, /* LATIN_CAPITAL_LETTER_O_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_U, 0, 0, 0x0168, /* LATIN_CAPITAL_LETTER_U_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_a, 0, 0, 0x00E3, /* LATIN_SMALL_LETTER_A_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_i, 0, 0, 0x0129, /* LATIN_SMALL_LETTER_I_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_n, 0, 0, 0x00F1, /* LATIN_SMALL_LETTER_N_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_o, 0, 0, 0x00F5, /* LATIN_SMALL_LETTER_O_WITH_TILDE */
+ GDK_Multi_key, GDK_asciitilde, GDK_u, 0, 0, 0x0169, /* LATIN_SMALL_LETTER_U_WITH_TILDE */
+ GDK_Multi_key, GDK_diaeresis, GDK_A, 0, 0, 0x00C4, /* LATIN_CAPITAL_LETTER_A_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_E, 0, 0, 0x00CB, /* LATIN_CAPITAL_LETTER_E_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_I, 0, 0, 0x00CF, /* LATIN_CAPITAL_LETTER_I_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_O, 0, 0, 0x00D6, /* LATIN_CAPITAL_LETTER_O_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_U, 0, 0, 0x00DC, /* LATIN_CAPITAL_LETTER_U_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_Y, 0, 0, 0x0178, /* LATIN_CAPITAL_LETTER_Y_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_a, 0, 0, 0x00E4, /* LATIN_SMALL_LETTER_A_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_e, 0, 0, 0x00EB, /* LATIN_SMALL_LETTER_E_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_i, 0, 0, 0x00EF, /* LATIN_SMALL_LETTER_I_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_o, 0, 0, 0x00F6, /* LATIN_SMALL_LETTER_O_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_u, 0, 0, 0x00FC, /* LATIN_SMALL_LETTER_U_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_diaeresis, GDK_y, 0, 0, 0x00FF, /* LATIN_SMALL_LETTER_Y_WITH_DIAERESIS */
+ GDK_Multi_key, GDK_acute, GDK_A, 0, 0, 0x00C1, /* LATIN_CAPITAL_LETTER_A_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_E, 0, 0, 0x00C9, /* LATIN_CAPITAL_LETTER_E_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_I, 0, 0, 0x00CD, /* LATIN_CAPITAL_LETTER_I_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_O, 0, 0, 0x00D3, /* LATIN_CAPITAL_LETTER_O_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_U, 0, 0, 0x00DA, /* LATIN_CAPITAL_LETTER_U_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_Y, 0, 0, 0x00DD, /* LATIN_CAPITAL_LETTER_Y_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_a, 0, 0, 0x00E1, /* LATIN_SMALL_LETTER_A_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_e, 0, 0, 0x00E9, /* LATIN_SMALL_LETTER_E_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_i, 0, 0, 0x00ED, /* LATIN_SMALL_LETTER_I_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_o, 0, 0, 0x00F3, /* LATIN_SMALL_LETTER_O_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_u, 0, 0, 0x00FA, /* LATIN_SMALL_LETTER_U_WITH_ACUTE */
+ GDK_Multi_key, GDK_acute, GDK_y, 0, 0, 0x00FD, /* LATIN_SMALL_LETTER_Y_WITH_ACUTE */
+ GDK_Multi_key, GDK_cedilla, GDK_S, 0, 0, 0x015E, /* LATIN_CAPITAL_LETTER_S_WITH_CEDILLA */
+ GDK_Multi_key, GDK_cedilla, GDK_s, 0, 0, 0x015F, /* LATIN_SMALL_LETTER_S_WITH_CEDILLA */
+ GDK_Multi_key, GDK_breve, GDK_G, 0, 0, 0x011E, /* LATIN_CAPITAL_LETTER_G_WITH_BREVE */
+ GDK_Multi_key, GDK_breve, GDK_g, 0, 0, 0x011F, /* LATIN_SMALL_LETTER_G_WITH_BREVE */
+};
+
+static const GtkComposeTable gtk_compose_table = {
+ gtk_compose_seqs,
+ 4,
+ G_N_ELEMENTS (gtk_compose_seqs) / 6
};
guint16 gtk_compose_ignore[] = {
@@ -732,11 +739,18 @@ guint16 gtk_compose_ignore[] = {
GDK_Hyper_R
};
-static void gtk_im_context_simple_class_init (GtkIMContextSimpleClass *class);
-static void gtk_im_context_simple_init (GtkIMContextSimple *im_context_simple);
+static void gtk_im_context_simple_class_init (GtkIMContextSimpleClass *class);
+static void gtk_im_context_simple_init (GtkIMContextSimple *im_context_simple);
+static void gtk_im_context_simple_finalize (GObject *obj);
+static gboolean gtk_im_context_simple_filter_keypress (GtkIMContext *context,
+ GdkEventKey *key);
+static void gtk_im_context_simple_reset (GtkIMContext *context);
+static void gtk_im_context_simple_get_preedit_string (GtkIMContext *context,
+ gchar **str,
+ PangoAttrList **attrs,
+ gint *cursor_pos);
-static gboolean gtk_im_context_simple_filter_keypress (GtkIMContext *context,
- GdkEventKey *key);
+static GObjectClass *parent_class;
GtkType
gtk_im_context_simple_get_type (void)
@@ -767,8 +781,14 @@ static void
gtk_im_context_simple_class_init (GtkIMContextSimpleClass *class)
{
GtkIMContextClass *im_context_class = GTK_IM_CONTEXT_CLASS (class);
-
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ parent_class = g_type_class_peek_parent (class);
+
im_context_class->filter_keypress = gtk_im_context_simple_filter_keypress;
+ im_context_class->reset = gtk_im_context_simple_reset;
+ im_context_class->get_preedit_string = gtk_im_context_simple_get_preedit_string;
+ gobject_class->finalize = gtk_im_context_simple_finalize;
}
static void
@@ -776,6 +796,14 @@ gtk_im_context_simple_init (GtkIMContextSimple *im_context_simple)
{
}
+static void
+gtk_im_context_simple_finalize (GObject *obj)
+{
+ GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (obj);
+
+ g_slist_free (context_simple->tables);
+}
+
GtkIMContext *
gtk_im_context_simple_new (void)
{
@@ -788,10 +816,20 @@ gtk_im_context_simple_commit_char (GtkIMContext *context,
{
gchar buf[10];
gint len;
+
+ GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
len = g_unichar_to_utf8 (ch, buf);
buf[len] = '\0';
+ if (context_simple->tentative_match)
+ {
+ context_simple->tentative_match = 0;
+ context_simple->tentative_match_len = 0;
+ gtk_signal_emit_by_name (GTK_OBJECT (context_simple),
+ "preedit-changed");
+ }
+
gtk_signal_emit_by_name (GTK_OBJECT (context), "commit", &buf);
}
@@ -800,13 +838,13 @@ compare_seq (const void *key, const void *value)
{
int i = 0;
const guint *keysyms = key;
- const GtkComposeSeq *seq = value;
+ const guint16 *seq = value;
while (keysyms[i])
{
- if (keysyms[i] < seq->keysyms[i])
+ if (keysyms[i] < seq[i])
return -1;
- else if (keysyms[i] > seq->keysyms[i])
+ else if (keysyms[i] > seq[i])
return 1;
i++;
@@ -816,11 +854,74 @@ compare_seq (const void *key, const void *value)
}
static gboolean
+check_table (GtkIMContextSimple *context_simple,
+ const GtkComposeTable *table,
+ gint n_compose)
+{
+ gint row_stride = table->max_seq_len + 2;
+ guint16 *seq = bsearch (context_simple->compose_buffer,
+ table->data, table->n_seqs,
+ sizeof (guint16) * row_stride,
+ compare_seq);
+
+ if (seq)
+ {
+ guint16 *prev_seq;
+
+ /* Back up to the first sequence that matches to make sure
+ * we find the exact match if their is one.
+ */
+ while (seq > table->data)
+ {
+ prev_seq = seq - row_stride;
+ if (compare_seq (context_simple->compose_buffer, prev_seq) != 0)
+ break;
+ seq = prev_seq;
+ }
+
+ if (n_compose == table->max_seq_len ||
+ seq[n_compose] == 0) /* complete sequence */
+ {
+ guint16 *next_seq;
+ gunichar value =
+ 0x10000 * seq[table->max_seq_len] + seq[table->max_seq_len + 1];
+
+
+ /* We found a tentative match. See if there are any longer
+ * sequences containing this subsequence
+ */
+ next_seq = seq + row_stride;
+ if (next_seq < table->data + row_stride * table->n_seqs)
+ {
+ if (compare_seq (context_simple->compose_buffer, next_seq) == 0)
+ {
+ context_simple->tentative_match = value;
+ context_simple->tentative_match_len = n_compose;
+
+ gtk_signal_emit_by_name (GTK_OBJECT (context_simple),
+ "preedit-changed");
+
+ return TRUE;
+ }
+ }
+
+ gtk_im_context_simple_commit_char (GTK_IM_CONTEXT (context_simple), value);
+ context_simple->compose_buffer[0] = 0;
+ }
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+static gboolean
gtk_im_context_simple_filter_keypress (GtkIMContext *context,
GdkEventKey *event)
{
GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
- GtkComposeSeq *seq;
+ GSList *tmp_list;
gunichar ch;
int n_compose = 0;
@@ -840,37 +941,138 @@ gtk_im_context_simple_filter_keypress (GtkIMContext *context,
context_simple->compose_buffer[n_compose++] = event->keyval;
context_simple->compose_buffer[n_compose] = 0;
- seq = bsearch (context_simple->compose_buffer,
- gtk_compose_seqs, G_N_ELEMENTS (gtk_compose_seqs),
- sizeof (GtkComposeSeq), compare_seq);
+ tmp_list = context_simple->tables;
+ while (tmp_list)
+ {
+ if (check_table (context_simple, tmp_list->data, n_compose))
+ return TRUE;
+ tmp_list = tmp_list->next;
+ }
+
+ if (check_table (context_simple, &gtk_compose_table, n_compose))
+ return TRUE;
+
+ /* No compose sequences found, check first if we have a partial
+ * match pending.
+ */
+ if (context_simple->tentative_match)
+ {
+ gint len = context_simple->tentative_match_len;
+ int i;
+
+ gtk_im_context_simple_commit_char (context, context_simple->tentative_match);
+ context_simple->compose_buffer[0] = 0;
+
+ for (i=0; i < n_compose - len - 1; i++)
+ {
+ GdkEventKey tmp_event = *event;
+ tmp_event.keyval = context_simple->compose_buffer[len + i];
+
+ gtk_im_context_filter_keypress (context, &tmp_event);
+ }
- if (seq)
+ return gtk_im_context_filter_keypress (context, event);
+ }
+ else
{
- if (n_compose == GTK_MAX_COMPOSE_LEN ||
- seq->keysyms[n_compose] == 0) /* complete sequence */
+ context_simple->compose_buffer[0] = 0;
+ if (n_compose > 1) /* Invalid sequence */
{
- gtk_im_context_simple_commit_char (context, seq->unicode);
- context_simple->compose_buffer[0] = 0;
+ gdk_beep();
+ return TRUE;
}
-
- return TRUE;
+
+ ch = gdk_keyval_to_unicode (event->keyval);
+ if (ch != 0)
+ {
+ gtk_im_context_simple_commit_char (context, ch);
+ return TRUE;
+ }
+ else
+ return FALSE;
}
+}
- /* No compose sequences found, try simple conversion to unicode
- */
+static void
+gtk_im_context_simple_reset (GtkIMContext *context)
+{
+ GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
+
context_simple->compose_buffer[0] = 0;
- if (n_compose > 1) /* Invalid sequence */
+
+ if (context_simple->tentative_match)
+ gtk_im_context_simple_commit_char (context, context_simple->tentative_match);
+}
+
+static void
+gtk_im_context_simple_get_preedit_string (GtkIMContext *context,
+ gchar **str,
+ PangoAttrList **attrs,
+ gint *cursor_pos)
+{
+ char outbuf[7];
+ int len = 0;
+
+ GtkIMContextSimple *context_simple = GTK_IM_CONTEXT_SIMPLE (context);
+
+ if (context_simple->tentative_match)
+ len = g_unichar_to_utf8 (context_simple->tentative_match, outbuf);
+
+ if (str)
+ *str = g_strndup (outbuf, len);
+
+ if (attrs)
{
- gdk_beep();
- return TRUE;
+ *attrs = pango_attr_list_new();
+
+ if (len)
+ {
+ PangoAttribute *attr = pango_attr_underline_new (PANGO_UNDERLINE_SINGLE);
+ attr->start_index = 0;
+ attr->end_index = len;
+ pango_attr_list_insert (*attrs, attr);
+ }
}
+
+ if (cursor_pos)
+ cursor_pos = context_simple->tentative_match ? 1 : 0;
+}
+
+/**
+ * gtk_im_context_simple_add_table:
+ * @context_simple: A #GtkIMContextSimple
+ * @data: the table
+ * @max_seq_len: Maximum length of a sequence in the table
+ * (cannot be greater than 7)
+ * @n_seqs: number of sequences in the table
+ *
+ * Add an additional table to search to the input context.
+ * Each row of the table consists of max_seq_len key symbols
+ * followed by two guint16 interpreted as the high and low
+ * words of a gunicode value. Tables are searched starting
+ * from the last added.
+ *
+ * The table must be sorted in dictionary order on the
+ * by numeric value of the key symbol fields. (Values beyond
+ * the length of the sequence should be zero.)
+ **/
+void
+gtk_im_context_simple_add_table (GtkIMContextSimple *context_simple,
+ guint16 *data,
+ gint max_seq_len,
+ gint n_seqs)
+{
+ GtkComposeTable *table;
+
+ g_return_if_fail (GTK_IS_IM_CONTEXT_SIMPLE (context_simple));
+ g_return_if_fail (data != NULL);
+ g_return_if_fail (max_seq_len <= GTK_MAX_COMPOSE_LEN);
- ch = gdk_keyval_to_unicode (event->keyval);
- if (ch != 0)
- {
- gtk_im_context_simple_commit_char (context, ch);
- return TRUE;
- }
- else
- return FALSE;
+ table = g_new (GtkComposeTable, 1);
+ table->data = data;
+ table->max_seq_len = max_seq_len;
+ table->n_seqs = n_seqs;
+
+ context_simple->tables = g_slist_prepend (context_simple->tables, table);
}
+
diff --git a/gtk/gtkimcontextsimple.h b/gtk/gtkimcontextsimple.h
index 80e3b2246b..f166d82b47 100644
--- a/gtk/gtkimcontextsimple.h
+++ b/gtk/gtkimcontextsimple.h
@@ -38,13 +38,17 @@ extern "C" {
typedef struct _GtkIMContextSimple GtkIMContextSimple;
typedef struct _GtkIMContextSimpleClass GtkIMContextSimpleClass;
-#define GTK_MAX_COMPOSE_LEN 4
+#define GTK_MAX_COMPOSE_LEN 7
struct _GtkIMContextSimple
{
GtkIMContext object;
+
+ GSList *tables;
guint compose_buffer[GTK_MAX_COMPOSE_LEN + 1];
+ gunichar tentative_match;
+ gint tentative_match_len;
};
struct _GtkIMContextSimpleClass
@@ -53,8 +57,12 @@ struct _GtkIMContextSimpleClass
};
GtkType gtk_im_context_simple_get_type (void) G_GNUC_CONST;
-GtkIMContext *gtk_im_context_simple_new (void);
+GtkIMContext *gtk_im_context_simple_new (void);
+void gtk_im_context_simple_add_table (GtkIMContextSimple *context_simple,
+ guint16 *data,
+ gint max_seq_len,
+ gint n_seqs);
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gtk/gtkimmodule.c b/gtk/gtkimmodule.c
new file mode 100644
index 0000000000..353100720b
--- /dev/null
+++ b/gtk/gtkimmodule.c
@@ -0,0 +1,527 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * Themes added by The Rasterman <raster@redhat.com>
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <gmodule.h>
+#include <pango/pango-utils.h>
+#include "gtkimmodule.h"
+#include "gtkimcontextsimple.h"
+#include "gtkrc.h"
+#include "config.h"
+#include "gtkintl.h"
+
+#define SIMPLE_ID "gtk-im-context-simple"
+
+typedef struct _GtkIMModule GtkIMModule;
+typedef struct _GtkIMModuleClass GtkIMModuleClass;
+
+#define GTK_TYPE_IM_MODULE (gtk_im_module_get_type ())
+#define GTK_IM_MODULE(im_module) (G_TYPE_CHECK_INSTANCE_CAST ((im_module), GTK_TYPE_IM_MODULE, GtkIMModule))
+#define GTK_IS_IM_MODULE(im_module) (G_TYPE_CHECK_INSTANCE_TYPE ((im_module), GTK_TYPE_IM_MODULE))
+
+struct _GtkIMModule
+{
+ GTypeModule parent_instance;
+
+ GModule *library;
+
+ void (*list) (const GtkIMContextInfo ***contexts,
+ guint *n_contexts);
+ void (*init) (GTypeModule *module);
+ void (*exit) (void);
+ GtkIMContext *(*create) (const gchar *context_id);
+
+ GtkIMContextInfo **contexts;
+ guint n_contexts;
+
+ gchar *path;
+};
+
+struct _GtkIMModuleClass
+{
+ GTypeModuleClass parent_class;
+};
+
+GType gtk_im_module_get_type (void);
+
+gint n_loaded_contexts = 0;
+static GHashTable *contexts_hash = NULL;
+static GSList *modules_list = NULL;
+
+static GObjectClass *parent_class = NULL;
+
+static gboolean
+gtk_im_module_load (GTypeModule *module)
+{
+ GtkIMModule *im_module = GTK_IM_MODULE (module);
+
+ im_module->library = g_module_open (im_module->path, 0);
+ if (!im_module->library)
+ {
+ g_warning (g_module_error());
+ return FALSE;
+ }
+
+ /* extract symbols from the lib */
+ if (!g_module_symbol (im_module->library, "im_module_init",
+ (gpointer *)&im_module->init) ||
+ !g_module_symbol (im_module->library, "im_module_exit",
+ (gpointer *)&im_module->exit) ||
+ !g_module_symbol (im_module->library, "im_module_list",
+ (gpointer *)&im_module->list) ||
+ !g_module_symbol (im_module->library, "im_module_create",
+ (gpointer *)&im_module->create))
+ {
+ g_warning (g_module_error());
+ g_module_close (im_module->library);
+
+ return FALSE;
+ }
+
+ /* call the theme's init (theme_init) function to let it */
+ /* setup anything it needs to set up. */
+ im_module->init (module);
+
+ return TRUE;
+}
+
+static void
+gtk_im_module_unload (GTypeModule *module)
+{
+ GtkIMModule *im_module = GTK_IM_MODULE (module);
+
+ im_module->exit();
+
+ g_module_close (im_module->library);
+ im_module->library = NULL;
+
+ im_module->init = NULL;
+ im_module->exit = NULL;
+ im_module->list = NULL;
+ im_module->create = NULL;
+}
+
+/* This only will ever be called if an error occurs during
+ * initialization
+ */
+static void
+gtk_im_module_finalize (GObject *object)
+{
+ GtkIMModule *module = GTK_IM_MODULE (object);
+
+ g_free (module->path);
+
+ parent_class->finalize (object);
+}
+
+static void
+gtk_im_module_class_init (GtkIMModuleClass *class)
+{
+ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
+ GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+
+ parent_class = G_OBJECT_CLASS (g_type_class_peek_parent (class));
+
+ module_class->load = gtk_im_module_load;
+ module_class->unload = gtk_im_module_unload;
+
+ gobject_class->finalize = gtk_im_module_finalize;
+}
+
+GType
+gtk_im_module_get_type (void)
+{
+ static GType im_module_type = 0;
+
+ if (!im_module_type)
+ {
+ static const GTypeInfo im_module_info = {
+ sizeof (GtkIMModuleClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_im_module_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkIMModule),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
+
+ im_module_type = g_type_register_static (G_TYPE_TYPE_MODULE, "GtkIMModule", &im_module_info, 0);
+ }
+
+ return im_module_type;
+}
+
+static void
+free_info (GtkIMContextInfo *info)
+{
+ g_free ((char *)info->context_id);
+ g_free ((char *)info->context_name);
+ g_free ((char *)info->domain);
+ g_free ((char *)info->domain_dirname);
+ g_free ((char *)info->default_locales);
+ g_free (info);
+}
+
+static void
+add_module (GtkIMModule *module, GSList *infos)
+{
+ GSList *tmp_list = infos;
+ gint i = 0;
+ gint n = g_slist_length (infos);
+ module->contexts = g_new (GtkIMContextInfo *, n);
+
+ while (tmp_list)
+ {
+ GtkIMContextInfo *info = tmp_list->data;
+
+ if (g_hash_table_lookup (contexts_hash, info->context_id))
+ {
+ free_info (info); /* Duplicate */
+ }
+ else
+ {
+ g_hash_table_insert (contexts_hash, (char *)info->context_id, module);
+ module->contexts[i++] = tmp_list->data;
+ n_loaded_contexts++;
+ }
+
+ tmp_list = tmp_list->next;
+ }
+ g_slist_free (infos);
+ module->n_contexts = i;
+
+ modules_list = g_slist_prepend (modules_list, module);
+}
+
+static void
+gtk_im_module_init ()
+{
+ GString *line_buf = g_string_new (NULL);
+ GString *tmp_buf = g_string_new (NULL);
+ const gchar *filename = gtk_rc_get_im_module_file();
+ FILE *file;
+ gboolean have_error = FALSE;
+
+ GtkIMModule *module = NULL;
+ GSList *infos = NULL;
+
+ contexts_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ file = fopen (filename, "r");
+ if (!file)
+ {
+ g_warning ("Can not open Input Method module file '%s': %s",
+ filename, g_strerror (errno));
+ return;
+ }
+
+ while (!have_error && pango_read_line (file, line_buf))
+ {
+ const char *p;
+
+ p = line_buf->str;
+
+ if (!pango_skip_space (&p))
+ {
+ /* Blank line marking the end of a module
+ */
+ if (module && *p != '#')
+ {
+ add_module (module, infos);
+ module = NULL;
+ infos = NULL;
+ }
+
+ continue;
+ }
+
+ if (!module)
+ {
+ /* Read a module location
+ */
+ module = g_object_new (GTK_TYPE_IM_MODULE, NULL);
+
+ if (!pango_scan_string (&p, tmp_buf) ||
+ pango_skip_space (&p))
+ {
+ g_warning ("Error parsing context info in '%s'\n %s",
+ filename, line_buf->str);
+ have_error = TRUE;
+ }
+
+ module->path = g_strdup (tmp_buf->str);
+ g_type_module_set_name (G_TYPE_MODULE (module), module->path);
+ }
+ else
+ {
+ GtkIMContextInfo *info = g_new0 (GtkIMContextInfo, 1);
+
+ /* Read information about a context type
+ */
+ if (!pango_scan_string (&p, tmp_buf))
+ goto context_error;
+ info->context_id = g_strdup (tmp_buf->str);
+
+ if (!pango_scan_string (&p, tmp_buf))
+ goto context_error;
+ info->context_name = g_strdup (tmp_buf->str);
+
+ if (!pango_scan_string (&p, tmp_buf))
+ goto context_error;
+ info->domain = g_strdup (tmp_buf->str);
+
+ if (!pango_scan_string (&p, tmp_buf))
+ goto context_error;
+ info->domain_dirname = g_strdup (tmp_buf->str);
+
+ if (!pango_scan_string (&p, tmp_buf))
+ goto context_error;
+ info->default_locales = g_strdup (tmp_buf->str);
+
+ if (pango_skip_space (&p))
+ goto context_error;
+
+ infos = g_slist_prepend (infos, info);
+ continue;
+
+ context_error:
+ g_warning ("Error parsing context info in '%s'\n %s",
+ filename, line_buf->str);
+ have_error = TRUE;
+ }
+ }
+
+ if (have_error)
+ {
+ GSList *tmp_list = infos;
+ while (tmp_list)
+ {
+ free_info (tmp_list->data);
+ tmp_list = tmp_list->next;
+ }
+ g_slist_free (infos);
+
+ g_object_unref (G_OBJECT (module));
+ }
+ else if (module)
+ add_module (module, infos);
+
+ fclose (file);
+ g_string_free (line_buf, TRUE);
+ g_string_free (tmp_buf, TRUE);
+}
+
+/**
+ * _gtk_im_module_list:
+ * @contexts: location to store an array of pointers to #GtkIMContextInfo
+ * this array should be freed with g_free() when you are finished.
+ * The structures it points are statically allocated and should
+ * not be modified or freed.
+ * @n_contexts: the length of the array stored in @contexts
+ *
+ * List all available types of input method context
+ **/
+void
+_gtk_im_module_list (const GtkIMContextInfo ***contexts,
+ guint *n_contexts)
+{
+ int n = 0;
+
+ static const GtkIMContextInfo simple_context_info = {
+ SIMPLE_ID,
+ "Default",
+ "gtk+",
+ NULL,
+ ""
+ };
+
+ if (!contexts_hash)
+ gtk_im_module_init ();
+
+ if (n_contexts)
+ *n_contexts = (n_loaded_contexts + 1);
+
+ if (contexts)
+ {
+ GSList *tmp_list;
+ int i;
+
+ *contexts = g_new (const GtkIMContextInfo *, n_loaded_contexts + 1);
+
+ (*contexts)[n++] = &simple_context_info;
+
+ tmp_list = modules_list;
+ while (tmp_list)
+ {
+ GtkIMModule *module = tmp_list->data;
+
+ for (i=0; i<module->n_contexts; i++)
+ (*contexts)[n++] = module->contexts[i];
+
+ tmp_list = tmp_list->next;
+ }
+ }
+}
+
+/**
+ * _gtk_im_module_create:
+ * @context_id: the context ID for the context type to create
+ *
+ * Create an IM context of a type specified by the string
+ * ID @context_id.
+ *
+ * Return value: a newly created input context of or @context_id, or
+ * if that could not be created, a newly created GtkIMContextSimple.
+ **/
+GtkIMContext *
+_gtk_im_module_create (const gchar *context_id)
+{
+ GtkIMModule *im_module;
+ GtkIMContext *context = NULL;
+
+ if (!contexts_hash)
+ gtk_im_module_init ();
+
+ if (strcmp (context_id, SIMPLE_ID) != 0)
+ {
+ im_module = g_hash_table_lookup (contexts_hash, context_id);
+ if (!im_module)
+ {
+ g_warning ("Attempt to load unknown IM context type '%s'", context_id);
+ }
+ else
+ {
+ if (g_type_module_use (G_TYPE_MODULE (im_module)))
+ {
+ context = im_module->create (context_id);
+ g_type_module_unuse (G_TYPE_MODULE (im_module));
+ }
+
+ if (!context)
+ g_warning ("Loading IM context type '%s' failed", context_id);
+ }
+ }
+
+ if (!context)
+ return gtk_im_context_simple_new ();
+ else
+ return context;
+}
+
+/* Match @locale against @against.
+ *
+ * 'en_US' against 'en_US' => 3
+ * 'en_US' against 'en' => 2
+ * 'en', 'en_UK' against 'en_US' => 1
+ */
+static gint
+match_locale (const gchar *locale,
+ const gchar *against,
+ gint against_len)
+{
+ if (strcmp (locale, against) == 0)
+ return 3;
+
+ if (strncmp (locale, against, 2) == 0)
+ return (against_len == 2) ? 2 : 1;
+
+ return 0;
+}
+
+/**
+ * _gtk_im_module_get_default_context_id:
+ * @locale: a locale id in the form 'en_US'
+ *
+ * Return the context_id of the best IM context type
+ * for the given locale ID.
+ *
+ * Return value: the context ID (will never be %NULL)
+ * the value is newly allocated and must be freed
+ * with g_free().
+ **/
+const gchar *
+_gtk_im_module_get_default_context_id (const gchar *locale)
+{
+ GSList *tmp_list;
+ const gchar *context_id = NULL;
+ gint best_goodness = 0;
+ gint i;
+ gchar *tmp_locale, *tmp;
+ gchar *envvar;
+
+ if (!contexts_hash)
+ gtk_im_module_init ();
+
+ envvar = g_getenv ("GTK_IM_MODULE");
+ if (envvar && g_hash_table_lookup (contexts_hash, envvar))
+ return g_strdup (envvar);
+
+ /* Strip the locale code down to the essentials
+ */
+ tmp_locale = g_strdup (locale);
+ tmp = strchr (tmp_locale, '.');
+ if (tmp)
+ *tmp = '\0';
+ tmp = strchr (tmp_locale, '@');
+ if (tmp)
+ *tmp = '\0';
+
+ tmp_list = modules_list;
+ while (tmp_list)
+ {
+ GtkIMModule *module = tmp_list->data;
+
+ for (i=0; i<module->n_contexts; i++)
+ {
+ const gchar *p = module->contexts[i]->default_locales;
+ while (p)
+ {
+ const gchar *q = strchr (p, ':');
+ gint goodness = match_locale (tmp_locale, p, q ? q - p : strlen (p));
+
+ if (goodness > best_goodness)
+ {
+ context_id = module->contexts[i]->context_id;
+ best_goodness = goodness;
+ }
+
+ p = q ? q + 1 : NULL;
+ }
+ }
+
+ tmp_list = tmp_list->next;
+ }
+
+ g_free (tmp_locale);
+
+ return g_strdup (context_id ? context_id : SIMPLE_ID);
+}
diff --git a/gtk/gtkimmodule.h b/gtk/gtkimmodule.h
new file mode 100644
index 0000000000..d9ce11b68e
--- /dev/null
+++ b/gtk/gtkimmodule.h
@@ -0,0 +1,62 @@
+/* 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_IM_MODULE_H__
+#define __GTK_IM_MODULE_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#include <gtk/gtkimcontext.h>
+
+typedef struct _GtkIMContextInfo GtkIMContextInfo;
+
+struct _GtkIMContextInfo
+{
+ const gchar *context_id;
+ const gchar *context_name;
+ const gchar *domain;
+ const gchar *domain_dirname;
+ const gchar *default_locales;
+};
+
+/* Functions for use within GTK+
+ */
+void _gtk_im_module_list (const GtkIMContextInfo ***contexts,
+ guint *n_contexts);
+GtkIMContext *_gtk_im_module_create (const gchar *context_id);
+const gchar * _gtk_im_module_get_default_context_id (const gchar *lang);
+
+/* The following entry points are exported by each input method module
+ */
+
+/*
+void im_module_list (const GtkIMContextInfo ***contexts,
+ guint *n_contexts);
+void im_module_init (GtkModule *module);
+void im_module_exit (void);
+GtkIMContext *im_module_create (const gchar *context_id);
+*/
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif __GTK_IM_MODULE_H__
diff --git a/gtk/gtkimmulticontext.c b/gtk/gtkimmulticontext.c
index 58b8296a18..2ec808356f 100644
--- a/gtk/gtkimmulticontext.c
+++ b/gtk/gtkimmulticontext.c
@@ -17,9 +17,18 @@
* Boston, MA 02111-1307, USA.
*/
+#include <string.h>
+
+#ifdef GDK_WINDOWING_X11
+#include <X11/Xlocale.h> /* so we get the right setlocale */
+#else
+#include <locale.h>
+#endif
+
#include "gtksignal.h"
#include "gtkimmulticontext.h"
-#include "gtkimcontextsimple.h"
+#include "gtkimmodule.h"
+#include "gtkmenuitem.h"
static void gtk_im_multicontext_class_init (GtkIMMulticontextClass *class);
static void gtk_im_multicontext_init (GtkIMMulticontext *im_multicontext);
@@ -32,11 +41,13 @@ static void gtk_im_multicontext_set_client_window (GtkIMContext
GdkWindow *window);
static void gtk_im_multicontext_get_preedit_string (GtkIMContext *context,
gchar **str,
- PangoAttrList **attrs);
+ PangoAttrList **attrs,
+ gint *cursor_pos);
static gboolean gtk_im_multicontext_filter_keypress (GtkIMContext *context,
GdkEventKey *event);
static void gtk_im_multicontext_focus_in (GtkIMContext *context);
static void gtk_im_multicontext_focus_out (GtkIMContext *context);
+static void gtk_im_multicontext_reset (GtkIMContext *context);
void gtk_im_multicontext_preedit_start_cb (GtkIMContext *slave,
GtkIMMulticontext *multicontext);
@@ -50,6 +61,8 @@ void gtk_im_multicontext_commit_cb (GtkIMContext
static GtkIMContextClass *parent_class;
+static const gchar *global_context_id = NULL;
+
GtkType
gtk_im_multicontext_get_type (void)
{
@@ -88,6 +101,7 @@ gtk_im_multicontext_class_init (GtkIMMulticontextClass *class)
im_context_class->filter_keypress = gtk_im_multicontext_filter_keypress;
im_context_class->focus_in = gtk_im_multicontext_focus_in;
im_context_class->focus_out = gtk_im_multicontext_focus_out;
+ im_context_class->reset = gtk_im_multicontext_reset;
gobject_class->finalize = gtk_im_multicontext_finalize;
}
@@ -141,6 +155,9 @@ gtk_im_multicontext_set_slave (GtkIMMulticontext *multicontext,
gtk_signal_connect (GTK_OBJECT (multicontext->slave), "commit",
GTK_SIGNAL_FUNC (gtk_im_multicontext_commit_cb),
multicontext);
+
+ if (multicontext->client_window)
+ gtk_im_context_set_client_window (slave, multicontext->client_window);
}
}
@@ -148,7 +165,22 @@ static GtkIMContext *
gtk_im_multicontext_get_slave (GtkIMMulticontext *multicontext)
{
if (!multicontext->slave)
- gtk_im_multicontext_set_slave (multicontext, gtk_im_context_simple_new ());
+ {
+ if (!global_context_id)
+ {
+ const char *locale;
+
+#ifdef HAVE_LC_MESSAGES
+ locale = setlocale (LC_MESSAGES, NULL);
+#else
+ locale = setlocale (LC_CTYPE, NULL);
+#endif
+ global_context_id = _gtk_im_module_get_default_context_id (locale);
+ }
+
+ gtk_im_multicontext_set_slave (multicontext, _gtk_im_module_create (global_context_id));
+ multicontext->context_id = global_context_id;
+ }
return multicontext->slave;
}
@@ -160,6 +192,8 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context,
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
+ multicontext->client_window = window;
+
if (slave)
gtk_im_context_set_client_window (slave, window);
}
@@ -167,13 +201,14 @@ gtk_im_multicontext_set_client_window (GtkIMContext *context,
static void
gtk_im_multicontext_get_preedit_string (GtkIMContext *context,
gchar **str,
- PangoAttrList **attrs)
+ PangoAttrList **attrs,
+ gint *cursor_pos)
{
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
if (slave)
- gtk_im_context_get_preedit_string (slave, str, attrs);
+ gtk_im_context_get_preedit_string (slave, str, attrs, cursor_pos);
else
{
if (str)
@@ -200,7 +235,17 @@ static void
gtk_im_multicontext_focus_in (GtkIMContext *context)
{
GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
- GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
+ GtkIMContext *slave;
+
+ /* If the global context type is different from the context we were
+ * using before, get rid of the old slave and create a new one
+ * for the new global context type.
+ */
+ if (!multicontext->context_id ||
+ strcmp (global_context_id, multicontext->context_id) != 0)
+ gtk_im_multicontext_set_slave (multicontext, NULL);
+
+ slave = gtk_im_multicontext_get_slave (multicontext);
if (slave)
gtk_im_context_focus_in (slave);
@@ -216,6 +261,16 @@ gtk_im_multicontext_focus_out (GtkIMContext *context)
gtk_im_context_focus_out (slave);
}
+static void
+gtk_im_multicontext_reset (GtkIMContext *context)
+{
+ GtkIMMulticontext *multicontext = GTK_IM_MULTICONTEXT (context);
+ GtkIMContext *slave = gtk_im_multicontext_get_slave (multicontext);
+
+ if (slave)
+ gtk_im_context_reset (slave);
+}
+
void
gtk_im_multicontext_preedit_start_cb (GtkIMContext *slave,
GtkIMMulticontext *multicontext)
@@ -245,3 +300,49 @@ gtk_im_multicontext_commit_cb (GtkIMContext *slave,
gtk_signal_emit_by_name (GTK_OBJECT (multicontext), "commit", str);;
}
+static void
+activate_cb (GtkWidget *menuitem,
+ GtkIMMulticontext *context)
+{
+ const gchar *id = gtk_object_get_data (GTK_OBJECT (menuitem), "gtk-context-id");
+
+ gtk_im_context_reset (GTK_IM_CONTEXT (context));
+
+ global_context_id = id;
+ gtk_im_multicontext_set_slave (context, NULL);
+}
+
+/**
+ * gtk_im_multicontext_append_menuitems:
+ * @context: a #GtkIMMultiContext
+ * @menushell: a #GtkMenuShell
+ *
+ * Add menuitems for various available input methods to a menu;
+ * the menuitems, when selected, will switch the input method
+ * for the context and the global default input method.
+ **/
+void
+gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
+ GtkMenuShell *menushell)
+{
+ const GtkIMContextInfo **contexts;
+ gint n_contexts, i;
+
+ _gtk_im_module_list (&contexts, &n_contexts);
+
+ for (i=0; i < n_contexts; i++)
+ {
+ GtkWidget *menuitem;
+
+ menuitem = gtk_menu_item_new_with_label (contexts[i]->context_name);
+
+ gtk_object_set_data (GTK_OBJECT (menuitem), "gtk-context-id",
+ (char *)contexts[i]->context_id);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ activate_cb, context);
+
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (menushell, menuitem);
+ }
+}
+
diff --git a/gtk/gtkimmulticontext.h b/gtk/gtkimmulticontext.h
index bed52f01d7..faa8b294d5 100644
--- a/gtk/gtkimmulticontext.h
+++ b/gtk/gtkimmulticontext.h
@@ -21,6 +21,7 @@
#define __GTK_IM_MULTICONTEXT_H__
#include <gtk/gtkimcontext.h>
+#include <gtk/gtkmenushell.h>
#ifdef __cplusplus
extern "C" {
@@ -43,6 +44,10 @@ struct _GtkIMMulticontext
GtkIMContext object;
GtkIMContext *slave;
+
+ GdkWindow *client_window;
+
+ const gchar *context_id;
};
struct _GtkIMMulticontextClass
@@ -53,6 +58,9 @@ struct _GtkIMMulticontextClass
GtkType gtk_im_multicontext_get_type (void) G_GNUC_CONST;
GtkIMContext *gtk_im_multicontext_new (void);
+void gtk_im_multicontext_append_menuitems (GtkIMMulticontext *context,
+ GtkMenuShell *menushell);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/gtk/gtkoldeditable.c b/gtk/gtkoldeditable.c
new file mode 100644
index 0000000000..a085d0639c
--- /dev/null
+++ b/gtk/gtkoldeditable.c
@@ -0,0 +1,859 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include <ctype.h>
+#include <string.h>
+#include "gdk/gdkkeysyms.h"
+#include "gdk/gdki18n.h"
+#include "gtkclipboard.h"
+#include "gtkoldeditable.h"
+#include "gtkmain.h"
+#include "gtkselection.h"
+#include "gtksignal.h"
+
+#define MIN_EDITABLE_WIDTH 150
+#define DRAW_TIMEOUT 20
+#define INNER_BORDER 2
+
+enum {
+ CHANGED,
+ INSERT_TEXT,
+ DELETE_TEXT,
+ /* Binding actions */
+ ACTIVATE,
+ SET_EDITABLE,
+ MOVE_CURSOR,
+ MOVE_WORD,
+ MOVE_PAGE,
+ MOVE_TO_ROW,
+ MOVE_TO_COLUMN,
+ KILL_CHAR,
+ KILL_WORD,
+ KILL_LINE,
+ CUT_CLIPBOARD,
+ COPY_CLIPBOARD,
+ PASTE_CLIPBOARD,
+ LAST_SIGNAL
+};
+
+enum {
+ ARG_0,
+ ARG_TEXT_POSITION,
+ ARG_EDITABLE
+};
+
+/* values for selection info */
+
+enum {
+ TARGET_STRING,
+ TARGET_TEXT,
+ TARGET_COMPOUND_TEXT
+};
+
+static void gtk_old_editable_class_init (GtkOldEditableClass *klass);
+static void gtk_old_editable_editable_init (GtkEditableClass *iface);
+static void gtk_old_editable_init (GtkOldEditable *editable);
+static void gtk_old_editable_set_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id);
+static void gtk_old_editable_get_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id);
+static void *gtk_old_editable_get_public_chars (GtkOldEditable *old_editable,
+ gint start,
+ gint end);
+
+static gint gtk_old_editable_selection_clear (GtkWidget *widget,
+ GdkEventSelection *event);
+static void gtk_old_editable_selection_get (GtkWidget *widget,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time);
+static void gtk_old_editable_selection_received (GtkWidget *widget,
+ GtkSelectionData *selection_data,
+ guint time);
+
+static void gtk_old_editable_set_selection (GtkOldEditable *old_editable,
+ gint start,
+ gint end);
+
+static void gtk_old_editable_real_set_editable (GtkOldEditable *old_editable,
+ gboolean is_editable);
+static void gtk_old_editable_real_cut_clipboard (GtkOldEditable *old_editable);
+static void gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable);
+static void gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable);
+
+static void gtk_old_editable_insert_text (GtkEditable *editable,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position);
+static void gtk_old_editable_delete_text (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos);
+static gchar * gtk_old_editable_get_chars (GtkEditable *editable,
+ gint start,
+ gint end);
+static void gtk_old_editable_set_selection_bounds (GtkEditable *editable,
+ gint start,
+ gint end);
+static gboolean gtk_old_editable_get_selection_bounds (GtkEditable *editable,
+ gint *start,
+ gint *end);
+static void gtk_old_editable_set_position (GtkEditable *editable,
+ gint position);
+static gint gtk_old_editable_get_position (GtkEditable *editable);
+
+static GtkWidgetClass *parent_class = NULL;
+static guint editable_signals[LAST_SIGNAL] = { 0 };
+
+GtkType
+gtk_old_editable_get_type (void)
+{
+ static GtkType old_editable_type = 0;
+
+ if (!old_editable_type)
+ {
+ static const GtkTypeInfo old_editable_info =
+ {
+ "GtkOldEditable",
+ sizeof (GtkOldEditable),
+ sizeof (GtkOldEditableClass),
+ (GtkClassInitFunc) gtk_old_editable_class_init,
+ (GtkObjectInitFunc) gtk_old_editable_init,
+ /* reserved_1 */ NULL,
+ /* reserved_2 */ NULL,
+ (GtkClassInitFunc) NULL,
+ };
+
+ static const GInterfaceInfo editable_info =
+ {
+ (GInterfaceInitFunc) gtk_old_editable_editable_init, /* interface_init */
+ NULL, /* interface_finalize */
+ NULL /* interface_data */
+ };
+
+ old_editable_type = gtk_type_unique (GTK_TYPE_WIDGET, &old_editable_info);
+ g_type_add_interface_static (old_editable_type,
+ GTK_TYPE_EDITABLE,
+ &editable_info);
+ }
+
+ return old_editable_type;
+}
+
+static void
+gtk_old_editable_class_init (GtkOldEditableClass *class)
+{
+ GtkObjectClass *object_class;
+ GtkWidgetClass *widget_class;
+
+ object_class = (GtkObjectClass*) class;
+ widget_class = (GtkWidgetClass*) class;
+
+ parent_class = gtk_type_class (GTK_TYPE_WIDGET);
+
+ editable_signals[CHANGED] =
+ gtk_signal_new ("changed",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, changed),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
+ editable_signals[INSERT_TEXT] =
+ gtk_signal_new ("insert_text",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, insert_text),
+ gtk_marshal_NONE__POINTER_INT_POINTER,
+ GTK_TYPE_NONE,
+ 3,
+ GTK_TYPE_STRING,
+ GTK_TYPE_INT,
+ GTK_TYPE_POINTER);
+
+ editable_signals[DELETE_TEXT] =
+ gtk_signal_new ("delete_text",
+ GTK_RUN_LAST,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, delete_text),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE,
+ 2,
+ GTK_TYPE_INT,
+ GTK_TYPE_INT);
+
+ editable_signals[ACTIVATE] =
+ gtk_signal_new ("activate",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, activate),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+ widget_class->activate_signal = editable_signals[ACTIVATE];
+
+ editable_signals[SET_EDITABLE] =
+ gtk_signal_new ("set-editable",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, set_editable),
+ gtk_marshal_NONE__BOOL,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_BOOL);
+
+ editable_signals[MOVE_CURSOR] =
+ gtk_signal_new ("move_cursor",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_cursor),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 2,
+ GTK_TYPE_INT,
+ GTK_TYPE_INT);
+
+ editable_signals[MOVE_WORD] =
+ gtk_signal_new ("move_word",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_word),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_INT);
+
+ editable_signals[MOVE_PAGE] =
+ gtk_signal_new ("move_page",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_page),
+ gtk_marshal_NONE__INT_INT,
+ GTK_TYPE_NONE, 2,
+ GTK_TYPE_INT,
+ GTK_TYPE_INT);
+
+ editable_signals[MOVE_TO_ROW] =
+ gtk_signal_new ("move_to_row",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_to_row),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_INT);
+
+ editable_signals[MOVE_TO_COLUMN] =
+ gtk_signal_new ("move_to_column",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, move_to_column),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_INT);
+
+ editable_signals[KILL_CHAR] =
+ gtk_signal_new ("kill_char",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_char),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_INT);
+
+ editable_signals[KILL_WORD] =
+ gtk_signal_new ("kill_word",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_word),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_INT);
+
+ editable_signals[KILL_LINE] =
+ gtk_signal_new ("kill_line",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, kill_line),
+ gtk_marshal_NONE__INT,
+ GTK_TYPE_NONE, 1,
+ GTK_TYPE_INT);
+
+ editable_signals[CUT_CLIPBOARD] =
+ gtk_signal_new ("cut_clipboard",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, cut_clipboard),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
+ editable_signals[COPY_CLIPBOARD] =
+ gtk_signal_new ("copy_clipboard",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, copy_clipboard),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
+ editable_signals[PASTE_CLIPBOARD] =
+ gtk_signal_new ("paste_clipboard",
+ GTK_RUN_LAST | GTK_RUN_ACTION,
+ GTK_CLASS_TYPE (object_class),
+ GTK_SIGNAL_OFFSET (GtkOldEditableClass, paste_clipboard),
+ gtk_marshal_NONE__NONE,
+ GTK_TYPE_NONE, 0);
+
+ gtk_object_class_add_signals (object_class, editable_signals, LAST_SIGNAL);
+
+ gtk_object_add_arg_type ("GtkOldEditable::text_position", GTK_TYPE_INT, GTK_ARG_READWRITE, ARG_TEXT_POSITION);
+ gtk_object_add_arg_type ("GtkOldEditable::editable", GTK_TYPE_BOOL, GTK_ARG_READWRITE, ARG_EDITABLE);
+
+ object_class->set_arg = gtk_old_editable_set_arg;
+ object_class->get_arg = gtk_old_editable_get_arg;
+
+ widget_class->selection_clear_event = gtk_old_editable_selection_clear;
+ widget_class->selection_received = gtk_old_editable_selection_received;
+ widget_class->selection_get = gtk_old_editable_selection_get;
+
+ class->insert_text = NULL;
+ class->delete_text = NULL;
+
+ class->activate = NULL;
+ class->set_editable = gtk_old_editable_real_set_editable;
+
+ class->move_cursor = NULL;
+ class->move_word = NULL;
+ class->move_page = NULL;
+ class->move_to_row = NULL;
+ class->move_to_column = NULL;
+
+ class->kill_char = NULL;
+ class->kill_word = NULL;
+ class->kill_line = NULL;
+
+ class->cut_clipboard = gtk_old_editable_real_cut_clipboard;
+ class->copy_clipboard = gtk_old_editable_real_copy_clipboard;
+ class->paste_clipboard = gtk_old_editable_real_paste_clipboard;
+
+ class->update_text = NULL;
+ class->get_chars = NULL;
+ class->set_selection = NULL;
+ class->set_position = NULL;
+}
+
+static void
+gtk_old_editable_editable_init (GtkEditableClass *iface)
+{
+ iface->insert_text = gtk_old_editable_insert_text;
+ iface->delete_text = gtk_old_editable_delete_text;
+ iface->get_chars = gtk_old_editable_get_chars;
+ iface->set_selection_bounds = gtk_old_editable_set_selection_bounds;
+ iface->get_selection_bounds = gtk_old_editable_get_selection_bounds;
+ iface->set_position = gtk_old_editable_set_position;
+ iface->get_position = gtk_old_editable_get_position;
+}
+
+static void
+gtk_old_editable_set_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id)
+{
+ GtkEditable *editable = GTK_EDITABLE (object);
+
+ switch (arg_id)
+ {
+ case ARG_TEXT_POSITION:
+ gtk_editable_set_position (editable, GTK_VALUE_INT (*arg));
+ break;
+ case ARG_EDITABLE:
+ gtk_signal_emit (object, editable_signals[SET_EDITABLE],
+ GTK_VALUE_BOOL (*arg) != FALSE);
+ break;
+ default:
+ break;
+ }
+}
+
+static void
+gtk_old_editable_get_arg (GtkObject *object,
+ GtkArg *arg,
+ guint arg_id)
+{
+ GtkOldEditable *old_editable;
+
+ old_editable = GTK_OLD_EDITABLE (object);
+
+ switch (arg_id)
+ {
+ case ARG_TEXT_POSITION:
+ GTK_VALUE_INT (*arg) = old_editable->current_pos;
+ break;
+ case ARG_EDITABLE:
+ GTK_VALUE_BOOL (*arg) = old_editable->editable;
+ break;
+ default:
+ arg->type = GTK_TYPE_INVALID;
+ break;
+ }
+}
+
+static void
+gtk_old_editable_init (GtkOldEditable *old_editable)
+{
+ static const GtkTargetEntry targets[] = {
+ { "UTF8_STRING", 0, 0 },
+ { "STRING", 0, 0 },
+ { "TEXT", 0, 0 },
+ { "COMPOUND_TEXT", 0, 0 }
+ };
+
+ GTK_WIDGET_SET_FLAGS (old_editable, GTK_CAN_FOCUS);
+
+ old_editable->selection_start_pos = 0;
+ old_editable->selection_end_pos = 0;
+ old_editable->has_selection = FALSE;
+ old_editable->editable = 1;
+ old_editable->visible = 1;
+ old_editable->clipboard_text = NULL;
+
+#ifdef USE_XIM
+ old_editable->ic = NULL;
+#endif
+
+ gtk_selection_add_targets (GTK_WIDGET (old_editable), GDK_SELECTION_PRIMARY,
+ targets, G_N_ELEMENTS (targets));
+}
+
+static void
+gtk_old_editable_insert_text (GtkEditable *editable,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position)
+{
+ gchar buf[64];
+ gchar *text;
+
+ gtk_widget_ref (GTK_WIDGET (editable));
+
+ if (new_text_length <= 63)
+ text = buf;
+ else
+ text = g_new (gchar, new_text_length + 1);
+
+ text[new_text_length] = '\0';
+ strncpy (text, new_text, new_text_length);
+
+ gtk_signal_emit (GTK_OBJECT (editable), editable_signals[INSERT_TEXT], text, new_text_length, position);
+ gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
+
+ if (new_text_length > 63)
+ g_free (text);
+
+ gtk_widget_unref (GTK_WIDGET (editable));
+}
+
+static void
+gtk_old_editable_delete_text (GtkEditable *editable,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
+
+ gtk_widget_ref (GTK_WIDGET (old_editable));
+
+ gtk_signal_emit (GTK_OBJECT (old_editable), editable_signals[DELETE_TEXT], start_pos, end_pos);
+ gtk_signal_emit (GTK_OBJECT (old_editable), editable_signals[CHANGED]);
+
+ if (old_editable->selection_start_pos == old_editable->selection_end_pos &&
+ old_editable->has_selection)
+ gtk_old_editable_claim_selection (old_editable, FALSE, GDK_CURRENT_TIME);
+
+ gtk_widget_unref (GTK_WIDGET (old_editable));
+}
+
+static void
+gtk_old_editable_update_text (GtkOldEditable *old_editable,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (old_editable);
+ klass->update_text (GTK_OLD_EDITABLE (old_editable), start_pos, end_pos);
+}
+
+static gchar *
+gtk_old_editable_get_chars (GtkEditable *editable,
+ gint start,
+ gint end)
+{
+ GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (editable);
+ return klass->get_chars (GTK_OLD_EDITABLE (editable), start, end);
+}
+
+/*
+ * Like gtk_editable_get_chars, but if the editable is not
+ * visible, return asterisks; also convert result to UTF-8.
+ */
+static void *
+gtk_old_editable_get_public_chars (GtkOldEditable *old_editable,
+ gint start,
+ gint end)
+{
+ gchar *str = NULL;
+ gchar *charset;
+ gboolean need_conversion = !g_get_charset (&charset);
+
+ if (old_editable->visible)
+ {
+ GError *error;
+ gchar *tmp = gtk_editable_get_chars (GTK_EDITABLE (old_editable), start, end);
+
+ if (need_conversion)
+ {
+ str = g_convert (tmp, -1,
+ "UTF-8", charset,
+ NULL, NULL, &error);
+
+ if (!str)
+ {
+ g_warning ("Cannot convert text from charset to UTF-8 %s: %s", charset, error->message);
+ g_error_free (error);
+ }
+
+ g_free (tmp);
+ }
+ else
+ str = tmp;
+ }
+ else
+ {
+ gint i;
+ gint nchars = end - start;
+
+ if (nchars < 0)
+ nchars = -nchars;
+
+ str = g_new (gchar, nchars + 1);
+ for (i = 0; i<nchars; i++)
+ str[i] = '*';
+ str[i] = '\0';
+ }
+
+ return str;
+}
+
+static void
+gtk_old_editable_set_selection (GtkOldEditable *old_editable,
+ gint start_pos,
+ gint end_pos)
+{
+ GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (old_editable);
+ klass->set_selection (old_editable, start_pos, end_pos);
+}
+
+static void
+gtk_old_editable_set_position (GtkEditable *editable,
+ gint position)
+{
+ GtkOldEditableClass *klass = GTK_OLD_EDITABLE_GET_CLASS (editable);
+
+ klass->set_position (GTK_OLD_EDITABLE (editable), position);
+}
+
+static gint
+gtk_old_editable_get_position (GtkEditable *editable)
+{
+ return GTK_OLD_EDITABLE (editable)->current_pos;
+}
+
+static gint
+gtk_old_editable_selection_clear (GtkWidget *widget,
+ GdkEventSelection *event)
+{
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
+
+ /* Let the selection handling code know that the selection
+ * has been changed, since we've overriden the default handler */
+ if (!gtk_selection_clear (widget, event))
+ return FALSE;
+
+ if (old_editable->has_selection)
+ {
+ old_editable->has_selection = FALSE;
+ gtk_old_editable_update_text (old_editable, old_editable->selection_start_pos,
+ old_editable->selection_end_pos);
+ }
+
+ return TRUE;
+}
+
+static void
+gtk_old_editable_selection_get (GtkWidget *widget,
+ GtkSelectionData *selection_data,
+ guint info,
+ guint time)
+{
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
+ gint selection_start_pos;
+ gint selection_end_pos;
+
+ gchar *str;
+
+ selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
+ selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
+
+ str = gtk_old_editable_get_public_chars (old_editable,
+ selection_start_pos,
+ selection_end_pos);
+
+ if (str)
+ {
+ gtk_selection_data_set_text (selection_data, str);
+ g_free (str);
+ }
+}
+
+static void
+gtk_old_editable_paste_received (GtkOldEditable *old_editable,
+ const gchar *text,
+ gboolean is_clipboard)
+{
+ const gchar *str = NULL;
+ gchar *charset;
+ gboolean need_conversion = FALSE;
+
+ if (text)
+ {
+ GError *error;
+
+ need_conversion = !g_get_charset (&charset);
+
+ if (need_conversion)
+ {
+ str = g_convert_with_fallback (text, -1,
+ charset, "UTF-8", NULL,
+ NULL, NULL, &error);
+ if (!str)
+ {
+ g_warning ("Cannot convert text from UTF-8 to %s: %s",
+ charset, error->message);
+ g_error_free (error);
+ return;
+ }
+ }
+ else
+ str = text;
+ }
+
+ if (str)
+ {
+ gboolean reselect;
+ gint old_pos;
+ gint tmp_pos;
+
+ reselect = FALSE;
+
+ if ((old_editable->selection_start_pos != old_editable->selection_end_pos) &&
+ (!old_editable->has_selection || is_clipboard))
+ {
+ reselect = TRUE;
+
+ /* Don't want to call gtk_editable_delete_selection here if we are going
+ * to reclaim the selection to avoid extra server traffic */
+ if (old_editable->has_selection)
+ {
+ gtk_editable_delete_text (GTK_EDITABLE (old_editable),
+ MIN (old_editable->selection_start_pos, old_editable->selection_end_pos),
+ MAX (old_editable->selection_start_pos, old_editable->selection_end_pos));
+ }
+ else
+ gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
+ }
+
+ tmp_pos = old_pos = old_editable->current_pos;
+
+ gtk_editable_insert_text (GTK_EDITABLE (old_editable), str, -1, &tmp_pos);
+
+ if (reselect)
+ gtk_old_editable_set_selection (old_editable, old_pos, old_editable->current_pos);
+
+ if (str && str != text)
+ g_free ((gchar *) str);
+ }
+}
+
+static void
+gtk_old_editable_selection_received (GtkWidget *widget,
+ GtkSelectionData *selection_data,
+ guint time)
+{
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (widget);
+
+ gchar *text = gtk_selection_data_get_text (selection_data);
+
+ if (!text)
+ {
+ /* If we asked for UTF8 and didn't get it, try text; if we asked
+ * for text and didn't get it, try string. If we asked for
+ * anything else and didn't get it, give up.
+ */
+ if (selection_data->target == gdk_atom_intern ("UTF8_STRING", FALSE))
+ {
+ gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
+ gdk_atom_intern ("TEXT", FALSE),
+ time);
+ return;
+ }
+ else if (selection_data->target == gdk_atom_intern ("TEXT", FALSE))
+ {
+ gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
+ GDK_TARGET_STRING,
+ time);
+ return;
+ }
+ }
+
+ if (text)
+ {
+ gtk_old_editable_paste_received (old_editable, text, FALSE);
+ g_free (text);
+ }
+}
+
+static void
+old_editable_text_received_cb (GtkClipboard *clipboard,
+ const gchar *text,
+ gpointer data)
+{
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (data);
+
+ gtk_old_editable_paste_received (old_editable, text, TRUE);
+ g_object_unref (G_OBJECT (old_editable));
+}
+
+void
+gtk_old_editable_claim_selection (GtkOldEditable *old_editable,
+ gboolean claim,
+ guint32 time)
+{
+ g_return_if_fail (old_editable != NULL);
+ g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable));
+ g_return_if_fail (GTK_WIDGET_REALIZED (old_editable));
+
+ old_editable->has_selection = FALSE;
+
+ if (claim)
+ {
+ if (gtk_selection_owner_set (GTK_WIDGET (old_editable), GDK_SELECTION_PRIMARY, time))
+ old_editable->has_selection = TRUE;
+ }
+ else
+ {
+ if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == GTK_WIDGET (old_editable)->window)
+ gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, time);
+ }
+}
+
+static void
+gtk_old_editable_set_selection_bounds (GtkEditable *editable,
+ gint start,
+ gint end)
+{
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
+
+ if (GTK_WIDGET_REALIZED (editable))
+ gtk_old_editable_claim_selection (old_editable, start != end, GDK_CURRENT_TIME);
+
+ gtk_old_editable_set_selection (old_editable, start, end);
+}
+
+static gboolean
+gtk_old_editable_get_selection_bounds (GtkEditable *editable,
+ gint *start,
+ gint *end)
+{
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (editable);
+
+ *start = old_editable->selection_start_pos;
+ *end = old_editable->selection_end_pos;
+
+ return (old_editable->selection_start_pos != old_editable->selection_end_pos);
+}
+
+static void
+gtk_old_editable_real_set_editable (GtkOldEditable *old_editable,
+ gboolean is_editable)
+{
+ is_editable = is_editable != FALSE;
+
+ if (old_editable->editable != is_editable)
+ {
+ old_editable->editable = is_editable;
+ gtk_widget_queue_draw (GTK_WIDGET (old_editable));
+ }
+}
+
+static void
+gtk_old_editable_real_cut_clipboard (GtkOldEditable *old_editable)
+{
+ gtk_old_editable_real_copy_clipboard (old_editable);
+ gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
+}
+
+static void
+gtk_old_editable_real_copy_clipboard (GtkOldEditable *old_editable)
+{
+ gint selection_start_pos;
+ gint selection_end_pos;
+
+ selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
+ selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
+
+ if (selection_start_pos != selection_end_pos)
+ {
+ gchar *text = gtk_old_editable_get_public_chars (old_editable,
+ selection_start_pos,
+ selection_end_pos);
+
+ if (text)
+ {
+ gtk_clipboard_set_text (gtk_clipboard_get (GDK_NONE), text, -1);
+ g_free (text);
+ }
+ }
+}
+
+static void
+gtk_old_editable_real_paste_clipboard (GtkOldEditable *old_editable)
+{
+ g_object_ref (G_OBJECT (old_editable));
+ gtk_clipboard_request_text (gtk_clipboard_get (GDK_NONE),
+ old_editable_text_received_cb, old_editable);
+}
+
+void
+gtk_old_editable_changed (GtkOldEditable *old_editable)
+{
+ g_return_if_fail (old_editable != NULL);
+ g_return_if_fail (GTK_IS_OLD_EDITABLE (old_editable));
+
+ gtk_signal_emit (GTK_OBJECT (old_editable), editable_signals[CHANGED]);
+}
diff --git a/gtk/gtkoldeditable.h b/gtk/gtkoldeditable.h
new file mode 100644
index 0000000000..5736539477
--- /dev/null
+++ b/gtk/gtkoldeditable.h
@@ -0,0 +1,142 @@
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
+ * file for a list of people on the GTK+ Team. See the ChangeLog
+ * files for a list of changes. These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __GTK_OLD_EDITABLE_H__
+#define __GTK_OLD_EDITABLE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkeditable.h>
+#include <gtk/gtkwidget.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+
+#define GTK_TYPE_OLD_EDITABLE (gtk_old_editable_get_type ())
+#define GTK_OLD_EDITABLE(obj) (GTK_CHECK_CAST ((obj), GTK_TYPE_OLD_EDITABLE, GtkOldEditable))
+#define GTK_OLD_EDITABLE_CLASS(klass) (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_OLD_EDITABLE, GtkOldEditableClass))
+#define GTK_IS_OLD_EDITABLE(obj) (GTK_CHECK_TYPE ((obj), GTK_TYPE_OLD_EDITABLE))
+#define GTK_IS_OLD_EDITABLE_CLASS(klass) (GTK_CHECK_CLASS_TYPE ((klass), GTK_TYPE_OLD_EDITABLE))
+#define GTK_OLD_EDITABLE_GET_CLASS(obj) (GTK_CHECK_GET_CLASS ((obj), GTK_TYPE_OLD_EDITABLE, GtkOldEditableClass))
+
+
+typedef struct _GtkOldEditable GtkOldEditable;
+typedef struct _GtkOldEditableClass GtkOldEditableClass;
+
+typedef void (*GtkTextFunction) (GtkOldEditable *editable, guint32 time);
+
+struct _GtkOldEditable
+{
+ GtkWidget widget;
+
+ /*< public >*/
+ guint current_pos;
+
+ guint selection_start_pos;
+ guint selection_end_pos;
+ guint has_selection : 1;
+
+ /*< private >*/
+ guint editable : 1;
+ guint visible : 1;
+ GdkIC *ic;
+ GdkICAttr *ic_attr;
+
+ gchar *clipboard_text;
+};
+
+struct _GtkOldEditableClass
+{
+ GtkWidgetClass parent_class;
+
+ /* Signals for notification/filtering of changes */
+ void (* changed) (GtkOldEditable *editable);
+ void (* insert_text) (GtkOldEditable *editable,
+ const gchar *text,
+ gint length,
+ gint *position);
+ void (* delete_text) (GtkOldEditable *editable,
+ gint start_pos,
+ gint end_pos);
+
+ /* Bindings actions */
+ void (* activate) (GtkOldEditable *editable);
+ void (* set_editable) (GtkOldEditable *editable,
+ gboolean is_editable);
+ void (* move_cursor) (GtkOldEditable *editable,
+ gint x,
+ gint y);
+ void (* move_word) (GtkOldEditable *editable,
+ gint n);
+ void (* move_page) (GtkOldEditable *editable,
+ gint x,
+ gint y);
+ void (* move_to_row) (GtkOldEditable *editable,
+ gint row);
+ void (* move_to_column) (GtkOldEditable *editable,
+ gint row);
+ void (* kill_char) (GtkOldEditable *editable,
+ gint direction);
+ void (* kill_word) (GtkOldEditable *editable,
+ gint direction);
+ void (* kill_line) (GtkOldEditable *editable,
+ gint direction);
+ void (* cut_clipboard) (GtkOldEditable *editable);
+ void (* copy_clipboard) (GtkOldEditable *editable);
+ void (* paste_clipboard) (GtkOldEditable *editable);
+
+ /* Virtual functions. get_chars is in paricular not a signal because
+ * it returns malloced memory. The others are not signals because
+ * they would not be particularly useful as such. (All changes to
+ * selection and position do not go through these functions)
+ */
+ void (* update_text) (GtkOldEditable *editable,
+ gint start_pos,
+ gint end_pos);
+ gchar* (* get_chars) (GtkOldEditable *editable,
+ gint start_pos,
+ gint end_pos);
+ void (* set_selection)(GtkOldEditable *editable,
+ gint start_pos,
+ gint end_pos);
+ void (* set_position) (GtkOldEditable *editable,
+ gint position);
+};
+
+GtkType gtk_old_editable_get_type (void) G_GNUC_CONST;
+void gtk_old_editable_claim_selection (GtkOldEditable *old_editable,
+ gboolean claim,
+ guint32 time);
+void gtk_old_editable_changed (GtkOldEditable *old_editable);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_OLD_EDITABLE_H__ */
diff --git a/gtk/gtkpreview.c b/gtk/gtkpreview.c
index 420bd0aa54..5e4da66dfd 100644
--- a/gtk/gtkpreview.c
+++ b/gtk/gtkpreview.c
@@ -184,7 +184,6 @@ gtk_preview_init (GtkPreview *preview)
void
gtk_preview_uninit (void)
{
-
/* unimplemented */
}
diff --git a/gtk/gtkrc.c b/gtk/gtkrc.c
index 70dfcdf084..06587a2dc9 100644
--- a/gtk/gtkrc.c
+++ b/gtk/gtkrc.c
@@ -26,9 +26,6 @@
#include "config.h"
-#include "glib.h"
-#include "gdkconfig.h"
-
#ifdef GDK_WINDOWING_X11
#include <X11/Xlocale.h> /* so we get the right setlocale */
#else
@@ -56,6 +53,9 @@
#include <io.h>
#endif
+#include <glib.h>
+#include "gdkconfig.h"
+
#include "gtkrc.h"
#include "gtkbindings.h"
#include "gtkthemes.h"
@@ -127,6 +127,8 @@ static guint gtk_rc_parse_pixmap_path (GScanner *scanner);
static void gtk_rc_parse_pixmap_path_string (gchar *pix_path);
static guint gtk_rc_parse_module_path (GScanner *scanner);
static void gtk_rc_parse_module_path_string (gchar *mod_path);
+static guint gtk_rc_parse_im_module_path (GScanner *scanner);
+static guint gtk_rc_parse_im_module_file (GScanner *scanner);
static guint gtk_rc_parse_path_pattern (GScanner *scanner);
static guint gtk_rc_parse_stock (GScanner *scanner,
GtkRcStyle *rc_style,
@@ -225,12 +227,17 @@ static const struct
{ "engine", GTK_RC_TOKEN_ENGINE },
{ "module_path", GTK_RC_TOKEN_MODULE_PATH },
{ "stock", GTK_RC_TOKEN_STOCK },
+ { "im_module_path", GTK_RC_TOKEN_IM_MODULE_PATH },
+ { "im_module_file", GTK_RC_TOKEN_IM_MODULE_FILE },
{ "LTR", GTK_RC_TOKEN_LTR },
{ "RTL", GTK_RC_TOKEN_RTL }
};
static const guint n_symbols = sizeof (symbols) / sizeof (symbols[0]);
+static gchar *im_module_path = NULL;
+static gchar *im_module_file = NULL;
+
static GHashTable *rc_style_ht = NULL;
static GHashTable *realized_style_ht = NULL;
static GSList *gtk_rc_sets_widget = NULL;
@@ -304,42 +311,80 @@ get_themes_directory (void)
#endif
-gchar *
-gtk_rc_get_theme_dir(void)
+static gchar *
+gtk_rc_make_default_dir (const gchar *type)
{
gchar *var, *path;
#ifndef G_OS_WIN32
- var = getenv("GTK_DATA_PREFIX");
+ var = getenv("GTK_EXE_PREFIX");
if (var)
- path = g_strdup_printf("%s%s", var, "/share/themes");
+ path = g_strdup_printf("%s%s%s", var, "/lib/gtk-2.0/" GTK_VERSION "/", type);
else
- path = g_strdup_printf("%s%s", GTK_DATA_PREFIX, "/share/themes");
+ path = g_strdup_printf("%s%s%s", GTK_EXE_PREFIX, "/lib/gtk-2.0/" GTK_VERSION "/", type);
#else
- path = g_strdup (get_themes_directory ());
+ path = g_strdup_printf ("%s\\%s", get_themes_directory (), type);
#endif
return path;
}
gchar *
-gtk_rc_get_module_dir(void)
+gtk_rc_get_im_module_path (void)
+{
+ gchar *result = g_getenv ("GTK_IM_MODULE_PATH");
+
+ if (!result)
+ {
+ if (im_module_path)
+ result = im_module_path;
+ else
+ return gtk_rc_make_default_dir ("immodules");
+ }
+
+ return g_strdup (result);
+}
+
+gchar *
+gtk_rc_get_im_module_file (void)
+{
+ gchar *result = g_getenv ("GTK_IM_MODULE_FILE");
+
+ if (!result)
+ {
+ if (im_module_file)
+ result = im_module_file;
+ else
+ result = GTK_SYSCONFDIR G_DIR_SEPARATOR_S "gtk-2.0" G_DIR_SEPARATOR_S "gtk.immodules";
+ }
+
+ return g_strdup (result);
+}
+
+gchar *
+gtk_rc_get_theme_dir(void)
{
gchar *var, *path;
#ifndef G_OS_WIN32
- var = getenv("GTK_EXE_PREFIX");
+ var = getenv("GTK_DATA_PREFIX");
if (var)
- path = g_strdup_printf("%s%s", var, "/lib/gtk-2.0/" GTK_VERSION "/engines");
+ path = g_strdup_printf("%s%s", var, "/share/themes");
else
- path = g_strdup_printf("%s%s", GTK_EXE_PREFIX, "/lib/gtk-2.0/" GTK_VERSION "/engines");
+ path = g_strdup_printf("%s%s", GTK_DATA_PREFIX, "/share/themes");
#else
- path = g_strdup_printf ("%s%s", get_themes_directory (), "\\engines");
+ path = g_strdup (get_themes_directory ());
#endif
return path;
}
+gchar *
+gtk_rc_get_module_dir(void)
+{
+ return gtk_rc_make_default_dir ("engines");
+}
+
static void
gtk_rc_append_default_module_path(void)
{
@@ -1544,6 +1589,12 @@ gtk_rc_parse_statement (GScanner *scanner)
case GTK_RC_TOKEN_MODULE_PATH:
return gtk_rc_parse_module_path (scanner);
+ case GTK_RC_TOKEN_IM_MODULE_PATH:
+ return gtk_rc_parse_im_module_path (scanner);
+
+ case GTK_RC_TOKEN_IM_MODULE_FILE:
+ return gtk_rc_parse_im_module_file (scanner);
+
default:
g_scanner_get_next_token (scanner);
return /* G_TOKEN_SYMBOL */ GTK_RC_TOKEN_STYLE;
@@ -2120,7 +2171,7 @@ gtk_rc_parse_engine (GScanner *scanner,
GtkRcStyleClass *new_class;
new_style = gtk_theme_engine_create_rc_style (engine);
- gtk_theme_engine_unref (engine);
+ g_type_module_unuse (G_TYPE_MODULE (engine));
new_class = GTK_RC_STYLE_GET_CLASS (new_style);
@@ -2460,6 +2511,48 @@ gtk_rc_parse_module_path (GScanner *scanner)
return G_TOKEN_NONE;
}
+static guint
+gtk_rc_parse_im_module_path (GScanner *scanner)
+{
+ guint token;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_IM_MODULE_FILE)
+ return GTK_RC_TOKEN_IM_MODULE_FILE;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_STRING)
+ return G_TOKEN_STRING;
+
+ if (im_module_path)
+ g_free (im_module_path);
+
+ im_module_path = g_strdup (scanner->value.v_string);
+
+ return G_TOKEN_NONE;
+}
+
+static guint
+gtk_rc_parse_im_module_file (GScanner *scanner)
+{
+ guint token;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != GTK_RC_TOKEN_IM_MODULE_FILE)
+ return GTK_RC_TOKEN_IM_MODULE_FILE;
+
+ token = g_scanner_get_next_token (scanner);
+ if (token != G_TOKEN_STRING)
+ return G_TOKEN_STRING;
+
+ if (im_module_file)
+ g_free (im_module_file);
+
+ im_module_file = g_strdup (scanner->value.v_string);
+
+ return G_TOKEN_NONE;
+}
+
static void
gtk_rc_parse_module_path_string (gchar *mod_path)
{
diff --git a/gtk/gtkrc.h b/gtk/gtkrc.h
index 0b37039311..5f281fc6cc 100644
--- a/gtk/gtkrc.h
+++ b/gtk/gtkrc.h
@@ -148,6 +148,8 @@ gchar* gtk_rc_find_pixmap_in_path (GScanner *scanner,
gchar* gtk_rc_find_module_in_path (const gchar *module_file);
gchar* gtk_rc_get_theme_dir (void);
gchar* gtk_rc_get_module_dir (void);
+gchar* gtk_rc_get_im_module_path (void);
+gchar* gtk_rc_get_im_module_file (void);
/* private functions/definitions */
typedef enum {
@@ -182,6 +184,8 @@ typedef enum {
GTK_RC_TOKEN_HIGHEST,
GTK_RC_TOKEN_ENGINE,
GTK_RC_TOKEN_MODULE_PATH,
+ GTK_RC_TOKEN_IM_MODULE_PATH,
+ GTK_RC_TOKEN_IM_MODULE_FILE,
GTK_RC_TOKEN_STOCK,
GTK_RC_TOKEN_LTR,
GTK_RC_TOKEN_RTL,
diff --git a/gtk/gtkspinbutton.c b/gtk/gtkspinbutton.c
index 4193ba28af..b5a55a8a9a 100644
--- a/gtk/gtkspinbutton.c
+++ b/gtk/gtkspinbutton.c
@@ -113,10 +113,10 @@ static gint gtk_spin_button_key_release (GtkWidget *widget,
GdkEventKey *event);
static gint gtk_spin_button_scroll (GtkWidget *widget,
GdkEventScroll *event);
-static void gtk_spin_button_activate (GtkEditable *editable);
+static void gtk_spin_button_activate (GtkEntry *entry);
static void gtk_spin_button_snap (GtkSpinButton *spin_button,
gfloat val);
-static void gtk_spin_button_insert_text (GtkEditable *editable,
+static void gtk_spin_button_insert_text (GtkEntry *entry,
const gchar *new_text,
gint new_text_length,
gint *position);
@@ -161,11 +161,11 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
- GtkEditableClass *editable_class;
+ GtkEntryClass *entry_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
- editable_class = (GtkEditableClass*) class;
+ entry_class = (GtkEntryClass*) class;
parent_class = gtk_type_class (GTK_TYPE_ENTRY);
@@ -192,8 +192,8 @@ gtk_spin_button_class_init (GtkSpinButtonClass *class)
widget_class->leave_notify_event = gtk_spin_button_leave_notify;
widget_class->focus_out_event = gtk_spin_button_focus_out;
- editable_class->insert_text = gtk_spin_button_insert_text;
- editable_class->activate = gtk_spin_button_activate;
+ entry_class->insert_text = gtk_spin_button_insert_text;
+ entry_class->activate = gtk_spin_button_activate;
class->input = NULL;
class->output = NULL;
@@ -756,7 +756,7 @@ gtk_spin_button_focus_out (GtkWidget *widget,
g_return_val_if_fail (GTK_IS_SPIN_BUTTON (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- if (GTK_EDITABLE (widget)->editable)
+ if (GTK_ENTRY (widget)->editable)
gtk_spin_button_update (GTK_SPIN_BUTTON (widget));
return GTK_WIDGET_CLASS (parent_class)->focus_out_event (widget, event);
@@ -813,7 +813,7 @@ gtk_spin_button_button_press (GtkWidget *widget,
gtk_grab_add (widget);
spin->button = event->button;
- if (GTK_EDITABLE (widget)->editable)
+ if (GTK_ENTRY (widget)->editable)
gtk_spin_button_update (spin);
if (event->y <= widget->requisition.height / 2)
@@ -1066,7 +1066,7 @@ gtk_spin_button_key_press (GtkWidget *widget,
key_repeat = (event->time == spin->ev_time);
- if (GTK_EDITABLE (widget)->editable &&
+ if (GTK_ENTRY (widget)->editable &&
(key == GDK_Up || key == GDK_Down ||
key == GDK_Page_Up || key == GDK_Page_Down))
gtk_spin_button_update (spin);
@@ -1204,30 +1204,21 @@ gtk_spin_button_snap (GtkSpinButton *spin_button,
}
static void
-gtk_spin_button_activate (GtkEditable *editable)
+gtk_spin_button_activate (GtkEntry *entry)
{
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_SPIN_BUTTON (editable));
-
- if (editable->editable)
- gtk_spin_button_update (GTK_SPIN_BUTTON (editable));
+ if (entry->editable)
+ gtk_spin_button_update (GTK_SPIN_BUTTON (entry));
}
static void
-gtk_spin_button_insert_text (GtkEditable *editable,
+gtk_spin_button_insert_text (GtkEntry *entry,
const gchar *new_text,
gint new_text_length,
gint *position)
{
- GtkEntry *entry;
- GtkSpinButton *spin;
+ GtkEditable *editable = GTK_EDITABLE (entry);
+ GtkSpinButton *spin = GTK_SPIN_BUTTON (editable);
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_SPIN_BUTTON (editable));
-
- entry = GTK_ENTRY (editable);
- spin = GTK_SPIN_BUTTON (editable);
-
if (spin->numeric)
{
struct lconv *lc;
@@ -1296,8 +1287,8 @@ gtk_spin_button_insert_text (GtkEditable *editable,
}
}
- GTK_EDITABLE_CLASS (parent_class)->insert_text (editable, new_text,
- new_text_length, position);
+ GTK_ENTRY_CLASS (parent_class)->insert_text (entry, new_text,
+ new_text_length, position);
}
static void
@@ -1565,7 +1556,7 @@ gtk_spin_button_set_snap_to_ticks (GtkSpinButton *spin_button,
if (new_val != spin_button->snap_to_ticks)
{
spin_button->snap_to_ticks = new_val;
- if (new_val && GTK_EDITABLE (spin_button)->editable)
+ if (new_val && GTK_ENTRY (spin_button)->editable)
gtk_spin_button_update (spin_button);
}
}
diff --git a/gtk/gtktext.c b/gtk/gtktext.c
index 5994b1949f..cd8bf8dde8 100644
--- a/gtk/gtktext.c
+++ b/gtk/gtktext.c
@@ -219,24 +219,24 @@ static void gtk_text_adjustment (GtkAdjustment *adjustment,
static void gtk_text_disconnect (GtkAdjustment *adjustment,
GtkText *text);
-static void gtk_text_insert_text (GtkEditable *editable,
- const gchar *new_text,
- gint new_text_length,
- gint *position);
-static void gtk_text_delete_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-static void gtk_text_update_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos);
-static gchar *gtk_text_get_chars (GtkEditable *editable,
- gint start,
- gint end);
-static void gtk_text_set_selection (GtkEditable *editable,
- gint start,
- gint end);
-static void gtk_text_real_set_editable (GtkEditable *editable,
- gboolean is_editable);
+static void gtk_text_insert_text (GtkOldEditable *old_editable,
+ const gchar *new_text,
+ gint new_text_length,
+ gint *position);
+static void gtk_text_delete_text (GtkOldEditable *old_editable,
+ gint start_pos,
+ gint end_pos);
+static void gtk_text_update_text (GtkOldEditable *old_editable,
+ gint start_pos,
+ gint end_pos);
+static gchar *gtk_text_get_chars (GtkOldEditable *old_editable,
+ gint start,
+ gint end);
+static void gtk_text_set_selection (GtkOldEditable *old_editable,
+ gint start,
+ gint end);
+static void gtk_text_real_set_editable (GtkOldEditable *old_editable,
+ gboolean is_editable);
/* Event handlers */
static void gtk_text_draw (GtkWidget *widget,
@@ -346,24 +346,24 @@ static void move_cursor_ver (GtkText *text, int count);
static void move_cursor_hor (GtkText *text, int count);
/* Binding actions */
-static void gtk_text_move_cursor (GtkEditable *editable,
- gint x,
- gint y);
-static void gtk_text_move_word (GtkEditable *editable,
- gint n);
-static void gtk_text_move_page (GtkEditable *editable,
- gint x,
- gint y);
-static void gtk_text_move_to_row (GtkEditable *editable,
- gint row);
-static void gtk_text_move_to_column (GtkEditable *editable,
- gint row);
-static void gtk_text_kill_char (GtkEditable *editable,
- gint direction);
-static void gtk_text_kill_word (GtkEditable *editable,
- gint direction);
-static void gtk_text_kill_line (GtkEditable *editable,
- gint direction);
+static void gtk_text_move_cursor (GtkOldEditable *old_editable,
+ gint x,
+ gint y);
+static void gtk_text_move_word (GtkOldEditable *old_editable,
+ gint n);
+static void gtk_text_move_page (GtkOldEditable *old_editable,
+ gint x,
+ gint y);
+static void gtk_text_move_to_row (GtkOldEditable *old_editable,
+ gint row);
+static void gtk_text_move_to_column (GtkOldEditable *old_editable,
+ gint row);
+static void gtk_text_kill_char (GtkOldEditable *old_editable,
+ gint direction);
+static void gtk_text_kill_word (GtkOldEditable *old_editable,
+ gint direction);
+static void gtk_text_kill_line (GtkOldEditable *old_editable,
+ gint direction);
/* To be removed */
static void gtk_text_move_forward_character (GtkText *text);
@@ -386,8 +386,8 @@ static void gtk_text_select_word (GtkText *text,
static void gtk_text_select_line (GtkText *text,
guint32 time);
-static void gtk_text_set_position (GtkEditable *editable,
- gint position);
+static void gtk_text_set_position (GtkOldEditable *old_editable,
+ gint position);
/* #define DEBUG_GTK_TEXT */
@@ -525,7 +525,7 @@ gtk_text_get_type (void)
(GtkClassInitFunc) NULL,
};
- text_type = gtk_type_unique (GTK_TYPE_EDITABLE, &text_info);
+ text_type = gtk_type_unique (GTK_TYPE_OLD_EDITABLE, &text_info);
}
return text_type;
@@ -537,12 +537,12 @@ gtk_text_class_init (GtkTextClass *class)
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
GtkObjectClass *object_class;
GtkWidgetClass *widget_class;
- GtkEditableClass *editable_class;
+ GtkOldEditableClass *old_editable_class;
object_class = (GtkObjectClass*) class;
widget_class = (GtkWidgetClass*) class;
- editable_class = (GtkEditableClass*) class;
- parent_class = gtk_type_class (GTK_TYPE_EDITABLE);
+ old_editable_class = (GtkOldEditableClass*) class;
+ parent_class = gtk_type_class (GTK_TYPE_OLD_EDITABLE);
gobject_class->finalize = gtk_text_finalize;
@@ -566,24 +566,24 @@ gtk_text_class_init (GtkTextClass *class)
widget_class->focus_in_event = gtk_text_focus_in;
widget_class->focus_out_event = gtk_text_focus_out;
- editable_class->set_editable = gtk_text_real_set_editable;
- editable_class->insert_text = gtk_text_insert_text;
- editable_class->delete_text = gtk_text_delete_text;
+ old_editable_class->set_editable = gtk_text_real_set_editable;
+ old_editable_class->insert_text = gtk_text_insert_text;
+ old_editable_class->delete_text = gtk_text_delete_text;
- editable_class->move_cursor = gtk_text_move_cursor;
- editable_class->move_word = gtk_text_move_word;
- editable_class->move_page = gtk_text_move_page;
- editable_class->move_to_row = gtk_text_move_to_row;
- editable_class->move_to_column = gtk_text_move_to_column;
+ old_editable_class->move_cursor = gtk_text_move_cursor;
+ old_editable_class->move_word = gtk_text_move_word;
+ old_editable_class->move_page = gtk_text_move_page;
+ old_editable_class->move_to_row = gtk_text_move_to_row;
+ old_editable_class->move_to_column = gtk_text_move_to_column;
- editable_class->kill_char = gtk_text_kill_char;
- editable_class->kill_word = gtk_text_kill_word;
- editable_class->kill_line = gtk_text_kill_line;
+ old_editable_class->kill_char = gtk_text_kill_char;
+ old_editable_class->kill_word = gtk_text_kill_word;
+ old_editable_class->kill_line = gtk_text_kill_line;
- editable_class->update_text = gtk_text_update_text;
- editable_class->get_chars = gtk_text_get_chars;
- editable_class->set_selection = gtk_text_set_selection;
- editable_class->set_position = gtk_text_set_position;
+ old_editable_class->update_text = gtk_text_update_text;
+ old_editable_class->get_chars = gtk_text_get_chars;
+ old_editable_class->set_selection = gtk_text_set_selection;
+ old_editable_class->set_position = gtk_text_set_position;
class->set_scroll_adjustments = gtk_text_set_adjustments;
@@ -721,7 +721,7 @@ gtk_text_init (GtkText *text)
init_properties (text);
- GTK_EDITABLE (text)->editable = FALSE;
+ GTK_OLD_EDITABLE (text)->editable = FALSE;
gtk_text_set_adjustments (text, NULL, NULL);
gtk_editable_set_position (GTK_EDITABLE (text), 0);
@@ -789,17 +789,17 @@ gtk_text_set_editable (GtkText *text,
}
static void
-gtk_text_real_set_editable (GtkEditable *editable,
- gboolean is_editable)
+gtk_text_real_set_editable (GtkOldEditable *old_editable,
+ gboolean is_editable)
{
GtkText *text;
- g_return_if_fail (editable != NULL);
- g_return_if_fail (GTK_IS_TEXT (editable));
+ g_return_if_fail (old_editable != NULL);
+ g_return_if_fail (GTK_IS_TEXT (old_editable));
- text = GTK_TEXT (editable);
+ text = GTK_TEXT (old_editable);
- editable->editable = (is_editable != FALSE);
+ old_editable->editable = (is_editable != FALSE);
if (is_editable)
draw_cursor (text, TRUE);
@@ -932,7 +932,7 @@ gtk_text_insert (GtkText *text,
const char *chars,
gint nchars)
{
- GtkEditable *editable = GTK_EDITABLE (text);
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (text);
gboolean frozen = FALSE;
gint new_line_count = 1;
@@ -1032,10 +1032,10 @@ gtk_text_insert (GtkText *text,
if (text->point.index < text->first_line_start_index)
text->first_line_start_index += numwcs;
- if (text->point.index < editable->selection_start_pos)
- editable->selection_start_pos += numwcs;
- if (text->point.index < editable->selection_end_pos)
- editable->selection_end_pos += numwcs;
+ if (text->point.index < old_editable->selection_start_pos)
+ old_editable->selection_start_pos += numwcs;
+ if (text->point.index < old_editable->selection_end_pos)
+ old_editable->selection_end_pos += numwcs;
/* We'll reset the cursor later anyways if we aren't frozen */
if (text->point.index < text->cursor_mark.index)
text->cursor_mark.index += numwcs;
@@ -1070,7 +1070,7 @@ gtk_text_forward_delete (GtkText *text,
guint nchars)
{
guint old_lines, old_height;
- GtkEditable *editable = GTK_EDITABLE (text);
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (text);
gboolean frozen = FALSE;
g_return_val_if_fail (text != NULL, 0);
@@ -1111,12 +1111,12 @@ gtk_text_forward_delete (GtkText *text,
text->first_line_start_index -= nchars;
}
- if (text->point.index < editable->selection_start_pos)
- editable->selection_start_pos -=
- MIN(nchars, editable->selection_start_pos - text->point.index);
- if (text->point.index < editable->selection_end_pos)
- editable->selection_end_pos -=
- MIN(nchars, editable->selection_end_pos - text->point.index);
+ if (text->point.index < old_editable->selection_start_pos)
+ old_editable->selection_start_pos -=
+ MIN(nchars, old_editable->selection_start_pos - text->point.index);
+ if (text->point.index < old_editable->selection_end_pos)
+ old_editable->selection_end_pos -=
+ MIN(nchars, old_editable->selection_end_pos - text->point.index);
/* We'll reset the cursor later anyways if we aren't frozen */
if (text->point.index < text->cursor_mark.index)
move_mark_n (&text->cursor_mark,
@@ -1141,30 +1141,30 @@ gtk_text_forward_delete (GtkText *text,
}
static void
-gtk_text_set_position (GtkEditable *editable,
- gint position)
+gtk_text_set_position (GtkOldEditable *old_editable,
+ gint position)
{
- GtkText *text = (GtkText *) editable;
+ GtkText *text = (GtkText *) old_editable;
undraw_cursor (text, FALSE);
text->cursor_mark = find_mark (text, position);
find_cursor (text, TRUE);
draw_cursor (text, FALSE);
- gtk_editable_select_region (editable, 0, 0);
+ gtk_editable_select_region (GTK_EDITABLE (old_editable), 0, 0);
}
static gchar *
-gtk_text_get_chars (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
+gtk_text_get_chars (GtkOldEditable *old_editable,
+ gint start_pos,
+ gint end_pos)
{
GtkText *text;
gchar *retval;
- g_return_val_if_fail (editable != NULL, NULL);
- g_return_val_if_fail (GTK_IS_TEXT (editable), NULL);
- text = GTK_TEXT (editable);
+ g_return_val_if_fail (old_editable != NULL, NULL);
+ g_return_val_if_fail (GTK_IS_TEXT (old_editable), NULL);
+ text = GTK_TEXT (old_editable);
if (end_pos < 0)
end_pos = TEXT_LENGTH (text);
@@ -1277,7 +1277,7 @@ static void
gtk_text_realize (GtkWidget *widget)
{
GtkText *text;
- GtkEditable *editable;
+ GtkOldEditable *old_editable;
GdkWindowAttr attributes;
gint attributes_mask;
@@ -1285,7 +1285,7 @@ gtk_text_realize (GtkWidget *widget)
g_return_if_fail (GTK_IS_TEXT (widget));
text = GTK_TEXT (widget);
- editable = GTK_EDITABLE (widget);
+ old_editable = GTK_OLD_EDITABLE (widget);
GTK_WIDGET_SET_FLAGS (text, GTK_REALIZED);
attributes.window_type = GDK_WINDOW_CHILD;
@@ -1341,12 +1341,12 @@ gtk_text_realize (GtkWidget *widget)
gdk_gc_set_foreground (text->gc, &widget->style->text[GTK_STATE_NORMAL]);
#ifdef USE_XIM
- if (gdk_im_ready () && (editable->ic_attr = gdk_ic_attr_new ()) != NULL)
+ if (gdk_im_ready () && (old_editable->ic_attr = gdk_ic_attr_new ()) != NULL)
{
gint width, height;
GdkColormap *colormap;
GdkEventMask mask;
- GdkICAttr *attr = editable->ic_attr;
+ GdkICAttr *attr = old_editable->ic_attr;
GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
GdkIMStyle style;
GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE |
@@ -1389,18 +1389,18 @@ gtk_text_realize (GtkWidget *widget)
break;
}
- editable->ic = gdk_ic_new (attr, attrmask);
+ old_editable->ic = gdk_ic_new (attr, attrmask);
- if (editable->ic == NULL)
+ if (old_editable->ic == NULL)
g_warning ("Can't create input context.");
else
{
mask = gdk_window_get_events (text->text_area);
- mask |= gdk_ic_get_events (editable->ic);
+ mask |= gdk_ic_get_events (old_editable->ic);
gdk_window_set_events (text->text_area, mask);
if (GTK_WIDGET_HAS_FOCUS (widget))
- gdk_im_begin (editable->ic, text->text_area);
+ gdk_im_begin (old_editable->ic, text->text_area);
}
}
#endif
@@ -1409,8 +1409,8 @@ gtk_text_realize (GtkWidget *widget)
gdk_window_show (text->text_area);
init_properties (text);
- if (editable->selection_start_pos != editable->selection_end_pos)
- gtk_editable_claim_selection (editable, TRUE, GDK_CURRENT_TIME);
+ if (old_editable->selection_start_pos != old_editable->selection_end_pos)
+ gtk_old_editable_claim_selection (old_editable, TRUE, GDK_CURRENT_TIME);
recompute_geometry (text);
}
@@ -1467,15 +1467,15 @@ gtk_text_unrealize (GtkWidget *widget)
text = GTK_TEXT (widget);
#ifdef USE_XIM
- if (GTK_EDITABLE (widget)->ic)
+ if (GTK_OLD_EDITABLE (widget)->ic)
{
- gdk_ic_destroy (GTK_EDITABLE (widget)->ic);
- GTK_EDITABLE (widget)->ic = NULL;
+ gdk_ic_destroy (GTK_OLD_EDITABLE (widget)->ic);
+ GTK_OLD_EDITABLE (widget)->ic = NULL;
}
- if (GTK_EDITABLE (widget)->ic_attr)
+ if (GTK_OLD_EDITABLE (widget)->ic_attr)
{
- gdk_ic_attr_destroy (GTK_EDITABLE (widget)->ic_attr);
- GTK_EDITABLE (widget)->ic_attr = NULL;
+ gdk_ic_attr_destroy (GTK_OLD_EDITABLE (widget)->ic_attr);
+ GTK_OLD_EDITABLE (widget)->ic_attr = NULL;
}
#endif
@@ -1628,14 +1628,14 @@ gtk_text_size_allocate (GtkWidget *widget,
GtkAllocation *allocation)
{
GtkText *text;
- GtkEditable *editable;
+ GtkOldEditable *old_editable;
g_return_if_fail (widget != NULL);
g_return_if_fail (GTK_IS_TEXT (widget));
g_return_if_fail (allocation != NULL);
text = GTK_TEXT (widget);
- editable = GTK_EDITABLE (widget);
+ old_editable = GTK_OLD_EDITABLE (widget);
widget->allocation = *allocation;
if (GTK_WIDGET_REALIZED (widget))
@@ -1653,16 +1653,16 @@ gtk_text_size_allocate (GtkWidget *widget,
(gint)TEXT_BORDER_ROOM) * 2));
#ifdef USE_XIM
- if (editable->ic && (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
+ if (old_editable->ic && (gdk_ic_get_style (old_editable->ic) & GDK_IM_PREEDIT_POSITION))
{
gint width, height;
gdk_window_get_size (text->text_area, &width, &height);
- editable->ic_attr->preedit_area.width = width;
- editable->ic_attr->preedit_area.height = height;
+ old_editable->ic_attr->preedit_area.width = width;
+ old_editable->ic_attr->preedit_area.height = height;
- gdk_ic_set_attr (editable->ic,
- editable->ic_attr, GDK_IC_PREEDIT_AREA);
+ gdk_ic_set_attr (old_editable->ic,
+ old_editable->ic_attr, GDK_IC_PREEDIT_AREA);
}
#endif
@@ -1742,18 +1742,14 @@ gtk_text_button_press (GtkWidget *widget,
GdkEventButton *event)
{
GtkText *text;
- GtkEditable *editable;
- static GdkAtom ctext_atom = GDK_NONE;
+ GtkOldEditable *old_editable;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
- if (ctext_atom == GDK_NONE)
- ctext_atom = gdk_atom_intern ("COMPOUND_TEXT", FALSE);
-
text = GTK_TEXT (widget);
- editable = GTK_EDITABLE (widget);
+ old_editable = GTK_OLD_EDITABLE (widget);
if (text->button && (event->button != text->button))
return FALSE;
@@ -1776,8 +1772,8 @@ gtk_text_button_press (GtkWidget *widget,
/* Set it now, so we display things right. We'll unset it
* later if things don't work out */
- editable->has_selection = TRUE;
- gtk_text_set_selection (GTK_EDITABLE(text),
+ old_editable->has_selection = TRUE;
+ gtk_text_set_selection (GTK_OLD_EDITABLE (text),
text->cursor_mark.index,
text->cursor_mark.index);
@@ -1797,10 +1793,10 @@ gtk_text_button_press (GtkWidget *widget,
}
else if (event->type == GDK_BUTTON_PRESS)
{
- if ((event->button == 2) && editable->editable)
+ if ((event->button == 2) && old_editable->editable)
{
- if (editable->selection_start_pos == editable->selection_end_pos ||
- editable->has_selection)
+ if (old_editable->selection_start_pos == old_editable->selection_end_pos ||
+ old_editable->has_selection)
{
undraw_cursor (text, FALSE);
find_mouse_cursor (text, (gint)event->x, (gint)event->y);
@@ -1809,7 +1805,8 @@ gtk_text_button_press (GtkWidget *widget,
}
gtk_selection_convert (widget, GDK_SELECTION_PRIMARY,
- ctext_atom, event->time);
+ gdk_atom_intern ("UTF8_STRING", FALSE),
+ event->time);
}
else
{
@@ -1819,11 +1816,11 @@ gtk_text_button_press (GtkWidget *widget,
find_mouse_cursor (text, event->x, event->y);
draw_cursor (text, FALSE);
- gtk_text_set_selection (GTK_EDITABLE(text),
+ gtk_text_set_selection (GTK_OLD_EDITABLE (text),
text->cursor_mark.index,
text->cursor_mark.index);
- editable->has_selection = FALSE;
+ old_editable->has_selection = FALSE;
if (gdk_selection_owner_get (GDK_SELECTION_PRIMARY) == widget->window)
gtk_selection_owner_set (NULL, GDK_SELECTION_PRIMARY, event->time);
}
@@ -1837,7 +1834,7 @@ gtk_text_button_release (GtkWidget *widget,
GdkEventButton *event)
{
GtkText *text;
- GtkEditable *editable;
+ GtkOldEditable *old_editable;
g_return_val_if_fail (widget != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TEXT (widget), FALSE);
g_return_val_if_fail (event != NULL, FALSE);
@@ -1860,20 +1857,20 @@ gtk_text_button_release (GtkWidget *widget,
if (event->button == 1)
{
text = GTK_TEXT (widget);
- editable = GTK_EDITABLE (widget);
+ old_editable = GTK_OLD_EDITABLE (widget);
gtk_grab_remove (widget);
- editable->has_selection = FALSE;
- if (editable->selection_start_pos != editable->selection_end_pos)
+ old_editable->has_selection = FALSE;
+ if (old_editable->selection_start_pos != old_editable->selection_end_pos)
{
if (gtk_selection_owner_set (widget,
GDK_SELECTION_PRIMARY,
event->time))
- editable->has_selection = TRUE;
+ old_editable->has_selection = TRUE;
else
- gtk_text_update_text (editable, editable->selection_start_pos,
- editable->selection_end_pos);
+ gtk_text_update_text (old_editable, old_editable->selection_start_pos,
+ old_editable->selection_end_pos);
}
else
{
@@ -1943,20 +1940,20 @@ gtk_text_motion_notify (GtkWidget *widget,
find_mouse_cursor (GTK_TEXT (widget), x, y);
draw_cursor (GTK_TEXT (widget), FALSE);
- gtk_text_set_selection (GTK_EDITABLE(text),
- GTK_EDITABLE(text)->selection_start_pos,
+ gtk_text_set_selection (GTK_OLD_EDITABLE (text),
+ GTK_OLD_EDITABLE (text)->selection_start_pos,
text->cursor_mark.index);
return FALSE;
}
static void
-gtk_text_insert_text (GtkEditable *editable,
+gtk_text_insert_text (GtkOldEditable *old_editable,
const gchar *new_text,
gint new_text_length,
gint *position)
{
- GtkText *text = GTK_TEXT (editable);
+ GtkText *text = GTK_TEXT (old_editable);
GdkFont *font;
GdkColor *fore, *back;
@@ -1975,7 +1972,7 @@ gtk_text_insert_text (GtkEditable *editable,
}
static void
-gtk_text_delete_text (GtkEditable *editable,
+gtk_text_delete_text (GtkOldEditable *old_editable,
gint start_pos,
gint end_pos)
{
@@ -1983,7 +1980,7 @@ gtk_text_delete_text (GtkEditable *editable,
g_return_if_fail (start_pos >= 0);
- text = GTK_TEXT (editable);
+ text = GTK_TEXT (old_editable);
gtk_text_set_point (text, start_pos);
if (end_pos < 0)
@@ -1998,7 +1995,7 @@ gtk_text_key_press (GtkWidget *widget,
GdkEventKey *event)
{
GtkText *text;
- GtkEditable *editable;
+ GtkOldEditable *old_editable;
gchar key;
gint return_val;
gint position;
@@ -2010,12 +2007,12 @@ gtk_text_key_press (GtkWidget *widget,
return_val = FALSE;
text = GTK_TEXT (widget);
- editable = GTK_EDITABLE (widget);
+ old_editable = GTK_OLD_EDITABLE (widget);
key = event->keyval;
return_val = TRUE;
- if ((GTK_EDITABLE(text)->editable == FALSE))
+ if ((GTK_OLD_EDITABLE(text)->editable == FALSE))
{
switch (event->keyval)
{
@@ -2050,7 +2047,7 @@ gtk_text_key_press (GtkWidget *widget,
{
gint extend_selection;
gint extend_start;
- guint initial_pos = editable->current_pos;
+ guint initial_pos = old_editable->current_pos;
text->point = find_mark (text, text->cursor_mark.index);
@@ -2059,15 +2056,15 @@ gtk_text_key_press (GtkWidget *widget,
if (extend_selection)
{
- editable->has_selection = TRUE;
+ old_editable->has_selection = TRUE;
- if (editable->selection_start_pos == editable->selection_end_pos)
+ if (old_editable->selection_start_pos == old_editable->selection_end_pos)
{
- editable->selection_start_pos = text->point.index;
- editable->selection_end_pos = text->point.index;
+ old_editable->selection_start_pos = text->point.index;
+ old_editable->selection_end_pos = text->point.index;
}
- extend_start = (text->point.index == editable->selection_start_pos);
+ extend_start = (text->point.index == old_editable->selection_start_pos);
}
switch (event->keyval)
@@ -2115,11 +2112,11 @@ gtk_text_key_press (GtkWidget *widget,
if (event->state & GDK_SHIFT_MASK)
{
extend_selection = FALSE;
- gtk_editable_paste_clipboard (editable);
+ gtk_editable_paste_clipboard (GTK_EDITABLE (old_editable));
}
else if (event->state & GDK_CONTROL_MASK)
{
- gtk_editable_copy_clipboard (editable);
+ gtk_editable_copy_clipboard (GTK_EDITABLE (old_editable));
}
else
{
@@ -2132,14 +2129,14 @@ gtk_text_key_press (GtkWidget *widget,
else if (event->state & GDK_SHIFT_MASK)
{
extend_selection = FALSE;
- gtk_editable_cut_clipboard (editable);
+ gtk_editable_cut_clipboard (GTK_EDITABLE (old_editable));
}
else
gtk_text_delete_forward_character (text);
break;
case GDK_Tab:
position = text->point.index;
- gtk_editable_insert_text (editable, "\t", 1, &position);
+ gtk_editable_insert_text (GTK_EDITABLE (old_editable), "\t", 1, &position);
break;
case GDK_Return:
if (event->state & GDK_CONTROL_MASK)
@@ -2147,7 +2144,7 @@ gtk_text_key_press (GtkWidget *widget,
else
{
position = text->point.index;
- gtk_editable_insert_text (editable, "\n", 1, &position);
+ gtk_editable_insert_text (GTK_EDITABLE (old_editable), "\n", 1, &position);
}
break;
case GDK_Escape:
@@ -2165,7 +2162,7 @@ gtk_text_key_press (GtkWidget *widget,
if ((key >= 'a') && (key <= 'z') && control_keys[(int) (key - 'a')])
{
- (* control_keys[(int) (key - 'a')]) (editable, event->time);
+ (* control_keys[(int) (key - 'a')]) (old_editable, event->time);
return_val = TRUE;
}
@@ -2178,7 +2175,7 @@ gtk_text_key_press (GtkWidget *widget,
if ((key >= 'a') && (key <= 'z') && alt_keys[(int) (key - 'a')])
{
- (* alt_keys[(int) (key - 'a')]) (editable, event->time);
+ (* alt_keys[(int) (key - 'a')]) (old_editable, event->time);
return_val = TRUE;
}
@@ -2188,9 +2185,9 @@ gtk_text_key_press (GtkWidget *widget,
{
extend_selection = FALSE;
- gtk_editable_delete_selection (editable);
+ gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
position = text->point.index;
- gtk_editable_insert_text (editable, event->string, event->length, &position);
+ gtk_editable_insert_text (GTK_EDITABLE (old_editable), event->string, event->length, &position);
return_val = TRUE;
}
@@ -2198,32 +2195,32 @@ gtk_text_key_press (GtkWidget *widget,
return_val = FALSE;
}
- if (return_val && (editable->current_pos != initial_pos))
+ if (return_val && (old_editable->current_pos != initial_pos))
{
if (extend_selection)
{
- if (editable->current_pos < editable->selection_start_pos)
- gtk_text_set_selection (editable, editable->current_pos,
- editable->selection_end_pos);
- else if (editable->current_pos > editable->selection_end_pos)
- gtk_text_set_selection (editable, editable->selection_start_pos,
- editable->current_pos);
+ if (old_editable->current_pos < old_editable->selection_start_pos)
+ gtk_text_set_selection (old_editable, old_editable->current_pos,
+ old_editable->selection_end_pos);
+ else if (old_editable->current_pos > old_editable->selection_end_pos)
+ gtk_text_set_selection (old_editable, old_editable->selection_start_pos,
+ old_editable->current_pos);
else
{
if (extend_start)
- gtk_text_set_selection (editable, editable->current_pos,
- editable->selection_end_pos);
+ gtk_text_set_selection (old_editable, old_editable->current_pos,
+ old_editable->selection_end_pos);
else
- gtk_text_set_selection (editable, editable->selection_start_pos,
- editable->current_pos);
+ gtk_text_set_selection (old_editable, old_editable->selection_start_pos,
+ old_editable->current_pos);
}
}
else
- gtk_text_set_selection (editable, 0, 0);
+ gtk_text_set_selection (old_editable, 0, 0);
- gtk_editable_claim_selection (editable,
- editable->selection_start_pos != editable->selection_end_pos,
- event->time);
+ gtk_old_editable_claim_selection (old_editable,
+ old_editable->selection_start_pos != old_editable->selection_end_pos,
+ event->time);
}
}
@@ -2244,8 +2241,8 @@ gtk_text_focus_in (GtkWidget *widget,
gtk_widget_draw_focus (widget);
#ifdef USE_XIM
- if (GTK_EDITABLE(widget)->ic)
- gdk_im_begin (GTK_EDITABLE(widget)->ic, GTK_TEXT(widget)->text_area);
+ if (GTK_OLD_EDITABLE (widget)->ic)
+ gdk_im_begin (GTK_OLD_EDITABLE (widget)->ic, GTK_TEXT(widget)->text_area);
#endif
draw_cursor (GTK_TEXT(widget), TRUE);
@@ -3734,7 +3731,7 @@ static void
find_cursor_at_line (GtkText* text, const LineParams* start_line, gint pixel_height)
{
GdkWChar ch;
- GtkEditable *editable = (GtkEditable *)text;
+ GtkOldEditable *old_editable = (GtkOldEditable *)text;
GtkPropertyMark mark = start_line->start;
TabStopMark tab_mark = start_line->tab_cont.tab_start;
@@ -3762,26 +3759,26 @@ find_cursor_at_line (GtkText* text, const LineParams* start_line, gint pixel_hei
text->cursor_char = ch;
#ifdef USE_XIM
- if (GTK_WIDGET_HAS_FOCUS(text) && gdk_im_ready() && editable->ic &&
- (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
+ if (GTK_WIDGET_HAS_FOCUS(text) && gdk_im_ready() && old_editable->ic &&
+ (gdk_ic_get_style (old_editable->ic) & GDK_IM_PREEDIT_POSITION))
{
GdkICAttributesType mask = GDK_IC_SPOT_LOCATION |
GDK_IC_PREEDIT_FOREGROUND |
GDK_IC_PREEDIT_BACKGROUND;
- editable->ic_attr->spot_location.x = text->cursor_pos_x;
- editable->ic_attr->spot_location.y
+ old_editable->ic_attr->spot_location.x = text->cursor_pos_x;
+ old_editable->ic_attr->spot_location.y
= text->cursor_pos_y - text->cursor_char_offset;
- editable->ic_attr->preedit_foreground = *MARK_CURRENT_FORE (text, &mark);
- editable->ic_attr->preedit_background = *MARK_CURRENT_BACK (text, &mark);
+ old_editable->ic_attr->preedit_foreground = *MARK_CURRENT_FORE (text, &mark);
+ old_editable->ic_attr->preedit_background = *MARK_CURRENT_BACK (text, &mark);
if (MARK_CURRENT_FONT (text, &mark)->type == GDK_FONT_FONTSET)
{
mask |= GDK_IC_PREEDIT_FONTSET;
- editable->ic_attr->preedit_fontset = MARK_CURRENT_FONT (text, &mark);
+ old_editable->ic_attr->preedit_fontset = MARK_CURRENT_FONT (text, &mark);
}
- gdk_ic_set_attr (editable->ic, editable->ic_attr, mask);
+ gdk_ic_set_attr (old_editable->ic, old_editable->ic_attr, mask);
}
#endif
}
@@ -3799,7 +3796,7 @@ find_cursor (GtkText* text, gboolean scroll)
pixel_height_of(text, text->current_line));
}
- GTK_EDITABLE (text)->current_pos = text->cursor_mark.index;
+ GTK_OLD_EDITABLE (text)->current_pos = text->cursor_mark.index;
}
static void
@@ -4023,30 +4020,30 @@ move_cursor_hor (GtkText *text, int count)
}
static void
-gtk_text_move_cursor (GtkEditable *editable,
- gint x,
- gint y)
+gtk_text_move_cursor (GtkOldEditable *old_editable,
+ gint x,
+ gint y)
{
if (x > 0)
{
while (x-- != 0)
- move_cursor_hor (GTK_TEXT (editable), 1);
+ move_cursor_hor (GTK_TEXT (old_editable), 1);
}
else if (x < 0)
{
while (x++ != 0)
- move_cursor_hor (GTK_TEXT (editable), -1);
+ move_cursor_hor (GTK_TEXT (old_editable), -1);
}
if (y > 0)
{
while (y-- != 0)
- move_cursor_ver (GTK_TEXT (editable), 1);
+ move_cursor_ver (GTK_TEXT (old_editable), 1);
}
else if (y < 0)
{
while (y++ != 0)
- move_cursor_ver (GTK_TEXT (editable), -1);
+ move_cursor_ver (GTK_TEXT (old_editable), -1);
}
}
@@ -4075,18 +4072,18 @@ gtk_text_move_previous_line (GtkText *text)
}
static void
-gtk_text_move_word (GtkEditable *editable,
- gint n)
+gtk_text_move_word (GtkOldEditable *old_editable,
+ gint n)
{
if (n > 0)
{
while (n-- != 0)
- gtk_text_move_forward_word (GTK_TEXT (editable));
+ gtk_text_move_forward_word (GTK_TEXT (old_editable));
}
else if (n < 0)
{
while (n++ != 0)
- gtk_text_move_backward_word (GTK_TEXT (editable));
+ gtk_text_move_backward_word (GTK_TEXT (old_editable));
}
}
@@ -4155,28 +4152,28 @@ gtk_text_move_backward_word (GtkText *text)
}
static void
-gtk_text_move_page (GtkEditable *editable,
- gint x,
- gint y)
+gtk_text_move_page (GtkOldEditable *old_editable,
+ gint x,
+ gint y)
{
if (y != 0)
- scroll_int (GTK_TEXT (editable),
- y * GTK_TEXT(editable)->vadj->page_increment);
+ scroll_int (GTK_TEXT (old_editable),
+ y * GTK_TEXT(old_editable)->vadj->page_increment);
}
static void
-gtk_text_move_to_row (GtkEditable *editable,
- gint row)
+gtk_text_move_to_row (GtkOldEditable *old_editable,
+ gint row)
{
}
static void
-gtk_text_move_to_column (GtkEditable *editable,
- gint column)
+gtk_text_move_to_column (GtkOldEditable *old_editable,
+ gint column)
{
GtkText *text;
- text = GTK_TEXT (editable);
+ text = GTK_TEXT (old_editable);
text->cursor_virtual_x = 0; /* FIXME */
@@ -4205,37 +4202,37 @@ gtk_text_move_to_column (GtkEditable *editable,
static void
gtk_text_move_beginning_of_line (GtkText *text)
{
- gtk_text_move_to_column (GTK_EDITABLE (text), 0);
+ gtk_text_move_to_column (GTK_OLD_EDITABLE (text), 0);
}
static void
gtk_text_move_end_of_line (GtkText *text)
{
- gtk_text_move_to_column (GTK_EDITABLE (text), -1);
+ gtk_text_move_to_column (GTK_OLD_EDITABLE (text), -1);
}
static void
-gtk_text_kill_char (GtkEditable *editable,
- gint direction)
+gtk_text_kill_char (GtkOldEditable *old_editable,
+ gint direction)
{
GtkText *text;
- text = GTK_TEXT (editable);
+ text = GTK_TEXT (old_editable);
- if (editable->selection_start_pos != editable->selection_end_pos)
- gtk_editable_delete_selection (editable);
+ if (old_editable->selection_start_pos != old_editable->selection_end_pos)
+ gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
else
{
if (direction >= 0)
{
if (text->point.index + 1 <= TEXT_LENGTH (text))
- gtk_editable_delete_text (editable, text->point.index, text->point.index + 1);
+ gtk_editable_delete_text (GTK_EDITABLE (old_editable), text->point.index, text->point.index + 1);
}
else
{
if (text->point.index > 0)
- gtk_editable_delete_text (editable, text->point.index - 1, text->point.index);
+ gtk_editable_delete_text (GTK_EDITABLE (old_editable), text->point.index - 1, text->point.index);
}
}
}
@@ -4243,33 +4240,33 @@ gtk_text_kill_char (GtkEditable *editable,
static void
gtk_text_delete_forward_character (GtkText *text)
{
- gtk_text_kill_char (GTK_EDITABLE (text), 1);
+ gtk_text_kill_char (GTK_OLD_EDITABLE (text), 1);
}
static void
gtk_text_delete_backward_character (GtkText *text)
{
- gtk_text_kill_char (GTK_EDITABLE (text), -1);
+ gtk_text_kill_char (GTK_OLD_EDITABLE (text), -1);
}
static void
-gtk_text_kill_word (GtkEditable *editable,
- gint direction)
+gtk_text_kill_word (GtkOldEditable *old_editable,
+ gint direction)
{
- if (editable->selection_start_pos != editable->selection_end_pos)
- gtk_editable_delete_selection (editable);
+ if (old_editable->selection_start_pos != old_editable->selection_end_pos)
+ gtk_editable_delete_selection (GTK_EDITABLE (old_editable));
else
{
- gint old_pos = editable->current_pos;
+ gint old_pos = old_editable->current_pos;
if (direction >= 0)
{
- gtk_text_move_word (editable, 1);
- gtk_editable_delete_text (editable, old_pos, editable->current_pos);
+ gtk_text_move_word (old_editable, 1);
+ gtk_editable_delete_text (GTK_EDITABLE (old_editable), old_pos, old_editable->current_pos);
}
else
{
- gtk_text_move_word (editable, -1);
- gtk_editable_delete_text (editable, editable->current_pos, old_pos);
+ gtk_text_move_word (old_editable, -1);
+ gtk_editable_delete_text (GTK_EDITABLE (old_editable), old_editable->current_pos, old_pos);
}
}
}
@@ -4277,43 +4274,43 @@ gtk_text_kill_word (GtkEditable *editable,
static void
gtk_text_delete_forward_word (GtkText *text)
{
- gtk_text_kill_word (GTK_EDITABLE (text), 1);
+ gtk_text_kill_word (GTK_OLD_EDITABLE (text), 1);
}
static void
gtk_text_delete_backward_word (GtkText *text)
{
- gtk_text_kill_word (GTK_EDITABLE (text), -1);
+ gtk_text_kill_word (GTK_OLD_EDITABLE (text), -1);
}
static void
-gtk_text_kill_line (GtkEditable *editable,
- gint direction)
+gtk_text_kill_line (GtkOldEditable *old_editable,
+ gint direction)
{
- gint old_pos = editable->current_pos;
+ gint old_pos = old_editable->current_pos;
if (direction >= 0)
{
- gtk_text_move_to_column (editable, -1);
- gtk_editable_delete_text (editable, old_pos, editable->current_pos);
+ gtk_text_move_to_column (old_editable, -1);
+ gtk_editable_delete_text (GTK_EDITABLE (old_editable), old_pos, old_editable->current_pos);
}
else
{
- gtk_text_move_to_column (editable, 0);
- gtk_editable_delete_text (editable, editable->current_pos, old_pos);
+ gtk_text_move_to_column (old_editable, 0);
+ gtk_editable_delete_text (GTK_EDITABLE (old_editable), old_editable->current_pos, old_pos);
}
}
static void
gtk_text_delete_line (GtkText *text)
{
- gtk_text_move_to_column (GTK_EDITABLE (text), 0);
- gtk_text_kill_line (GTK_EDITABLE (text), 1);
+ gtk_text_move_to_column (GTK_OLD_EDITABLE (text), 0);
+ gtk_text_kill_line (GTK_OLD_EDITABLE (text), 1);
}
static void
gtk_text_delete_to_line_end (GtkText *text)
{
- gtk_text_kill_line (GTK_EDITABLE (text), 1);
+ gtk_text_kill_line (GTK_OLD_EDITABLE (text), 1);
}
static void
@@ -4322,8 +4319,8 @@ gtk_text_select_word (GtkText *text, guint32 time)
gint start_pos;
gint end_pos;
- GtkEditable *editable;
- editable = GTK_EDITABLE (text);
+ GtkOldEditable *old_editable;
+ old_editable = GTK_OLD_EDITABLE (text);
gtk_text_move_backward_word (text);
start_pos = text->cursor_mark.index;
@@ -4331,9 +4328,9 @@ gtk_text_select_word (GtkText *text, guint32 time)
gtk_text_move_forward_word (text);
end_pos = text->cursor_mark.index;
- editable->has_selection = TRUE;
- gtk_text_set_selection (editable, start_pos, end_pos);
- gtk_editable_claim_selection (editable, start_pos != end_pos, time);
+ old_editable->has_selection = TRUE;
+ gtk_text_set_selection (old_editable, start_pos, end_pos);
+ gtk_old_editable_claim_selection (old_editable, start_pos != end_pos, time);
}
static void
@@ -4342,8 +4339,8 @@ gtk_text_select_line (GtkText *text, guint32 time)
gint start_pos;
gint end_pos;
- GtkEditable *editable;
- editable = GTK_EDITABLE (text);
+ GtkOldEditable *old_editable;
+ old_editable = GTK_OLD_EDITABLE (text);
gtk_text_move_beginning_of_line (text);
start_pos = text->cursor_mark.index;
@@ -4352,9 +4349,9 @@ gtk_text_select_line (GtkText *text, guint32 time)
gtk_text_move_forward_character (text);
end_pos = text->cursor_mark.index;
- editable->has_selection = TRUE;
- gtk_text_set_selection (editable, start_pos, end_pos);
- gtk_editable_claim_selection (editable, start_pos != end_pos, time);
+ old_editable->has_selection = TRUE;
+ gtk_text_set_selection (old_editable, start_pos, end_pos);
+ gtk_old_editable_claim_selection (old_editable, start_pos != end_pos, time);
}
/**********************************************************************/
@@ -4867,19 +4864,18 @@ expand_scratch_buffer (GtkText* text, guint len)
/* Side effect: modifies text->gc
*/
-
static void
draw_bg_rect (GtkText* text, GtkPropertyMark *mark,
gint x, gint y, gint width, gint height,
gboolean already_cleared)
{
- GtkEditable *editable = GTK_EDITABLE(text);
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (text);
- if ((mark->index >= MIN(editable->selection_start_pos, editable->selection_end_pos) &&
- mark->index < MAX(editable->selection_start_pos, editable->selection_end_pos)))
+ if ((mark->index >= MIN(old_editable->selection_start_pos, old_editable->selection_end_pos) &&
+ mark->index < MAX(old_editable->selection_start_pos, old_editable->selection_end_pos)))
{
gtk_paint_flat_box(GTK_WIDGET(text)->style, text->text_area,
- editable->has_selection ?
+ old_editable->has_selection ?
GTK_STATE_SELECTED : GTK_STATE_ACTIVE,
GTK_SHADOW_NONE,
NULL, GTK_WIDGET(text), "text",
@@ -4921,10 +4917,10 @@ draw_line (GtkText* text,
union { GdkWChar *wc; guchar *ch; } buffer;
GdkGC *fg_gc;
- GtkEditable *editable = GTK_EDITABLE(text);
+ GtkOldEditable *old_editable = GTK_OLD_EDITABLE (text);
- guint selection_start_pos = MIN (editable->selection_start_pos, editable->selection_end_pos);
- guint selection_end_pos = MAX (editable->selection_start_pos, editable->selection_end_pos);
+ guint selection_start_pos = MIN (old_editable->selection_start_pos, old_editable->selection_end_pos);
+ guint selection_end_pos = MAX (old_editable->selection_start_pos, old_editable->selection_end_pos);
GtkPropertyMark mark = lp->start;
TabStopMark tab_mark = lp->tab_cont.tab_start;
@@ -5044,7 +5040,7 @@ draw_line (GtkText* text,
if ((mark.index >= selection_start_pos) &&
(mark.index < selection_end_pos))
{
- if (editable->has_selection)
+ if (old_editable->has_selection)
fg_gc = GTK_WIDGET(text)->style->fg_gc[GTK_STATE_SELECTED];
else
fg_gc = GTK_WIDGET(text)->style->fg_gc[GTK_STATE_ACTIVE];
@@ -5159,7 +5155,7 @@ draw_line_wrap (GtkText* text, guint height /* baseline height */)
static void
undraw_cursor (GtkText* text, gint absolute)
{
- GtkEditable *editable = (GtkEditable *)text;
+ GtkOldEditable *old_editable = (GtkOldEditable *) text;
TDEBUG (("in undraw_cursor\n"));
@@ -5167,7 +5163,7 @@ undraw_cursor (GtkText* text, gint absolute)
text->cursor_drawn_level = 0;
if ((text->cursor_drawn_level ++ == 0) &&
- (editable->selection_start_pos == editable->selection_end_pos) &&
+ (old_editable->selection_start_pos == old_editable->selection_end_pos) &&
GTK_WIDGET_DRAWABLE (text) && text->line_start_cache)
{
GdkFont* font;
@@ -5225,7 +5221,7 @@ drawn_cursor_max (GtkText* text)
static void
draw_cursor (GtkText* text, gint absolute)
{
- GtkEditable *editable = (GtkEditable *)text;
+ GtkOldEditable *old_editable = (GtkOldEditable *)text;
TDEBUG (("in draw_cursor\n"));
@@ -5233,8 +5229,8 @@ draw_cursor (GtkText* text, gint absolute)
text->cursor_drawn_level = 1;
if ((--text->cursor_drawn_level == 0) &&
- editable->editable &&
- (editable->selection_start_pos == editable->selection_end_pos) &&
+ old_editable->editable &&
+ (old_editable->selection_start_pos == old_editable->selection_end_pos) &&
GTK_WIDGET_DRAWABLE (text) && text->line_start_cache)
{
GdkFont* font;
@@ -5339,11 +5335,11 @@ expose_text (GtkText* text, GdkRectangle *area, gboolean cursor)
}
static void
-gtk_text_update_text (GtkEditable *editable,
- gint start_pos,
- gint end_pos)
+gtk_text_update_text (GtkOldEditable *old_editable,
+ gint start_pos,
+ gint end_pos)
{
- GtkText *text = GTK_TEXT (editable);
+ GtkText *text = GTK_TEXT (old_editable);
GList *cache = text->line_start_cache;
gint pixels = - text->first_cut_pixels;
@@ -5454,11 +5450,11 @@ recompute_geometry (GtkText* text)
/**********************************************************************/
static void
-gtk_text_set_selection (GtkEditable *editable,
- gint start,
- gint end)
+gtk_text_set_selection (GtkOldEditable *old_editable,
+ gint start,
+ gint end)
{
- GtkText *text = GTK_TEXT (editable);
+ GtkText *text = GTK_TEXT (old_editable);
guint start1, end1, start2, end2;
@@ -5467,8 +5463,8 @@ gtk_text_set_selection (GtkEditable *editable,
start1 = MIN(start,end);
end1 = MAX(start,end);
- start2 = MIN(editable->selection_start_pos, editable->selection_end_pos);
- end2 = MAX(editable->selection_start_pos, editable->selection_end_pos);
+ start2 = MIN(old_editable->selection_start_pos, old_editable->selection_end_pos);
+ end2 = MAX(old_editable->selection_start_pos, old_editable->selection_end_pos);
if (start2 < start1)
{
@@ -5479,19 +5475,19 @@ gtk_text_set_selection (GtkEditable *editable,
}
undraw_cursor (text, FALSE);
- editable->selection_start_pos = start;
- editable->selection_end_pos = end;
+ old_editable->selection_start_pos = start;
+ old_editable->selection_end_pos = end;
draw_cursor (text, FALSE);
/* Expose only what changed */
if (start1 < start2)
- gtk_text_update_text (editable, start1, MIN(end1, start2));
+ gtk_text_update_text (old_editable, start1, MIN(end1, start2));
if (end2 > end1)
- gtk_text_update_text (editable, MAX(end1, start2), end2);
+ gtk_text_update_text (old_editable, MAX(end1, start2), end2);
else if (end2 < end1)
- gtk_text_update_text (editable, end2, end1);
+ gtk_text_update_text (old_editable, end2, end1);
}
diff --git a/gtk/gtktext.h b/gtk/gtktext.h
index 96eb30f183..b51f7b56e8 100644
--- a/gtk/gtktext.h
+++ b/gtk/gtktext.h
@@ -30,7 +30,7 @@
#include <gdk/gdk.h>
#include <gtk/gtkadjustment.h>
-#include <gtk/gtkeditable.h>
+#include <gtk/gtkoldeditable.h>
#ifdef __cplusplus
extern "C" {
@@ -64,7 +64,7 @@ struct _GtkPropertyMark
struct _GtkText
{
- GtkEditable editable;
+ GtkOldEditable old_editable;
GdkWindow *text_area;
@@ -169,7 +169,7 @@ struct _GtkText
struct _GtkTextClass
{
- GtkEditableClass parent_class;
+ GtkOldEditableClass parent_class;
void (*set_scroll_adjustments) (GtkText *text,
GtkAdjustment *hadjustment,
diff --git a/gtk/gtktextlayout.c b/gtk/gtktextlayout.c
index cbbd5cebea..7487d3d20c 100644
--- a/gtk/gtktextlayout.c
+++ b/gtk/gtktextlayout.c
@@ -92,11 +92,6 @@ static GtkTextLineData *gtk_text_layout_real_wrap (GtkTextLayout *layout,
/* may be NULL */
GtkTextLineData *line_data);
-static void gtk_text_layout_real_get_log_attrs (GtkTextLayout *layout,
- GtkTextLine *line,
- PangoLogAttr **attrs,
- gint *n_attrs);
-
static void gtk_text_layout_invalidated (GtkTextLayout *layout);
static void gtk_text_layout_real_invalidate (GtkTextLayout *layout,
@@ -207,7 +202,6 @@ gtk_text_layout_class_init (GtkTextLayoutClass *klass)
gobject_class->finalize = gtk_text_layout_finalize;
klass->wrap = gtk_text_layout_real_wrap;
- klass->get_log_attrs = gtk_text_layout_real_get_log_attrs;
klass->invalidate = gtk_text_layout_real_invalidate;
klass->free_line_data = gtk_text_layout_real_free_line_data;
}
@@ -418,6 +412,69 @@ gtk_text_layout_get_cursor_visible (GtkTextLayout *layout)
return layout->cursor_visible;
}
+/**
+ * gtk_text_layout_set_preedit_string:
+ * @layout: a #PangoLayout
+ * @preedit_string: a string to display at the insertion point
+ * @preedit_attrs: a #PangoAttrList of attributes that apply to @preedit_string
+ * @cursor_pos: position of cursor within preedit string in chars
+ *
+ * Set the preedit string and attributes. The preedit string is a
+ * string showing text that is currently being edited and not
+ * yet committed into the buffer.
+ **/
+void
+gtk_text_layout_set_preedit_string (GtkTextLayout *layout,
+ const gchar *preedit_string,
+ PangoAttrList *preedit_attrs,
+ gint cursor_pos)
+{
+ GtkTextIter iter;
+ GtkTextLine *line;
+ GtkTextLineData *line_data;
+
+ g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
+ g_return_if_fail (preedit_attrs != NULL || preedit_string == NULL);
+
+ if (layout->preedit_string)
+ g_free (layout->preedit_string);
+
+ if (layout->preedit_attrs)
+ pango_attr_list_unref (layout->preedit_attrs);
+
+ if (preedit_string)
+ {
+ layout->preedit_string = g_strdup (preedit_string);
+ layout->preedit_len = strlen (layout->preedit_string);
+ pango_attr_list_ref (preedit_attrs);
+ layout->preedit_attrs = preedit_attrs;
+
+ cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (layout->preedit_string, -1));
+ layout->preedit_cursor = g_utf8_offset_to_pointer (layout->preedit_string, cursor_pos) - layout->preedit_string;
+ }
+ else
+ {
+ layout->preedit_string = NULL;
+ layout->preedit_len = 0;
+ layout->preedit_attrs = NULL;
+ layout->preedit_cursor = 0;
+ }
+
+ /* Now invalidate the paragraph containing the cursor
+ */
+ gtk_text_buffer_get_iter_at_mark (layout->buffer, &iter,
+ gtk_text_buffer_get_mark (layout->buffer, "insert"));
+
+ line = gtk_text_iter_get_text_line (&iter);
+ line_data = gtk_text_line_get_data (line, layout);
+ if (line_data)
+ {
+ gtk_text_layout_invalidate_cache (layout, line);
+ gtk_text_line_invalidate_wrap (line, line_data);
+ gtk_text_layout_invalidated (layout);
+ }
+}
+
void
gtk_text_layout_get_size (GtkTextLayout *layout,
gint *width,
@@ -483,16 +540,6 @@ gtk_text_layout_wrap (GtkTextLayout *layout,
return (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->wrap) (layout, line, line_data);
}
-void
-gtk_text_layout_get_log_attrs (GtkTextLayout *layout,
- GtkTextLine *line,
- PangoLogAttr **attrs,
- gint *n_attrs)
-{
- (* GTK_TEXT_LAYOUT_GET_CLASS (layout)->get_log_attrs)
- (layout, line, attrs, n_attrs);
-}
-
GSList*
gtk_text_layout_get_lines (GtkTextLayout *layout,
/* [top_y, bottom_y) */
@@ -856,21 +903,6 @@ gtk_text_layout_real_wrap (GtkTextLayout *layout,
return line_data;
}
-static void
-gtk_text_layout_real_get_log_attrs (GtkTextLayout *layout,
- GtkTextLine *line,
- PangoLogAttr **attrs,
- gint *n_attrs)
-{
- GtkTextLineDisplay *display;
-
- g_return_if_fail (GTK_IS_TEXT_LAYOUT (layout));
-
- display = gtk_text_layout_get_line_display (layout, line, TRUE);
- pango_layout_get_log_attrs (display->layout, attrs, n_attrs);
- gtk_text_layout_free_line_display (layout, display);
-}
-
/*
* Layout utility functions
*/
@@ -1285,6 +1317,18 @@ add_child_attrs (GtkTextLayout *layout,
return;
}
+
+ if (layout->preedit_string)
+ {
+ g_free (layout->preedit_string);
+ layout->preedit_string = NULL;
+ }
+
+ if (layout->preedit_attrs)
+ {
+ pango_attr_list_unref (layout->preedit_attrs);
+ layout->preedit_attrs = NULL;
+ }
logical_rect.x = 0;
logical_rect.y = -height * PANGO_SCALE;
@@ -1355,6 +1399,96 @@ allocate_child_widgets (GtkTextLayout *layout,
#endif
}
+static void
+convert_color (GdkColor *result,
+ PangoAttrColor *attr)
+{
+ result->red = attr->red;
+ result->blue = attr->blue;
+ result->green = attr->green;
+}
+
+/* This function is used to convert the preedit string attributes, which are
+ * standard PangoAttributes, into the custom attributes used by the text
+ * widget and insert them into a attr list with a given offset.
+ */
+static void
+add_preedit_attrs (GtkTextLayout *layout,
+ GtkTextAttributes *style,
+ PangoAttrList *attrs,
+ gint offset,
+ gboolean size_only)
+{
+ PangoAttrIterator *iter = pango_attr_list_get_iterator (layout->preedit_attrs);
+
+ do
+ {
+ GtkTextAppearance appearance = style->appearance;
+ PangoFontDescription font_desc;
+ PangoAttribute *insert_attr;
+ GSList *extra_attrs = NULL;
+ GSList *tmp_list;
+ gint start, end;
+
+ pango_attr_iterator_range (iter, &start, &end);
+
+ if (end == G_MAXINT)
+ end = layout->preedit_len;
+
+ pango_attr_iterator_get_font (iter, style->font_desc,
+ &font_desc, size_only ? NULL : &extra_attrs);
+
+ tmp_list = extra_attrs;
+ while (tmp_list)
+ {
+ PangoAttribute *attr = tmp_list->data;
+
+ switch (attr->klass->type)
+ {
+ case PANGO_ATTR_FOREGROUND:
+ convert_color (&appearance.fg_color, (PangoAttrColor *)attr);
+ break;
+ case PANGO_ATTR_BACKGROUND:
+ convert_color (&appearance.bg_color, (PangoAttrColor *)attr);
+ appearance.draw_bg = TRUE;
+ break;
+ case PANGO_ATTR_UNDERLINE:
+ appearance.underline = ((PangoAttrInt *)attr)->value;
+ break;
+ case PANGO_ATTR_STRIKETHROUGH:
+ appearance.strikethrough = ((PangoAttrInt *)attr)->value;
+ break;
+ default:
+ break;
+ }
+
+ pango_attribute_destroy (attr);
+ tmp_list = tmp_list->next;
+ }
+
+ g_slist_free (extra_attrs);
+
+ insert_attr = pango_attr_font_desc_new (&font_desc);
+ insert_attr->start_index = start + offset;
+ insert_attr->end_index = end + offset;
+
+ pango_attr_list_insert (attrs, insert_attr);
+
+ if (!size_only)
+ {
+ insert_attr = gtk_text_attr_appearance_new (&appearance);
+
+ insert_attr->start_index = start + offset;
+ insert_attr->end_index = end + offset;
+
+ pango_attr_list_insert (attrs, insert_attr);
+ }
+ }
+ while (pango_attr_iterator_next (iter));
+
+ pango_attr_iterator_destroy (iter);
+}
+
GtkTextLineDisplay *
gtk_text_layout_get_line_display (GtkTextLayout *layout,
GtkTextLine *line,
@@ -1393,6 +1527,7 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
display->size_only = size_only;
display->line = line;
+ display->insert_index = -1;
gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
&iter, line, 0);
@@ -1454,8 +1589,9 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
*/
gint byte_count = 0;
-
- while (TRUE)
+ GtkTextLineSegment *prev_seg = NULL;
+
+ while (seg)
{
if (seg->type == &gtk_text_char_type)
{
@@ -1463,21 +1599,32 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
byte_offset += seg->byte_count;
byte_count += seg->byte_count;
}
- else if (seg->body.mark.visible)
+ else if (seg->type == &gtk_text_right_mark_type ||
+ seg->type == &gtk_text_left_mark_type)
{
- cursor_byte_offsets = g_slist_prepend (cursor_byte_offsets, GINT_TO_POINTER (byte_offset));
- cursor_segs = g_slist_prepend (cursor_segs, seg);
+ /* If we have preedit string, break out of this loop - we'll almost
+ * certainly have different attributes on the preedit string
+ */
+
+ if (layout->preedit_len > 0 &&
+ gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
+ seg->body.mark.obj))
+ break;
+
+ if (seg->body.mark.visible)
+ {
+ cursor_byte_offsets = g_slist_prepend (cursor_byte_offsets, GINT_TO_POINTER (byte_offset));
+ cursor_segs = g_slist_prepend (cursor_segs, seg);
+ }
}
+ else
+ break;
- if (!seg->next ||
- (seg->next->type != &gtk_text_right_mark_type &&
- seg->next->type != &gtk_text_left_mark_type &&
- seg->next->type != &gtk_text_char_type))
- break;
-
+ prev_seg = seg;
seg = seg->next;
}
+ seg = prev_seg; /* Back up one */
add_text_attrs (layout, style, byte_count, attrs,
byte_offset - byte_count, size_only);
}
@@ -1519,12 +1666,38 @@ gtk_text_layout_get_line_display (GtkTextLayout *layout,
else if (seg->type == &gtk_text_right_mark_type ||
seg->type == &gtk_text_left_mark_type)
{
+ gint cursor_offset = 0;
+
+ /* At the insertion point, add the preedit string, if any */
+
+ if (gtk_text_btree_mark_is_insert (_gtk_text_buffer_get_btree (layout->buffer),
+ seg->body.mark.obj))
+ {
+ display->insert_index = byte_offset;
+
+ if (layout->preedit_len > 0)
+ {
+ byte_count += layout->preedit_len;
+ text = g_realloc (text, byte_count);
+
+ style = get_style (layout, &iter);
+ add_preedit_attrs (layout, style, attrs, byte_offset, size_only);
+ release_style (layout, style);
+
+ memcpy (text + byte_offset, layout->preedit_string, layout->preedit_len);
+ byte_offset += layout->preedit_len;
+
+ cursor_offset = layout->preedit_cursor - layout->preedit_len;
+ }
+ }
+
+
/* Display visible marks */
if (seg->body.mark.visible)
{
cursor_byte_offsets = g_slist_prepend (cursor_byte_offsets,
- GINT_TO_POINTER (byte_offset));
+ GINT_TO_POINTER (byte_offset + cursor_offset));
cursor_segs = g_slist_prepend (cursor_segs, seg);
}
}
@@ -1602,6 +1775,46 @@ gtk_text_layout_free_line_display (GtkTextLayout *layout,
}
}
+/* Functions to convert iter <=> index for the line of a GtkTextLineDisplay
+ * taking into account the preedit string, if necessary.
+ */
+gint
+line_display_iter_to_index (GtkTextLayout *layout,
+ GtkTextLineDisplay *display,
+ const GtkTextIter *iter)
+{
+ gint index;
+
+ g_return_val_if_fail (gtk_text_iter_get_text_line (iter) == display->line, 0);
+
+ index = gtk_text_iter_get_line_index (iter);
+
+ if (index >= display->insert_index)
+ index += layout->preedit_len;
+
+ return index;
+}
+
+void
+line_display_index_to_iter (GtkTextLayout *layout,
+ GtkTextLineDisplay *display,
+ GtkTextIter *iter,
+ gint index,
+ gint trailing)
+{
+ if (index >= display->insert_index + layout->preedit_len)
+ index -= layout->preedit_len;
+ else if (index > display->insert_index)
+ {
+ index = display->insert_index;
+ trailing = 0;
+ }
+
+ gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
+ iter, display->line, index);
+ gtk_text_iter_forward_chars (iter, trailing);
+}
+
/* FIXME: This really doesn't belong in this file ... */
static GtkTextLineData*
gtk_text_line_data_new (GtkTextLayout *layout,
@@ -1711,12 +1924,7 @@ gtk_text_layout_get_iter_at_pixel (GtkTextLayout *layout,
trailing = 0;
}
- gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- target_iter,
- line, byte_index);
-
- while (trailing--)
- gtk_text_iter_next_char (target_iter);
+ line_display_index_to_iter (layout, display, target_iter, byte_index, trailing);
gtk_text_layout_free_line_display (layout, display);
}
@@ -1746,6 +1954,7 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout *layout,
GtkTextLine *line;
GtkTextLineDisplay *display;
gint line_top;
+ gint index;
PangoRectangle pango_strong_pos;
PangoRectangle pango_weak_pos;
@@ -1754,12 +1963,13 @@ gtk_text_layout_get_cursor_locations (GtkTextLayout *layout,
g_return_if_fail (iter != NULL);
line = gtk_text_iter_get_text_line (iter);
+ display = gtk_text_layout_get_line_display (layout, line, FALSE);
+ index = line_display_iter_to_index (layout, display, iter);
+
line_top = gtk_text_btree_find_line_top (_gtk_text_buffer_get_btree (layout->buffer),
line, layout);
-
- display = gtk_text_layout_get_line_display (layout, line, FALSE);
-
- pango_layout_get_cursor_pos (display->layout, gtk_text_iter_get_line_index (iter),
+
+ pango_layout_get_cursor_pos (display->layout, index,
strong_pos ? &pango_strong_pos : NULL,
weak_pos ? &pango_weak_pos : NULL);
@@ -1885,7 +2095,7 @@ gtk_text_layout_get_iter_location (GtkTextLayout *layout,
}
else
{
- byte_index = gtk_text_iter_get_line_index (iter);
+ byte_index = line_display_iter_to_index (layout, display, iter);
pango_layout_index_to_pos (display->layout, byte_index, &pango_rect);
@@ -1898,6 +2108,8 @@ gtk_text_layout_get_iter_location (GtkTextLayout *layout,
gtk_text_layout_free_line_display (layout, display);
}
+/* FFIXX */
+
/* Find the iter for the logical beginning of the first display line whose
* top y is >= y. If none exists, move the iter to the logical beginning
* of the last line in the buffer.
@@ -2104,9 +2316,8 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
g_return_if_fail (iter != NULL);
line = gtk_text_iter_get_text_line (iter);
- line_byte = gtk_text_iter_get_line_index (iter);
-
display = gtk_text_layout_get_line_display (layout, line, FALSE);
+ line_byte = line_display_iter_to_index (layout, display, iter);
tmp_list = pango_layout_get_lines (display->layout);
layout_line = tmp_list->data;
@@ -2122,7 +2333,7 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
gtk_text_layout_free_line_display (layout, display);
display = gtk_text_layout_get_line_display (layout, prev_line, FALSE);
- tmp_list = pango_layout_get_lines (display->layout);
+ tmp_list = pango_layout_get_lines (display->layout);
while (tmp_list->next)
{
@@ -2132,12 +2343,10 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
byte_offset += layout_line->length;
}
- gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, prev_line, byte_offset);
+ line_display_index_to_iter (layout, display, iter, byte_offset, 0);
}
else
- gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, line, 0);
+ line_display_index_to_iter (layout, display, iter, 0, 0);
}
else
{
@@ -2151,8 +2360,7 @@ gtk_text_layout_move_iter_to_previous_line (GtkTextLayout *layout,
if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
{
- gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, line, prev_offset);
+ line_display_index_to_iter (layout, display, iter, prev_offset, 0);
break;
}
@@ -2190,7 +2398,6 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
g_return_if_fail (iter != NULL);
line = gtk_text_iter_get_text_line (iter);
- line_byte = gtk_text_iter_get_line_index (iter);
while (line && !found_after)
{
@@ -2198,6 +2405,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
GSList *tmp_list;
display = gtk_text_layout_get_line_display (layout, line, FALSE);
+ line_byte = line_display_iter_to_index (layout, display, iter);
tmp_list = pango_layout_get_lines (display->layout);
while (tmp_list && !found_after)
@@ -2206,9 +2414,7 @@ gtk_text_layout_move_iter_to_next_line (GtkTextLayout *layout,
if (found)
{
- gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, line,
- byte_offset);
+ line_display_index_to_iter (layout, display, iter, byte_offset, 0);
found_after = TRUE;
}
else if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
@@ -2248,9 +2454,8 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
g_return_if_fail (iter != NULL);
line = gtk_text_iter_get_text_line (iter);
- line_byte = gtk_text_iter_get_line_index (iter);
-
display = gtk_text_layout_get_line_display (layout, line, FALSE);
+ line_byte = line_display_iter_to_index (layout, display, iter);
tmp_list = pango_layout_get_lines (display->layout);
while (tmp_list)
@@ -2259,11 +2464,13 @@ gtk_text_layout_move_iter_to_line_end (GtkTextLayout *layout,
if (line_byte < byte_offset + layout_line->length || !tmp_list->next)
{
- gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter, line,
- direction < 0 ? byte_offset : byte_offset + layout_line->length);
+ line_display_index_to_iter (layout, display, iter,
+ direction < 0 ? byte_offset : byte_offset + layout_line->length,
+ 0);
- /* FIXME: Move back one position to avoid going to next line
+ /* FIXME: As a bad hack, we move back one position to avoid going
+ * to next line on a forced break not at whitespace. Real fix
+ * is to keep track of whether marks are at leading or trailing edge?
*/
if (direction < 0 && layout_line->length > 0)
gtk_text_iter_prev_char (iter);
@@ -2304,9 +2511,9 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
g_return_if_fail (iter != NULL);
line = gtk_text_iter_get_text_line (iter);
- line_byte = gtk_text_iter_get_line_index (iter);
display = gtk_text_layout_get_line_display (layout, line, FALSE);
+ line_byte = line_display_iter_to_index (layout, display, iter);
tmp_list = pango_layout_get_lines (display->layout);
while (tmp_list)
@@ -2342,13 +2549,8 @@ gtk_text_layout_move_iter_to_x (GtkTextLayout *layout,
x * PANGO_SCALE - x_offset,
&byte_index, &trailing);
- gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter,
- line, byte_index);
-
- while (trailing--)
- gtk_text_iter_next_char (iter);
-
+ line_display_index_to_iter (layout, display, iter, byte_index, trailing);
+
break;
}
@@ -2383,20 +2585,27 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
GtkTextIter *iter,
gint count)
{
+ GtkTextLineDisplay *display = NULL;
+
g_return_if_fail (layout != NULL);
g_return_if_fail (iter != NULL);
while (count != 0)
{
GtkTextLine *line = gtk_text_iter_get_text_line (iter);
- gint line_byte = gtk_text_iter_get_line_index (iter);
- GtkTextLineDisplay *display = gtk_text_layout_get_line_display (layout, line, FALSE);
+ gint line_byte;
+ gint extra_back = 0;
int byte_count = gtk_text_line_byte_count (line);
int new_index;
int new_trailing;
+
+ if (!display)
+ display = gtk_text_layout_get_line_display (layout, line, FALSE);
+ line_byte = line_display_iter_to_index (layout, display, iter);
+
if (count > 0)
{
pango_layout_move_cursor_visually (display->layout, line_byte, 0, 1, &new_index, &new_trailing);
@@ -2408,16 +2617,32 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
count++;
}
- gtk_text_layout_free_line_display (layout, display);
-
- if (new_index < 0)
+ /* We need to handle the preedit string specially. Well, we don't really need to
+ * handle it specially, since hopefully calling gtk_im_context_reset() will
+ * remove the preedit string; but if we start off in front of the preedit
+ * string (logically) and end up in or on the back edge of the preedit string,
+ * we should move the iter one place farther.
+ */
+ if (layout->preedit_len > 0 && display->insert_index >= 0)
+ {
+ if (line_byte == display->insert_index + layout->preedit_len &&
+ new_index < display->insert_index + layout->preedit_len)
+ {
+ line_byte = display->insert_index;
+ extra_back = 1;
+ }
+ }
+
+ if (new_index < 0 || (new_index == 0 && extra_back))
{
line = gtk_text_line_previous (line);
+
if (!line)
return;
+ gtk_text_layout_free_line_display (layout, display);
+ display = gtk_text_layout_get_line_display (layout, line, FALSE);
new_index = gtk_text_line_byte_count (line);
-
}
else if (new_index > byte_count)
{
@@ -2425,16 +2650,17 @@ gtk_text_layout_move_iter_visually (GtkTextLayout *layout,
if (!line)
return;
+ gtk_text_layout_free_line_display (layout, display);
+ display = gtk_text_layout_get_line_display (layout, line, FALSE);
new_index = 0;
}
-
- gtk_text_btree_get_iter_at_line (_gtk_text_buffer_get_btree (layout->buffer),
- iter,
- line, new_index);
- while (new_trailing--)
- gtk_text_iter_next_char (iter);
+
+ line_display_index_to_iter (layout, display, iter, new_index, new_trailing);
+ if (extra_back)
+ gtk_text_iter_prev_char (iter);
}
+ gtk_text_layout_free_line_display (layout, display);
}
void
@@ -2472,5 +2698,3 @@ gtk_text_layout_spew (GtkTextLayout *layout)
layout->height, layout->screen_width);
#endif
}
-
-
diff --git a/gtk/gtktextlayout.h b/gtk/gtktextlayout.h
index 04ae9c0c77..dca8e362e5 100644
--- a/gtk/gtktextlayout.h
+++ b/gtk/gtktextlayout.h
@@ -156,6 +156,13 @@ struct _GtkTextLayout
/* Whether to show the insertion cursor */
guint cursor_visible : 1;
+
+ /* The preedit string and attributes, if any */
+
+ gchar *preedit_string;
+ PangoAttrList *preedit_attrs;
+ gint preedit_len;
+ gint preedit_cursor;
};
struct _GtkTextLayoutClass
@@ -221,6 +228,7 @@ struct _GtkTextLineDisplay
gint right_margin;
gint top_margin;
gint bottom_margin;
+ gint insert_index; /* Byte index of insert cursor within para or -1 */
gboolean size_only;
GtkTextLine *line;
@@ -238,8 +246,14 @@ void gtk_text_layout_set_contexts (GtkTextLayout *layout,
PangoContext *ltr_context,
PangoContext *rtl_context);
void gtk_text_layout_default_style_changed (GtkTextLayout *layout);
+
void gtk_text_layout_set_screen_width (GtkTextLayout *layout,
gint width);
+void gtk_text_layout_set_preedit_string (GtkTextLayout *layout,
+ const gchar *preedit_string,
+ PangoAttrList *preedit_attrs,
+ gint cursor_pos);
+
void gtk_text_layout_set_cursor_visible (GtkTextLayout *layout,
gboolean cursor_visible);
gboolean gtk_text_layout_get_cursor_visible (GtkTextLayout *layout);
@@ -302,10 +316,6 @@ void gtk_text_layout_validate (GtkTextLayout *layout,
GtkTextLineData* gtk_text_layout_wrap (GtkTextLayout *layout,
GtkTextLine *line,
GtkTextLineData *line_data); /* may be NULL */
-void gtk_text_layout_get_log_attrs (GtkTextLayout *layout,
- GtkTextLine *line,
- PangoLogAttr **attrs,
- gint *n_attrs);
void gtk_text_layout_changed (GtkTextLayout *layout,
gint y,
gint old_height,
diff --git a/gtk/gtktextview.c b/gtk/gtktextview.c
index ef21c82fb3..707cc98cd4 100644
--- a/gtk/gtktextview.c
+++ b/gtk/gtktextview.c
@@ -28,7 +28,10 @@
#include "gtkbindings.h"
#include "gtkdnd.h"
+#include "gtkintl.h"
#include "gtkmain.h"
+#include "gtkmenu.h"
+#include "gtkmenuitem.h"
#include "gtksignal.h"
#include "gtktext.h"
#include "gtktextdisplay.h"
@@ -176,6 +179,7 @@ static void gtk_text_view_set_attributes_from_style (GtkTextView *tex
GtkStyle *style);
static void gtk_text_view_ensure_layout (GtkTextView *text_view);
static void gtk_text_view_destroy_layout (GtkTextView *text_view);
+static void gtk_text_view_reset_im_context (GtkTextView *text_view);
static void gtk_text_view_start_selection_drag (GtkTextView *text_view,
const GtkTextIter *iter,
GdkEventButton *event);
@@ -187,11 +191,13 @@ static void gtk_text_view_start_selection_dnd (GtkTextView *text_vi
static void gtk_text_view_start_cursor_blink (GtkTextView *text_view);
static void gtk_text_view_stop_cursor_blink (GtkTextView *text_view);
-static void gtk_text_view_value_changed (GtkAdjustment *adj,
- GtkTextView *view);
-static void gtk_text_view_commit_handler (GtkIMContext *context,
- const gchar *str,
- GtkTextView *text_view);
+static void gtk_text_view_value_changed (GtkAdjustment *adj,
+ GtkTextView *view);
+static void gtk_text_view_commit_handler (GtkIMContext *context,
+ const gchar *str,
+ GtkTextView *text_view);
+static void gtk_text_view_preedit_changed_handler (GtkIMContext *context,
+ GtkTextView *text_view);
static void gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
const GtkTextIter *location,
@@ -207,6 +213,9 @@ static void gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view,
static GtkAdjustment* get_hadjustment (GtkTextView *text_view);
static GtkAdjustment* get_vadjustment (GtkTextView *text_view);
+static void gtk_text_view_popup_menu (GtkTextView *text_view,
+ GdkEventButton *event);
+
/* Container methods */
static void gtk_text_view_add (GtkContainer *container,
GtkWidget *child);
@@ -682,6 +691,9 @@ gtk_text_view_init (GtkTextView *text_view)
gtk_signal_connect (GTK_OBJECT (text_view->im_context), "commit",
GTK_SIGNAL_FUNC (gtk_text_view_commit_handler), text_view);
+ gtk_signal_connect (GTK_OBJECT (text_view->im_context), "preedit_changed",
+ GTK_SIGNAL_FUNC (gtk_text_view_preedit_changed_handler), text_view);
+
text_view->editable = TRUE;
text_view->cursor_visible = TRUE;
@@ -1578,7 +1590,6 @@ gtk_text_view_size_allocate (GtkWidget *widget,
GdkRectangle right_rect;
GdkRectangle top_rect;
GdkRectangle bottom_rect;
- GSList *tmp_list;
text_view = GTK_TEXT_VIEW (widget);
@@ -1914,6 +1925,12 @@ gtk_text_view_unrealize (GtkWidget *widget)
text_view->incremental_validate_idle = 0;
}
+ if (text_view->popup_menu)
+ {
+ gtk_widget_destroy (text_view->popup_menu);
+ text_view->popup_menu = NULL;
+ }
+
text_window_unrealize (text_view->text_window);
if (text_view->left_window)
@@ -2123,14 +2140,13 @@ gtk_text_view_key_press_event (GtkWidget *widget, GdkEventKey *event)
get_buffer (text_view) == NULL)
return FALSE;
- if (GTK_WIDGET_CLASS (parent_class)->key_press_event &&
- GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
- return TRUE;
-
- if (event->window != text_view->text_window->bin_window)
- return FALSE;
-
if (gtk_im_context_filter_keypress (text_view->im_context, event))
+ {
+ text_view->need_im_reset = TRUE;
+ return TRUE;
+ }
+ else if (GTK_WIDGET_CLASS (parent_class)->key_press_event &&
+ GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
return TRUE;
else if (event->keyval == GDK_Return)
{
@@ -2179,14 +2195,18 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
return FALSE;
}
+#if 0
/* debug hack */
if (event->button == 3 && (event->state & GDK_CONTROL_MASK) != 0)
_gtk_text_buffer_spew (GTK_TEXT_VIEW (widget)->buffer);
else if (event->button == 3)
gtk_text_layout_spew (GTK_TEXT_VIEW (widget)->layout);
+#endif
if (event->type == GDK_BUTTON_PRESS)
{
+ gtk_text_view_reset_im_context (text_view);
+
if (event->button == 1)
{
/* If we're in the selection, start a drag copy/move of the
@@ -2230,10 +2250,7 @@ gtk_text_view_button_press_event (GtkWidget *widget, GdkEventButton *event)
}
else if (event->button == 3)
{
- if (gtk_text_view_end_selection_drag (text_view, event))
- return TRUE;
- else
- return FALSE;
+ gtk_text_view_popup_menu (text_view, event);
}
}
@@ -2287,6 +2304,7 @@ gtk_text_view_focus_in_event (GtkWidget *widget, GdkEventFocus *event)
gtk_text_view_start_cursor_blink (text_view);
}
+ text_view->need_im_reset = TRUE;
gtk_im_context_focus_in (GTK_TEXT_VIEW (widget)->im_context);
return FALSE;
@@ -2306,6 +2324,7 @@ gtk_text_view_focus_out_event (GtkWidget *widget, GdkEventFocus *event)
gtk_text_view_stop_cursor_blink (text_view);
}
+ text_view->need_im_reset = TRUE;
gtk_im_context_focus_out (GTK_TEXT_VIEW (widget)->im_context);
return FALSE;
@@ -2642,6 +2661,8 @@ gtk_text_view_move_cursor (GtkTextView *text_view,
gint cursor_x_pos = 0;
+ gtk_text_view_reset_im_context (text_view);
+
if (step == GTK_MOVEMENT_PAGES)
{
gtk_text_view_scroll_pages (text_view, count);
@@ -2847,6 +2868,8 @@ gtk_text_view_delete_from_cursor (GtkTextView *text_view,
GtkTextIter end;
gboolean leave_one = FALSE;
+ gtk_text_view_reset_im_context (text_view);
+
if (type == GTK_DELETE_CHARS)
{
/* Char delete deletes the selection, if one exists */
@@ -3358,6 +3381,14 @@ gtk_text_view_destroy_layout (GtkTextView *text_view)
}
}
+static void
+gtk_text_view_reset_im_context (GtkTextView *text_view)
+{
+ if (text_view->need_im_reset)
+ text_view->need_im_reset = 0;
+
+ gtk_im_context_reset (text_view->im_context);
+}
/*
* DND feature
@@ -3836,6 +3867,21 @@ gtk_text_view_commit_handler (GtkIMContext *context,
0);
}
+static void
+gtk_text_view_preedit_changed_handler (GtkIMContext *context,
+ GtkTextView *text_view)
+{
+ gchar *str;
+ PangoAttrList *attrs;
+ gint cursor_pos;
+
+ gtk_im_context_get_preedit_string (context, &str, &attrs, &cursor_pos);
+ gtk_text_layout_set_preedit_string (text_view->layout, str, attrs, cursor_pos);
+
+ pango_attr_list_unref (attrs);
+ g_free (str);
+}
+
static void
gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
const GtkTextIter *location,
@@ -3843,12 +3889,21 @@ gtk_text_view_mark_set_handler (GtkTextBuffer *buffer,
gpointer data)
{
GtkTextView *text_view = GTK_TEXT_VIEW (data);
+ gboolean need_reset = FALSE;
if (mark == gtk_text_buffer_get_insert (buffer))
{
text_view->virtual_cursor_x = -1;
text_view->virtual_cursor_y = -1;
+ need_reset = TRUE;
+ }
+ else if (mark == gtk_text_buffer_get_selection_bound (buffer))
+ {
+ need_reset = TRUE;
}
+
+ if (need_reset)
+ gtk_text_view_reset_im_context (text_view);
}
static void
@@ -3903,6 +3958,70 @@ gtk_text_view_set_virtual_cursor_pos (GtkTextView *text_view,
text_view->virtual_cursor_y = (y == -1) ? strong_pos.y + strong_pos.height / 2 : y;
}
+/* Quick hack of a popup menu
+ */
+static void
+activate_cb (GtkWidget *menuitem,
+ GtkTextView *text_view)
+{
+ const gchar *signal = gtk_object_get_data (GTK_OBJECT (menuitem), "gtk-signal");
+ gtk_signal_emit_by_name (GTK_OBJECT (text_view), signal);
+}
+
+static void
+append_action_signal (GtkTextView *text_view,
+ GtkWidget *menu,
+ const gchar *label,
+ const gchar *signal)
+{
+ GtkWidget *menuitem = gtk_menu_item_new_with_label (label);
+
+ gtk_object_set_data (GTK_OBJECT (menuitem), "gtk-signal", (char *)signal);
+ gtk_signal_connect (GTK_OBJECT (menuitem), "activate",
+ activate_cb, text_view);
+
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
+}
+
+static void
+popup_menu_detach (GtkWidget *attach_widget,
+ GtkMenu *menu)
+{
+ GTK_TEXT_VIEW (attach_widget)->popup_menu = NULL;
+}
+
+static void
+gtk_text_view_popup_menu (GtkTextView *text_view,
+ GdkEventButton *event)
+{
+ if (!text_view->popup_menu)
+ {
+ GtkWidget *menuitem;
+
+ text_view->popup_menu = gtk_menu_new ();
+
+ gtk_menu_attach_to_widget (GTK_MENU (text_view->popup_menu),
+ GTK_WIDGET (text_view),
+ popup_menu_detach);
+
+ append_action_signal (text_view, text_view->popup_menu, _("Cut"), "cut_clipboard");
+ append_action_signal (text_view, text_view->popup_menu, _("Copy"), "copy_clipboard");
+ append_action_signal (text_view, text_view->popup_menu, _("Paste"), "paste_clipboard");
+
+ menuitem = gtk_menu_item_new (); /* Separator */
+ gtk_widget_show (menuitem);
+ gtk_menu_shell_append (GTK_MENU_SHELL (text_view->popup_menu), menuitem);
+
+ gtk_im_multicontext_append_menuitems (GTK_IM_MULTICONTEXT (text_view->im_context),
+ GTK_MENU_SHELL (text_view->popup_menu));
+ }
+
+ gtk_menu_popup (GTK_MENU (text_view->popup_menu), NULL, NULL,
+ NULL, NULL,
+ event->button, event->time);
+}
+
/* Child GdkWindows */
diff --git a/gtk/gtktextview.h b/gtk/gtktextview.h
index 5d96ca7be8..5943aceab8 100644
--- a/gtk/gtktextview.h
+++ b/gtk/gtktextview.h
@@ -70,13 +70,12 @@ struct _GtkTextView
guint selection_drag_scan_timeout;
gint scrolling_accel_factor;
- gboolean overwrite_mode;
-
GtkWrapMode wrap_mode; /* Default wrap mode */
- gboolean editable; /* default editability */
-
- gboolean cursor_visible;
+ guint editable : 1; /* default editability */
+ guint overwrite_mode : 1;
+ guint cursor_visible : 1;
+ guint need_im_reset : 1; /* If we have reset the IM since the last character entered */
GtkTextWindow *text_window;
GtkTextWindow *left_window;
@@ -114,6 +113,7 @@ struct _GtkTextView
guint incremental_validate_idle; /* Idle to revalidate offscreen portions, runs after redraw */
GtkIMContext *im_context;
+ GtkWidget *popup_menu;
gint drag_start_x;
gint drag_start_y;
diff --git a/gtk/gtkthemes.c b/gtk/gtkthemes.c
index dc10495400..af3a2cb048 100644
--- a/gtk/gtkthemes.c
+++ b/gtk/gtkthemes.c
@@ -29,384 +29,166 @@
#include <stdlib.h>
#include <gmodule.h>
#include "gtkthemes.h"
-#include "gtkmain.h"
#include "gtkrc.h"
-#include "gtkselection.h"
-#include "gtksignal.h"
-#include "gtkwidget.h"
#include "config.h"
#include "gtkintl.h"
-/*****************************
- *****************************
- * temporary compat code, make GtkThemeEnginePlugin a GObject plus GTypePlugin interface
- */
-typedef struct _GtkThemeEnginePlugin GtkThemeEnginePlugin;
-typedef struct _GObjectClass GtkThemeEnginePluginClass;
-static void gtk_theme_engine_plugin_use (GTypePlugin *plugin);
-static void gtk_theme_engine_plugin_unuse (GTypePlugin *plugin);
-static void gtk_theme_engine_plugin_complete_type_info (GTypePlugin *plugin,
- GType g_type,
- GTypeInfo *info,
- GTypeValueTable *value_table);
-GType gtk_theme_engine_plugin_get_type (void);
-struct _GtkThemeEnginePlugin
-{
- GObject parent_instance;
-
- GtkThemeEngine *engine;
- gchar *engine_name;
- GTypeInfo info;
- GType type;
- GType parent_type;
-};
-#define GTK_TYPE_THEME_ENGINE_PLUGIN (gtk_theme_engine_plugin_get_type ())
-#define GTK_THEME_ENGINE_PLUGIN(plugin) (G_TYPE_CHECK_INSTANCE_CAST ((plugin), GTK_TYPE_THEME_ENGINE_PLUGIN, GtkThemeEnginePlugin))
-#define GTK_THEME_ENGINE_PLUGIN_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), GTK_TYPE_THEME_ENGINE_PLUGIN, GtkThemeEnginePluginClass))
-#define GTK_IS_THEME_ENGINE_PLUGIN(plugin) (G_TYPE_CHECK_INSTANCE_TYPE ((plugin), GTK_TYPE_THEME_ENGINE_PLUGIN))
-#define GTK_IS_THEME_ENGINE_PLUGIN_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), GTK_TYPE_THEME_ENGINE_PLUGIN))
-#define GTK_THEME_ENGINE_PLUGIN_GET_CLASS(plugin) (G_TYPE_INSTANCE_GET_CLASS ((plugin), GTK_TYPE_THEME_ENGINE_PLUGIN, GtkThemeEnginePluginClass))
-static void
-gtk_theme_engine_plugin_shutdown (GObject *object)
-{
- GtkThemeEnginePlugin *plugin = GTK_THEME_ENGINE_PLUGIN (object);
-
- g_warning (G_STRLOC ": shutdown should never happen for static type plugins");
-
- g_object_ref (object);
-
- /* chain parent class handler */
- G_OBJECT_CLASS (g_type_class_peek_parent (GTK_THEME_ENGINE_PLUGIN_GET_CLASS (plugin)))->shutdown (object);
-}
-static void
-gtk_theme_engine_plugin_class_init (GtkThemeEnginePluginClass *class)
-{
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-
- gobject_class->shutdown = gtk_theme_engine_plugin_shutdown;
-}
-static void
-theme_engine_plugin_iface_init (GTypePluginClass *iface)
-{
- iface->use_plugin = gtk_theme_engine_plugin_use;
- iface->unuse_plugin = gtk_theme_engine_plugin_unuse;
- iface->complete_type_info = gtk_theme_engine_plugin_complete_type_info;
-}
-GType
-gtk_theme_engine_plugin_get_type (void)
-{
- static GType theme_engine_plugin_type = 0;
-
- if (!theme_engine_plugin_type)
- {
- static const GTypeInfo theme_engine_plugin_info = {
- sizeof (GtkThemeEnginePluginClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) gtk_theme_engine_plugin_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof (GtkThemeEnginePlugin),
- 0, /* n_preallocs */
- NULL, /* instance_init */
- };
- static const GInterfaceInfo iface_info = {
- (GInterfaceInitFunc) theme_engine_plugin_iface_init,
- NULL, /* interface_finalize */
- NULL, /* interface_data */
- };
-
- theme_engine_plugin_type = g_type_register_static (G_TYPE_OBJECT, "GtkThemeEnginePlugin", &theme_engine_plugin_info, 0);
-
- g_type_add_interface_static (theme_engine_plugin_type, G_TYPE_TYPE_PLUGIN, &iface_info);
- }
-
- return theme_engine_plugin_type;
-}
-/* end of GtkThemeEnginePlugin object implementation stuff
- *****************************
- *****************************/
+typedef struct _GtkThemeEngineClass GtkThemeEngineClass;
struct _GtkThemeEngine
{
+ GTypeModule parent_instance;
+
GModule *library;
- void (*init) (GtkThemeEngine *);
+ void (*init) (GTypeModule *);
void (*exit) (void);
GtkRcStyle *(*create_rc_style) ();
gchar *name;
+};
- GSList *plugins; /* TypePlugins for this engine */
-
- guint refcount;
+struct _GtkThemeEngineClass
+{
+ GTypeModuleClass parent_class;
};
static GHashTable *engine_hash = NULL;
-#ifdef __EMX__
-static void gen_8_3_dll_name(gchar *name, gchar *fullname)
-{
- /* 8.3 dll filename restriction */
- fullname[0] = '_';
- strncpy (fullname + 1, name, 7);
- fullname[8] = '\0';
- strcat (fullname, ".dll");
-}
-#endif
-
-GtkThemeEngine*
-gtk_theme_engine_get (const gchar *name)
+static gboolean
+gtk_theme_engine_load (GTypeModule *module)
{
- GtkThemeEngine *result;
+ GtkThemeEngine *engine = GTK_THEME_ENGINE (module);
- if (!engine_hash)
- engine_hash = g_hash_table_new (g_str_hash, g_str_equal);
-
- /* get the library name for the theme */
+ gchar *fullname;
+ gchar *engine_path;
+
+ fullname = g_module_build_path (NULL, engine->name);
+ engine_path = gtk_rc_find_module_in_path (fullname);
- result = g_hash_table_lookup (engine_hash, name);
-
- if (!result)
+ if (!engine_path)
{
- gchar *fullname;
- gchar *engine_path;
- GModule *library;
+ g_warning (_("Unable to locate loadable module in module_path: \"%s\","),
+ fullname);
-#ifndef __EMX__
- fullname = g_module_build_path (NULL, name);
-#else
- fullname = g_malloc (13);
- gen_8_3_dll_name(name, fullname);
-#endif
- engine_path = gtk_rc_find_module_in_path (fullname);
-#ifdef __EMX__
- if (!engine_path)
- {
- /* try theme name without prefix '_' */
- memmove(fullname, fullname + 1, strlen(fullname));
- engine_path = gtk_rc_find_module_in_path (fullname);
- }
-#endif
-
- if (!engine_path)
- {
- g_warning (_("Unable to locate loadable module in module_path: \"%s\","),
- fullname);
-
- g_free (fullname);
- return NULL;
- }
- g_free (fullname);
+ g_free (fullname);
+ return FALSE;
+ }
+
+ g_free (fullname);
- /* load the lib */
-
- GTK_NOTE (MISC, g_message ("Loading Theme %s\n", engine_path));
+ /* load the lib */
+
+ GTK_NOTE (MISC, g_message ("Loading Theme %s\n", engine_path));
- library = g_module_open (engine_path, 0);
- g_free(engine_path);
- if (!library)
- {
- g_warning (g_module_error());
- return NULL;
- }
- else
- {
- result = g_new (GtkThemeEngine, 1);
-
- result->refcount = 1;
- result->name = g_strdup (name);
- result->library = library;
- result->plugins = NULL;
-
- /* extract symbols from the lib */
- if (!g_module_symbol (library, "theme_init",
- (gpointer *)&result->init) ||
- !g_module_symbol (library, "theme_exit",
- (gpointer *)&result->exit) ||
- !g_module_symbol (library, "theme_create_rc_style",
- (gpointer *)&result->create_rc_style))
- {
- g_warning (g_module_error());
- g_free (result);
- return NULL;
- }
-
- /* call the theme's init (theme_init) function to let it */
- /* setup anything it needs to set up. */
- result->init((GtkThemeEngine *)result);
-
- g_hash_table_insert (engine_hash, result->name, result);
- }
+ engine->library = g_module_open (engine_path, 0);
+ g_free(engine_path);
+ if (!engine->library)
+ {
+ g_warning (g_module_error());
+ return FALSE;
}
- else
- result->refcount++;
-
- return (GtkThemeEngine *)result;
-}
-
-void
-gtk_theme_engine_ref (GtkThemeEngine *engine)
-{
- g_return_if_fail (engine != NULL);
- engine->refcount++;
-}
-
-void
-gtk_theme_engine_unref (GtkThemeEngine *engine)
-{
- GSList *tmp_list;
-
- g_return_if_fail (engine != NULL);
- g_return_if_fail (engine->refcount > 0);
-
- engine->refcount--;
-
- if (engine->refcount == 0)
+ /* extract symbols from the lib */
+ if (!g_module_symbol (engine->library, "theme_init",
+ (gpointer *)&engine->init) ||
+ !g_module_symbol (engine->library, "theme_exit",
+ (gpointer *)&engine->exit) ||
+ !g_module_symbol (engine->library, "theme_create_rc_style",
+ (gpointer *)&engine->create_rc_style))
{
- engine->exit();
-
- g_hash_table_remove (engine_hash, engine->name);
-
- tmp_list = engine->plugins;
- while (tmp_list)
- {
- GtkThemeEnginePlugin *plugin = tmp_list->data;
- plugin->engine = NULL;
-
- tmp_list = tmp_list->next;
- }
- g_slist_free (engine->plugins);
-
+ g_warning (g_module_error());
g_module_close (engine->library);
- g_free (engine->name);
- g_free (engine);
+
+ return FALSE;
}
-}
+
+ /* call the theme's init (theme_init) function to let it */
+ /* setup anything it needs to set up. */
+ engine->init (module);
-GtkRcStyle *
-gtk_theme_engine_create_rc_style (GtkThemeEngine *engine)
-{
- g_return_val_if_fail (engine != NULL, NULL);
-
- return engine->create_rc_style ();
+ return TRUE;
}
static void
-gtk_theme_engine_plugin_use (GTypePlugin *plugin)
+gtk_theme_engine_unload (GTypeModule *module)
{
- GtkThemeEnginePlugin *theme_plugin = GTK_THEME_ENGINE_PLUGIN (plugin);
+ GtkThemeEngine *engine = GTK_THEME_ENGINE (module);
- if (theme_plugin->engine == NULL)
- {
- gtk_theme_engine_get (theme_plugin->engine_name);
- if (!theme_plugin->engine)
- {
- g_warning ("An attempt to create an instance of a type from\n"
- "a previously loaded theme engine was made after the engine\n"
- "was unloaded, but the engine could not be reloaded or no longer\n"
- "implements the type. Bad things will happen.\n");
- }
- }
- else
- gtk_theme_engine_ref (theme_plugin->engine);
-}
+ engine->exit();
-static void
-gtk_theme_engine_plugin_unuse (GTypePlugin *plugin)
-{
- GtkThemeEnginePlugin *theme_plugin = GTK_THEME_ENGINE_PLUGIN (plugin);
+ g_module_close (engine->library);
+ engine->library = NULL;
- g_return_if_fail (theme_plugin->engine != NULL);
-
- gtk_theme_engine_unref (theme_plugin->engine);
+ engine->init = NULL;
+ engine->exit = NULL;
+ engine->create_rc_style = NULL;
}
-
+
static void
-gtk_theme_engine_plugin_complete_type_info (GTypePlugin *plugin,
- GType g_type,
- GTypeInfo *info,
- GTypeValueTable *value_table)
+gtk_theme_engine_class_init (GtkThemeEngineClass *class)
{
- GtkThemeEnginePlugin *theme_plugin = GTK_THEME_ENGINE_PLUGIN (plugin);
+ GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
- *info = theme_plugin->info;
+ module_class->load = gtk_theme_engine_load;
+ module_class->unload = gtk_theme_engine_unload;
}
-/**
- * gtk_theme_engine_register_type:
- * @engine: a #GtkThemeEngine
- * @parent_type: the type for the parent class
- * @type_name: name for the type
- * @type_info: type information structure
- *
- * Looks up or registers a type that is implemented with a particular
- * theme engine. If a type with name @type_name is already registered,
- * the #GType identifier for the type is returned, otherwise the type
- * is newly registered, and the resulting #GType identifier returned.
- *
- * As long as any instances of the type exist, the a reference will be
- * held to the theme engine and the theme engine will not be unloaded.
- *
- * Return value: the type identifier for the class.
- **/
GType
-gtk_theme_engine_register_type (GtkThemeEngine *engine,
- GType parent_type,
- const gchar *type_name,
- const GTypeInfo *type_info)
+gtk_theme_engine_get_type (void)
{
- GtkThemeEnginePlugin *plugin;
- GType type;
-
- g_return_val_if_fail (engine != NULL, 0);
- g_return_val_if_fail (type_name != NULL, 0);
- g_return_val_if_fail (type_info != NULL, 0);
+ static GType theme_engine_type = 0;
- type = g_type_from_name (type_name);
- if (type)
- plugin = GTK_THEME_ENGINE_PLUGIN (g_type_get_plugin (type));
- else
+ if (!theme_engine_type)
{
- plugin = g_object_new (GTK_TYPE_THEME_ENGINE_PLUGIN, NULL);
+ static const GTypeInfo theme_engine_info = {
+ sizeof (GtkThemeEngineClass),
+ NULL, /* base_init */
+ NULL, /* base_finalize */
+ (GClassInitFunc) gtk_theme_engine_class_init,
+ NULL, /* class_finalize */
+ NULL, /* class_data */
+ sizeof (GtkThemeEngine),
+ 0, /* n_preallocs */
+ NULL, /* instance_init */
+ };
- plugin->engine = NULL;
- plugin->engine_name = NULL;
- plugin->parent_type = parent_type;
- plugin->type = g_type_register_dynamic (parent_type, type_name, G_TYPE_PLUGIN (plugin), 0);
+ theme_engine_type = g_type_register_static (G_TYPE_TYPE_MODULE, "GtkThemeEngine", &theme_engine_info, 0);
}
- if (plugin->engine)
- {
- if (plugin->engine != engine)
- {
- g_warning ("Two different theme engines tried to register '%s'.", type_name);
- return 0;
- }
+ return theme_engine_type;
+}
- if (plugin->parent_type != parent_type)
- {
- g_warning ("Type '%s' recreated with different parent type.\n"
- "(was '%s', now '%s')", type_name,
- g_type_name (plugin->parent_type),
- g_type_name (parent_type));
- return 0;
- }
- }
- else
- {
- plugin->engine = engine;
- if (plugin->engine_name)
- g_free (plugin->engine_name);
+GtkThemeEngine*
+gtk_theme_engine_get (const gchar *name)
+{
+ GtkThemeEngine *result;
+
+ if (!engine_hash)
+ engine_hash = g_hash_table_new (g_str_hash, g_str_equal);
- plugin->engine_name = g_strdup (engine->name);
-
- plugin->info = *type_info;
+ /* get the library name for the theme
+ */
+ result = g_hash_table_lookup (engine_hash, name);
- engine->plugins = g_slist_prepend (engine->plugins, plugin);
+ if (!result)
+ {
+ result = GTK_THEME_ENGINE (g_object_new (GTK_TYPE_THEME_ENGINE, NULL));
+ g_type_module_set_name (G_TYPE_MODULE (result), name);
+
+ g_hash_table_insert (engine_hash, result->name, result);
}
- return plugin->type;
+ if (!g_type_module_use (G_TYPE_MODULE (result)))
+ return NULL;
+
+ return result;
}
+GtkRcStyle *
+gtk_theme_engine_create_rc_style (GtkThemeEngine *engine)
+{
+ g_return_val_if_fail (engine != NULL, NULL);
+
+ return engine->create_rc_style ();
+}
diff --git a/gtk/gtkthemes.h b/gtk/gtkthemes.h
index 713bda7b65..4c8b9a5550 100644
--- a/gtk/gtkthemes.h
+++ b/gtk/gtkthemes.h
@@ -32,21 +32,17 @@
#include <gtk/gtkstyle.h>
#include <gtk/gtkwidget.h>
-
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
-GtkThemeEngine * gtk_theme_engine_get (const gchar *name);
-void gtk_theme_engine_ref (GtkThemeEngine *engine);
-void gtk_theme_engine_unref (GtkThemeEngine *engine);
-GtkRcStyle * gtk_theme_engine_create_rc_style (GtkThemeEngine *engine);
-
-GType gtk_theme_engine_register_type (GtkThemeEngine *engine,
- GType parent_type,
- const gchar *type_name,
- const GTypeInfo *type_info);
+#define GTK_TYPE_THEME_ENGINE (gtk_theme_engine_get_type ())
+#define GTK_THEME_ENGINE(theme_engine) (G_TYPE_CHECK_INSTANCE_CAST ((theme_engine), GTK_TYPE_THEME_ENGINE, GtkThemeEngine))
+#define GTK_IS_THEME_ENGINE(theme_engine) (G_TYPE_CHECK_INSTANCE_TYPE ((theme_engine), GTK_TYPE_THEME_ENGINE))
+GType gtk_theme_engine_get_type (void);
+GtkThemeEngine *gtk_theme_engine_get (const gchar *name);
+GtkRcStyle *gtk_theme_engine_create_rc_style (GtkThemeEngine *engine);
#ifdef __cplusplus
}
diff --git a/gtk/queryimmodules.c b/gtk/queryimmodules.c
new file mode 100644
index 0000000000..ff4987b2ea
--- /dev/null
+++ b/gtk/queryimmodules.c
@@ -0,0 +1,170 @@
+/* GTK+
+ * querymodules.c:
+ *
+ * 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 Library 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
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <glib.h>
+#ifdef HAVE_DIRENT_H
+#include <dirent.h>
+#endif
+#include <gmodule.h>
+
+#include <errno.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+
+#ifdef G_OS_WIN32
+#define SOEXT ".dll"
+#else
+#define SOEXT ".so"
+#endif
+
+#include <pango/pango-utils.h>
+#include "gtk/gtkrc.h"
+#include "gtk/gtkimmodule.h"
+
+void
+print_escaped (const char *str)
+{
+ char *tmp = g_strescape (str, NULL);
+ printf ("\"%s\" ", tmp);
+ g_free (tmp);
+}
+
+gboolean
+query_module (const char *dir, const char *name)
+{
+ void (*list) (const GtkIMContextInfo ***contexts,
+ guint *n_contexts);
+ void (*init) (GTypeModule *type_module);
+ void (*exit) (void);
+ GtkIMContext *(*create) (const gchar *context_id);
+
+ GModule *module;
+ gchar *path;
+ gboolean error = FALSE;
+
+ if (name[0] == G_DIR_SEPARATOR)
+ path = g_strdup (name);
+ else
+ path = g_strconcat (dir, G_DIR_SEPARATOR_S, name, NULL);
+
+ module = g_module_open (path, 0);
+
+ if (!module)
+ {
+ fprintf(stderr, "Cannot load module %s: %s\n", path, g_module_error());
+ error = TRUE;
+ }
+
+ if (module &&
+ g_module_symbol (module, "im_module_list", (gpointer)&list) &&
+ g_module_symbol (module, "im_module_init", (gpointer)&init) &&
+ g_module_symbol (module, "im_module_exit", (gpointer)&exit) &&
+ g_module_symbol (module, "im_module_create", (gpointer)&create))
+ {
+ const GtkIMContextInfo **contexts;
+ guint n_contexts;
+ int i;
+
+ print_escaped (path);
+ fputs ("\n", stdout);
+
+ (*list) (&contexts, &n_contexts);
+
+ for (i=0; i<n_contexts; i++)
+ {
+ print_escaped (contexts[i]->context_id);
+ print_escaped (contexts[i]->context_name);
+ print_escaped (contexts[i]->domain);
+ print_escaped (contexts[i]->domain_dirname);
+ print_escaped (contexts[i]->default_locales);
+ fputs ("\n", stdout);
+ }
+ fputs ("\n", stdout);
+ }
+ else
+ {
+ fprintf (stderr, "%s does not export GTK+ IM module API: %s\n", path,
+ g_module_error());
+ error = TRUE;
+ }
+
+ g_free (path);
+ if (module)
+ g_module_close (module);
+
+ return error;
+}
+
+int main (int argc, char **argv)
+{
+ char cwd[PATH_MAX];
+ int i;
+ char *path;
+ gboolean error = FALSE;
+
+ printf ("# GTK+ Input Method Modules file\n"
+ "# Automatically generated file, do not edit\n"
+ "#\n");
+
+ if (argc == 1) /* No arguments given */
+ {
+ char **dirs;
+ int i;
+
+ path = gtk_rc_get_im_module_path ();
+
+ printf ("# ModulesPath = %s\n#\n", path);
+
+ dirs = pango_split_file_list (path);
+
+ for (i=0; dirs[i]; i++)
+ {
+ DIR *dir = opendir (dirs[i]);
+ if (dir)
+ {
+ struct dirent *dent;
+
+ while ((dent = readdir (dir)))
+ {
+ int len = strlen (dent->d_name);
+ if (len > 3 && strcmp (dent->d_name + len - strlen (SOEXT), SOEXT) == 0)
+ error |= query_module (dirs[i], dent->d_name);
+ }
+
+ closedir (dir);
+ }
+ }
+ }
+ else
+ {
+ getcwd (cwd, PATH_MAX);
+
+ for (i=1; i<argc; i++)
+ error |= query_module (cwd, argv[i]);
+ }
+
+ return error ? 1 : 0;
+}
diff --git a/gtk/testgtk.c b/gtk/testgtk.c
index cf36663f28..fd1795f2f6 100644
--- a/gtk/testgtk.c
+++ b/gtk/testgtk.c
@@ -9229,11 +9229,14 @@ create_main_window (void)
gtk_widget_show_all (window);
}
-void
-pixbuf_init ()
+static void
+test_init ()
{
if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
- putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
+ {
+ putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
+ putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
+ }
}
int
@@ -9243,7 +9246,7 @@ main (int argc, char *argv[])
srand (time (NULL));
- pixbuf_init ();
+ test_init ();
gtk_set_locale ();
/* Check to see if we are being run from the correct
diff --git a/gtk/testtext.c b/gtk/testtext.c
index 5424dc0f7f..279535aecd 100644
--- a/gtk/testtext.c
+++ b/gtk/testtext.c
@@ -1922,13 +1922,32 @@ create_view (Buffer *buffer)
return view;
}
+static gboolean
+file_exists (const char *filename)
+{
+ struct stat statbuf;
+
+ return stat (filename, &statbuf) == 0;
+}
+void
+test_init ()
+{
+ if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
+ {
+ putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
+ putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
+ }
+}
+
int
main (int argc, char** argv)
{
Buffer *buffer;
View *view;
int i;
-
+
+ test_init ();
+ gtk_set_locale ();
gtk_init (&argc, &argv);
buffer = create_buffer ();
diff --git a/tests/testgtk.c b/tests/testgtk.c
index cf36663f28..fd1795f2f6 100644
--- a/tests/testgtk.c
+++ b/tests/testgtk.c
@@ -9229,11 +9229,14 @@ create_main_window (void)
gtk_widget_show_all (window);
}
-void
-pixbuf_init ()
+static void
+test_init ()
{
if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
- putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
+ {
+ putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
+ putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
+ }
}
int
@@ -9243,7 +9246,7 @@ main (int argc, char *argv[])
srand (time (NULL));
- pixbuf_init ();
+ test_init ();
gtk_set_locale ();
/* Check to see if we are being run from the correct
diff --git a/tests/testtext.c b/tests/testtext.c
index 5424dc0f7f..279535aecd 100644
--- a/tests/testtext.c
+++ b/tests/testtext.c
@@ -1922,13 +1922,32 @@ create_view (Buffer *buffer)
return view;
}
+static gboolean
+file_exists (const char *filename)
+{
+ struct stat statbuf;
+
+ return stat (filename, &statbuf) == 0;
+}
+void
+test_init ()
+{
+ if (file_exists ("../gdk-pixbuf/.libs/libpixbufloader-pnm.so"))
+ {
+ putenv ("GDK_PIXBUF_MODULEDIR=../gdk-pixbuf/.libs");
+ putenv ("GTK_IM_MODULE_FILE=./gtk.immodules");
+ }
+}
+
int
main (int argc, char** argv)
{
Buffer *buffer;
View *view;
int i;
-
+
+ test_init ();
+ gtk_set_locale ();
gtk_init (&argc, &argv);
buffer = create_buffer ();