Added some support for i18n. The support for input methods, including

Tue Feb 24 22:47:01 1998  Owen Taylor  <owt1@cornell.edu>

	* gtk/gtktext.c: Added some support for i18n. The support
	for input methods, including preedit, is there, but input
	is ignored unless it comes one byte at a time, so the
	CJK locales won't really work. Fixing that would require
	variable-width character support in the Text widget, which
	is probably the wrong approach. Eventually we'll probably
	want to go to UCS-4 internally.

	Also, revised key press handling, which should improve
	the forwarding of non-handled keypresses to the toplevel,
	and make adding selection handling easier.

	* gtk/gtkentry.c: Minor changes so that C-d, etc delete
	the selection if there is one.
This commit is contained in:
Owen Taylor 1998-02-25 03:51:04 +00:00 committed by Owen Taylor
parent 203476915a
commit 82d7ac35ed
9 changed files with 398 additions and 105 deletions

View File

@ -1,3 +1,24 @@
Tue Feb 24 22:47:01 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtktext.c: Added some support for i18n. The support
for input methods, including preedit, is there, but input
is ignored unless it comes one byte at a time, so the
CJK locales won't really work. Fixing that would require
variable-width character support in the Text widget, which
is probably the wrong approach. Eventually we'll probably
want to go to UCS-4 internally.
Also, revised key press handling, which should improve
the forwarding of non-handled keypresses to the toplevel,
and make adding selection handling easier.
* gtk/gtkentry.c: Minor changes so that C-d, etc delete
the selection if there is one.
* gdk/gdk.c (gdk_ic_get_events): Check the result of
XGetICValues - it is failing for some reason, and
causing some warnings to be printed.
Mon Feb 23 15:41:13 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkwidget.c gtk/gtkmenu.c: Don't process configure events

View File

@ -1,3 +1,24 @@
Tue Feb 24 22:47:01 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtktext.c: Added some support for i18n. The support
for input methods, including preedit, is there, but input
is ignored unless it comes one byte at a time, so the
CJK locales won't really work. Fixing that would require
variable-width character support in the Text widget, which
is probably the wrong approach. Eventually we'll probably
want to go to UCS-4 internally.
Also, revised key press handling, which should improve
the forwarding of non-handled keypresses to the toplevel,
and make adding selection handling easier.
* gtk/gtkentry.c: Minor changes so that C-d, etc delete
the selection if there is one.
* gdk/gdk.c (gdk_ic_get_events): Check the result of
XGetICValues - it is failing for some reason, and
causing some warnings to be printed.
Mon Feb 23 15:41:13 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkwidget.c gtk/gtkmenu.c: Don't process configure events

View File

@ -1,3 +1,24 @@
Tue Feb 24 22:47:01 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtktext.c: Added some support for i18n. The support
for input methods, including preedit, is there, but input
is ignored unless it comes one byte at a time, so the
CJK locales won't really work. Fixing that would require
variable-width character support in the Text widget, which
is probably the wrong approach. Eventually we'll probably
want to go to UCS-4 internally.
Also, revised key press handling, which should improve
the forwarding of non-handled keypresses to the toplevel,
and make adding selection handling easier.
* gtk/gtkentry.c: Minor changes so that C-d, etc delete
the selection if there is one.
* gdk/gdk.c (gdk_ic_get_events): Check the result of
XGetICValues - it is failing for some reason, and
causing some warnings to be printed.
Mon Feb 23 15:41:13 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkwidget.c gtk/gtkmenu.c: Don't process configure events

View File

@ -1,3 +1,24 @@
Tue Feb 24 22:47:01 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtktext.c: Added some support for i18n. The support
for input methods, including preedit, is there, but input
is ignored unless it comes one byte at a time, so the
CJK locales won't really work. Fixing that would require
variable-width character support in the Text widget, which
is probably the wrong approach. Eventually we'll probably
want to go to UCS-4 internally.
Also, revised key press handling, which should improve
the forwarding of non-handled keypresses to the toplevel,
and make adding selection handling easier.
* gtk/gtkentry.c: Minor changes so that C-d, etc delete
the selection if there is one.
* gdk/gdk.c (gdk_ic_get_events): Check the result of
XGetICValues - it is failing for some reason, and
causing some warnings to be printed.
Mon Feb 23 15:41:13 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkwidget.c gtk/gtkmenu.c: Don't process configure events

View File

@ -1,3 +1,24 @@
Tue Feb 24 22:47:01 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtktext.c: Added some support for i18n. The support
for input methods, including preedit, is there, but input
is ignored unless it comes one byte at a time, so the
CJK locales won't really work. Fixing that would require
variable-width character support in the Text widget, which
is probably the wrong approach. Eventually we'll probably
want to go to UCS-4 internally.
Also, revised key press handling, which should improve
the forwarding of non-handled keypresses to the toplevel,
and make adding selection handling easier.
* gtk/gtkentry.c: Minor changes so that C-d, etc delete
the selection if there is one.
* gdk/gdk.c (gdk_ic_get_events): Check the result of
XGetICValues - it is failing for some reason, and
causing some warnings to be printed.
Mon Feb 23 15:41:13 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkwidget.c gtk/gtkmenu.c: Don't process configure events

View File

@ -1,3 +1,24 @@
Tue Feb 24 22:47:01 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtktext.c: Added some support for i18n. The support
for input methods, including preedit, is there, but input
is ignored unless it comes one byte at a time, so the
CJK locales won't really work. Fixing that would require
variable-width character support in the Text widget, which
is probably the wrong approach. Eventually we'll probably
want to go to UCS-4 internally.
Also, revised key press handling, which should improve
the forwarding of non-handled keypresses to the toplevel,
and make adding selection handling easier.
* gtk/gtkentry.c: Minor changes so that C-d, etc delete
the selection if there is one.
* gdk/gdk.c (gdk_ic_get_events): Check the result of
XGetICValues - it is failing for some reason, and
causing some warnings to be printed.
Mon Feb 23 15:41:13 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkwidget.c gtk/gtkmenu.c: Don't process configure events

View File

@ -1,3 +1,24 @@
Tue Feb 24 22:47:01 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtktext.c: Added some support for i18n. The support
for input methods, including preedit, is there, but input
is ignored unless it comes one byte at a time, so the
CJK locales won't really work. Fixing that would require
variable-width character support in the Text widget, which
is probably the wrong approach. Eventually we'll probably
want to go to UCS-4 internally.
Also, revised key press handling, which should improve
the forwarding of non-handled keypresses to the toplevel,
and make adding selection handling easier.
* gtk/gtkentry.c: Minor changes so that C-d, etc delete
the selection if there is one.
* gdk/gdk.c (gdk_ic_get_events): Check the result of
XGetICValues - it is failing for some reason, and
causing some warnings to be printed.
Mon Feb 23 15:41:13 1998 Owen Taylor <owt1@cornell.edu>
* gtk/gtkwidget.c gtk/gtkmenu.c: Don't process configure events

View File

@ -1038,17 +1038,12 @@ gtk_entry_key_press (GtkWidget *widget,
break;
case GDK_Delete:
return_val = TRUE;
if (entry->selection_start_pos != entry->selection_end_pos)
gtk_delete_selection (entry);
if (event->state & GDK_CONTROL_MASK)
gtk_delete_line (entry);
else if (event->state & GDK_SHIFT_MASK)
gtk_entry_cut_clipboard (entry, event);
else
{
if (event->state & GDK_CONTROL_MASK)
gtk_delete_line (entry);
else if (event->state & GDK_SHIFT_MASK)
gtk_entry_cut_clipboard (entry, event);
else
gtk_delete_forward_character (entry);
}
gtk_delete_forward_character (entry);
break;
case GDK_Home:
return_val = TRUE;
@ -1965,9 +1960,14 @@ gtk_delete_forward_character (GtkEntry *entry)
{
gint old_pos;
old_pos = entry->current_pos;
gtk_move_forward_character (entry);
gtk_entry_delete_text (entry, old_pos, entry->current_pos);
if (entry->selection_start_pos != entry->selection_end_pos)
gtk_delete_selection (entry);
else
{
old_pos = entry->current_pos;
gtk_move_forward_character (entry);
gtk_entry_delete_text (entry, old_pos, entry->current_pos);
}
}
static void
@ -1975,9 +1975,14 @@ gtk_delete_backward_character (GtkEntry *entry)
{
gint old_pos;
old_pos = entry->current_pos;
gtk_move_backward_character (entry);
gtk_entry_delete_text (entry, entry->current_pos, old_pos);
if (entry->selection_start_pos != entry->selection_end_pos)
gtk_delete_selection (entry);
else
{
old_pos = entry->current_pos;
gtk_move_backward_character (entry);
gtk_entry_delete_text (entry, entry->current_pos, old_pos);
}
}
static void
@ -1985,9 +1990,14 @@ gtk_delete_forward_word (GtkEntry *entry)
{
gint old_pos;
old_pos = entry->current_pos;
gtk_move_forward_word (entry);
gtk_entry_delete_text (entry, old_pos, entry->current_pos);
if (entry->selection_start_pos != entry->selection_end_pos)
gtk_delete_selection (entry);
else
{
old_pos = entry->current_pos;
gtk_move_forward_word (entry);
gtk_entry_delete_text (entry, old_pos, entry->current_pos);
}
}
static void
@ -1995,9 +2005,14 @@ gtk_delete_backward_word (GtkEntry *entry)
{
gint old_pos;
old_pos = entry->current_pos;
gtk_move_backward_word (entry);
gtk_entry_delete_text (entry, entry->current_pos, old_pos);
if (entry->selection_start_pos != entry->selection_end_pos)
gtk_delete_selection (entry);
else
{
old_pos = entry->current_pos;
gtk_move_backward_word (entry);
gtk_entry_delete_text (entry, entry->current_pos, old_pos);
}
}
static void

View File

@ -18,6 +18,9 @@
#include <ctype.h>
#include <string.h>
#include "gdk/gdkkeysyms.h"
#ifdef USE_XIM
#include "gdk/gdkx.h"
#endif
#include "gtkmain.h"
#include "gtksignal.h"
#include "gtktext.h"
@ -619,6 +622,14 @@ gtk_text_finalize (GtkObject *object)
if (text->vadj)
gtk_object_unref (GTK_OBJECT (text->vadj));
#ifdef USE_XIM
if (text->ic)
{
gdk_ic_destroy (text->ic);
text->ic = NULL;
}
#endif
GTK_OBJECT_CLASS(parent_class)->finalize (object);
}
@ -687,6 +698,71 @@ gtk_text_realize (GtkWidget *widget)
gdk_gc_set_exposures (text->gc, TRUE);
gdk_gc_set_foreground (text->gc, &widget->style->fg[GTK_STATE_NORMAL]);
#ifdef USE_XIM
if (gdk_im_ready ())
{
GdkPoint spot;
GdkRectangle rect;
gint width, height;
GdkEventMask mask;
GdkIMStyle style;
GdkIMStyle supported_style = GdkIMPreeditNone | GdkIMPreeditNothing |
GdkIMPreeditPosition |
GdkIMStatusNone | GdkIMStatusNothing;
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
supported_style &= ~GdkIMPreeditPosition;
style = gdk_im_decide_style (supported_style);
switch (style & GdkIMPreeditMask)
{
case GdkIMPreeditPosition:
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
{
g_warning ("over-the-spot style requires fontset");
break;
}
gdk_window_get_size (text->text_area, &width, &height);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
spot.x = 0;
spot.y = height;
text->ic = gdk_ic_new (text->text_area, text->text_area,
style,
"spotLocation", &spot,
"area", &rect,
"fontSet", GDK_FONT_XFONT (widget->style->font),
NULL);
break;
default:
text->ic = gdk_ic_new (text->text_area, text->text_area,
style, NULL);
}
if (text->ic == NULL)
g_warning ("Can't create input context.");
else
{
GdkColormap *colormap;
mask = gdk_window_get_events (text->text_area);
mask |= gdk_ic_get_events (text->ic);
gdk_window_set_events (text->text_area, mask);
if ((colormap = gtk_widget_get_colormap (widget)) !=
gtk_widget_get_default_colormap ())
{
gdk_ic_set_attr (text->ic, "preeditAttributes",
"colorMap", GDK_COLORMAP_XCOLORMAP (colormap),
NULL);
}
}
}
#endif
init_properties (text);
gdk_window_show (text->text_area);
@ -884,6 +960,21 @@ gtk_text_size_allocate (GtkWidget *widget,
widget->allocation.height - (widget->style->klass->ythickness +
TEXT_BORDER_ROOM) * 2);
#ifdef USE_XIM
if (text->ic && (gdk_ic_get_style (text->ic) & GdkIMPreeditPosition))
{
gint width, height;
GdkRectangle rect;
gdk_window_get_size (text->text_area, &width, &height);
rect.x = 0;
rect.y = 0;
rect.width = width;
rect.height = height;
gdk_ic_set_attr (text->ic, "preeditAttributes", "area", &rect, NULL);
}
#endif
recompute_geometry (text);
}
}
@ -1085,100 +1176,108 @@ gtk_text_key_press (GtkWidget *widget,
text = GTK_TEXT (widget);
if (!return_val)
key = event->keyval;
return_val = TRUE;
if (text->is_editable == FALSE)
{
key = event->keyval;
return_val = TRUE;
if (text->is_editable == FALSE)
switch (event->keyval)
{
switch (event->keyval)
{
case GDK_Home: scroll_int (text, -text->vadj->value); break;
case GDK_End: scroll_int (text, +text->vadj->upper); break;
case GDK_Page_Up: scroll_int (text, -text->vadj->page_increment); break;
case GDK_Page_Down: scroll_int (text, +text->vadj->page_increment); break;
case GDK_Up: scroll_int (text, -KEY_SCROLL_PIXELS); break;
case GDK_Down: scroll_int (text, +KEY_SCROLL_PIXELS); break;
default: break;
}
case GDK_Home: scroll_int (text, -text->vadj->value); break;
case GDK_End: scroll_int (text, +text->vadj->upper); break;
case GDK_Page_Up: scroll_int (text, -text->vadj->page_increment); break;
case GDK_Page_Down: scroll_int (text, +text->vadj->page_increment); break;
case GDK_Up: scroll_int (text, -KEY_SCROLL_PIXELS); break;
case GDK_Down: scroll_int (text, +KEY_SCROLL_PIXELS); break;
default:
return_val = FALSE;
break;
}
else
}
else
{
text->point = find_mark (text, text->cursor_mark.index);
switch (event->keyval)
{
text->point = find_mark (text, text->cursor_mark.index);
case GDK_Home: move_cursor_buffer_ver (text, -1); break;
case GDK_End: move_cursor_buffer_ver (text, +1); break;
case GDK_Page_Up: move_cursor_page_ver (text, -1); break;
case GDK_Page_Down: move_cursor_page_ver (text, +1); break;
case GDK_Up: move_cursor_ver (text, -1); break;
case GDK_Down: move_cursor_ver (text, +1); break;
case GDK_Left: move_cursor_hor (text, -1); break;
case GDK_Right: move_cursor_hor (text, +1); break;
switch (event->keyval)
case GDK_BackSpace:
if (!text->has_cursor || text->cursor_mark.index == 0)
break;
gtk_text_backward_delete_1_at_point (text);
break;
case GDK_Delete:
if (!text->has_cursor || LAST_INDEX (text, text->cursor_mark))
break;
gtk_text_forward_delete_1_at_point (text);
break;
case GDK_Tab:
if (!text->has_cursor)
break;
gtk_text_insert_1_at_point (text, '\t');
break;
case GDK_Return:
if (!text->has_cursor)
break;
gtk_text_insert_1_at_point (text, '\n');
break;
case GDK_Escape:
/* Don't insert literally */
return_val = FALSE;
break;
default:
return_val = FALSE;
if (!text->has_cursor)
break;
if (event->state & GDK_CONTROL_MASK)
{
case GDK_Home: move_cursor_buffer_ver (text, -1); break;
case GDK_End: move_cursor_buffer_ver (text, +1); break;
case GDK_Page_Up: move_cursor_page_ver (text, -1); break;
case GDK_Page_Down: move_cursor_page_ver (text, +1); break;
case GDK_Up: move_cursor_ver (text, -1); break;
case GDK_Down: move_cursor_ver (text, +1); break;
case GDK_Left: move_cursor_hor (text, -1); break;
case GDK_Right: move_cursor_hor (text, +1); break;
if ((key >= 'A') && (key <= 'Z'))
key -= 'A' - 'a';
case GDK_BackSpace:
if (!text->has_cursor || text->cursor_mark.index == 0)
break;
gtk_text_backward_delete_1_at_point (text);
break;
case GDK_Delete:
if (!text->has_cursor || LAST_INDEX (text, text->cursor_mark))
break;
gtk_text_forward_delete_1_at_point (text);
break;
case GDK_Tab:
if (!text->has_cursor)
break;
gtk_text_insert_1_at_point (text, '\t');
break;
case GDK_Return:
if (!text->has_cursor)
break;
gtk_text_insert_1_at_point (text, '\n');
break;
default:
if (!text->has_cursor)
break;
if ((event->keyval >= 0x20) && (event->keyval <= 0x7e))
if ((key >= 'a') && (key <= 'z') && text->control_keys[(int) (key - 'a')])
{
(* text->control_keys[(int) (key - 'a')]) (text);
return_val = TRUE;
if (event->state & GDK_CONTROL_MASK)
{
if ((key >= 'A') && (key <= 'Z'))
key -= 'A' - 'a';
if ((key >= 'a') && (key <= 'z') && text->control_keys[(int) (key - 'a')])
(* text->control_keys[(int) (key - 'a')]) (text);
}
else if (event->state & GDK_MOD1_MASK)
{
g_message ("alt key");
if ((key >= 'A') && (key <= 'Z'))
key -= 'A' - 'a';
if ((key >= 'a') && (key <= 'z') && text->alt_keys[(int) (key - 'a')])
(* text->alt_keys[(int) (key - 'a')]) (text);
}
else
{
gtk_text_insert_1_at_point (text, key);
}
}
else
{
return_val = FALSE;
}
break;
}
else if (event->state & GDK_MOD1_MASK)
{
if ((key >= 'A') && (key <= 'Z'))
key -= 'A' - 'a';
if ((key >= 'a') && (key <= 'z') && text->alt_keys[(int) (key - 'a')])
{
(* text->alt_keys[(int) (key - 'a')]) (text);
return_val = TRUE;
}
break;
}
else if (event->length > 0)
{
if (event->length == 1)
gtk_text_insert_1_at_point (text, event->string[0]);
return_val = TRUE;
}
else
return_val = FALSE;
}
}
@ -1198,6 +1297,11 @@ gtk_text_focus_in (GtkWidget *widget,
GTK_WIDGET_SET_FLAGS (widget, GTK_HAS_FOCUS);
gtk_widget_draw_focus (widget);
#ifdef USE_XIM
if (GTK_TEXT(widget)->ic)
gdk_im_begin (GTK_TEXT(widget)->ic, GTK_TEXT(widget)->text_area);
#endif
draw_cursor (GTK_TEXT(widget), TRUE);
return FALSE;
@ -1218,6 +1322,10 @@ gtk_text_focus_out (GtkWidget *widget,
undraw_cursor (GTK_TEXT(widget), TRUE);
#ifdef USE_XIM
gdk_im_end ();
#endif
return FALSE;
}
@ -2265,6 +2373,28 @@ find_cursor_at_line (GtkText* text, const LineParams* start_line, gint pixel_hei
text->cursor_char = ch;
else
text->cursor_char = 0;
#ifdef USE_XIM
if (gdk_im_ready() && text->ic &&
gdk_ic_get_style (text->ic) & GdkIMPreeditPosition)
{
GdkPoint spot;
spot.x = text->cursor_pos_x;
spot.y = text->cursor_pos_y - text->cursor_char_offset;
if (MARK_CURRENT_FONT (&mark)->type == GDK_FONT_FONTSET)
gdk_ic_set_attr (text->ic, "preeditAttributes",
"fontSet", GDK_FONT_XFONT (MARK_CURRENT_FONT (&mark)),
NULL);
gdk_ic_set_attr (text->ic, "preeditAttributes",
"spotLocation", &spot,
"lineSpace", LINE_HEIGHT (*start_line),
"foreground", MARK_CURRENT_FORE (&mark)->pixel,
"background", MARK_CURRENT_BACK (&mark)->pixel,
NULL);
}
#endif
}
static void
@ -2281,6 +2411,7 @@ find_cursor (GtkText* text)
find_cursor_at_line (text,
&CACHE_DATA(text->current_line),
pixel_height_of(text, text->current_line));
}
static void