summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gtk')
-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
34 files changed, 5482 insertions, 3535 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 ();