]> Pileus Git - ~andy/gtk/commitdiff
Destroy widgets _after_ propagating unrealize signals through the widget
authorOwen Taylor <otaylor@redhat.com>
Wed, 9 Dec 1998 06:36:57 +0000 (06:36 +0000)
committerOwen Taylor <otaylor@src.gnome.org>
Wed, 9 Dec 1998 06:36:57 +0000 (06:36 +0000)
Mon Dec  7 10:27:09 1998  Owen Taylor  <otaylor@redhat.com>

* gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize
signals through the widget heirarchy. This is unpleasant, as it
causes more X traffic, but is necessary, because we have to clean
up our Input Contexts before destroying the X windows.
(from matsu-981109-0.patch)

Mon Dec  7 10:18:18 1998  Owen Taylor  <otaylor@redhat.com>

Applied gtk-a-higuti-981202-0 :
[ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ]

* gdk/gdk.h gdk/gdk.c
(gdk_mbstowcs): New function. Nearly equals to mbstowcs, but
implemented by a combination of Xlib functions, so
it works even with X_LOCALE.
(gdk_wcstombs): New function.
(g_mbtowc): Removed. No longer needed.

* gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c:
        Added _wc() variants to gdk_text_width(),
gdk_char_width(), gdk_draw_text(),

* gdk/gdki18n.h
(mblen, mbtowc, wctomb, mbstowcs, wcstombs,
 wcslen, wcscpy, wcsncpy):
Removed. No longer needed.
(iswalnum): Removed.
(gdk_iswalnum): New macro.
(gdk_iswspace): New macro.
* gdk/gdktype.h
(GdkWChar): New typedef.

* gtk/gtkentry.h, gtk/gtkentry.c
There are many changes according to the change of the
internal representation of text, from multibyte string
to wide characters.
* gtk/gtkprivate.h, gtk/gtkmain.c
Removed the variable gtk_use_mb and related codes.
* gtk/gtkspinbutton.c
Some changes according to the change of type of entry->text.
* gtk/gtktext.h, gtk/gtktext.c
Changed the internal representation of text. We use GdkWchar
if a fontset is supplied. If not, we use guchar to save
memory.

35 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
gdk/Makefile.am
gdk/gdk.c
gdk/gdk.h
gdk/gdkdraw.c
gdk/gdkfont.c
gdk/gdkglobals.c
gdk/gdki18n.h
gdk/gdkprivate.h
gdk/gdktypes.h
gdk/gdkwindow.c
gdk/x11/gdkfont-x11.c
gdk/x11/gdkglobals-x11.c
gdk/x11/gdkmain-x11.c
gdk/x11/gdkwindow-x11.c
gtk/gtkeditable.c
gtk/gtkeditable.h
gtk/gtkentry.c
gtk/gtkentry.h
gtk/gtkmain.c
gtk/gtkprivate.h
gtk/gtkspinbutton.c
gtk/gtktext.c
gtk/gtktext.h
gtk/gtkwidget.c
gtk/testgtk.c
gtk/testgtkrc
tests/testgtk.c
tests/testgtkrc

index af8d9629b3b8ab460df7aa46b078333fb61121e6..c37d061508c80b9a15a1b575f84803aef4efbbca 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,80 @@
+Mon Dec  7 10:27:09 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize
+       signals through the widget heirarchy. This is unpleasant, as it
+       causes more X traffic, but is necessary, because we have to clean
+       up our Input Contexts before destroying the X windows.
+       (from matsu-981109-0.patch)
+       
+Mon Dec  7 10:18:18 1998  Owen Taylor  <otaylor@redhat.com>
+
+       Applied gtk-a-higuti-981202-0 : 
+       [ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ]
+       
+       * gdk/gdk.h gdk/gdk.c
+               (gdk_mbstowcs): New function. Nearly equals to mbstowcs, but
+                       implemented by a combination of Xlib functions, so
+                       it works even with X_LOCALE.
+               (gdk_wcstombs): New function.
+               (g_mbtowc): Removed. No longer needed.
+
+       * gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c: 
+               Added _wc() variants to gdk_text_width(), 
+               gdk_char_width(), gdk_draw_text(),
+               
+       * gdk/gdki18n.h
+               (mblen, mbtowc, wctomb, mbstowcs, wcstombs,
+                wcslen, wcscpy, wcsncpy):
+                       Removed. No longer needed.
+               (iswalnum): Removed.
+               (gdk_iswalnum): New macro.
+               (gdk_iswspace): New macro.
+       * gdk/gdktype.h
+               (GdkWChar): New typedef.
+       
+       * gtk/gtkentry.h, gtk/gtkentry.c
+               There are many changes according to the change of the
+               internal representation of text, from multibyte string
+               to wide characters. 
+       * gtk/gtkprivate.h, gtk/gtkmain.c
+               Removed the variable gtk_use_mb and related codes.
+       * gtk/gtkspinbutton.c
+               Some changes according to the change of type of entry->text.
+       * gtk/gtktext.h, gtk/gtktext.c
+               Changed the internal representation of text. We use GdkWchar
+               if a fontset is supplied. If not, we use guchar to save
+               memory.
+       
+Tue Dec  1 15:20:39 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.c (gdk_window_new): When creating
+       a window with a specified non-system visual, use
+       a matching colormap.
+
+Mon Nov 30 11:50:13 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c gdk/gdkprivate.h gdk/gdk.h
+         gdk/gdktypes.h gtk/gtkeditable.c gtk/gtkmain.c
+         gtk/gtkentry.c gtk/gtktext.c:
+
+        Applied matsu-981109-0
+        [ matsu@arch.comp.kyutech.ac.jp (Takashi Matsuda) ]
+       
+        - Change system of setting input method values 
+          from varargs to a structure, similar to GC's
+          or window attributes.
+
+        - Various fixes to event handling.
+
+        Also:
+
+        * gdk/gdkim.c: Split of input method stuff into
+          a separate source file.
+
+        * Remove GdkIM typedef, change everything from
+          GdkIC to GdkIC * to be consistent with the
+          rest of GTK.
+       
 Wed Dec  9 00:41:41 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkrc.c (gtk_rc_add_initial_default_files): Allocate
index af8d9629b3b8ab460df7aa46b078333fb61121e6..c37d061508c80b9a15a1b575f84803aef4efbbca 100644 (file)
@@ -1,3 +1,80 @@
+Mon Dec  7 10:27:09 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize
+       signals through the widget heirarchy. This is unpleasant, as it
+       causes more X traffic, but is necessary, because we have to clean
+       up our Input Contexts before destroying the X windows.
+       (from matsu-981109-0.patch)
+       
+Mon Dec  7 10:18:18 1998  Owen Taylor  <otaylor@redhat.com>
+
+       Applied gtk-a-higuti-981202-0 : 
+       [ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ]
+       
+       * gdk/gdk.h gdk/gdk.c
+               (gdk_mbstowcs): New function. Nearly equals to mbstowcs, but
+                       implemented by a combination of Xlib functions, so
+                       it works even with X_LOCALE.
+               (gdk_wcstombs): New function.
+               (g_mbtowc): Removed. No longer needed.
+
+       * gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c: 
+               Added _wc() variants to gdk_text_width(), 
+               gdk_char_width(), gdk_draw_text(),
+               
+       * gdk/gdki18n.h
+               (mblen, mbtowc, wctomb, mbstowcs, wcstombs,
+                wcslen, wcscpy, wcsncpy):
+                       Removed. No longer needed.
+               (iswalnum): Removed.
+               (gdk_iswalnum): New macro.
+               (gdk_iswspace): New macro.
+       * gdk/gdktype.h
+               (GdkWChar): New typedef.
+       
+       * gtk/gtkentry.h, gtk/gtkentry.c
+               There are many changes according to the change of the
+               internal representation of text, from multibyte string
+               to wide characters. 
+       * gtk/gtkprivate.h, gtk/gtkmain.c
+               Removed the variable gtk_use_mb and related codes.
+       * gtk/gtkspinbutton.c
+               Some changes according to the change of type of entry->text.
+       * gtk/gtktext.h, gtk/gtktext.c
+               Changed the internal representation of text. We use GdkWchar
+               if a fontset is supplied. If not, we use guchar to save
+               memory.
+       
+Tue Dec  1 15:20:39 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.c (gdk_window_new): When creating
+       a window with a specified non-system visual, use
+       a matching colormap.
+
+Mon Nov 30 11:50:13 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c gdk/gdkprivate.h gdk/gdk.h
+         gdk/gdktypes.h gtk/gtkeditable.c gtk/gtkmain.c
+         gtk/gtkentry.c gtk/gtktext.c:
+
+        Applied matsu-981109-0
+        [ matsu@arch.comp.kyutech.ac.jp (Takashi Matsuda) ]
+       
+        - Change system of setting input method values 
+          from varargs to a structure, similar to GC's
+          or window attributes.
+
+        - Various fixes to event handling.
+
+        Also:
+
+        * gdk/gdkim.c: Split of input method stuff into
+          a separate source file.
+
+        * Remove GdkIM typedef, change everything from
+          GdkIC to GdkIC * to be consistent with the
+          rest of GTK.
+       
 Wed Dec  9 00:41:41 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkrc.c (gtk_rc_add_initial_default_files): Allocate
index af8d9629b3b8ab460df7aa46b078333fb61121e6..c37d061508c80b9a15a1b575f84803aef4efbbca 100644 (file)
@@ -1,3 +1,80 @@
+Mon Dec  7 10:27:09 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize
+       signals through the widget heirarchy. This is unpleasant, as it
+       causes more X traffic, but is necessary, because we have to clean
+       up our Input Contexts before destroying the X windows.
+       (from matsu-981109-0.patch)
+       
+Mon Dec  7 10:18:18 1998  Owen Taylor  <otaylor@redhat.com>
+
+       Applied gtk-a-higuti-981202-0 : 
+       [ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ]
+       
+       * gdk/gdk.h gdk/gdk.c
+               (gdk_mbstowcs): New function. Nearly equals to mbstowcs, but
+                       implemented by a combination of Xlib functions, so
+                       it works even with X_LOCALE.
+               (gdk_wcstombs): New function.
+               (g_mbtowc): Removed. No longer needed.
+
+       * gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c: 
+               Added _wc() variants to gdk_text_width(), 
+               gdk_char_width(), gdk_draw_text(),
+               
+       * gdk/gdki18n.h
+               (mblen, mbtowc, wctomb, mbstowcs, wcstombs,
+                wcslen, wcscpy, wcsncpy):
+                       Removed. No longer needed.
+               (iswalnum): Removed.
+               (gdk_iswalnum): New macro.
+               (gdk_iswspace): New macro.
+       * gdk/gdktype.h
+               (GdkWChar): New typedef.
+       
+       * gtk/gtkentry.h, gtk/gtkentry.c
+               There are many changes according to the change of the
+               internal representation of text, from multibyte string
+               to wide characters. 
+       * gtk/gtkprivate.h, gtk/gtkmain.c
+               Removed the variable gtk_use_mb and related codes.
+       * gtk/gtkspinbutton.c
+               Some changes according to the change of type of entry->text.
+       * gtk/gtktext.h, gtk/gtktext.c
+               Changed the internal representation of text. We use GdkWchar
+               if a fontset is supplied. If not, we use guchar to save
+               memory.
+       
+Tue Dec  1 15:20:39 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.c (gdk_window_new): When creating
+       a window with a specified non-system visual, use
+       a matching colormap.
+
+Mon Nov 30 11:50:13 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c gdk/gdkprivate.h gdk/gdk.h
+         gdk/gdktypes.h gtk/gtkeditable.c gtk/gtkmain.c
+         gtk/gtkentry.c gtk/gtktext.c:
+
+        Applied matsu-981109-0
+        [ matsu@arch.comp.kyutech.ac.jp (Takashi Matsuda) ]
+       
+        - Change system of setting input method values 
+          from varargs to a structure, similar to GC's
+          or window attributes.
+
+        - Various fixes to event handling.
+
+        Also:
+
+        * gdk/gdkim.c: Split of input method stuff into
+          a separate source file.
+
+        * Remove GdkIM typedef, change everything from
+          GdkIC to GdkIC * to be consistent with the
+          rest of GTK.
+       
 Wed Dec  9 00:41:41 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkrc.c (gtk_rc_add_initial_default_files): Allocate
index af8d9629b3b8ab460df7aa46b078333fb61121e6..c37d061508c80b9a15a1b575f84803aef4efbbca 100644 (file)
@@ -1,3 +1,80 @@
+Mon Dec  7 10:27:09 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize
+       signals through the widget heirarchy. This is unpleasant, as it
+       causes more X traffic, but is necessary, because we have to clean
+       up our Input Contexts before destroying the X windows.
+       (from matsu-981109-0.patch)
+       
+Mon Dec  7 10:18:18 1998  Owen Taylor  <otaylor@redhat.com>
+
+       Applied gtk-a-higuti-981202-0 : 
+       [ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ]
+       
+       * gdk/gdk.h gdk/gdk.c
+               (gdk_mbstowcs): New function. Nearly equals to mbstowcs, but
+                       implemented by a combination of Xlib functions, so
+                       it works even with X_LOCALE.
+               (gdk_wcstombs): New function.
+               (g_mbtowc): Removed. No longer needed.
+
+       * gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c: 
+               Added _wc() variants to gdk_text_width(), 
+               gdk_char_width(), gdk_draw_text(),
+               
+       * gdk/gdki18n.h
+               (mblen, mbtowc, wctomb, mbstowcs, wcstombs,
+                wcslen, wcscpy, wcsncpy):
+                       Removed. No longer needed.
+               (iswalnum): Removed.
+               (gdk_iswalnum): New macro.
+               (gdk_iswspace): New macro.
+       * gdk/gdktype.h
+               (GdkWChar): New typedef.
+       
+       * gtk/gtkentry.h, gtk/gtkentry.c
+               There are many changes according to the change of the
+               internal representation of text, from multibyte string
+               to wide characters. 
+       * gtk/gtkprivate.h, gtk/gtkmain.c
+               Removed the variable gtk_use_mb and related codes.
+       * gtk/gtkspinbutton.c
+               Some changes according to the change of type of entry->text.
+       * gtk/gtktext.h, gtk/gtktext.c
+               Changed the internal representation of text. We use GdkWchar
+               if a fontset is supplied. If not, we use guchar to save
+               memory.
+       
+Tue Dec  1 15:20:39 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.c (gdk_window_new): When creating
+       a window with a specified non-system visual, use
+       a matching colormap.
+
+Mon Nov 30 11:50:13 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c gdk/gdkprivate.h gdk/gdk.h
+         gdk/gdktypes.h gtk/gtkeditable.c gtk/gtkmain.c
+         gtk/gtkentry.c gtk/gtktext.c:
+
+        Applied matsu-981109-0
+        [ matsu@arch.comp.kyutech.ac.jp (Takashi Matsuda) ]
+       
+        - Change system of setting input method values 
+          from varargs to a structure, similar to GC's
+          or window attributes.
+
+        - Various fixes to event handling.
+
+        Also:
+
+        * gdk/gdkim.c: Split of input method stuff into
+          a separate source file.
+
+        * Remove GdkIM typedef, change everything from
+          GdkIC to GdkIC * to be consistent with the
+          rest of GTK.
+       
 Wed Dec  9 00:41:41 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkrc.c (gtk_rc_add_initial_default_files): Allocate
index af8d9629b3b8ab460df7aa46b078333fb61121e6..c37d061508c80b9a15a1b575f84803aef4efbbca 100644 (file)
@@ -1,3 +1,80 @@
+Mon Dec  7 10:27:09 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize
+       signals through the widget heirarchy. This is unpleasant, as it
+       causes more X traffic, but is necessary, because we have to clean
+       up our Input Contexts before destroying the X windows.
+       (from matsu-981109-0.patch)
+       
+Mon Dec  7 10:18:18 1998  Owen Taylor  <otaylor@redhat.com>
+
+       Applied gtk-a-higuti-981202-0 : 
+       [ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ]
+       
+       * gdk/gdk.h gdk/gdk.c
+               (gdk_mbstowcs): New function. Nearly equals to mbstowcs, but
+                       implemented by a combination of Xlib functions, so
+                       it works even with X_LOCALE.
+               (gdk_wcstombs): New function.
+               (g_mbtowc): Removed. No longer needed.
+
+       * gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c: 
+               Added _wc() variants to gdk_text_width(), 
+               gdk_char_width(), gdk_draw_text(),
+               
+       * gdk/gdki18n.h
+               (mblen, mbtowc, wctomb, mbstowcs, wcstombs,
+                wcslen, wcscpy, wcsncpy):
+                       Removed. No longer needed.
+               (iswalnum): Removed.
+               (gdk_iswalnum): New macro.
+               (gdk_iswspace): New macro.
+       * gdk/gdktype.h
+               (GdkWChar): New typedef.
+       
+       * gtk/gtkentry.h, gtk/gtkentry.c
+               There are many changes according to the change of the
+               internal representation of text, from multibyte string
+               to wide characters. 
+       * gtk/gtkprivate.h, gtk/gtkmain.c
+               Removed the variable gtk_use_mb and related codes.
+       * gtk/gtkspinbutton.c
+               Some changes according to the change of type of entry->text.
+       * gtk/gtktext.h, gtk/gtktext.c
+               Changed the internal representation of text. We use GdkWchar
+               if a fontset is supplied. If not, we use guchar to save
+               memory.
+       
+Tue Dec  1 15:20:39 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.c (gdk_window_new): When creating
+       a window with a specified non-system visual, use
+       a matching colormap.
+
+Mon Nov 30 11:50:13 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c gdk/gdkprivate.h gdk/gdk.h
+         gdk/gdktypes.h gtk/gtkeditable.c gtk/gtkmain.c
+         gtk/gtkentry.c gtk/gtktext.c:
+
+        Applied matsu-981109-0
+        [ matsu@arch.comp.kyutech.ac.jp (Takashi Matsuda) ]
+       
+        - Change system of setting input method values 
+          from varargs to a structure, similar to GC's
+          or window attributes.
+
+        - Various fixes to event handling.
+
+        Also:
+
+        * gdk/gdkim.c: Split of input method stuff into
+          a separate source file.
+
+        * Remove GdkIM typedef, change everything from
+          GdkIC to GdkIC * to be consistent with the
+          rest of GTK.
+       
 Wed Dec  9 00:41:41 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkrc.c (gtk_rc_add_initial_default_files): Allocate
index af8d9629b3b8ab460df7aa46b078333fb61121e6..c37d061508c80b9a15a1b575f84803aef4efbbca 100644 (file)
@@ -1,3 +1,80 @@
+Mon Dec  7 10:27:09 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize
+       signals through the widget heirarchy. This is unpleasant, as it
+       causes more X traffic, but is necessary, because we have to clean
+       up our Input Contexts before destroying the X windows.
+       (from matsu-981109-0.patch)
+       
+Mon Dec  7 10:18:18 1998  Owen Taylor  <otaylor@redhat.com>
+
+       Applied gtk-a-higuti-981202-0 : 
+       [ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ]
+       
+       * gdk/gdk.h gdk/gdk.c
+               (gdk_mbstowcs): New function. Nearly equals to mbstowcs, but
+                       implemented by a combination of Xlib functions, so
+                       it works even with X_LOCALE.
+               (gdk_wcstombs): New function.
+               (g_mbtowc): Removed. No longer needed.
+
+       * gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c: 
+               Added _wc() variants to gdk_text_width(), 
+               gdk_char_width(), gdk_draw_text(),
+               
+       * gdk/gdki18n.h
+               (mblen, mbtowc, wctomb, mbstowcs, wcstombs,
+                wcslen, wcscpy, wcsncpy):
+                       Removed. No longer needed.
+               (iswalnum): Removed.
+               (gdk_iswalnum): New macro.
+               (gdk_iswspace): New macro.
+       * gdk/gdktype.h
+               (GdkWChar): New typedef.
+       
+       * gtk/gtkentry.h, gtk/gtkentry.c
+               There are many changes according to the change of the
+               internal representation of text, from multibyte string
+               to wide characters. 
+       * gtk/gtkprivate.h, gtk/gtkmain.c
+               Removed the variable gtk_use_mb and related codes.
+       * gtk/gtkspinbutton.c
+               Some changes according to the change of type of entry->text.
+       * gtk/gtktext.h, gtk/gtktext.c
+               Changed the internal representation of text. We use GdkWchar
+               if a fontset is supplied. If not, we use guchar to save
+               memory.
+       
+Tue Dec  1 15:20:39 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.c (gdk_window_new): When creating
+       a window with a specified non-system visual, use
+       a matching colormap.
+
+Mon Nov 30 11:50:13 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c gdk/gdkprivate.h gdk/gdk.h
+         gdk/gdktypes.h gtk/gtkeditable.c gtk/gtkmain.c
+         gtk/gtkentry.c gtk/gtktext.c:
+
+        Applied matsu-981109-0
+        [ matsu@arch.comp.kyutech.ac.jp (Takashi Matsuda) ]
+       
+        - Change system of setting input method values 
+          from varargs to a structure, similar to GC's
+          or window attributes.
+
+        - Various fixes to event handling.
+
+        Also:
+
+        * gdk/gdkim.c: Split of input method stuff into
+          a separate source file.
+
+        * Remove GdkIM typedef, change everything from
+          GdkIC to GdkIC * to be consistent with the
+          rest of GTK.
+       
 Wed Dec  9 00:41:41 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkrc.c (gtk_rc_add_initial_default_files): Allocate
index af8d9629b3b8ab460df7aa46b078333fb61121e6..c37d061508c80b9a15a1b575f84803aef4efbbca 100644 (file)
@@ -1,3 +1,80 @@
+Mon Dec  7 10:27:09 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gtk/gtkwidget.c: Destroy widgets _after_ propagating unrealize
+       signals through the widget heirarchy. This is unpleasant, as it
+       causes more X traffic, but is necessary, because we have to clean
+       up our Input Contexts before destroying the X windows.
+       (from matsu-981109-0.patch)
+       
+Mon Dec  7 10:18:18 1998  Owen Taylor  <otaylor@redhat.com>
+
+       Applied gtk-a-higuti-981202-0 : 
+       [ a-higuti@math.sci.hokudai.ac.jp (Akira Higuchi) ]
+       
+       * gdk/gdk.h gdk/gdk.c
+               (gdk_mbstowcs): New function. Nearly equals to mbstowcs, but
+                       implemented by a combination of Xlib functions, so
+                       it works even with X_LOCALE.
+               (gdk_wcstombs): New function.
+               (g_mbtowc): Removed. No longer needed.
+
+       * gdk/gdk.h gdk/gdkfont.c gdk/gdkdraw.c: 
+               Added _wc() variants to gdk_text_width(), 
+               gdk_char_width(), gdk_draw_text(),
+               
+       * gdk/gdki18n.h
+               (mblen, mbtowc, wctomb, mbstowcs, wcstombs,
+                wcslen, wcscpy, wcsncpy):
+                       Removed. No longer needed.
+               (iswalnum): Removed.
+               (gdk_iswalnum): New macro.
+               (gdk_iswspace): New macro.
+       * gdk/gdktype.h
+               (GdkWChar): New typedef.
+       
+       * gtk/gtkentry.h, gtk/gtkentry.c
+               There are many changes according to the change of the
+               internal representation of text, from multibyte string
+               to wide characters. 
+       * gtk/gtkprivate.h, gtk/gtkmain.c
+               Removed the variable gtk_use_mb and related codes.
+       * gtk/gtkspinbutton.c
+               Some changes according to the change of type of entry->text.
+       * gtk/gtktext.h, gtk/gtktext.c
+               Changed the internal representation of text. We use GdkWchar
+               if a fontset is supplied. If not, we use guchar to save
+               memory.
+       
+Tue Dec  1 15:20:39 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdkwindow.c (gdk_window_new): When creating
+       a window with a specified non-system visual, use
+       a matching colormap.
+
+Mon Nov 30 11:50:13 1998  Owen Taylor  <otaylor@redhat.com>
+
+       * gdk/gdk.c gdk/gdkim.c gdk/gdkprivate.h gdk/gdk.h
+         gdk/gdktypes.h gtk/gtkeditable.c gtk/gtkmain.c
+         gtk/gtkentry.c gtk/gtktext.c:
+
+        Applied matsu-981109-0
+        [ matsu@arch.comp.kyutech.ac.jp (Takashi Matsuda) ]
+       
+        - Change system of setting input method values 
+          from varargs to a structure, similar to GC's
+          or window attributes.
+
+        - Various fixes to event handling.
+
+        Also:
+
+        * gdk/gdkim.c: Split of input method stuff into
+          a separate source file.
+
+        * Remove GdkIM typedef, change everything from
+          GdkIC to GdkIC * to be consistent with the
+          rest of GTK.
+       
 Wed Dec  9 00:41:41 1998  Owen Taylor  <otaylor@redhat.com>
 
        * gtk/gtkrc.c (gtk_rc_add_initial_default_files): Allocate
index ec4f78af9ad0546c0808f4af85dc1aeaac134c4c..2766b3781a1d9a3ccad47ebc7f24d8df0e0c9084 100644 (file)
@@ -24,6 +24,7 @@ libgdk_la_SOURCES = \
        gdkfont.c       \
        gdkgc.c         \
        gdkglobals.c    \
+       gdkim.c         \
        gdkimage.c      \
        gdkinput.c      \
        gdkinput.h      \
@@ -53,7 +54,7 @@ gdkinclude_HEADERS = \
        gdk.h           \
        gdkcursors.h    \
        gdkrgb.h        \
-       gdki18n.h       \
+       gdki18n.h       \
        gdkkeysyms.h    \
        gdkprivate.h    \
        gdktypes.h      \
index f504ea313a840f671ea294e619c81ea08ebc7e51..15dcaa3035395731d93f4147dd7dce55301aefd4 100644 (file)
--- a/gdk/gdk.c
+++ b/gdk/gdk.c
@@ -28,9 +28,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
-#ifdef USE_XIM
-#include <stdarg.h>
-#endif
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #include <X11/Xos.h>
 #include <X11/Xutil.h>
 #include <X11/Xmu/WinUtil.h>
-#ifdef USE_XIM
-#include <X11/Xresource.h>
-#endif
 #include <X11/cursorfont.h>
 #include "gdk.h"
 #include "gdkprivate.h"
 #include "gdkinput.h"
+#include "gdki18n.h"
 #include "gdkx.h"
 #include "gdkkeysyms.h"
-#include "gdki18n.h"
 
 #ifndef X_GETTIMEOFDAY
 #define X_GETTIMEOFDAY(tv)  gettimeofday (tv, NULL)
@@ -139,21 +133,6 @@ static int     gdk_x_error                  (Display     *display,
 static int         gdk_x_io_error               (Display     *display);
 static RETSIGTYPE   gdk_signal                  (int          signum);
 
-
-#ifdef USE_XIM
-static guint        gdk_im_va_count     (va_list list);
-static XVaNestedList gdk_im_va_to_nested (va_list list, 
-                                         guint   count);
-
-static GdkIM  gdk_im_get               (void);
-static gint   gdk_im_open              (XrmDatabase db,
-                                        gchar* res_name,
-                                        gchar* rec_class);
-static void   gdk_im_close             (void);
-static void   gdk_ic_cleanup           (void);
-
-#endif /* USE_XIM */
-
 GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev,
                                         GdkEvent  *event,
                                         gpointer   data);
@@ -212,17 +191,6 @@ static GdkWindowPrivate *xgrab_window = NULL;          /* Window that currently holds
 
 static GList *client_filters;                      /* Filters for client messages */
 
-#ifdef USE_XIM
-static gint xim_using;                         /* using XIM Protocol if TRUE */
-static GdkIM xim_im;                           /* global IM */
-static XIMStyles* xim_styles;                  /* im supports these styles */
-static XIMStyle xim_best_allowed_style;
-static GdkICPrivate *xim_ic;                   /* currently using IC */
-static GdkWindow* xim_window;                  /* currently using Widow */
-static GList* xim_ic_list;
-
-#endif
-
 static GList *putback_events = NULL;
 
 static gulong base_id;
@@ -570,18 +538,7 @@ gdk_init (int       *argc,
                                 gdk_wm_protocols_filter, NULL);
   
 #ifdef USE_XIM
-  /* initialize XIM Protocol variables */
-  xim_using = FALSE;
-  xim_im = NULL;
-  xim_styles = NULL;
-  if (!(xim_best_allowed_style & GDK_IM_PREEDIT_MASK))
-    gdk_im_set_best_style (GDK_IM_PREEDIT_CALLBACKS);
-  if (!(xim_best_allowed_style & GDK_IM_STATUS_MASK))
-    gdk_im_set_best_style (GDK_IM_STATUS_CALLBACKS);
-  xim_ic = NULL;
-  xim_window = (GdkWindow*)NULL;
-  
-  gdk_im_open (NULL, NULL, NULL);
+  gdk_im_open ();
 #endif
   
   gdk_initialized = 1;
@@ -1005,16 +962,22 @@ gdk_event_get (void)
        *  has occurred. Read it.
        */
 #ifdef USE_XIM
-      gint filter_status;
-      if (xim_using && xim_window)
-       do
-         {             /* don't dispatch events used by IM */
-           XNextEvent (gdk_display, &xevent);
-           filter_status = XFilterEvent (&xevent, 
-                                         GDK_WINDOW_XWINDOW (xim_window));
-         } while (filter_status == True);
-      else
-       XNextEvent (gdk_display, &xevent);
+      Window w = None;
+
+      XNextEvent (gdk_display, &xevent);
+      if (gdk_xim_window)
+       switch (xevent.type)
+         {
+         case KeyPress:
+         case KeyRelease:
+         case ButtonPress:
+         case ButtonRelease:
+           w = GDK_WINDOW_XWINDOW (gdk_xim_window);
+           break;
+         }
+
+      if (XFilterEvent (&xevent, w))
+       return NULL;
 #else
       XNextEvent (gdk_display, &xevent);
 #endif
@@ -2067,13 +2030,6 @@ gdk_event_translate (GdkEvent *event,
   
   if (window != NULL)
     gdk_window_ref (window);
-#ifdef USE_XIM
-  else if (XFilterEvent(xevent, None)) /* for xlib XIM handling */
-    return FALSE;
-#endif
-  else
-    GDK_NOTE (EVENTS, 
-      g_message ("Got event for unknown window: %#lx\n", xevent->xany.window));
   
   event->any.window = window;
   event->any.send_event = xevent->xany.send_event;
@@ -2088,17 +2044,46 @@ gdk_event_translate (GdkEvent *event,
       /* Check for filters for this window */
   
       GdkFilterReturn result;
+
+#ifdef USE_XIM
+      if (window == NULL && 
+         xevent->type == KeyPress &&
+         gdk_xim_window && 
+         !((GdkWindowPrivate *) gdk_xim_window)->destroyed)
+       {
+         /*
+          * If user presses a key in Preedit or Status window, keypress event
+          * is sometimes sent to these windows. These windows are not managed
+          * by GDK, so we redirect KeyPress event to gdk_xim_window.
+          *
+          * If someone want to use the window whitch is not managed by GDK
+          * and want to get KeyPress event, he/she must register the filter
+          * function to gdk_default_filters to intercept the event.
+          */
+         
+         window = gdk_xim_window;
+         window_private = (GdkWindowPrivate *) window;
+         gdk_window_ref (window);
+         event->any.window = window;
+         
+         GDK_NOTE (XIM,
+                   g_message ("KeyPress event is redirected to gdk_xim_window: %#lx",
+                              xevent->xany.window));
+       }
+#endif /* USE_XIM */
+      
       result = gdk_event_apply_filters (xevent, event,
                                        window_private
                                        ?window_private->filters
                                        :gdk_default_filters);
       
       if (result != GDK_FILTER_CONTINUE)
-       {
-         return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
-       }
+       return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
     }
 
+  if (window == NULL)
+    g_message ("Got event for unknown window: %#lx\n", xevent->xany.window);
+
   /* We do a "manual" conversion of the XEvent to a
    *  GdkEvent. The structures are mostly the same so
    *  the conversion is fairly straightforward. We also
@@ -2121,12 +2106,12 @@ gdk_event_translate (GdkEvent *event,
        }
       keysym = GDK_VoidSymbol;
       
-      if (xim_using == TRUE && xim_ic)
+      if (gdk_xim_ic && gdk_xim_ic->xic)
        {
          Status status;
          
          /* Clear keyval. Depending on status, may not be set */
-         charcount = XmbLookupString(xim_ic->xic,
+         charcount = XmbLookupString(gdk_xim_ic->xic,
                                      &xevent->xkey, buf, buf_len-1,
                                      &keysym, &status);
          if (status == XBufferOverflow)
@@ -2139,7 +2124,7 @@ gdk_event_translate (GdkEvent *event,
                buf_len *= 2;
              buf = (gchar *) g_realloc (buf, buf_len);
              
-             charcount = XmbLookupString (xim_ic->xic,
+             charcount = XmbLookupString (gdk_xim_ic->xic,
                                           &xevent->xkey, buf, buf_len-1,
                                           &keysym, &status);
            }
@@ -2520,6 +2505,13 @@ gdk_event_translate (GdkEvent *event,
                               (xevent->xany.type == FocusIn) ? "in" : "out",
                               xevent->xfocus.window - base_id));
          
+         /* gdk_keyboard_grab() causes following events. These events confuse
+          * the XIM focus, so ignore them.
+          */
+         if (xevent->xfocus.mode == NotifyGrab ||
+             xevent->xfocus.mode == NotifyUngrab)
+           break;
+
          event->focus_change.type = GDK_FOCUS_CHANGE;
          event->focus_change.window = window;
          event->focus_change.in = (xevent->xany.type == FocusIn);
@@ -3186,652 +3178,6 @@ gdk_signal (int sig_num)
 #endif /* !G_ENABLE_DEBUG */
 }
 
-#ifdef USE_XIM
-
-/* The following routines duplicate functionality in Xlib to
- * translate from varargs to X's internal opaque XVaNestedList.
- * 
- * If all vendors have stuck close to the reference implementation,
- * then we should hopefully be OK. 
- */
-
-/* This needs to match XIMArg as defined in Xlcint.h exactly */
-
-typedef struct {
-  gchar          *name;
-  gpointer value;
-} GdkImArg;
-
-/*************************************************************
- * gdk_im_va_count:
- *    Counts the number of name/value pairs in the vararg list
- *
- *   arguments:
- *     
- *   results:
- *************************************************************/
-
-static guint 
-gdk_im_va_count (va_list list)
-{
-  gint count = 0;
-  gchar *name;
-  
-  name = va_arg (list, gchar *);
-  while (name)
-    {
-      count++;
-      (void)va_arg (list, gpointer);
-      name = va_arg (list, gchar *);
-    }
-  
-  return count;
-}
-
-/*************************************************************
- * gdk_im_va_to_nested:
- *     Given a varargs list and the result of gdk_im_va_count,
- *     create a XVaNestedList.
- *
- *   arguments:
- *     
- *   results:
- *************************************************************/
-
-static XVaNestedList
-gdk_im_va_to_nested (va_list list, guint count)
-{
-  GdkImArg *result;
-  GdkImArg *arg;
-  
-  gchar *name;
-  
-  if (count == 0)
-    return NULL;
-  
-  result = g_new (GdkImArg, count+1);
-  arg = result;
-  
-  name = va_arg (list, gchar *);
-  while (name)
-    {
-      arg->name = name;
-      arg->value = va_arg (list, gpointer);
-      arg++;
-      name = va_arg (list, gchar *);
-    }
-  
-  arg->name = NULL;
-  
-  return (XVaNestedList)result;
-}
-
-/*
- *--------------------------------------------------------------
- * gdk_im_begin
- *
- *   Begin using input method with XIM Protocol(X11R6 standard)
- *
- * Arguments:
- *   "ic" is the "Input Context" which is created by gtk_ic_new.
- *   The input area is specified with "window".
- *
- * Results:
- *   The gdk's event handling routine is switched to XIM based routine.
- *   XIM based routine uses XFilterEvent to get rid of events used by IM,
- *   and uses XmbLookupString instead of XLookupString.
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-void 
-gdk_im_begin (GdkIC ic, GdkWindow* window)
-{
-  GdkICPrivate *private;
-  Window xwin;
-  
-  g_return_if_fail (ic != NULL);
-  g_return_if_fail (window);
-  
-  private = (GdkICPrivate *) ic;
-  
-  xim_using = TRUE;
-  xim_ic = private;
-  xim_window = window;
-  if (gdk_im_ready())
-    {
-      XGetICValues (private->xic, XNFocusWindow, &xwin, NULL);
-      if (xwin != GDK_WINDOW_XWINDOW(window))
-       XSetICValues (private->xic, XNFocusWindow, 
-                     GDK_WINDOW_XWINDOW(window), NULL);
-      if (private != xim_ic)
-       XSetICFocus (private->xic);
-    }
-}
-
-/*
- *--------------------------------------------------------------
- * gdk_im_end
- *
- *   End using input method with XIM Protocol(X11R6 standard)
- *
- * Arguments:
- *
- * Results:
- *   The gdk's event handling routine is switched to normal routine.
- *   User should call this function before ic and window will be destroyed.
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-void 
-gdk_im_end (void)
-{
-  xim_using = FALSE;
-  xim_ic = NULL;
-  xim_window = NULL;
-}
-
-static GdkIM 
-gdk_im_get (void)
-{
-  return xim_im;
-}
-
-static GdkIMStyle 
-gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2) 
-{
-  GdkIMStyle s1, s2, u;
-  
-  if (style1 == 0) return style2;
-  if (style2 == 0) return style1;
-  if ((style1 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK))
-       == (style2 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK)))
-    return style1;
-
-  s1 = style1 & GDK_IM_PREEDIT_MASK;
-  s2 = style2 & GDK_IM_PREEDIT_MASK;
-  u = s1 | s2;
-  if (s1 != s2) {
-    if (u & GDK_IM_PREEDIT_CALLBACKS)
-      return (s1 == GDK_IM_PREEDIT_CALLBACKS)? style1:style2;
-    else if (u & GDK_IM_PREEDIT_POSITION)
-      return (s1 == GDK_IM_PREEDIT_POSITION)? style1:style2;
-    else if (u & GDK_IM_PREEDIT_AREA)
-      return (s1 == GDK_IM_PREEDIT_AREA)? style1:style2;
-    else if (u & GDK_IM_PREEDIT_NOTHING)
-      return (s1 == GDK_IM_PREEDIT_NOTHING)? style1:style2;
-  } else {
-    s1 = style1 & GDK_IM_STATUS_MASK;
-    s2 = style2 & GDK_IM_STATUS_MASK;
-    u = s1 | s2;
-    if ( u & GDK_IM_STATUS_CALLBACKS)
-      return (s1 == GDK_IM_STATUS_CALLBACKS)? style1:style2;
-    else if ( u & GDK_IM_STATUS_AREA)
-      return (s1 == GDK_IM_STATUS_AREA)? style1:style2;
-    else if ( u & GDK_IM_STATUS_NOTHING)
-      return (s1 == GDK_IM_STATUS_NOTHING)? style1:style2;
-    else if ( u & GDK_IM_STATUS_NONE)
-      return (s1 == GDK_IM_STATUS_NONE)? style1:style2;
-  }
-  return 0; /* Get rid of stupid warning */
-}
-
-GdkIMStyle
-gdk_im_decide_style (GdkIMStyle supported_style)
-{
-  gint i;
-  GdkIMStyle style, tmp;
-  
-  g_return_val_if_fail (xim_styles != NULL, 0);
-  
-  style = 0;
-  for (i=0; i<xim_styles->count_styles; i++)
-    {
-      tmp = xim_styles->supported_styles[i];
-      if (tmp == (tmp & supported_style & xim_best_allowed_style))
-       style = gdk_im_choose_better_style (style, tmp);
-    }
-  return style;
-}
-
-GdkIMStyle
-gdk_im_set_best_style (GdkIMStyle style)
-{
-  if (style & GDK_IM_PREEDIT_MASK)
-    {
-      xim_best_allowed_style &= ~GDK_IM_PREEDIT_MASK;
-
-      xim_best_allowed_style |= GDK_IM_PREEDIT_NONE;
-      if (!(style & GDK_IM_PREEDIT_NONE))
-       {
-         xim_best_allowed_style |= GDK_IM_PREEDIT_NOTHING;
-         if (!(style & GDK_IM_PREEDIT_NOTHING))
-           {
-             xim_best_allowed_style |= GDK_IM_PREEDIT_AREA;
-             if (!(style & GDK_IM_PREEDIT_AREA))
-               {
-                 xim_best_allowed_style |= GDK_IM_PREEDIT_POSITION;
-                 if (!(style & GDK_IM_PREEDIT_POSITION))
-                   xim_best_allowed_style |= GDK_IM_PREEDIT_CALLBACKS;
-               }
-           }
-       }
-    }
-  if (style & GDK_IM_STATUS_MASK)
-    {
-      xim_best_allowed_style &= ~GDK_IM_STATUS_MASK;
-
-      xim_best_allowed_style |= GDK_IM_STATUS_NONE;
-      if (!(style & GDK_IM_STATUS_NONE))
-       {
-         xim_best_allowed_style |= GDK_IM_STATUS_NOTHING;
-         if (!(style & GDK_IM_STATUS_NOTHING))
-           {
-             xim_best_allowed_style |= GDK_IM_STATUS_AREA;
-             if (!(style & GDK_IM_STATUS_AREA))
-               xim_best_allowed_style |= GDK_IM_STATUS_CALLBACKS;
-           }
-       }
-    }
-  
-  return xim_best_allowed_style;
-}
-
-static gint 
-gdk_im_open (XrmDatabase db, gchar* res_name, gchar* res_class)
-{
-  xim_im = XOpenIM (GDK_DISPLAY(), db, res_name, res_class);
-  if (xim_im == NULL)
-    {
-      GDK_NOTE (XIM, g_warning ("Unable to open open IM."));
-      return FALSE;
-    }
-  XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL);
-  
-  return TRUE;
-}
-
-static void 
-gdk_im_close (void)
-{
-  if (xim_im)
-    {
-      XCloseIM (xim_im);
-      xim_im = NULL;
-    }
-  if (xim_styles)
-    {
-      XFree (xim_styles);
-      xim_styles = NULL;
-    }
-}
-
-gint 
-gdk_im_ready (void)
-{
-  return (xim_im != NULL);
-}
-
-GdkIC 
-gdk_ic_new (GdkWindow* client_window,
-           GdkWindow* focus_window,
-           GdkIMStyle style, ...)
-{
-  va_list list;
-  GdkICPrivate *private;
-  XVaNestedList preedit_attr = NULL;
-  guint count;
-  
-  g_return_val_if_fail (client_window != NULL, NULL);
-  g_return_val_if_fail (focus_window != NULL, NULL);
-  g_return_val_if_fail (gdk_im_ready(), NULL);
-  
-  private = g_new (GdkICPrivate, 1);
-  
-  va_start (list, style);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, style);
-  preedit_attr = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  private->style = gdk_im_decide_style (style);
-  if (private->style != style)
-    {
-      g_warning ("can not create input context with specified input style.");
-      g_free (private);
-      return NULL;
-    }
-  
-  private->xic = XCreateIC(gdk_im_get (),
-                          XNInputStyle,   style,
-                          XNClientWindow, GDK_WINDOW_XWINDOW (client_window),
-                          XNFocusWindow,  GDK_WINDOW_XWINDOW (focus_window),
-                          preedit_attr? XNPreeditAttributes : NULL, preedit_attr,
-                          NULL);
-  
-  g_free (preedit_attr);
-  
-  if (!private->xic)
-    {
-      g_free (private);
-      return NULL;
-    }
-  
-  xim_ic_list = g_list_append (xim_ic_list, private);
-  return private;
-}
-
-void 
-gdk_ic_destroy (GdkIC ic)
-{
-  GdkICPrivate *private;
-  
-  g_return_if_fail (ic != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  if (xim_ic == private)
-    gdk_im_end ();
-  
-  XDestroyIC (private->xic);
-  xim_ic_list = g_list_remove (xim_ic_list, private);
-  g_free (private);
-}
-
-GdkIMStyle
-gdk_ic_get_style (GdkIC ic)
-{
-  GdkICPrivate *private;
-  
-  g_return_val_if_fail (ic != NULL, 0);
-  
-  private = (GdkICPrivate *) ic;
-  
-  return private->style;
-}
-
-void 
-gdk_ic_set_values (GdkIC ic, ...)
-{
-  va_list list;
-  XVaNestedList args;
-  GdkICPrivate *private;
-  guint count;
-  
-  g_return_if_fail (ic != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  va_start (list, ic);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, ic);
-  args = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  XSetICValues (private->xic, XNVaNestedList, args, NULL);
-  
-  g_free (args);
-}
-
-void 
-gdk_ic_get_values (GdkIC ic, ...)
-{
-  va_list list;
-  XVaNestedList args;
-  GdkICPrivate *private;
-  guint count;
-  
-  g_return_if_fail (ic != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  va_start (list, ic);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, ic);
-  args = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  XGetICValues (private->xic, XNVaNestedList, args, NULL);
-  
-  g_free (args);
-}
-
-void 
-gdk_ic_set_attr (GdkIC ic, const char *target, ...)
-{
-  va_list list;
-  XVaNestedList attr;
-  GdkICPrivate *private;
-  guint count;
-  
-  g_return_if_fail (ic != NULL);
-  g_return_if_fail (target != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  va_start (list, target);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, target);
-  attr = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  XSetICValues (private->xic, target, attr, NULL);
-  
-  g_free (attr);
-}
-
-void 
-gdk_ic_get_attr (GdkIC ic, const char *target, ...)
-{
-  va_list list;
-  XVaNestedList attr;
-  GdkICPrivate *private;
-  guint count;
-  
-  g_return_if_fail (ic != NULL);
-  g_return_if_fail (target != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  va_start (list, target);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, target);
-  attr = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  XGetICValues (private->xic, target, attr, NULL);
-  
-  g_free (attr);
-}
-
-GdkEventMask 
-gdk_ic_get_events (GdkIC ic)
-{
-  GdkEventMask mask;
-  glong xmask;
-  glong bit;
-  GdkICPrivate *private;
-  gint i;
-  
-  /*  From gdkwindow.c */
-  extern int nevent_masks;
-  extern int event_mask_table[];
-  
-  g_return_val_if_fail (ic != NULL, 0);
-  
-  private = (GdkICPrivate *) ic;
-  
-  if (XGetICValues (private->xic, XNFilterEvents, &xmask, NULL) != NULL)
-    {
-      GDK_NOTE (XIM, g_warning ("Call to XGetICValues: %s failed", XNFilterEvents));
-      return 0;
-    }
-  
-  mask = 0;
-  for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1)
-    if (xmask & event_mask_table [i])
-      {
-       mask |= bit;
-       xmask &= ~ event_mask_table [i];
-      }
-  
-  if (xmask)
-    g_warning ("ic requires events not supported by the application (%#04lx)", xmask);
-  
-  return mask;
-}
-
-static void 
-gdk_ic_cleanup (void)
-{
-  GList* node;
-  gint destroyed;
-  GdkICPrivate *private;
-  
-  destroyed = 0;
-  for (node = xim_ic_list; node != NULL; node = node->next)
-    {
-      if (node->data)
-       {
-         private = (GdkICPrivate *) (node->data);
-         XDestroyIC (private->xic);
-         g_free (private);
-         destroyed++;
-       }
-    }
-#ifdef G_ENABLE_DEBUG
-  if ((gdk_debug_flags & GDK_DEBUG_XIM) && destroyed > 0)
-    {
-      g_warning ("Cleaned up %i IC(s)\n", destroyed);
-    }
-#endif /* G_ENABLE_DEBUG */
-  g_list_free(xim_ic_list);
-  xim_ic_list = NULL;
-}
-
-#else /* !USE_XIM */
-
-void 
-gdk_im_begin (GdkIC ic, GdkWindow* window)
-{
-}
-
-void 
-gdk_im_end (void)
-{
-}
-
-GdkIMStyle
-gdk_im_decide_style (GdkIMStyle supported_style)
-{
-  return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-GdkIMStyle
-gdk_im_set_best_style (GdkIMStyle style)
-{
-  return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-gint 
-gdk_im_ready (void)
-{
-  return FALSE;
-}
-
-GdkIC 
-gdk_ic_new (GdkWindow* client_window,
-           GdkWindow* focus_window,
-           GdkIMStyle style, ...)
-{
-  return NULL;
-}
-
-void 
-gdk_ic_destroy (GdkIC ic)
-{
-}
-
-GdkIMStyle
-gdk_ic_get_style (GdkIC ic)
-{
-  return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-void 
-gdk_ic_set_values (GdkIC ic, ...)
-{
-}
-
-void 
-gdk_ic_get_values (GdkIC ic, ...)
-{
-}
-
-void 
-gdk_ic_set_attr (GdkIC ic, const char *target, ...)
-{
-}
-
-void 
-gdk_ic_get_attr (GdkIC ic, const char *target, ...)
-{
-}
-
-GdkEventMask 
-gdk_ic_get_events (GdkIC ic)
-{
-  return 0;
-}
-
-#endif /* USE_XIM */
-
-#ifdef X_LOCALE
-
-gint
-_g_mbtowc (wchar_t *wstr, const char *str, size_t len)
-{
-  static wchar_t wcs[MB_CUR_MAX + 1];
-  static gchar mbs[MB_CUR_MAX + 1];
-  
-  wcs[0] = (wchar_t) NULL;
-  mbs[0] = '\0';
-  
-  /* The last argument isn't a mistake. The X locale code trims
-   *  the input string to the length of the output string!
-   */
-  len = _Xmbstowcs (wcs, str, (len<MB_CUR_MAX)? len:MB_CUR_MAX);
-  if (len < 1)
-    return len;
-  else if (wcs[0] == (wchar_t) NULL)
-    return -1;
-  
-  len = _Xwctomb (mbs, wcs[0]);
-  if (mbs[0] == '\0')
-    return -1;
-  if (wstr)
-    *wstr = wcs[0];
-  
-  return len;
-}
-
-#endif /* X_LOCALE */
-
 /* Sends a ClientMessage to all toplevel client windows */
 gboolean
 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
index 4cd435a841ef329265b2a25e11b0583357e52da8..0127077fc241006847e11587682ae482fbbf66f3 100644 (file)
--- a/gdk/gdk.h
+++ b/gdk/gdk.h
@@ -22,7 +22,6 @@
 
 #include <gdk/gdktypes.h>
 
-
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -571,8 +570,13 @@ gint        gdk_string_width   (GdkFont        *font,
 gint    gdk_text_width     (GdkFont        *font,
                             const gchar    *text,
                             gint            text_length);
+gint    gdk_text_width_wc  (GdkFont        *font,
+                            const GdkWChar *text,
+                            gint            text_length);
 gint    gdk_char_width     (GdkFont        *font,
                             gchar           character);
+gint    gdk_char_width_wc  (GdkFont        *font,
+                            GdkWChar        character);
 gint    gdk_string_measure (GdkFont        *font,
                             const gchar    *string);
 gint    gdk_text_measure   (GdkFont        *font,
@@ -642,14 +646,21 @@ void gdk_draw_string       (GdkDrawable  *drawable,
                          GdkGC        *gc,
                          gint          x,
                          gint          y,
-                         const gchar        *string);
+                         const gchar  *string);
 void gdk_draw_text      (GdkDrawable  *drawable,
                          GdkFont      *font,
                          GdkGC        *gc,
                          gint          x,
                          gint          y,
-                         const gchar        *text,
+                         const gchar  *text,
                          gint          text_length);
+void gdk_draw_text_wc   (GdkDrawable    *drawable,
+                         GdkFont        *font,
+                         GdkGC          *gc,
+                         gint            x,
+                         gint            y,
+                         const GdkWChar *text,
+                         gint            text_length);
 void gdk_draw_pixmap    (GdkDrawable  *drawable,
                          GdkGC        *gc,
                          GdkDrawable  *src,
@@ -798,25 +809,35 @@ GdkTimeCoord *gdk_input_motion_events (GdkWindow *window,
 
 gint         gdk_im_ready         (void);
 
-void         gdk_im_begin         (GdkIC      ic, 
-                                   GdkWindowwindow);
+void         gdk_im_begin         (GdkIC               *ic, 
+                                   GdkWindow           *window);
 void         gdk_im_end                   (void);
-GdkIMStyle   gdk_im_decide_style   (GdkIMStyle supported_style);
-GdkIMStyle   gdk_im_set_best_style (GdkIMStyle best_allowed_style);
-GdkIC        gdk_ic_new                   (GdkWindow* client_window,
-                                   GdkWindow* focus_window,
-                                   GdkIMStyle style, ...);
-void         gdk_ic_destroy       (GdkIC      ic);
-GdkIMStyle   gdk_ic_get_style     (GdkIC      ic);
-void         gdk_ic_set_values    (GdkIC      ic,  
-                                   ...);
-void         gdk_ic_get_values    (GdkIC      ic, 
-                                   ...);
-void         gdk_ic_set_attr      (GdkIC      ic, 
-                                   const char *target, ...);
-void         gdk_ic_get_attr      (GdkIC       ic, 
-                                   const char *target, ...);
-GdkEventMask gdk_ic_get_events    (GdkIC       ic);
+GdkIMStyle   gdk_im_decide_style   (GdkIMStyle           supported_style);
+GdkIMStyle   gdk_im_set_best_style (GdkIMStyle           best_allowed_style);
+
+GdkIC*       gdk_ic_new                   (GdkICAttr           *attr,
+                                   GdkICAttributesType mask);
+void         gdk_ic_destroy       (GdkIC               *ic);
+GdkIMStyle   gdk_ic_get_style     (GdkIC               *ic);
+GdkEventMask gdk_ic_get_events     (GdkIC               *ic);
+
+GdkICAttr*   gdk_ic_attr_new       (void);
+void         gdk_ic_attr_destroy   (GdkICAttr *attr);
+
+GdkICAttributesType  gdk_ic_set_attr (GdkIC              *ic,  
+                                      GdkICAttr          *attr,
+                                      GdkICAttributesType mask);
+GdkICAttributesType  gdk_ic_get_attr (GdkIC              *ic, 
+                                      GdkICAttr          *attr,
+                                      GdkICAttributesType mask);
+
+/* Conversion functions between wide char and multibyte strings. 
+ */
+gchar     *gdk_wcstombs          (const GdkWChar   *src);
+gint       gdk_mbstowcs          (GdkWChar         *dest,
+                                 const gchar      *src,
+                                 gint              dest_max);
+
 
 /* Color Context */
 
index 2725367c16ecc976ca8021332dce7715c4da0889..2d61d5dc4aa64ad95c3d3c2a3dce24f869308cbc 100644 (file)
@@ -293,6 +293,66 @@ gdk_draw_text (GdkDrawable *drawable,
     g_error("undefined font type\n");
 }
 
+void
+gdk_draw_text_wc (GdkDrawable   *drawable,
+                 GdkFont        *font,
+                 GdkGC          *gc,
+                 gint            x,
+                 gint            y,
+                 const GdkWChar *text,
+                 gint            text_length)
+{
+  GdkWindowPrivate *drawable_private;
+  GdkFontPrivate *font_private;
+  GdkGCPrivate *gc_private;
+
+  g_return_if_fail (drawable != NULL);
+  g_return_if_fail (font != NULL);
+  g_return_if_fail (gc != NULL);
+  g_return_if_fail (text != NULL);
+
+  drawable_private = (GdkWindowPrivate*) drawable;
+  if (drawable_private->destroyed)
+    return;
+  gc_private = (GdkGCPrivate*) gc;
+  font_private = (GdkFontPrivate*) font;
+
+  if (font->type == GDK_FONT_FONT)
+    {
+      XFontStruct *xfont = (XFontStruct *) font_private->xfont;
+      gchar *text_8bit;
+      gint i;
+      XSetFont(drawable_private->xdisplay, gc_private->xgc, xfont->fid);
+      text_8bit = g_new (gchar, text_length);
+      for (i=0; i<text_length; i++) text_8bit[i] = text[i];
+      XDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+                   gc_private->xgc, x, y, text_8bit, text_length);
+      g_free (text_8bit);
+    }
+  else if (font->type == GDK_FONT_FONTSET)
+    {
+      if (sizeof(GdkWChar) == sizeof(wchar_t))
+       {
+         XwcDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+                        (XFontSet) font_private->xfont,
+                        gc_private->xgc, x, y, (wchar_t *)text, text_length);
+       }
+      else
+       {
+         wchar_t *text_wchar;
+         gint i;
+         text_wchar = g_new (wchar_t, text_length);
+         for (i=0; i<text_length; i++) text_wchar[i] = text[i];
+         XwcDrawString (drawable_private->xdisplay, drawable_private->xwindow,
+                        (XFontSet) font_private->xfont,
+                        gc_private->xgc, x, y, text_wchar, text_length);
+         g_free (text_wchar);
+       }
+    }
+  else
+    g_error("undefined font type\n");
+}
+
 void
 gdk_draw_pixmap (GdkDrawable *drawable,
                 GdkGC       *gc,
index cc1274a0d6b15427fd47bfd41cb3d53aa58acd0a..0308fa8e0d332914f54b2018d6657e661610ea81 100644 (file)
@@ -271,6 +271,62 @@ gdk_text_width (GdkFont      *font,
   return width;
 }
 
+gint
+gdk_text_width_wc (GdkFont       *font,
+                  const GdkWChar *text,
+                  gint            text_length)
+{
+  GdkFontPrivate *private;
+  gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (text != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+        {
+          gchar *text_8bit;
+          gint i;
+          text_8bit = g_new (gchar, text_length);
+          for (i=0; i<text_length; i++) text_8bit[i] = text[i];
+          width = XTextWidth (xfont, text_8bit, text_length);
+          g_free (text_8bit);
+        }
+      else
+        {
+          width = 0;
+        }
+      break;
+    case GDK_FONT_FONTSET:
+      if (sizeof(GdkWChar) == sizeof(wchar_t))
+       {
+         fontset = (XFontSet) private->xfont;
+         width = XwcTextEscapement (fontset, (wchar_t *)text, text_length);
+       }
+      else
+       {
+         wchar_t *text_wchar;
+         gint i;
+         fontset = (XFontSet) private->xfont;
+         text_wchar = g_new(wchar_t, text_length);
+         for (i=0; i<text_length; i++) text_wchar[i] = text[i];
+         width = XwcTextEscapement (fontset, text_wchar, text_length);
+         g_free (text_wchar);
+       }
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
 /* Problem: What if a character is a 16 bits character ?? */
 gint
 gdk_char_width (GdkFont *font,
@@ -318,6 +374,56 @@ gdk_char_width (GdkFont *font,
   return width;
 }
 
+gint
+gdk_char_width_wc (GdkFont *font,
+                  GdkWChar character)
+{
+  GdkFontPrivate *private;
+  XCharStruct *chars;
+  gint width;
+  guint ch = character & 0xff;  /* get rid of sign-extension */
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      /* only 8 bits characters are considered here */
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) &&
+          (xfont->max_byte1 == 0) &&
+          (ch >= xfont->min_char_or_byte2) &&
+          (ch <= xfont->max_char_or_byte2))
+        {
+          chars = xfont->per_char;
+          if (chars)
+            width = chars[ch - xfont->min_char_or_byte2].width;
+          else
+            width = xfont->min_bounds.width;
+        }
+      else
+        {
+          char ch2 = character;
+          width = XTextWidth (xfont, &ch2, 1);
+        }
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      {
+       wchar_t char_wc = character;
+        width = XwcTextEscapement (fontset, &char_wc, 1) ;
+      }
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
 gint
 gdk_string_measure (GdkFont     *font,
                     const gchar *string)
index 5736a1a80d2e740f3d3bd402b4531ecae1df3110..eeebb514914145e72c34138a200af46ad5833958 100644 (file)
@@ -62,4 +62,8 @@ gint              gdk_threads_pipe[2];
 gboolean          gdk_select_waiting = FALSE;
 #endif
 
+#ifdef USE_XIM
+GdkICPrivate *gdk_xim_ic;              /* currently using IC */
+GdkWindow *gdk_xim_window;             /* currently using Window */
+#endif
 
index f2bf8553df134fbfdf4f02d4ba79a40f8a1d4ba9..c7dba9e70290cdc3693419a3e4bd942757c24a00 100644 (file)
 
 #include <stdlib.h>
 
-#ifdef X_LOCALE
-
-#include <X11/Xfuncproto.h>
-#include <X11/Xosdefs.h>
-
-#ifdef  __cplusplus
-extern "C" {
-#endif
-
-_XFUNCPROTOBEGIN
-extern int _Xmblen (
-#if NeedFunctionPrototypes
-  const char *s, size_t n
-#endif
-
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern int _Xmbtowc (
-#if NeedFunctionPrototypes
-  wchar_t *wstr, const char *str, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern int _Xwctomb (
-#if NeedFunctionPrototypes
-  char *str, wchar_t wc
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern size_t _Xmbstowcs (
-#if NeedFunctionPrototypes
-  wchar_t *wstr, const char *str, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern size_t _Xwcstombs (
-#if NeedFunctionPrototypes
-  char *str, const wchar_t *wstr, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern size_t _Xwcslen (
-#if NeedFunctionPrototypes
-  const wchar_t *wstr
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern wchar_t* _Xwcscpy (
-#if NeedFunctionPrototypes
-  wchar_t *wstr1, const wchar_t *wstr2
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern wchar_t* _Xwcsncpy (
-#if NeedFunctionPrototypes
-  wchar_t *wstr1, const wchar_t *wstr2, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern int _Xwcscmp (
-#if NeedFunctionPrototypes
-  const wchar_t *wstr1, const wchar_t *wstr2
-#endif
-);
-_XFUNCPROTOEND
-
-_XFUNCPROTOBEGIN
-extern int _Xwcsncmp (
-#if NeedFunctionPrototypes
-  const wchar_t *wstr1, const wchar_t *wstr2, size_t len
-#endif
-);
-_XFUNCPROTOEND
-
-/* 
- * mblen, mbtowc, and mbstowcs of the locale "ja_JP.eucJP" are buggy.
- */
-
-#ifdef MB_CUR_MAX
-# undef MB_CUR_MAX
-#endif
-#define MB_CUR_MAX 4
-extern int _g_mbtowc (wchar_t *wstr, const char *str, size_t len);
-
-/* #define mblen _Xmblen */
-/* #define mbtowc _Xmbtowc */
-#define mblen(a,b)     _g_mbtowc ((wchar_t *)(NULL), (a), (b))
-#define mbtowc(a,b,c)  _g_mbtowc ((a),(b),(c))
-
-#define wctomb(a,b)    _Xwctomb ((a),(b))
-#define mbstowcs(a,b,c)        _Xmbstowcs ((a),(b),(c))
-#define wcstombs(a,b,c) _Xwcstombs ((a),(b),(c))
-#define wcslen(a)      _Xwcslen ((a))
-#define wcscpy(a,b)    _Xwcscpy ((a),(b))
-#define wcsncpy(a,b,c) _Xwcsncpy ((a),(b),(c))
-
-#ifdef  __cplusplus
-}
-#endif
-
-#endif /* X_LOCALE */
-
 #if !defined(G_HAVE_BROKEN_WCTYPE) && (defined(G_HAVE_WCTYPE_H) || defined(G_HAVE_WCHAR_H)) && !defined(X_LOCALE)
 #  ifdef G_HAVE_WCTYPE_H
 #    include <wctype.h>
@@ -154,8 +36,11 @@ extern int _g_mbtowc (wchar_t *wstr, const char *str, size_t len);
 #      include <wchar.h>
 #    endif
 #  endif
+#  define gdk_iswalnum(c) iswalnum(c)
+#  define gdk_iswspace(c) iswspace(c)
 #else
-#  define iswalnum(c) ((wchar_t)(c) <= 0xFF && isalnum(c))
+#  define gdk_iswalnum(c) ((wchar_t)(c) <= 0xFF && isalnum(c))
+#  define gdk_iswspace(c) ((wchar_t)(c) <= 0xFF && isspace(c))
 #endif
 
 #endif /* __GDK_I18N_H__ */
index d7f71cd22479b6878b9dadbd147acdc55e54f98e..e095853d3fe013b69430d95a9657989c605e8ab9 100644 (file)
@@ -186,14 +186,15 @@ struct _GdkClientFilter {
 
 #ifdef USE_XIM
 
+typedef struct _GdkICPrivate GdkICPrivate;
+
 struct _GdkICPrivate
 {
   XIC xic;
-  GdkIMStyle style;
+  GdkICAttr *attr;
+  GdkICAttributesType mask;
 };
 
-typedef struct _GdkICPrivate GdkICPrivate;
-
 #endif /* USE_XIM */
 
 struct _GdkColorContextPrivate
@@ -282,6 +283,16 @@ extern gint              gdk_threads_pipe[2];
 extern gboolean          gdk_select_waiting;
 #endif
 
+#ifdef USE_XIM
+/* XIM support */
+gint   gdk_im_open              (void);
+void   gdk_im_close             (void);
+void   gdk_ic_cleanup           (void);
+
+extern GdkICPrivate *gdk_xim_ic;               /* currently using IC */
+extern GdkWindow *gdk_xim_window;              /* currently using Window */
+#endif USE_XIM
+
 /* Debugging support */
 
 #ifdef G_ENABLE_DEBUG
index bb38385b848995850d068852745b828ada67ce45..99befe3cb953cdbee20e4b23b6441e8716278718 100644 (file)
@@ -89,9 +89,11 @@ typedef struct _GdkRegion        GdkRegion;
 typedef gint (*GdkEventFunc) (GdkEvent *event,
                              gpointer  data);
 
-typedef void*                    GdkIC;
-typedef void*                    GdkIM;
+typedef struct _GdkIC               GdkIC;
+typedef struct _GdkICAttr          GdkICAttr;
 
+typedef guint32                            GdkWChar;
 
 /* Types of windows.
  *   Root: There is only 1 root window and it is initialized
@@ -617,6 +619,45 @@ typedef enum                       /*< flags >*/
   GDK_IM_STATUS_MASK      = 0x0f00 
 } GdkIMStyle;
 
+typedef enum
+{
+  GDK_IC_STYLE                 = 1 << 0,
+  GDK_IC_CLIENT_WINDOW         = 1 << 1,
+  GDK_IC_FOCUS_WINDOW          = 1 << 2,
+  GDK_IC_FILTER_EVENTS         = 1 << 3,
+  GDK_IC_SPOT_LOCATION         = 1 << 4,
+  GDK_IC_LINE_SPACING          = 1 << 5,
+  GDK_IC_CURSOR                        = 1 << 6,
+
+  GDK_IC_PREEDIT_FONTSET       = 1 << 10,
+  GDK_IC_PREEDIT_AREA          = 1 << 11,
+  GDK_IC_PREEDIT_AREA_NEEDED   = 1 << 12,
+  GDK_IC_PREEDIT_FOREGROUND    = 1 << 13,
+  GDK_IC_PREEDIT_BACKGROUND    = 1 << 14,
+  GDK_IC_PREEDIT_PIXMAP                = 1 << 15,
+  GDK_IC_PREEDIT_COLORMAP      = 1 << 16,
+
+  GDK_IC_STATUS_FONTSET                = 1 << 21,
+  GDK_IC_STATUS_AREA           = 1 << 22,
+  GDK_IC_STATUS_AREA_NEEDED    = 1 << 23,
+  GDK_IC_STATUS_FOREGROUND     = 1 << 24,
+  GDK_IC_STATUS_BACKGROUND     = 1 << 25,
+  GDK_IC_STATUS_PIXMAP         = 1 << 26,
+  GDK_IC_STATUS_COLORMAP       = 1 << 27,
+
+  GDK_IC_ALL_REQ               = GDK_IC_STYLE |
+                                 GDK_IC_CLIENT_WINDOW,
+
+  GDK_IC_PREEDIT_AREA_REQ      = GDK_IC_PREEDIT_AREA | 
+                                 GDK_IC_PREEDIT_FONTSET,
+  GDK_IC_PREEDIT_POSITION_REQ  = GDK_IC_PREEDIT_AREA | 
+                                 GDK_IC_SPOT_LOCATION |
+                                 GDK_IC_PREEDIT_FONTSET,
+
+  GDK_IC_STATUS_AREA_REQ       = GDK_IC_STATUS_AREA | 
+                                 GDK_IC_STATUS_FONTSET,
+} GdkICAttributesType;
+
 /* The next two enumeration values current match the
  * Motif constants. If this is changed, the implementation
  * of gdk_window_set_decorations/gdk_window_set_functions
@@ -1182,7 +1223,32 @@ struct _GdkRegion
   gpointer user_data;
 };
 
+struct _GdkICAttr
+{
+  GdkIMStyle style;
+  GdkWindow *client_window;
+  GdkWindow *focus_window;
+  GdkEventMask filter_events;
+  GdkPoint spot_location;
+  gint line_spacing;
+  GdkCursor *cursor;
 
+  GdkFont *preedit_fontset;
+  GdkRectangle preedit_area;
+  GdkRectangle preedit_area_needed; 
+  GdkColor preedit_foreground;
+  GdkColor preedit_background;
+  GdkPixmap *preedit_pixmap;
+  GdkColormap *preedit_colormap;
+
+  GdkFont *status_fontset;
+  GdkRectangle status_area;
+  GdkRectangle status_area_needed; 
+  GdkColor status_foreground;
+  GdkColor status_background;
+  GdkPixmap *status_pixmap;
+  GdkColormap *status_colormap;
+};
 
 #ifdef __cplusplus
 }
index efbd713144839046787d03a44e19044f876dee3f..72a56d85843f7bdd6fe0e68699400946ef3eae05 100644 (file)
@@ -323,7 +323,12 @@ gdk_window_new (GdkWindow     *parent,
       if (attributes_mask & GDK_WA_COLORMAP)
        private->colormap = attributes->colormap;
       else
-       private->colormap = gdk_colormap_get_system ();
+       {
+         if ((((GdkVisualPrivate*)gdk_visual_get_system())->xvisual) == xvisual)
+           private->colormap = gdk_colormap_get_system ();
+         else
+           private->colormap = gdk_colormap_new (visual, False);
+       }
 
       xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
       xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
index cc1274a0d6b15427fd47bfd41cb3d53aa58acd0a..0308fa8e0d332914f54b2018d6657e661610ea81 100644 (file)
@@ -271,6 +271,62 @@ gdk_text_width (GdkFont      *font,
   return width;
 }
 
+gint
+gdk_text_width_wc (GdkFont       *font,
+                  const GdkWChar *text,
+                  gint            text_length)
+{
+  GdkFontPrivate *private;
+  gint width;
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+  g_return_val_if_fail (text != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) && (xfont->max_byte1 == 0))
+        {
+          gchar *text_8bit;
+          gint i;
+          text_8bit = g_new (gchar, text_length);
+          for (i=0; i<text_length; i++) text_8bit[i] = text[i];
+          width = XTextWidth (xfont, text_8bit, text_length);
+          g_free (text_8bit);
+        }
+      else
+        {
+          width = 0;
+        }
+      break;
+    case GDK_FONT_FONTSET:
+      if (sizeof(GdkWChar) == sizeof(wchar_t))
+       {
+         fontset = (XFontSet) private->xfont;
+         width = XwcTextEscapement (fontset, (wchar_t *)text, text_length);
+       }
+      else
+       {
+         wchar_t *text_wchar;
+         gint i;
+         fontset = (XFontSet) private->xfont;
+         text_wchar = g_new(wchar_t, text_length);
+         for (i=0; i<text_length; i++) text_wchar[i] = text[i];
+         width = XwcTextEscapement (fontset, text_wchar, text_length);
+         g_free (text_wchar);
+       }
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
 /* Problem: What if a character is a 16 bits character ?? */
 gint
 gdk_char_width (GdkFont *font,
@@ -318,6 +374,56 @@ gdk_char_width (GdkFont *font,
   return width;
 }
 
+gint
+gdk_char_width_wc (GdkFont *font,
+                  GdkWChar character)
+{
+  GdkFontPrivate *private;
+  XCharStruct *chars;
+  gint width;
+  guint ch = character & 0xff;  /* get rid of sign-extension */
+  XFontStruct *xfont;
+  XFontSet fontset;
+
+  g_return_val_if_fail (font != NULL, -1);
+
+  private = (GdkFontPrivate*) font;
+
+  switch (font->type)
+    {
+    case GDK_FONT_FONT:
+      /* only 8 bits characters are considered here */
+      xfont = (XFontStruct *) private->xfont;
+      if ((xfont->min_byte1 == 0) &&
+          (xfont->max_byte1 == 0) &&
+          (ch >= xfont->min_char_or_byte2) &&
+          (ch <= xfont->max_char_or_byte2))
+        {
+          chars = xfont->per_char;
+          if (chars)
+            width = chars[ch - xfont->min_char_or_byte2].width;
+          else
+            width = xfont->min_bounds.width;
+        }
+      else
+        {
+          char ch2 = character;
+          width = XTextWidth (xfont, &ch2, 1);
+        }
+      break;
+    case GDK_FONT_FONTSET:
+      fontset = (XFontSet) private->xfont;
+      {
+       wchar_t char_wc = character;
+        width = XwcTextEscapement (fontset, &char_wc, 1) ;
+      }
+      break;
+    default:
+      width = 0;
+    }
+  return width;
+}
+
 gint
 gdk_string_measure (GdkFont     *font,
                     const gchar *string)
index 5736a1a80d2e740f3d3bd402b4531ecae1df3110..eeebb514914145e72c34138a200af46ad5833958 100644 (file)
@@ -62,4 +62,8 @@ gint              gdk_threads_pipe[2];
 gboolean          gdk_select_waiting = FALSE;
 #endif
 
+#ifdef USE_XIM
+GdkICPrivate *gdk_xim_ic;              /* currently using IC */
+GdkWindow *gdk_xim_window;             /* currently using Window */
+#endif
 
index f504ea313a840f671ea294e619c81ea08ebc7e51..15dcaa3035395731d93f4147dd7dce55301aefd4 100644 (file)
@@ -28,9 +28,6 @@
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
-#ifdef USE_XIM
-#include <stdarg.h>
-#endif
 
 #ifdef HAVE_SYS_SELECT_H
 #include <sys/select.h>
 #include <X11/Xos.h>
 #include <X11/Xutil.h>
 #include <X11/Xmu/WinUtil.h>
-#ifdef USE_XIM
-#include <X11/Xresource.h>
-#endif
 #include <X11/cursorfont.h>
 #include "gdk.h"
 #include "gdkprivate.h"
 #include "gdkinput.h"
+#include "gdki18n.h"
 #include "gdkx.h"
 #include "gdkkeysyms.h"
-#include "gdki18n.h"
 
 #ifndef X_GETTIMEOFDAY
 #define X_GETTIMEOFDAY(tv)  gettimeofday (tv, NULL)
@@ -139,21 +133,6 @@ static int     gdk_x_error                  (Display     *display,
 static int         gdk_x_io_error               (Display     *display);
 static RETSIGTYPE   gdk_signal                  (int          signum);
 
-
-#ifdef USE_XIM
-static guint        gdk_im_va_count     (va_list list);
-static XVaNestedList gdk_im_va_to_nested (va_list list, 
-                                         guint   count);
-
-static GdkIM  gdk_im_get               (void);
-static gint   gdk_im_open              (XrmDatabase db,
-                                        gchar* res_name,
-                                        gchar* rec_class);
-static void   gdk_im_close             (void);
-static void   gdk_ic_cleanup           (void);
-
-#endif /* USE_XIM */
-
 GdkFilterReturn gdk_wm_protocols_filter (GdkXEvent *xev,
                                         GdkEvent  *event,
                                         gpointer   data);
@@ -212,17 +191,6 @@ static GdkWindowPrivate *xgrab_window = NULL;          /* Window that currently holds
 
 static GList *client_filters;                      /* Filters for client messages */
 
-#ifdef USE_XIM
-static gint xim_using;                         /* using XIM Protocol if TRUE */
-static GdkIM xim_im;                           /* global IM */
-static XIMStyles* xim_styles;                  /* im supports these styles */
-static XIMStyle xim_best_allowed_style;
-static GdkICPrivate *xim_ic;                   /* currently using IC */
-static GdkWindow* xim_window;                  /* currently using Widow */
-static GList* xim_ic_list;
-
-#endif
-
 static GList *putback_events = NULL;
 
 static gulong base_id;
@@ -570,18 +538,7 @@ gdk_init (int       *argc,
                                 gdk_wm_protocols_filter, NULL);
   
 #ifdef USE_XIM
-  /* initialize XIM Protocol variables */
-  xim_using = FALSE;
-  xim_im = NULL;
-  xim_styles = NULL;
-  if (!(xim_best_allowed_style & GDK_IM_PREEDIT_MASK))
-    gdk_im_set_best_style (GDK_IM_PREEDIT_CALLBACKS);
-  if (!(xim_best_allowed_style & GDK_IM_STATUS_MASK))
-    gdk_im_set_best_style (GDK_IM_STATUS_CALLBACKS);
-  xim_ic = NULL;
-  xim_window = (GdkWindow*)NULL;
-  
-  gdk_im_open (NULL, NULL, NULL);
+  gdk_im_open ();
 #endif
   
   gdk_initialized = 1;
@@ -1005,16 +962,22 @@ gdk_event_get (void)
        *  has occurred. Read it.
        */
 #ifdef USE_XIM
-      gint filter_status;
-      if (xim_using && xim_window)
-       do
-         {             /* don't dispatch events used by IM */
-           XNextEvent (gdk_display, &xevent);
-           filter_status = XFilterEvent (&xevent, 
-                                         GDK_WINDOW_XWINDOW (xim_window));
-         } while (filter_status == True);
-      else
-       XNextEvent (gdk_display, &xevent);
+      Window w = None;
+
+      XNextEvent (gdk_display, &xevent);
+      if (gdk_xim_window)
+       switch (xevent.type)
+         {
+         case KeyPress:
+         case KeyRelease:
+         case ButtonPress:
+         case ButtonRelease:
+           w = GDK_WINDOW_XWINDOW (gdk_xim_window);
+           break;
+         }
+
+      if (XFilterEvent (&xevent, w))
+       return NULL;
 #else
       XNextEvent (gdk_display, &xevent);
 #endif
@@ -2067,13 +2030,6 @@ gdk_event_translate (GdkEvent *event,
   
   if (window != NULL)
     gdk_window_ref (window);
-#ifdef USE_XIM
-  else if (XFilterEvent(xevent, None)) /* for xlib XIM handling */
-    return FALSE;
-#endif
-  else
-    GDK_NOTE (EVENTS, 
-      g_message ("Got event for unknown window: %#lx\n", xevent->xany.window));
   
   event->any.window = window;
   event->any.send_event = xevent->xany.send_event;
@@ -2088,17 +2044,46 @@ gdk_event_translate (GdkEvent *event,
       /* Check for filters for this window */
   
       GdkFilterReturn result;
+
+#ifdef USE_XIM
+      if (window == NULL && 
+         xevent->type == KeyPress &&
+         gdk_xim_window && 
+         !((GdkWindowPrivate *) gdk_xim_window)->destroyed)
+       {
+         /*
+          * If user presses a key in Preedit or Status window, keypress event
+          * is sometimes sent to these windows. These windows are not managed
+          * by GDK, so we redirect KeyPress event to gdk_xim_window.
+          *
+          * If someone want to use the window whitch is not managed by GDK
+          * and want to get KeyPress event, he/she must register the filter
+          * function to gdk_default_filters to intercept the event.
+          */
+         
+         window = gdk_xim_window;
+         window_private = (GdkWindowPrivate *) window;
+         gdk_window_ref (window);
+         event->any.window = window;
+         
+         GDK_NOTE (XIM,
+                   g_message ("KeyPress event is redirected to gdk_xim_window: %#lx",
+                              xevent->xany.window));
+       }
+#endif /* USE_XIM */
+      
       result = gdk_event_apply_filters (xevent, event,
                                        window_private
                                        ?window_private->filters
                                        :gdk_default_filters);
       
       if (result != GDK_FILTER_CONTINUE)
-       {
-         return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
-       }
+       return (result == GDK_FILTER_TRANSLATE) ? TRUE : FALSE;
     }
 
+  if (window == NULL)
+    g_message ("Got event for unknown window: %#lx\n", xevent->xany.window);
+
   /* We do a "manual" conversion of the XEvent to a
    *  GdkEvent. The structures are mostly the same so
    *  the conversion is fairly straightforward. We also
@@ -2121,12 +2106,12 @@ gdk_event_translate (GdkEvent *event,
        }
       keysym = GDK_VoidSymbol;
       
-      if (xim_using == TRUE && xim_ic)
+      if (gdk_xim_ic && gdk_xim_ic->xic)
        {
          Status status;
          
          /* Clear keyval. Depending on status, may not be set */
-         charcount = XmbLookupString(xim_ic->xic,
+         charcount = XmbLookupString(gdk_xim_ic->xic,
                                      &xevent->xkey, buf, buf_len-1,
                                      &keysym, &status);
          if (status == XBufferOverflow)
@@ -2139,7 +2124,7 @@ gdk_event_translate (GdkEvent *event,
                buf_len *= 2;
              buf = (gchar *) g_realloc (buf, buf_len);
              
-             charcount = XmbLookupString (xim_ic->xic,
+             charcount = XmbLookupString (gdk_xim_ic->xic,
                                           &xevent->xkey, buf, buf_len-1,
                                           &keysym, &status);
            }
@@ -2520,6 +2505,13 @@ gdk_event_translate (GdkEvent *event,
                               (xevent->xany.type == FocusIn) ? "in" : "out",
                               xevent->xfocus.window - base_id));
          
+         /* gdk_keyboard_grab() causes following events. These events confuse
+          * the XIM focus, so ignore them.
+          */
+         if (xevent->xfocus.mode == NotifyGrab ||
+             xevent->xfocus.mode == NotifyUngrab)
+           break;
+
          event->focus_change.type = GDK_FOCUS_CHANGE;
          event->focus_change.window = window;
          event->focus_change.in = (xevent->xany.type == FocusIn);
@@ -3186,652 +3178,6 @@ gdk_signal (int sig_num)
 #endif /* !G_ENABLE_DEBUG */
 }
 
-#ifdef USE_XIM
-
-/* The following routines duplicate functionality in Xlib to
- * translate from varargs to X's internal opaque XVaNestedList.
- * 
- * If all vendors have stuck close to the reference implementation,
- * then we should hopefully be OK. 
- */
-
-/* This needs to match XIMArg as defined in Xlcint.h exactly */
-
-typedef struct {
-  gchar          *name;
-  gpointer value;
-} GdkImArg;
-
-/*************************************************************
- * gdk_im_va_count:
- *    Counts the number of name/value pairs in the vararg list
- *
- *   arguments:
- *     
- *   results:
- *************************************************************/
-
-static guint 
-gdk_im_va_count (va_list list)
-{
-  gint count = 0;
-  gchar *name;
-  
-  name = va_arg (list, gchar *);
-  while (name)
-    {
-      count++;
-      (void)va_arg (list, gpointer);
-      name = va_arg (list, gchar *);
-    }
-  
-  return count;
-}
-
-/*************************************************************
- * gdk_im_va_to_nested:
- *     Given a varargs list and the result of gdk_im_va_count,
- *     create a XVaNestedList.
- *
- *   arguments:
- *     
- *   results:
- *************************************************************/
-
-static XVaNestedList
-gdk_im_va_to_nested (va_list list, guint count)
-{
-  GdkImArg *result;
-  GdkImArg *arg;
-  
-  gchar *name;
-  
-  if (count == 0)
-    return NULL;
-  
-  result = g_new (GdkImArg, count+1);
-  arg = result;
-  
-  name = va_arg (list, gchar *);
-  while (name)
-    {
-      arg->name = name;
-      arg->value = va_arg (list, gpointer);
-      arg++;
-      name = va_arg (list, gchar *);
-    }
-  
-  arg->name = NULL;
-  
-  return (XVaNestedList)result;
-}
-
-/*
- *--------------------------------------------------------------
- * gdk_im_begin
- *
- *   Begin using input method with XIM Protocol(X11R6 standard)
- *
- * Arguments:
- *   "ic" is the "Input Context" which is created by gtk_ic_new.
- *   The input area is specified with "window".
- *
- * Results:
- *   The gdk's event handling routine is switched to XIM based routine.
- *   XIM based routine uses XFilterEvent to get rid of events used by IM,
- *   and uses XmbLookupString instead of XLookupString.
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-void 
-gdk_im_begin (GdkIC ic, GdkWindow* window)
-{
-  GdkICPrivate *private;
-  Window xwin;
-  
-  g_return_if_fail (ic != NULL);
-  g_return_if_fail (window);
-  
-  private = (GdkICPrivate *) ic;
-  
-  xim_using = TRUE;
-  xim_ic = private;
-  xim_window = window;
-  if (gdk_im_ready())
-    {
-      XGetICValues (private->xic, XNFocusWindow, &xwin, NULL);
-      if (xwin != GDK_WINDOW_XWINDOW(window))
-       XSetICValues (private->xic, XNFocusWindow, 
-                     GDK_WINDOW_XWINDOW(window), NULL);
-      if (private != xim_ic)
-       XSetICFocus (private->xic);
-    }
-}
-
-/*
- *--------------------------------------------------------------
- * gdk_im_end
- *
- *   End using input method with XIM Protocol(X11R6 standard)
- *
- * Arguments:
- *
- * Results:
- *   The gdk's event handling routine is switched to normal routine.
- *   User should call this function before ic and window will be destroyed.
- *
- * Side effects:
- *
- *--------------------------------------------------------------
- */
-
-void 
-gdk_im_end (void)
-{
-  xim_using = FALSE;
-  xim_ic = NULL;
-  xim_window = NULL;
-}
-
-static GdkIM 
-gdk_im_get (void)
-{
-  return xim_im;
-}
-
-static GdkIMStyle 
-gdk_im_choose_better_style (GdkIMStyle style1, GdkIMStyle style2) 
-{
-  GdkIMStyle s1, s2, u;
-  
-  if (style1 == 0) return style2;
-  if (style2 == 0) return style1;
-  if ((style1 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK))
-       == (style2 & (GDK_IM_PREEDIT_MASK | GDK_IM_STATUS_MASK)))
-    return style1;
-
-  s1 = style1 & GDK_IM_PREEDIT_MASK;
-  s2 = style2 & GDK_IM_PREEDIT_MASK;
-  u = s1 | s2;
-  if (s1 != s2) {
-    if (u & GDK_IM_PREEDIT_CALLBACKS)
-      return (s1 == GDK_IM_PREEDIT_CALLBACKS)? style1:style2;
-    else if (u & GDK_IM_PREEDIT_POSITION)
-      return (s1 == GDK_IM_PREEDIT_POSITION)? style1:style2;
-    else if (u & GDK_IM_PREEDIT_AREA)
-      return (s1 == GDK_IM_PREEDIT_AREA)? style1:style2;
-    else if (u & GDK_IM_PREEDIT_NOTHING)
-      return (s1 == GDK_IM_PREEDIT_NOTHING)? style1:style2;
-  } else {
-    s1 = style1 & GDK_IM_STATUS_MASK;
-    s2 = style2 & GDK_IM_STATUS_MASK;
-    u = s1 | s2;
-    if ( u & GDK_IM_STATUS_CALLBACKS)
-      return (s1 == GDK_IM_STATUS_CALLBACKS)? style1:style2;
-    else if ( u & GDK_IM_STATUS_AREA)
-      return (s1 == GDK_IM_STATUS_AREA)? style1:style2;
-    else if ( u & GDK_IM_STATUS_NOTHING)
-      return (s1 == GDK_IM_STATUS_NOTHING)? style1:style2;
-    else if ( u & GDK_IM_STATUS_NONE)
-      return (s1 == GDK_IM_STATUS_NONE)? style1:style2;
-  }
-  return 0; /* Get rid of stupid warning */
-}
-
-GdkIMStyle
-gdk_im_decide_style (GdkIMStyle supported_style)
-{
-  gint i;
-  GdkIMStyle style, tmp;
-  
-  g_return_val_if_fail (xim_styles != NULL, 0);
-  
-  style = 0;
-  for (i=0; i<xim_styles->count_styles; i++)
-    {
-      tmp = xim_styles->supported_styles[i];
-      if (tmp == (tmp & supported_style & xim_best_allowed_style))
-       style = gdk_im_choose_better_style (style, tmp);
-    }
-  return style;
-}
-
-GdkIMStyle
-gdk_im_set_best_style (GdkIMStyle style)
-{
-  if (style & GDK_IM_PREEDIT_MASK)
-    {
-      xim_best_allowed_style &= ~GDK_IM_PREEDIT_MASK;
-
-      xim_best_allowed_style |= GDK_IM_PREEDIT_NONE;
-      if (!(style & GDK_IM_PREEDIT_NONE))
-       {
-         xim_best_allowed_style |= GDK_IM_PREEDIT_NOTHING;
-         if (!(style & GDK_IM_PREEDIT_NOTHING))
-           {
-             xim_best_allowed_style |= GDK_IM_PREEDIT_AREA;
-             if (!(style & GDK_IM_PREEDIT_AREA))
-               {
-                 xim_best_allowed_style |= GDK_IM_PREEDIT_POSITION;
-                 if (!(style & GDK_IM_PREEDIT_POSITION))
-                   xim_best_allowed_style |= GDK_IM_PREEDIT_CALLBACKS;
-               }
-           }
-       }
-    }
-  if (style & GDK_IM_STATUS_MASK)
-    {
-      xim_best_allowed_style &= ~GDK_IM_STATUS_MASK;
-
-      xim_best_allowed_style |= GDK_IM_STATUS_NONE;
-      if (!(style & GDK_IM_STATUS_NONE))
-       {
-         xim_best_allowed_style |= GDK_IM_STATUS_NOTHING;
-         if (!(style & GDK_IM_STATUS_NOTHING))
-           {
-             xim_best_allowed_style |= GDK_IM_STATUS_AREA;
-             if (!(style & GDK_IM_STATUS_AREA))
-               xim_best_allowed_style |= GDK_IM_STATUS_CALLBACKS;
-           }
-       }
-    }
-  
-  return xim_best_allowed_style;
-}
-
-static gint 
-gdk_im_open (XrmDatabase db, gchar* res_name, gchar* res_class)
-{
-  xim_im = XOpenIM (GDK_DISPLAY(), db, res_name, res_class);
-  if (xim_im == NULL)
-    {
-      GDK_NOTE (XIM, g_warning ("Unable to open open IM."));
-      return FALSE;
-    }
-  XGetIMValues (xim_im, XNQueryInputStyle, &xim_styles, NULL, NULL);
-  
-  return TRUE;
-}
-
-static void 
-gdk_im_close (void)
-{
-  if (xim_im)
-    {
-      XCloseIM (xim_im);
-      xim_im = NULL;
-    }
-  if (xim_styles)
-    {
-      XFree (xim_styles);
-      xim_styles = NULL;
-    }
-}
-
-gint 
-gdk_im_ready (void)
-{
-  return (xim_im != NULL);
-}
-
-GdkIC 
-gdk_ic_new (GdkWindow* client_window,
-           GdkWindow* focus_window,
-           GdkIMStyle style, ...)
-{
-  va_list list;
-  GdkICPrivate *private;
-  XVaNestedList preedit_attr = NULL;
-  guint count;
-  
-  g_return_val_if_fail (client_window != NULL, NULL);
-  g_return_val_if_fail (focus_window != NULL, NULL);
-  g_return_val_if_fail (gdk_im_ready(), NULL);
-  
-  private = g_new (GdkICPrivate, 1);
-  
-  va_start (list, style);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, style);
-  preedit_attr = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  private->style = gdk_im_decide_style (style);
-  if (private->style != style)
-    {
-      g_warning ("can not create input context with specified input style.");
-      g_free (private);
-      return NULL;
-    }
-  
-  private->xic = XCreateIC(gdk_im_get (),
-                          XNInputStyle,   style,
-                          XNClientWindow, GDK_WINDOW_XWINDOW (client_window),
-                          XNFocusWindow,  GDK_WINDOW_XWINDOW (focus_window),
-                          preedit_attr? XNPreeditAttributes : NULL, preedit_attr,
-                          NULL);
-  
-  g_free (preedit_attr);
-  
-  if (!private->xic)
-    {
-      g_free (private);
-      return NULL;
-    }
-  
-  xim_ic_list = g_list_append (xim_ic_list, private);
-  return private;
-}
-
-void 
-gdk_ic_destroy (GdkIC ic)
-{
-  GdkICPrivate *private;
-  
-  g_return_if_fail (ic != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  if (xim_ic == private)
-    gdk_im_end ();
-  
-  XDestroyIC (private->xic);
-  xim_ic_list = g_list_remove (xim_ic_list, private);
-  g_free (private);
-}
-
-GdkIMStyle
-gdk_ic_get_style (GdkIC ic)
-{
-  GdkICPrivate *private;
-  
-  g_return_val_if_fail (ic != NULL, 0);
-  
-  private = (GdkICPrivate *) ic;
-  
-  return private->style;
-}
-
-void 
-gdk_ic_set_values (GdkIC ic, ...)
-{
-  va_list list;
-  XVaNestedList args;
-  GdkICPrivate *private;
-  guint count;
-  
-  g_return_if_fail (ic != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  va_start (list, ic);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, ic);
-  args = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  XSetICValues (private->xic, XNVaNestedList, args, NULL);
-  
-  g_free (args);
-}
-
-void 
-gdk_ic_get_values (GdkIC ic, ...)
-{
-  va_list list;
-  XVaNestedList args;
-  GdkICPrivate *private;
-  guint count;
-  
-  g_return_if_fail (ic != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  va_start (list, ic);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, ic);
-  args = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  XGetICValues (private->xic, XNVaNestedList, args, NULL);
-  
-  g_free (args);
-}
-
-void 
-gdk_ic_set_attr (GdkIC ic, const char *target, ...)
-{
-  va_list list;
-  XVaNestedList attr;
-  GdkICPrivate *private;
-  guint count;
-  
-  g_return_if_fail (ic != NULL);
-  g_return_if_fail (target != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  va_start (list, target);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, target);
-  attr = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  XSetICValues (private->xic, target, attr, NULL);
-  
-  g_free (attr);
-}
-
-void 
-gdk_ic_get_attr (GdkIC ic, const char *target, ...)
-{
-  va_list list;
-  XVaNestedList attr;
-  GdkICPrivate *private;
-  guint count;
-  
-  g_return_if_fail (ic != NULL);
-  g_return_if_fail (target != NULL);
-  
-  private = (GdkICPrivate *) ic;
-  
-  va_start (list, target);
-  count = gdk_im_va_count (list);
-  va_end (list);
-  
-  va_start (list, target);
-  attr = gdk_im_va_to_nested (list, count);
-  va_end (list);
-  
-  XGetICValues (private->xic, target, attr, NULL);
-  
-  g_free (attr);
-}
-
-GdkEventMask 
-gdk_ic_get_events (GdkIC ic)
-{
-  GdkEventMask mask;
-  glong xmask;
-  glong bit;
-  GdkICPrivate *private;
-  gint i;
-  
-  /*  From gdkwindow.c */
-  extern int nevent_masks;
-  extern int event_mask_table[];
-  
-  g_return_val_if_fail (ic != NULL, 0);
-  
-  private = (GdkICPrivate *) ic;
-  
-  if (XGetICValues (private->xic, XNFilterEvents, &xmask, NULL) != NULL)
-    {
-      GDK_NOTE (XIM, g_warning ("Call to XGetICValues: %s failed", XNFilterEvents));
-      return 0;
-    }
-  
-  mask = 0;
-  for (i=0, bit=2; i < nevent_masks; i++, bit <<= 1)
-    if (xmask & event_mask_table [i])
-      {
-       mask |= bit;
-       xmask &= ~ event_mask_table [i];
-      }
-  
-  if (xmask)
-    g_warning ("ic requires events not supported by the application (%#04lx)", xmask);
-  
-  return mask;
-}
-
-static void 
-gdk_ic_cleanup (void)
-{
-  GList* node;
-  gint destroyed;
-  GdkICPrivate *private;
-  
-  destroyed = 0;
-  for (node = xim_ic_list; node != NULL; node = node->next)
-    {
-      if (node->data)
-       {
-         private = (GdkICPrivate *) (node->data);
-         XDestroyIC (private->xic);
-         g_free (private);
-         destroyed++;
-       }
-    }
-#ifdef G_ENABLE_DEBUG
-  if ((gdk_debug_flags & GDK_DEBUG_XIM) && destroyed > 0)
-    {
-      g_warning ("Cleaned up %i IC(s)\n", destroyed);
-    }
-#endif /* G_ENABLE_DEBUG */
-  g_list_free(xim_ic_list);
-  xim_ic_list = NULL;
-}
-
-#else /* !USE_XIM */
-
-void 
-gdk_im_begin (GdkIC ic, GdkWindow* window)
-{
-}
-
-void 
-gdk_im_end (void)
-{
-}
-
-GdkIMStyle
-gdk_im_decide_style (GdkIMStyle supported_style)
-{
-  return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-GdkIMStyle
-gdk_im_set_best_style (GdkIMStyle style)
-{
-  return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-gint 
-gdk_im_ready (void)
-{
-  return FALSE;
-}
-
-GdkIC 
-gdk_ic_new (GdkWindow* client_window,
-           GdkWindow* focus_window,
-           GdkIMStyle style, ...)
-{
-  return NULL;
-}
-
-void 
-gdk_ic_destroy (GdkIC ic)
-{
-}
-
-GdkIMStyle
-gdk_ic_get_style (GdkIC ic)
-{
-  return GDK_IM_PREEDIT_NONE | GDK_IM_STATUS_NONE;
-}
-
-void 
-gdk_ic_set_values (GdkIC ic, ...)
-{
-}
-
-void 
-gdk_ic_get_values (GdkIC ic, ...)
-{
-}
-
-void 
-gdk_ic_set_attr (GdkIC ic, const char *target, ...)
-{
-}
-
-void 
-gdk_ic_get_attr (GdkIC ic, const char *target, ...)
-{
-}
-
-GdkEventMask 
-gdk_ic_get_events (GdkIC ic)
-{
-  return 0;
-}
-
-#endif /* USE_XIM */
-
-#ifdef X_LOCALE
-
-gint
-_g_mbtowc (wchar_t *wstr, const char *str, size_t len)
-{
-  static wchar_t wcs[MB_CUR_MAX + 1];
-  static gchar mbs[MB_CUR_MAX + 1];
-  
-  wcs[0] = (wchar_t) NULL;
-  mbs[0] = '\0';
-  
-  /* The last argument isn't a mistake. The X locale code trims
-   *  the input string to the length of the output string!
-   */
-  len = _Xmbstowcs (wcs, str, (len<MB_CUR_MAX)? len:MB_CUR_MAX);
-  if (len < 1)
-    return len;
-  else if (wcs[0] == (wchar_t) NULL)
-    return -1;
-  
-  len = _Xwctomb (mbs, wcs[0]);
-  if (mbs[0] == '\0')
-    return -1;
-  if (wstr)
-    *wstr = wcs[0];
-  
-  return len;
-}
-
-#endif /* X_LOCALE */
-
 /* Sends a ClientMessage to all toplevel client windows */
 gboolean
 gdk_event_send_client_message (GdkEvent *event, guint32 xid)
index efbd713144839046787d03a44e19044f876dee3f..72a56d85843f7bdd6fe0e68699400946ef3eae05 100644 (file)
@@ -323,7 +323,12 @@ gdk_window_new (GdkWindow     *parent,
       if (attributes_mask & GDK_WA_COLORMAP)
        private->colormap = attributes->colormap;
       else
-       private->colormap = gdk_colormap_get_system ();
+       {
+         if ((((GdkVisualPrivate*)gdk_visual_get_system())->xvisual) == xvisual)
+           private->colormap = gdk_colormap_get_system ();
+         else
+           private->colormap = gdk_colormap_new (visual, False);
+       }
 
       xattributes.background_pixel = BlackPixel (gdk_display, gdk_screen);
       xattributes.border_pixel = BlackPixel (gdk_display, gdk_screen);
index 533527487638d6525015f647ed5ec8a1c24c7264..5d8248471ec073df5a499fba33f3682a335e2228 100644 (file)
@@ -75,7 +75,6 @@ static void gtk_editable_set_arg           (GtkObject        *object,
 static void gtk_editable_get_arg            (GtkObject        *object,
                                              GtkArg           *arg,
                                              guint             arg_id);
-static void gtk_editable_finalize            (GtkObject        *object);
 static gint gtk_editable_selection_clear     (GtkWidget        *widget,
                                             GdkEventSelection *event);
 static void gtk_editable_selection_get      (GtkWidget         *widget,
@@ -96,7 +95,7 @@ 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 };
 
@@ -291,7 +290,6 @@ gtk_editable_class_init (GtkEditableClass *class)
     
   object_class->set_arg = gtk_editable_set_arg;
   object_class->get_arg = gtk_editable_get_arg;
-  object_class->finalize = gtk_editable_finalize;
 
   widget_class->selection_clear_event = gtk_editable_selection_clear;
   widget_class->selection_received = gtk_editable_selection_received;
@@ -399,27 +397,6 @@ gtk_editable_init (GtkEditable *editable)
                             targets, n_targets);
 }
 
-static void
-gtk_editable_finalize (GtkObject *object)
-{
-  GtkEditable *editable;
-
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (GTK_IS_EDITABLE (object));
-
-  editable = GTK_EDITABLE (object);
-
-#ifdef USE_XIM
-  if (editable->ic)
-    {
-      gdk_ic_destroy (editable->ic);
-      editable->ic = NULL;
-    }
-#endif
-
-  (* GTK_OBJECT_CLASS (parent_class)->finalize) (object);
-}
-
 void
 gtk_editable_insert_text (GtkEditable *editable,
                          const gchar *new_text,
@@ -594,7 +571,9 @@ gtk_editable_selection_get (GtkWidget        *widget,
       str = gtk_editable_get_chars(editable, 
                                   selection_start_pos, 
                                   selection_end_pos);
-      length = selection_end_pos - selection_start_pos;
+      if (!str)
+        return;                /* Refuse */
+      length = strlen (str);
     }
   else                         /* CLIPBOARD */
     {
@@ -938,3 +917,32 @@ gtk_editable_changed (GtkEditable *editable)
   
   gtk_signal_emit (GTK_OBJECT (editable), editable_signals[CHANGED]);
 }
+
+#if 0
+static void
+gtk_editable_parent_set (GtkWidget *widget, 
+                        GtkWidget *old_parent, 
+                        GtkWidget *editable)
+{
+  GtkWidget *parent;
+
+  parent = old_parent;
+  while (parent)
+    {
+      gtk_signal_disconnect_by_func (GTK_OBJECT (parent),
+                                    GTK_SIGNAL_FUNC (gtk_editable_parent_set),
+                                    editable);
+      parent = parent->parent;
+    }
+
+  parent = widget->parent;
+  while (parent)
+    {
+      gtk_signal_connect (GTK_OBJECT (parent), "parent_set",
+                         GTK_SIGNAL_FUNC (gtk_editable_parent_set), 
+                         editable);
+      
+      parent = parent->parent;
+    }
+}
+#endif
index be8c1ef9bd239d1dc0e8bccd9f8043365e7f6ab3..672d7cb61b3943822dc8b0e518e3455407661d95 100644 (file)
@@ -45,13 +45,14 @@ struct _GtkEditable
 {
   GtkWidget widget;
 
-  guint   current_pos;
-
-  guint   selection_start_pos;
-  guint   selection_end_pos;
-  guint   has_selection : 1;
-  guint   editable : 1;
-  GdkIC   ic;
+  guint      current_pos;
+
+  guint      selection_start_pos;
+  guint      selection_end_pos;
+  guint      has_selection : 1;
+  guint      editable : 1;
+  GdkIC     *ic;
+  GdkICAttr *ic_attr;
 
   gchar *clipboard_text;
 };
index 77079d2ae4122b07e0cafee3d6564ffda3ef38ac..76e6d5b7b455e1cc0676201a413b1ca4267ff843 100644 (file)
@@ -18,9 +18,6 @@
  */
 #include <ctype.h>
 #include <string.h>
-#ifdef USE_XIM
-#include "gdk/gdkx.h"
-#endif
 #include "gdk/gdkkeysyms.h"
 #include "gdk/gdki18n.h"
 #include "gtkentry.h"
@@ -28,7 +25,6 @@
 #include "gtkselection.h"
 #include "gtksignal.h"
 #include "gtkstyle.h"
-#include "gtkprivate.h"
 
 #define MIN_ENTRY_WIDTH  150
 #define DRAW_TIMEOUT     20
@@ -84,6 +80,9 @@ static void gtk_entry_style_set                 (GtkWidget         *widget,
                                           GtkStyle          *previous_style);
 static void gtk_entry_state_changed      (GtkWidget         *widget,
                                           GtkStateType       previous_state);
+#ifdef USE_XIM
+static void gtk_entry_update_ic_attr      (GtkWidget         *widget);
+#endif
 static void gtk_entry_queue_draw          (GtkEntry          *entry);
 static gint gtk_entry_timer               (gpointer           data);
 static gint gtk_entry_position            (GtkEntry          *entry,
@@ -143,8 +142,6 @@ static void gtk_entry_set_selection       (GtkEditable       *editable,
                                           gint               end);
 
 static void gtk_entry_recompute_offsets   (GtkEntry          *entry);
-static gint gtk_entry_find_char           (GtkEntry          *entry, 
-                                          gint               position);
 static gint gtk_entry_find_position       (GtkEntry          *entry, 
                                           gint               position);
 static void gtk_entry_set_position_from_editable (GtkEditable *editable,
@@ -353,9 +350,10 @@ gtk_entry_init (GtkEntry *entry)
   entry->button = 0;
   entry->visible = 1;
 
-  entry->nchars = 0;
-  entry->char_pos = NULL;
   entry->char_offset = NULL;
+  entry->text_mb = NULL;
+  entry->text_mb_dirty = TRUE;
+  entry->use_wchar = FALSE;
 
   gtk_entry_grow_text (entry);
 }
@@ -480,14 +478,27 @@ gtk_entry_set_editable(GtkEntry *entry,
 gchar*
 gtk_entry_get_text (GtkEntry *entry)
 {
-  static char empty_str[2] = "";
-
   g_return_val_if_fail (entry != NULL, NULL);
   g_return_val_if_fail (GTK_IS_ENTRY (entry), NULL);
 
+  if (!entry->text_mb_dirty)
+    return entry->text_mb;
+
+  if (entry->text_mb)
+    g_free(entry->text_mb);
+
   if (!entry->text)
-    return empty_str;
-  return entry->text;
+    {
+      entry->text_mb = g_new(gchar, 1);
+      entry->text_mb[0] = 0;
+    }
+  else
+    {
+      entry->text_mb = gtk_entry_get_chars(GTK_EDITABLE(entry), 0, -1);
+    }
+  entry->text_mb_dirty = 0;
+
+  return entry->text_mb;
 }
 
 static void
@@ -500,26 +511,22 @@ gtk_entry_finalize (GtkObject *object)
 
   entry = GTK_ENTRY (object);
 
-#ifdef USE_XIM
-  if (GTK_EDITABLE(entry)->ic)
-    {
-      gdk_ic_destroy (GTK_EDITABLE(entry)->ic);
-      GTK_EDITABLE(entry)->ic = NULL;
-    }
-#endif
-
   if (entry->timer)
     gtk_timeout_remove (entry->timer);
 
   entry->text_size = 0;
+
   if (entry->text)
     g_free (entry->text);
-  if (entry->char_pos)
-    g_free (entry->char_pos);
   if (entry->char_offset)
     g_free (entry->char_offset);
   entry->text = NULL;
 
+  if (entry->text_mb)
+    g_free (entry->text_mb);
+  entry->text_mb = NULL;
+   if (entry->backing_pixmap)
   if (entry->backing_pixmap)
     gdk_pixmap_unref (entry->backing_pixmap);
 
@@ -581,21 +588,37 @@ gtk_entry_realize (GtkWidget *widget)
   gdk_window_set_background (entry->text_area, &widget->style->base[GTK_WIDGET_STATE (widget)]);
 
 #ifdef USE_XIM
-  if (gdk_im_ready ())
+  if (gdk_im_ready () && (editable->ic_attr = gdk_ic_attr_new ()) != NULL)
     {
-      GdkPoint spot;
-      GdkRectangle rect;
       gint width, height;
       GdkEventMask mask;
+      GdkColormap *colormap;
+      GdkICAttr *attr = editable->ic_attr;
+      GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
       GdkIMStyle style;
-      GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE | GDK_IM_PREEDIT_NOTHING |
-                       GDK_IM_PREEDIT_POSITION |
-                       GDK_IM_STATUS_NONE | GDK_IM_STATUS_NOTHING;
+      GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE |
+                                  GDK_IM_PREEDIT_NOTHING |
+                                  GDK_IM_PREEDIT_POSITION |
+                                  GDK_IM_STATUS_NONE |
+                                  GDK_IM_STATUS_NOTHING;
 
       if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
        supported_style &= ~GDK_IM_PREEDIT_POSITION;
 
-      style = gdk_im_decide_style (supported_style);
+      attr->style = style = gdk_im_decide_style (supported_style);
+      attr->client_window = entry->text_area;
+
+      if ((colormap = gtk_widget_get_colormap (widget)) !=
+           gtk_widget_get_default_colormap ())
+       {
+         attrmask |= GDK_IC_PREEDIT_COLORMAP;
+         attr->preedit_colormap = colormap;
+       }
+      attrmask |= GDK_IC_PREEDIT_FOREGROUND;
+      attrmask |= GDK_IC_PREEDIT_BACKGROUND;
+      attr->preedit_foreground = widget->style->fg[GTK_STATE_NORMAL];
+      attr->preedit_background = widget->style->base[GTK_STATE_NORMAL];
+
       switch (style & GDK_IM_PREEDIT_MASK)
        {
        case GDK_IM_PREEDIT_POSITION:
@@ -604,46 +627,32 @@ gtk_entry_realize (GtkWidget *widget)
              g_warning ("over-the-spot style requires fontset");
              break;
            }
+
          gdk_window_get_size (entry->text_area, &width, &height);
-         rect.x = 0;
-         rect.y = 0;
-         rect.width = width;
-         rect.height = height;
-         spot.x = 0;
-         spot.y = height;
-         editable->ic = gdk_ic_new (entry->text_area, entry->text_area,
-                              style,
-                              "spotLocation", &spot,
-                              "area", &rect,
-                              "fontSet", GDK_FONT_XFONT (widget->style->font),
-                              NULL);
+
+         attrmask |= GDK_IC_PREEDIT_POSITION_REQ;
+         attr->spot_location.x = 0;
+         attr->spot_location.y = height;
+         attr->preedit_area.x = 0;
+         attr->preedit_area.y = 0;
+         attr->preedit_area.width = width;
+         attr->preedit_area.height = height;
+         attr->preedit_fontset = widget->style->font;
+
          break;
-       default:
-         editable->ic = gdk_ic_new (entry->text_area, entry->text_area,
-                                 style, NULL);
        }
+      editable->ic = gdk_ic_new (attr, attrmask);
      
       if (editable->ic == NULL)
        g_warning ("Can't create input context.");
       else
        {
-         GdkColormap *colormap;
-
          mask = gdk_window_get_events (entry->text_area);
          mask |= gdk_ic_get_events (editable->ic);
          gdk_window_set_events (entry->text_area, mask);
 
-         if ((colormap = gtk_widget_get_colormap (widget)) !=
-               gtk_widget_get_default_colormap ())
-           {
-             gdk_ic_set_attr (editable->ic, "preeditAttributes",
-                              "colorMap", GDK_COLORMAP_XCOLORMAP (colormap),
-                              NULL);
-           }
-         gdk_ic_set_attr (editable->ic,"preeditAttributes",
-                    "foreground", widget->style->fg[GTK_STATE_NORMAL].pixel,
-                    "background", widget->style->base[GTK_STATE_NORMAL].pixel,
-                    NULL);
+         if (GTK_WIDGET_HAS_FOCUS(widget))
+           gdk_im_begin (editable->ic, entry->text_area);
        }
     }
 #endif
@@ -666,6 +675,19 @@ gtk_entry_unrealize (GtkWidget *widget)
 
   entry = GTK_ENTRY (widget);
 
+#ifdef USE_XIM
+  if (GTK_EDITABLE (widget)->ic)
+    {
+      gdk_ic_destroy (GTK_EDITABLE (widget)->ic);
+      GTK_EDITABLE (widget)->ic = NULL;
+    }
+  if (GTK_EDITABLE (widget)->ic_attr)
+    {
+      gdk_ic_attr_destroy (GTK_EDITABLE (widget)->ic_attr);
+      GTK_EDITABLE (widget)->ic_attr = NULL;
+    }
+#endif
+
   if (entry->text_area)
     {
       gdk_window_set_user_data (entry->text_area, NULL);
@@ -765,17 +787,16 @@ gtk_entry_size_allocate (GtkWidget     *widget,
       entry_adjust_scroll (entry);
       
 #ifdef USE_XIM
-      if (editable->ic && (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
+      if (editable->ic &&
+         (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
        {
          gint width, height;
-         GdkRectangle rect;
 
          gdk_window_get_size (entry->text_area, &width, &height);
-         rect.x = 0;
-         rect.y = 0;
-         rect.width = width;
-         rect.height = height;
-         gdk_ic_set_attr (editable->ic, "preeditAttributes", "area", &rect, NULL);
+         editable->ic_attr->preedit_area.width = width;
+         editable->ic_attr->preedit_area.height = height;
+         gdk_ic_set_attr (editable->ic, editable->ic_attr,
+                          GDK_IC_PREEDIT_AREA);
        }
 #endif
     }
@@ -1236,13 +1257,9 @@ gtk_entry_draw_text (GtkEntry *entry)
   GtkWidget *widget;
   GtkEditable *editable;
   GtkStateType selected_state;
-  gint start_char;
   gint start_pos;
   gint end_pos;
-  gint end_char;
   gint start_xoffset;
-  gint selection_start_char;
-  gint selection_end_char;
   gint selection_start_pos;
   gint selection_end_pos;
   gint selection_start_xoffset;
@@ -1251,8 +1268,8 @@ gtk_entry_draw_text (GtkEntry *entry)
   gint y;
   GdkDrawable *drawable;
   gint use_backing_pixmap;
-  gchar *stars;
-  gchar *toprint;
+  GdkWChar *stars;
+  GdkWChar *toprint;
 
   g_return_if_fail (entry != NULL);
   g_return_if_fail (GTK_IS_ENTRY (entry));
@@ -1305,12 +1322,10 @@ gtk_entry_draw_text (GtkEntry *entry)
       y = (height - (widget->style->font->ascent + widget->style->font->descent)) / 2;
       y += widget->style->font->ascent;
 
-      start_char = gtk_entry_find_position (entry, entry->scroll_offset);
-      start_pos = entry->char_pos[start_char];
-      start_xoffset = entry->char_offset[start_char] - entry->scroll_offset;
+      start_pos = gtk_entry_find_position (entry, entry->scroll_offset);
+      start_xoffset = entry->char_offset[start_pos] - entry->scroll_offset;
 
-      end_char = gtk_entry_find_position (entry, entry->scroll_offset + width);
-      end_pos = entry->char_pos[end_char];
+      end_pos = gtk_entry_find_position (entry, entry->scroll_offset + width);
       if (end_pos < entry->text_length)
        end_pos += 1;
 
@@ -1324,13 +1339,10 @@ gtk_entry_draw_text (GtkEntry *entry)
       selection_start_pos = CLAMP (selection_start_pos, start_pos, end_pos);
       selection_end_pos = CLAMP (selection_end_pos, start_pos, end_pos);
 
-      selection_start_char = gtk_entry_find_char(entry,selection_start_pos);
-      selection_end_char = gtk_entry_find_char(entry,selection_end_pos);
-
       selection_start_xoffset = 
-       entry->char_offset[selection_start_char] - entry->scroll_offset;
+       entry->char_offset[selection_start_pos] - entry->scroll_offset;
       selection_end_xoffset = 
-       entry->char_offset[selection_end_char] -entry->scroll_offset;
+       entry->char_offset[selection_end_pos] -entry->scroll_offset;
 
       /* if entry->visible, print a bunch of stars.  If not, print the standard text. */
       if (entry->visible)
@@ -1341,24 +1353,18 @@ gtk_entry_draw_text (GtkEntry *entry)
        {
          gint i;
          
-         stars = g_malloc (end_char - start_char);
-         for (i = 0; i < end_char - start_char; i++)
+         stars = g_new (GdkWChar, end_pos - start_pos);
+         for (i = 0; i < end_pos - start_pos; i++)
            stars[i] = '*';
          toprint = stars;
-
-         /* Since '*' is always one byte, work in bytes */
-         start_pos = start_char;
-         selection_start_pos = selection_start_char;
-         selection_end_pos = selection_end_char;
-         end_pos = end_char;
        }
       
       if (selection_start_pos > start_pos)
-       gdk_draw_text (drawable, widget->style->font,
-                      widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-                      INNER_BORDER + start_xoffset, y,
-                      toprint,
-                      selection_start_pos - start_pos);
+       gdk_draw_text_wc (drawable, widget->style->font,
+                         widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                         INNER_BORDER + start_xoffset, y,
+                         toprint,
+                         selection_start_pos - start_pos);
       
       if ((selection_end_pos >= start_pos) && 
          (selection_start_pos < end_pos) &&
@@ -1371,19 +1377,19 @@ gtk_entry_draw_text (GtkEntry *entry)
                                INNER_BORDER,
                                selection_end_xoffset - selection_start_xoffset,
                                height - 2*INNER_BORDER);
-           gdk_draw_text (drawable, widget->style->font,
-                          widget->style->fg_gc[selected_state],
-                          INNER_BORDER + selection_start_xoffset, y,
-                          toprint + selection_start_pos - start_pos,
-                          selection_end_pos - selection_start_pos);
+           gdk_draw_text_wc (drawable, widget->style->font,
+                             widget->style->fg_gc[selected_state],
+                             INNER_BORDER + selection_start_xoffset, y,
+                             toprint + selection_start_pos - start_pos,
+                             selection_end_pos - selection_start_pos);
         }          
        
        if (selection_end_pos < end_pos)
-        gdk_draw_text (drawable, widget->style->font,
-                       widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-                       INNER_BORDER + selection_end_xoffset, y,
-                       toprint + selection_end_pos - start_pos,
-                       end_pos - selection_end_pos);
+        gdk_draw_text_wc (drawable, widget->style->font,
+                          widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                          INNER_BORDER + selection_end_xoffset, y,
+                          toprint + selection_end_pos - start_pos,
+                          end_pos - selection_end_pos);
        /* free the space allocated for the stars if it's neccessary. */
       if (!entry->visible)
        g_free (toprint);
@@ -1424,7 +1430,7 @@ gtk_entry_draw_cursor_on_drawable (GtkEntry *entry, GdkDrawable *drawable)
       widget = GTK_WIDGET (entry);
       editable = GTK_EDITABLE (entry);
 
-      xoffset = INNER_BORDER + entry->char_offset[gtk_entry_find_char (entry, editable->current_pos)];
+      xoffset = INNER_BORDER + entry->char_offset[editable->current_pos];
       xoffset -= entry->scroll_offset;
 
       gdk_window_get_size (entry->text_area, NULL, &text_area_height);
@@ -1444,14 +1450,16 @@ gtk_entry_draw_cursor_on_drawable (GtkEntry *entry, GdkDrawable *drawable)
        }
 
 #ifdef USE_XIM
-      if (gdk_im_ready() && editable->ic && 
-         gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION)
+      if (GTK_WIDGET_HAS_FOCUS(widget) && gdk_im_ready() && editable->ic && 
+         (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
        {
-         GdkPoint spot;
+         editable->ic_attr->spot_location.x = xoffset;
+         editable->ic_attr->spot_location.y =
+           (text_area_height + (widget->style->font->ascent
+               - widget->style->font->descent) + 1) / 2;
 
-         spot.x = xoffset;
-         spot.y = (text_area_height + (widget->style->font->ascent - widget->style->font->descent) + 1) / 2;
-         gdk_ic_set_attr (editable->ic, "preeditAttributes", "spotLocation", &spot, NULL);
+         gdk_ic_set_attr (editable->ic,
+                          editable->ic_attr, GDK_IC_SPOT_LOCATION);
        }
 #endif 
     }
@@ -1486,7 +1494,7 @@ gtk_entry_find_position (GtkEntry *entry,
                         gint      x)
 {
   gint start = 0;
-  gint end = entry->nchars;
+  gint end = entry->text_length;
   gint half;
 
   if (x <= 0)
@@ -1514,7 +1522,7 @@ static gint
 gtk_entry_position (GtkEntry *entry,
                    gint      x)
 {
-  return entry->char_pos[gtk_entry_find_position(entry, x)];
+  return gtk_entry_find_position(entry, x);
 }
 
 void
@@ -1543,13 +1551,13 @@ entry_adjust_scroll (GtkEntry *entry)
   gdk_window_get_size (entry->text_area, &text_area_width, NULL);
 
   /* Display as much text as we can */
-  max_offset = MAX(0, entry->char_offset[entry->nchars] - text_area_width);
+  max_offset = MAX(0, entry->char_offset[entry->text_length] - text_area_width);
 
   if (entry->scroll_offset > max_offset)
     entry->scroll_offset = max_offset;
 
   /* And make sure cursor is on screen */
-  xoffset = entry->char_offset[gtk_entry_find_char (entry, GTK_EDITABLE(entry)->current_pos)];
+  xoffset = entry->char_offset[GTK_EDITABLE(entry)->current_pos];
   xoffset -= entry->scroll_offset;
 
   if (xoffset < 0)
@@ -1574,15 +1582,12 @@ gtk_entry_grow_text (GtkEntry *entry)
     entry->text_size = 128;
   else
     entry->text_size *= 2;
-  entry->text = g_realloc (entry->text, entry->text_size);
-  entry->char_pos = g_realloc (entry->char_pos, 
-                              entry->text_size * sizeof(guint16));
+  entry->text = g_realloc (entry->text, entry->text_size * sizeof(GdkWChar));
   entry->char_offset = g_realloc (entry->char_offset, 
                                  entry->text_size * sizeof(guint));
 
   if (entry->text_length == 0) /* initial allocation */
     {
-      entry->char_pos[0] = 0;
       entry->char_offset[0] = 0;
     }
 
@@ -1596,28 +1601,51 @@ gtk_entry_insert_text (GtkEditable *editable,
                       gint         new_text_length,
                       gint        *position)
 {
-  gchar *text;
-  gint start_char;
-  gint end_char;
+  GdkWChar *text;
   gint start_pos;
-  gint last_char;
   gint end_pos;
   gint last_pos;
   gint max_length;
   gint i;
 
-  gint insertion_chars;
-  guint16 *insertion_pos = NULL; /* Quiet the compiler */
+  guchar *new_text_nt;
+  gint insertion_length;
+  GdkWChar *insertion_text;
   
   GtkEntry *entry;
+  GtkWidget *widget;
   
   g_return_if_fail (editable != NULL);
   g_return_if_fail (GTK_IS_ENTRY (editable));
 
   entry = GTK_ENTRY (editable);
+  widget = GTK_WIDGET (editable);
+
+  if ((entry->text_length == 0) && (entry->use_wchar == FALSE))
+    {
+      if (!GTK_WIDGET_REALIZED (widget))
+       gtk_widget_ensure_style (widget);
+      if ((widget->style) && (widget->style->font->type == GDK_FONT_FONTSET))
+       entry->use_wchar = TRUE;
+    }
 
   if (new_text_length < 0)
-    new_text_length = strlen (new_text);
+    {
+      new_text_nt = (gchar *)new_text;
+      new_text_length = strlen (new_text);
+      if (new_text_length <= 0) return;
+    }
+  else if (new_text_length == 0)
+    {
+      return;
+    }
+  else
+    {
+      /* make a null-terminated copy of new_text */
+      new_text_nt = g_new (gchar, new_text_length + 1);
+      memcpy (new_text_nt, new_text, new_text_length);
+      new_text_nt[new_text_length] = 0;
+    }
     
   /* The algorithms here will work as long as, the text size (a
    * multiple of 2), fits into a guint16 but we specify a shorter
@@ -1629,49 +1657,42 @@ gtk_entry_insert_text (GtkEditable *editable,
   else
     max_length = MIN (2047, entry->text_max_length);
 
+  /* Convert to wide characters */
+  insertion_text = g_new (GdkWChar, new_text_length);
+  if (entry->use_wchar)
+    insertion_length = gdk_mbstowcs (insertion_text, new_text_nt,
+                                    new_text_length);
+  else
+    for (insertion_length=0; new_text_nt[insertion_length]; insertion_length++)
+      insertion_text[insertion_length] = new_text_nt[insertion_length];
+  if (new_text_nt != (guchar *)new_text)
+    g_free (new_text_nt);
+
   /* Make sure we do not exceed the maximum size of the entry. */
-  if (new_text_length + entry->text_length > max_length)
-    new_text_length = max_length - entry->text_length;
+  if (insertion_length + entry->text_length > max_length)
+    insertion_length = max_length - entry->text_length;
 
   /* Don't insert anything, if there was nothing to insert. */
-  if (new_text_length <= 0)
-    return;
-
-  /* Find the length of the inserted text in characters, chop off
-     partial/invalid characters */
-  if (gtk_use_mb)
+  if (insertion_length <= 0)
     {
-      gint len = 0;
-      
-      insertion_pos = g_new (guint16, new_text_length+1);
-      insertion_chars = 0;
-      
-      for (i=0; i<new_text_length; i+=len)
-       {
-         len = mblen (&new_text[i], MIN(MB_CUR_MAX,new_text_length-i));
-         if (len < 0)
-           break;
-         insertion_pos[insertion_chars] =  i;
-         insertion_chars++;
-       }
-      insertion_pos[insertion_chars] =  i;
-
-      new_text_length = i;
+      g_free(insertion_text);
+      return;
     }
-  else
-    insertion_chars = new_text_length;
 
   /* Make sure we are inserting at integral character position */
-  start_char = gtk_entry_find_char (entry, *position);
-  start_pos = entry->char_pos[start_char];
+  start_pos = *position;
+  if (start_pos < 0)
+    start_pos = 0;
+  else if (start_pos > entry->text_length)
+    start_pos = entry->text_length;
 
-  end_pos = start_pos + new_text_length;
-  last_pos = new_text_length + entry->text_length;
+  end_pos = start_pos + insertion_length;
+  last_pos = insertion_length + entry->text_length;
 
   if (editable->selection_start_pos >= *position)
-    editable->selection_start_pos += new_text_length;
+    editable->selection_start_pos += insertion_length;
   if (editable->selection_end_pos >= *position)
-    editable->selection_end_pos += new_text_length;
+    editable->selection_end_pos += insertion_length;
 
   while (last_pos >= entry->text_size)
     gtk_entry_grow_text (entry);
@@ -1680,33 +1701,8 @@ gtk_entry_insert_text (GtkEditable *editable,
   for (i = last_pos - 1; i >= end_pos; i--)
     text[i] = text[i- (end_pos - start_pos)];
   for (i = start_pos; i < end_pos; i++)
-    text[i] = new_text[i - start_pos];
-
-  if (gtk_use_mb)
-    {
-      /* Fix up the character positions */
-
-      end_char = start_char + insertion_chars;
-      last_char = entry->nchars + insertion_chars;
-      
-      for (i = last_char; i >= end_char; i--)
-       entry->char_pos[i] 
-         = entry->char_pos[i - insertion_chars] + new_text_length;
-      
-      for (i = 1; i < insertion_chars ; i++)
-       entry->char_pos[start_char+i] = 
-         entry->char_pos[start_char] + insertion_pos[i];
-
-      g_free (insertion_pos);
-    }
-  else
-    {
-      end_char = end_pos;
-      last_char = last_pos;
-
-      for (i = start_char ; i <= last_char ; i++)
-       entry->char_pos[i] = i;
-    }
+    text[i] = insertion_text[i - start_pos];
+  g_free (insertion_text);
 
   /* Fix up the the character offsets */
   
@@ -1714,32 +1710,31 @@ gtk_entry_insert_text (GtkEditable *editable,
     {
       gint offset = 0;
       
-      for (i = last_char; i >= end_char; i--)
+      for (i = last_pos; i >= end_pos; i--)
        entry->char_offset[i] 
-         = entry->char_offset[i - insertion_chars];
+         = entry->char_offset[i - insertion_length];
       
-      for (i=start_char; i<end_char; i++)
+      for (i=start_pos; i<end_pos; i++)
        {
-         entry->char_offset[i] = entry->char_offset[start_char] + offset;
+         entry->char_offset[i] = entry->char_offset[start_pos] + offset;
          if (entry->visible)
            {
-             offset += gdk_text_width (GTK_WIDGET (entry)->style->font,
-                                       entry->text + entry->char_pos[i],
-                                       entry->char_pos[i+1] - entry->char_pos[i]);
+             offset += gdk_char_width_wc (GTK_WIDGET (entry)->style->font,
+                                          entry->text[i]);
            }
          else
            {
-             offset += gdk_text_width (GTK_WIDGET (entry)->style->font, "*", 1);
+             offset += gdk_char_width (GTK_WIDGET (entry)->style->font, '*');
            }
        }
-      for (i = end_char ; i <= last_char ; i++)
+      for (i = end_pos; i <= last_pos; i++)
        entry->char_offset[i] += offset;
     }
 
-  entry->text_length += new_text_length;
-  entry->nchars += insertion_chars;
+  entry->text_length += insertion_length;
   *position = end_pos;
 
+  entry->text_mb_dirty = 1;
   gtk_entry_queue_draw (entry);
 }
 
@@ -1750,64 +1745,30 @@ gtk_entry_recompute_offsets (GtkEntry *entry)
   gint i;
   gint offset = 0;
 
-  for (i=0; i<entry->nchars; i++)
+  for (i=0; i<entry->text_length; i++)
     {
       entry->char_offset[i] = offset;
       if (entry->visible)
        {
-         offset += gdk_text_width (GTK_WIDGET (entry)->style->font,
-                                   entry->text + entry->char_pos[i],
-                                   entry->char_pos[i+1] - entry->char_pos[i]);
+         offset += gdk_char_width_wc (GTK_WIDGET (entry)->style->font,
+                                      entry->text[i]);
        }
       else
        {
-         offset += gdk_text_width (GTK_WIDGET (entry)->style->font, "*", 1);
+         offset += gdk_char_width (GTK_WIDGET (entry)->style->font, '*');
        }
     }
 
   entry->char_offset[i] = offset;
 }
 
-/* Given a position in the entry, find the character index of the
- * last character with position <= the given position
- */
-static gint
-gtk_entry_find_char (GtkEntry *entry, gint position)
-{
-  gint start = 0;
-  gint end = entry->nchars;
-  gint half;
-
-  if (position >= entry->char_pos[end])
-    return end;
-  if (position < 0)
-    return 0;
-  
-  /* invariant - char_pos[start] <= position < char_pos[end] */
-
-  while (start != end)
-    {
-      half = (start+end)/2;
-      if (half == start)
-       return half;
-      else if (entry->char_pos[half] <= position)
-       start = half;
-      else
-       end = half;
-    }
-
-  return start;
-}
-
 static void
 gtk_entry_delete_text (GtkEditable *editable,
                       gint         start_pos,
                       gint         end_pos)
 {
-  gchar *text;
+  GdkWChar *text;
   gint deletion_length;
-  gint start_char;
-  gint end_char;
   gint i;
 
   GtkEntry *entry;
@@ -1820,11 +1781,6 @@ gtk_entry_delete_text (GtkEditable *editable,
   if (end_pos < 0)
     end_pos = entry->text_length;
 
-  start_char = gtk_entry_find_char (entry, start_pos);
-  end_char = gtk_entry_find_char (entry, end_pos);
-  start_pos = entry->char_pos[start_char];
-  end_pos = entry->char_pos[end_char];
-
   if (editable->selection_start_pos > start_pos)
     editable->selection_start_pos -= MIN(end_pos, editable->selection_start_pos) - start_pos;
   if (editable->selection_end_pos > start_pos)
@@ -1841,10 +1797,10 @@ gtk_entry_delete_text (GtkEditable *editable,
       if (GTK_WIDGET_REALIZED (entry))
        {
          gint deletion_width = 
-           entry->char_offset[end_char] - entry->char_offset[start_char];
+           entry->char_offset[end_pos] - entry->char_offset[start_pos];
 
-         for (i = 0 ; i <= entry->nchars - end_char; i++)
-           entry->char_offset[start_char+i] = entry->char_offset[end_char+i] - deletion_width;
+         for (i = 0 ; i <= entry->text_length - end_pos; i++)
+           entry->char_offset[start_pos+i] = entry->char_offset[end_pos+i] - deletion_width;
        }
 
       for (i = end_pos; i < entry->text_length; i++)
@@ -1853,15 +1809,11 @@ gtk_entry_delete_text (GtkEditable *editable,
       for (i = entry->text_length - deletion_length; i < entry->text_length; i++)
         text[i] = '\0';
 
-      for (i = 0 ; i <= entry->nchars - end_char; i++)
-       entry->char_pos[start_char+i] = entry->char_pos[end_char+i] - deletion_length;
-
-      entry->nchars -= end_char - start_char;
-      
       entry->text_length -= deletion_length;
       editable->current_pos = start_pos;
     }
 
+  entry->text_mb_dirty = 1;
   gtk_entry_queue_draw (entry);
 }
 
@@ -1878,9 +1830,7 @@ gtk_entry_get_chars      (GtkEditable   *editable,
                          gint           start_pos,
                          gint           end_pos)
 {
-  gchar *retval;
   GtkEntry *entry;
-  gchar c;
   
   g_return_val_if_fail (editable != NULL, NULL);
   g_return_val_if_fail (GTK_IS_ENTRY (editable), NULL);
@@ -1895,14 +1845,27 @@ gtk_entry_get_chars      (GtkEditable   *editable,
 
   if (start_pos <= end_pos)
     {
-      c = entry->text[end_pos];
-      entry->text[end_pos] = '\0';
-      
-      retval = g_strdup (&entry->text[start_pos]);
-      
-      entry->text[end_pos] = c;
-      
-      return retval;
+      guchar *mbstr;
+      if (entry->use_wchar)
+       {
+         GdkWChar ch;
+         if (end_pos >= entry->text_size)
+           gtk_entry_grow_text(entry);
+         ch = entry->text[end_pos];
+         entry->text[end_pos] = 0;
+         mbstr = gdk_wcstombs (entry->text + start_pos);
+         entry->text[end_pos] = ch;
+         return (gchar *)mbstr;
+       }
+      else
+       {
+         gint i;
+         mbstr = g_new (gchar, end_pos - start_pos + 1);
+         for (i=0; i<end_pos-start_pos; i++)
+           mbstr[i] = entry->text[start_pos + i];
+         mbstr[i] = 0;
+         return (gchar *)mbstr;
+       }
     }
   else
     return NULL;
@@ -1913,47 +1876,16 @@ gtk_entry_move_cursor (GtkEditable *editable,
                       gint         x,
                       gint         y)
 {
-  gint len;
-
   GtkEntry *entry;
   entry = GTK_ENTRY (editable);
 
   /* Horizontal motion */
-  if (x > 0)
-    {
-      while (x-- != 0)
-       {
-         if (gtk_use_mb)
-           {
-             if (editable->current_pos < entry->text_length)
-               {
-                 len = mblen (entry->text+editable->current_pos, MB_CUR_MAX);
-                 editable->current_pos += (len>0)? len:1;
-               }
-         if (editable->current_pos > entry->text_length)
-           editable->current_pos = entry->text_length;
-           }
-         else
-           {
-             if (editable->current_pos < entry->text_length)
-               editable->current_pos ++;
-           }
-       }
-    }
-  else if (x < 0)
-    {
-      while (x++ != 0)
-       {
-         if (0 < editable->current_pos)
-           {
-             if (gtk_use_mb)
-               editable->current_pos = 
-                 entry->char_pos[gtk_entry_find_char (entry, editable->current_pos - 1)];
-             else
-               editable->current_pos--;
-           }
-       }
-    }
+  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 */
 }
@@ -1974,26 +1906,18 @@ static void
 gtk_entry_move_word (GtkEditable *editable,
                     gint         n)
 {
-  if (n > 0)
-    {
-      while (n-- != 0)
-       gtk_move_forward_word (GTK_ENTRY (editable));
-    }
-  else if (n < 0)
-    {
-      while (n++ != 0)
-       gtk_move_backward_word (GTK_ENTRY (editable));
-    }
+  while (n-- > 0)
+    gtk_move_forward_word (GTK_ENTRY (editable));
+  while (n++ < 0)
+    gtk_move_backward_word (GTK_ENTRY (editable));
 }
 
 static void
 gtk_move_forward_word (GtkEntry *entry)
 {
   GtkEditable *editable;
-  gchar *text;
+  GdkWChar *text;
   gint i;
-  wchar_t c;
-  gint len;
 
   editable = GTK_EDITABLE (entry);
 
@@ -2002,45 +1926,20 @@ gtk_move_forward_word (GtkEntry *entry)
       text = entry->text;
       i = editable->current_pos;
          
-      if (gtk_use_mb)
+      if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
+       for (; i < entry->text_length; i++)
+         {
+           if ((entry->use_wchar) ? gdk_iswalnum (text[i]) : isalnum (text[i]))
+             break;
+         }
+
+      for (; i < entry->text_length; i++)
        {
-         len = mbtowc (&c, text+i, MB_CUR_MAX);
-         if (!iswalnum(c))
-           for (; i < entry->text_length; i+=len)
-             {
-               len = mbtowc (&c, text+i, MB_CUR_MAX);
-               if (len < 1 || iswalnum(c))
-                 break;
-             }
-         
-         for (; i < entry->text_length; i+=len)
-           {
-             len = mbtowc (&c, text+i, MB_CUR_MAX);
-             if (len < 1 || !iswalnum(c))
-               break;
-           }
-         
-         editable->current_pos = i;
-         if (editable->current_pos > entry->text_length)
-           editable->current_pos = entry->text_length;
+         if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
+           break;
        }
-      else
-       {
-         if (!isalnum (text[i]))
-           for (; i < entry->text_length; i++)
-             {
-               if (isalnum(text[i]))
-                 break;
-             }
-         
-         for (; i < entry->text_length; i++)
-           {
-             if (!isalnum(text[i]))
-               break;
-           }
 
-         editable->current_pos = i;
-       }
+      editable->current_pos = i;
     }
 }
 
@@ -2048,70 +1947,34 @@ static void
 gtk_move_backward_word (GtkEntry *entry)
 {
   GtkEditable *editable;
-  gchar *text;
+  GdkWChar *text;
   gint i;
-  wchar_t c;
 
   editable = GTK_EDITABLE (entry);
 
   if (entry->text && editable->current_pos > 0)
     {
       text = entry->text;
-
-      if (gtk_use_mb)
+      i = editable->current_pos - 1;
+      if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
+       for (; i >= 0; i--)
+         {
+           if ((entry->use_wchar) ? gdk_iswalnum (text[i]) : isalnum (text[i]))
+             break;
+         }
+      for (; i >= 0; i--)
        {
-         i = gtk_entry_find_char (entry, editable->current_pos - 1);
-         
-         mbtowc (&c, text+entry->char_pos[i], MB_CUR_MAX);
-         if (!iswalnum(c))
-           for (; i >= 0; i--)
-             {
-               mbtowc (&c, text+entry->char_pos[i], MB_CUR_MAX);
-               if (iswalnum(c))
-                 break;
-             }
-         
-         for (; i >= 0; i--)
+         if ((entry->use_wchar) ? (!gdk_iswalnum (text[i])) : (!isalnum (text[i])))
            {
-             mbtowc (&c, text+entry->char_pos[i], MB_CUR_MAX);
-             if (!iswalnum(c))
-               {
-                 i++;
-                 break;
-               }
+             i++;
+             break;
            }
-
-         if (i < 0)
-           i = 0;
-         
-         editable->current_pos = entry->char_pos[i];
        }
-      else
-       {
-         i = editable->current_pos - 1;
-         
-         if (!isalnum(text[i]))
-           for (; i >= 0; i--)
-             {
-               if (isalnum(text[i]))
-                 break;
-             }
-         
-         for (; i >= 0; i--)
-           {
-             if (!isalnum(text[i]))
-               {
-                 i++;
-                 break;
-               }
-           }
          
-         if (i < 0)
-           i = 0;
+      if (i < 0)
+       i = 0;
          
-         editable->current_pos = i;
-       }
-        
+      editable->current_pos = i;
     }
 }
 
@@ -2122,10 +1985,10 @@ gtk_entry_move_to_column (GtkEditable *editable, gint column)
 
   entry = GTK_ENTRY (editable);
   
-  if (column < 0 || column > entry->nchars)
+  if (column < 0 || column > entry->text_length)
     editable->current_pos = entry->text_length;
   else
-    editable->current_pos = entry->char_pos[column];
+    editable->current_pos = column;
 }
 
 static void
@@ -2311,6 +2174,45 @@ gtk_entry_set_max_length (GtkEntry     *entry,
   entry->text_max_length = max;
 }
 
+#ifdef USE_XIM
+static void
+gtk_entry_update_ic_attr (GtkWidget *widget)
+{
+  GtkEditable *editable = (GtkEditable *) widget;
+  GdkICAttributesType mask = 0;
+
+  gdk_ic_get_attr (editable->ic, editable->ic_attr,
+                  GDK_IC_PREEDIT_FOREGROUND |
+                  GDK_IC_PREEDIT_BACKGROUND |
+                  GDK_IC_PREEDIT_FONTSET);
+
+  if (editable->ic_attr->preedit_foreground.pixel != 
+      widget->style->fg[GTK_STATE_NORMAL].pixel)
+    {
+      mask |= GDK_IC_PREEDIT_FOREGROUND;
+      editable->ic_attr->preedit_foreground
+       = widget->style->fg[GTK_STATE_NORMAL];
+    }
+  if (editable->ic_attr->preedit_background.pixel != 
+      widget->style->base[GTK_STATE_NORMAL].pixel)
+    {
+      mask |= GDK_IC_PREEDIT_BACKGROUND;
+      editable->ic_attr->preedit_background
+       = widget->style->base[GTK_STATE_NORMAL];
+    }
+  if ((gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION) && 
+      !gdk_font_equal (editable->ic_attr->preedit_fontset,
+                      widget->style->font))
+    {
+      mask |= GDK_IC_PREEDIT_FONTSET;
+      editable->ic_attr->preedit_fontset = widget->style->font;
+    }
+  
+  if (mask)
+    gdk_ic_set_attr (editable->ic, editable->ic_attr, mask);
+}
+#endif /* USE_XIM */
+                         
 static void 
 gtk_entry_style_set    (GtkWidget      *widget,
                         GtkStyle       *previous_style)
@@ -2332,6 +2234,10 @@ gtk_entry_style_set      (GtkWidget      *widget,
 
       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)]);
+
+#ifdef USE_XIM
+      gtk_entry_update_ic_attr (widget);
+#endif
     }
 
   if (GTK_WIDGET_DRAWABLE (widget))
@@ -2349,6 +2255,10 @@ gtk_entry_state_changed (GtkWidget      *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)]);
+
+#ifdef USE_XIM
+      gtk_entry_update_ic_attr (widget);
+#endif
     }
 
   if (GTK_WIDGET_DRAWABLE (widget))
index a487c5e56b79648fc11d151d72e26d956b4b65a4..c1b6f9065222196c9970edf7769a137b4f62492d 100644 (file)
@@ -46,26 +46,27 @@ struct _GtkEntry
   GdkWindow *text_area;
   GdkPixmap *backing_pixmap;
   GdkCursor *cursor;
-  gchar *text;
+  GdkWChar  *text;
 
-  guint16 text_size;
-  guint16 text_length;
+  guint16 text_size;   /* allocated size */
+  guint16 text_length; /* length in use */
   guint16 text_max_length;
   gint    scroll_offset;
   guint   visible : 1;
   guint32 timer;
   guint   button;
 
-  /* The total number of characters (not bytes) in the entry */
-  guint nchars;
-
-  /* The byte offset of each character 
-   *  (including the last insertion position) */
-  guint16 *char_pos;
-
   /* The x-offset of each character (including the last insertion position)
    * only valid when the widget is realized */
-  gint *char_offset;
+  gint   *char_offset;
+
+  /* Same as 'text', but in multibyte */
+  gchar  *text_mb;
+  /* If true, 'text' and 'text_mb' are not coherent */
+  guint   text_mb_dirty : 1;
+  /* If true, we use the encoding of wchar_t as the encoding of 'text'.
+   * Otherwise we use the encoding of multi-byte characters instead. */
+  guint   use_wchar : 1;
 };
 
 struct _GtkEntryClass
@@ -75,7 +76,7 @@ struct _GtkEntryClass
 
 GtkType    gtk_entry_get_type                  (void);
 GtkWidget* gtk_entry_new                       (void);
-GtkWidget* gtk_entry_new_with_max_length       (guint16   max);
+GtkWidget* gtk_entry_new_with_max_length       (guint16       max);
 void       gtk_entry_set_text                  (GtkEntry      *entry,
                                                 const gchar   *text);
 void       gtk_entry_append_text               (GtkEntry      *entry,
@@ -84,6 +85,7 @@ 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,
index 2f3d58b073af7929b9f40f02d78b940aad8e85bc..cabdf87e7dd90da34cba429d243c20d1b002618e 100644 (file)
@@ -248,15 +248,12 @@ gtk_check_version (guint required_major,
 }
 
 
-gint gtk_use_mb = -1;
-
 void
 gtk_init (int   *argc,
          char ***argv)
 {
   GSList *gtk_modules = NULL;
   GSList *slist;
-  gchar *current_locale;
   gchar *env_string = NULL;
 
   if (gtk_initialized)
@@ -397,42 +394,6 @@ gtk_init (int       *argc,
        }
     }
   
-  /* Check if there is a good chance the mb functions will handle things
-   * correctly - set if either mblen("\xc0", MB_CUR_MAX) == 1 in the
-   * C locale, or we're using X's mb functions. (-DX_LOCALE && locale != C)
-   */
-  current_locale = setlocale (LC_CTYPE, NULL);
-
-#ifdef X_LOCALE
-  if ((strcmp (current_locale, "C")) && (strcmp (current_locale, "POSIX")))
-    gtk_use_mb = TRUE;
-  else
-#endif /* X_LOCALE */
-    {
-      /* Detect GNU libc, where mb == UTF8. Not useful unless it's
-       * really a UTF8 locale. The below still probably will
-       * screw up on Greek, Cyrillic, etc, encoded as UTF8.
-       */
-      
-      wchar_t result;
-      gtk_use_mb = TRUE;
-      
-      if ((MB_CUR_MAX == 2) &&
-         (mbstowcs (&result, "\xdd\xa5", 1) > 0) &&
-         result == 0x765)
-       {
-         if ((strlen (current_locale) < 4) ||
-             g_strcasecmp (current_locale + strlen(current_locale) - 4, "utf8"))
-           gtk_use_mb = FALSE;
-       }
-    }
-
-  GTK_NOTE (MISC,
-           g_message ("%s multi-byte string functions.", 
-                      gtk_use_mb ? "Using" : "Not using"));
-
-
   /* load gtk modules */
   gtk_modules = g_slist_reverse (gtk_modules);
   for (slist = gtk_modules; slist; slist = slist->next)
index 9ec6863478e3f4a2d6b47da7e24efce8cc4be26d..a71cd73161bf0900f155b4713ec9956369deb689 100644 (file)
@@ -60,12 +60,6 @@ typedef enum
 #define GTK_PRIVATE_SET_FLAG(wid,flag)    G_STMT_START{ (GTK_PRIVATE_FLAGS (wid) |= (PRIVATE_ ## flag)); }G_STMT_END
 #define GTK_PRIVATE_UNSET_FLAG(wid,flag)  G_STMT_START{ (GTK_PRIVATE_FLAGS (wid) &= ~(PRIVATE_ ## flag)); }G_STMT_END
 
-/* True if there is a good chance the mb functions will handle things
- * correctly - set if either mblen("\xc0", MB_CUR_MAX) == 1 in the
- * C locale, or were using X's mb functions. (-DX_LOCALE && locale != C)
- */
-extern gint gtk_use_mb;
-
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
index 1307119235b330d0ed5bd0d8045ccace1532daee..e806f85704842478267f946954afe51cfcde315c 100644 (file)
@@ -1182,8 +1182,11 @@ gtk_spin_button_insert_text (GtkEditable *editable,
       gboolean sign;
       gint dotpos = -1;
       gint i;
-      gchar pos_sign;
-      gchar neg_sign;
+      GdkWChar pos_sign;
+      GdkWChar neg_sign;
+      guint entry_length;
+
+      entry_length = entry->text_length;
 
       lc = localeconv ();
 
@@ -1197,16 +1200,27 @@ gtk_spin_button_insert_text (GtkEditable *editable,
       else 
        pos_sign = '+';
 
-      sign = ((strchr (entry->text, neg_sign) != 0) ||
-             (strchr (entry->text, pos_sign) != 0));
+      for (sign=0, i=0; i<entry_length; i++)
+       if ((entry->text[i] == neg_sign) ||
+           (entry->text[i] == pos_sign))
+         {
+           sign = 1;
+           break;
+         }
 
       if (sign && !(*position))
        return;
 
-      dotpos = strchr (entry->text, *(lc->decimal_point)) - entry->text;
-      
+      for (dotpos=-1, i=0; i<entry_length; i++)
+       if (entry->text[i] == *(lc->decimal_point))
+         {
+           dotpos = i;
+           break;
+         }
+
       if (dotpos > -1 && *position > dotpos &&
-         spin->digits - entry->text_length + dotpos - new_text_length + 1 < 0)
+         spin->digits - entry_length
+           + dotpos - new_text_length + 1 < 0)
        return;
 
       for (i = 0; i < new_text_length; i++)
@@ -1220,8 +1234,8 @@ gtk_spin_button_insert_text (GtkEditable *editable,
          else if (new_text[i] == *(lc->decimal_point))
            {
              if (!spin->digits || dotpos > -1 || 
-                 (new_text_length - 1 - i + entry->text_length - *position > 
-                  spin->digits)) 
+                 (new_text_length - 1 - i + entry_length
+                   - *position > spin->digits)) 
                return;
              dotpos = *position + i;
            }
index 18281ccd185b2a9f8983a22879f567c5d96e209d..0a993a2fd2a18b9221c6716fcae56a8eea5a50fe 100644 (file)
@@ -19,9 +19,7 @@
 #include <ctype.h>
 #include <string.h>
 #include "gdk/gdkkeysyms.h"
-#ifdef USE_XIM
-#include "gdk/gdkx.h"
-#endif
+#include "gdk/gdki18n.h"
 #include "gtkmain.h"
 #include "gtkselection.h"
 #include "gtksignal.h"
@@ -248,7 +246,7 @@ static gint  gtk_text_focus_in          (GtkWidget         *widget,
 static gint  gtk_text_focus_out         (GtkWidget         *widget,
                                         GdkEventFocus     *event);
 
-static void move_gap_to_point (GtkText* text);
+static void move_gap (GtkText* text, guint index);
 static void make_forward_space (GtkText* text, guint len);
 
 /* Property management */
@@ -674,9 +672,13 @@ gtk_text_init (GtkText *text)
   text->line_wrap_bitmap = NULL;
   text->line_arrow_bitmap = NULL;
   
-  text->text = g_new (guchar, INITIAL_BUFFER_SIZE);
+  text->use_wchar = FALSE;
+  text->text.ch = g_new (guchar, INITIAL_BUFFER_SIZE);
   text->text_len = INITIAL_BUFFER_SIZE;
-
+  text->scratch_buffer.ch = NULL;
+  text->scratch_buffer_len = 0;
   text->freeze_count = 0;
   
   if (!params_mem_chunk)
@@ -921,6 +923,7 @@ gtk_text_insert (GtkText    *text,
   guint old_height = 0;
   guint length;
   guint i;
+  gint numwcs;
   
   g_return_if_fail (text != NULL);
   g_return_if_fail (GTK_IS_TEXT (text));
@@ -943,37 +946,90 @@ gtk_text_insert (GtkText    *text,
     {
       find_line_containing_point (text, text->point.index, TRUE);
       old_height = total_line_height (text, text->current_line, 1);
-      for (i=0; i<length; i++)
-       if (chars[i] == '\n')
-         new_line_count++;
     }
   
-  if (text->point.index < text->first_line_start_index)
-    text->first_line_start_index += length;
-  
-  if (text->point.index < editable->selection_start_pos)
-    editable->selection_start_pos += length;
-  if (text->point.index < editable->selection_end_pos)
-    editable->selection_end_pos += length;
-  /* We'll reset the cursor later anyways if we aren't frozen */
-  if (text->point.index < text->cursor_mark.index)
-    text->cursor_mark.index += length;
-  
-  move_gap_to_point (text);
-
+  if ((TEXT_LENGTH (text) == 0) && (text->use_wchar == FALSE))
+    {
+      GtkWidget *widget;
+      widget = GTK_WIDGET (text);
+      gtk_widget_ensure_style (widget);
+      if ((widget->style) && (widget->style->font->type == GDK_FONT_FONTSET))
+       {
+         text->use_wchar = TRUE;
+         g_free (text->text.ch);
+         text->text.wc = g_new (GdkWChar, INITIAL_BUFFER_SIZE);
+         text->text_len = INITIAL_BUFFER_SIZE;
+         if (text->scratch_buffer.ch)
+           g_free (text->scratch_buffer.ch);
+         text->scratch_buffer.wc = NULL;
+         text->scratch_buffer_len = 0;
+       }
+    }
+  move_gap (text, text->point.index);
   make_forward_space (text, length);
-  memcpy (text->text + text->gap_position, chars, length);
-  
-  insert_text_property (text, font, fore, back, length);
-  
-  text->gap_size -= length;
-  text->gap_position += length;
-  
-  advance_mark_n (&text->point, length);
+  if (text->use_wchar)
+    {
+      char *chars_nt = (char *)chars;
+      if (nchars > 0)
+       {
+         chars_nt = g_new (char, length+1);
+         memcpy (chars_nt, chars, length);
+         chars_nt[length] = 0;
+       }
+      numwcs = gdk_mbstowcs (text->text.wc + text->gap_position, chars_nt,
+                            length);
+      if (chars_nt != chars)
+       g_free(chars_nt);
+      if (numwcs < 0)
+       numwcs = 0;
+    }
+  else
+    {
+      numwcs = length;
+      memcpy(text->text.ch + text->gap_position, chars, length);
+    }
+  if (!text->freeze_count && (text->line_start_cache != NULL))
+    {
+      if (text->use_wchar)
+       {
+         for (i=0; i<numwcs; i++)
+           if (text->text.wc[text->gap_position + i] == '\n')
+             new_line_count++;
+       }
+      else
+       {
+         for (i=0; i<numwcs; i++)
+           if (text->text.ch[text->gap_position + i] == '\n')
+             new_line_count++;
+       }
+    }
+  if (numwcs > 0)
+    {
+      insert_text_property (text, font, fore, back, numwcs);
+   
+      text->gap_size -= numwcs;
+      text->gap_position += numwcs;
+   
+      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;
+      /* 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;
   
-  if (!text->freeze_count && text->line_start_cache != NULL)
-    insert_expose (text, old_height, length, new_line_count);
+      advance_mark_n (&text->point, numwcs);
   
+      if (!text->freeze_count && (text->line_start_cache != NULL))
+       insert_expose (text, old_height, numwcs, new_line_count);
+    }
+
   if (frozen)
     gtk_text_thaw (text);
 }
@@ -1030,7 +1086,8 @@ gtk_text_forward_delete (GtkText *text,
        {
          text->first_line_start_index = text->point.index;
          while ((text->first_line_start_index > 0) &&
-                (GTK_TEXT_INDEX (text, text->first_line_start_index - 1) != LINE_DELIM))
+                (GTK_TEXT_INDEX (text, text->first_line_start_index - 1)
+                 != LINE_DELIM))
            text->first_line_start_index -= 1;
          
        }
@@ -1049,7 +1106,7 @@ gtk_text_forward_delete (GtkText *text,
     move_mark_n (&text->cursor_mark, 
                 -MIN(nchars, text->cursor_mark.index - text->point.index));
   
-  move_gap_to_point (text);
+  move_gap (text, text->point.index);
   
   text->gap_size += nchars;
   
@@ -1086,10 +1143,8 @@ gtk_text_get_chars (GtkEditable   *editable,
                    gint           end_pos)
 {
   GtkText *text;
-  
+
   gchar *retval;
-  gchar *p;
-  guint n, nchars;
   
   g_return_val_if_fail (editable != NULL, NULL);
   g_return_val_if_fail (GTK_IS_TEXT (editable), NULL);
@@ -1103,31 +1158,26 @@ gtk_text_get_chars (GtkEditable   *editable,
       (end_pos < start_pos))
     return NULL;
   
-  nchars = end_pos - start_pos;
-  
-  retval = g_new (gchar, nchars+1);
-  p = retval;
-  
-  if (start_pos < text->gap_position) 
+  move_gap (text, TEXT_LENGTH (text));
+  make_forward_space (text, 1);
+
+  if (text->use_wchar)
     {
-      n = MIN (text->gap_position - start_pos, nchars);
-      memcpy (p, &text->text[start_pos], n);
-      p += n;
-      start_pos += n;
-      nchars -= n;
+      GdkWChar ch;
+      ch = text->text.wc[end_pos];
+      text->text.wc[end_pos] = 0;
+      retval = gdk_wcstombs (text->text.wc + start_pos);
+      text->text.wc[end_pos] = ch;
     }
-  
-  if (start_pos+nchars >= text->gap_position)
+  else
     {
-      memcpy (p, 
-             text->text + MAX (text->gap_position + text->gap_size, 
-                               start_pos + text->gap_size),
-             nchars);
-      p += nchars;
+      guchar ch;
+      ch = text->text.ch[end_pos];
+      text->text.ch[end_pos] = 0;
+      retval = g_strdup (text->text.ch + start_pos);
+      text->text.ch[end_pos] = ch;
     }
-  
-  *p = 0;
-  
+
   return retval;
 }
 
@@ -1169,7 +1219,10 @@ gtk_text_finalize (GtkObject *object)
   gtk_object_unref (GTK_OBJECT (text->vadj));
 
   /* Clean up the internal structures */
-  g_free (text->text);
+  if (text->use_wchar)
+    g_free (text->text.wc);
+  else
+    g_free (text->text.ch);
   free_cache (text);
   
   tmp_list = text->text_properties;
@@ -1184,8 +1237,16 @@ gtk_text_finalize (GtkObject *object)
   
   g_list_free (text->text_properties);
   
-  if (text->scratch_buffer)
-    g_free (text->scratch_buffer);
+  if (text->use_wchar)
+    {
+      if (text->scratch_buffer.wc)
+       g_free (text->scratch_buffer.wc);
+    }
+  else
+    {
+      if (text->scratch_buffer.ch)
+       g_free (text->scratch_buffer.ch);
+    }
   
   g_list_free (text->tab_stops);
   
@@ -1257,12 +1318,13 @@ gtk_text_realize (GtkWidget *widget)
   gdk_gc_set_foreground (text->gc, &widget->style->text[GTK_STATE_NORMAL]);
   
 #ifdef USE_XIM
-  if (gdk_im_ready ())
+  if (gdk_im_ready () && (editable->ic_attr = gdk_ic_attr_new ()) != NULL)
     {
-      GdkPoint spot;
-      GdkRectangle rect;
       gint width, height;
+      GdkColormap *colormap;
       GdkEventMask mask;
+      GdkICAttr *attr = editable->ic_attr;
+      GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
       GdkIMStyle style;
       GdkIMStyle supported_style = GDK_IM_PREEDIT_NONE | 
                                   GDK_IM_PREEDIT_NOTHING |
@@ -1273,7 +1335,16 @@ gtk_text_realize (GtkWidget *widget)
       if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
        supported_style &= ~GDK_IM_PREEDIT_POSITION;
       
-      style = gdk_im_decide_style (supported_style);
+      attr->style = style = gdk_im_decide_style (supported_style);
+      attr->client_window = text->text_area;
+
+      if ((colormap = gtk_widget_get_colormap (widget)) !=
+         gtk_widget_get_default_colormap ())
+       {
+         attrmask |= GDK_IC_PREEDIT_COLORMAP;
+         attr->preedit_colormap = colormap;
+       }
+
       switch (style & GDK_IM_PREEDIT_MASK)
        {
        case GDK_IM_PREEDIT_POSITION:
@@ -1282,43 +1353,31 @@ gtk_text_realize (GtkWidget *widget)
              g_warning ("over-the-spot style requires fontset");
              break;
            }
+
+         attrmask |= GDK_IC_PREEDIT_POSITION_REQ;
          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;
+         attr->spot_location.x = 0;
+         attr->spot_location.y = height;
+         attr->preedit_area.x = 0;
+         attr->preedit_area.y = 0;
+         attr->preedit_area.width = width;
+         attr->preedit_area.height = height;
+         attr->preedit_fontset = widget->style->font;
          
-         editable->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:
-         editable->ic = gdk_ic_new (text->text_area, text->text_area,
-                                    style, NULL);
        }
+      editable->ic = gdk_ic_new (attr, attrmask);
       
       if (editable->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 (editable->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 (editable->ic, "preeditAttributes",
-                              "colorMap", GDK_COLORMAP_XCOLORMAP (colormap),
-                              NULL);
-           }
+         if (GTK_WIDGET_HAS_FOCUS (widget))
+           gdk_im_begin (editable->ic, text->text_area);
        }
     }
 #endif
@@ -1368,7 +1427,20 @@ gtk_text_unrealize (GtkWidget *widget)
   g_return_if_fail (GTK_IS_TEXT (widget));
   
   text = GTK_TEXT (widget);
-  
+
+#ifdef USE_XIM
+  if (GTK_EDITABLE (widget)->ic)
+    {
+      gdk_ic_destroy (GTK_EDITABLE (widget)->ic);
+      GTK_EDITABLE (widget)->ic = NULL;
+    }
+  if (GTK_EDITABLE (widget)->ic_attr)
+    {
+      gdk_ic_attr_destroy (GTK_EDITABLE (widget)->ic_attr);
+      GTK_EDITABLE (widget)->ic_attr = NULL;
+    }
+#endif
+
   gdk_window_set_user_data (text->text_area, NULL);
   gdk_window_destroy (text->text_area);
   text->text_area = NULL;
@@ -1569,14 +1641,13 @@ gtk_text_size_allocate (GtkWidget     *widget,
       if (editable->ic && (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
        {
          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 (editable->ic, "preeditAttributes", "area", &rect, NULL);
+         editable->ic_attr->preedit_area.width = width;
+         editable->ic_attr->preedit_area.height = height;
+
+         gdk_ic_set_attr (editable->ic,
+                          editable->ic_attr, GDK_IC_PREEDIT_AREA);
        }
 #endif
       
@@ -2095,12 +2166,9 @@ gtk_text_key_press (GtkWidget   *widget,
            {
              extend_selection = FALSE;
              
-             if (event->length == 1)
-               {
-                 gtk_editable_delete_selection (editable);
-                 position = text->point.index;
-                 gtk_editable_insert_text (editable, &(event->string[0]), 1, &position);
-               }
+             gtk_editable_delete_selection (editable);
+             position = text->point.index;
+             gtk_editable_insert_text (editable, event->string, event->length, &position);
              
              return_val = TRUE;
            }
@@ -3023,27 +3091,37 @@ destroy_text_property (TextProperty *prop)
 /* Flop the memory between the point and the gap around like a
  * dead fish. */
 static void
-move_gap_to_point (GtkText* text)
+move_gap (GtkText* text, guint index)
 {
-  if (text->gap_position < text->point.index)
+  if (text->gap_position < index)
     {
-      gint diff = text->point.index - text->gap_position;
+      gint diff = index - text->gap_position;
       
-      g_memmove (text->text + text->gap_position,
-                text->text + text->gap_position + text->gap_size,
-                diff);
+      if (text->use_wchar)
+       g_memmove (text->text.wc + text->gap_position,
+                  text->text.wc + text->gap_position + text->gap_size,
+                  diff*sizeof (GdkWChar));
+      else
+       g_memmove (text->text.ch + text->gap_position,
+                  text->text.ch + text->gap_position + text->gap_size,
+                  diff);
       
-      text->gap_position = text->point.index;
+      text->gap_position = index;
     }
-  else if (text->gap_position > text->point.index)
+  else if (text->gap_position > index)
     {
-      gint diff = text->gap_position - text->point.index;
+      gint diff = text->gap_position - index;
       
-      g_memmove (text->text + text->point.index + text->gap_size,
-                text->text + text->point.index,
-                diff);
+      if (text->use_wchar)
+       g_memmove (text->text.wc + index + text->gap_size,
+                  text->text.wc + index,
+                  diff*sizeof (GdkWChar));
+      else
+       g_memmove (text->text.ch + index + text->gap_size,
+                  text->text.ch + index,
+                  diff);
       
-      text->gap_position = text->point.index;
+      text->gap_position = index;
     }
 }
 
@@ -3061,12 +3139,23 @@ make_forward_space (GtkText* text, guint len)
          
          while (i <= sum) i <<= 1;
          
-         text->text = (guchar*)g_realloc(text->text, i);
+         if (text->use_wchar)
+           text->text.wc = (GdkWChar *)g_realloc(text->text.wc,
+                                                 i*sizeof(GdkWChar));
+         else
+           text->text.ch = (guchar *)g_realloc(text->text.ch, i);
+         text->text_len = i;
        }
       
-      g_memmove (text->text + text->gap_position + text->gap_size + 2*len,
-                text->text + text->gap_position + text->gap_size,
-                text->text_end - (text->gap_position + text->gap_size));
+      if (text->use_wchar)
+       g_memmove (text->text.wc + text->gap_position + text->gap_size + 2*len,
+                  text->text.wc + text->gap_position + text->gap_size,
+                  (text->text_end - (text->gap_position + text->gap_size))
+                  *sizeof(GdkWChar));
+      else
+       g_memmove (text->text.ch + text->gap_position + text->gap_size + 2*len,
+                  text->text.ch + text->gap_position + text->gap_size,
+                  text->text_end - (text->gap_position + text->gap_size));
       
       text->text_end += len*2;
       text->gap_size += len*2;
@@ -3498,8 +3587,8 @@ find_line_containing_point (GtkText* text, guint point,
          ( (text->first_cut_pixels == 0) &&
            (CACHE_DATA(text->line_start_cache).start.index > point) ) )
     {
-      scroll_int (text, - SCROLL_PIXELS);
       g_assert (text->line_start_cache->next);
+      scroll_int (text, - LINE_HEIGHT(CACHE_DATA(text->line_start_cache->next)));
     }
   
   TEXT_SHOW (text);
@@ -3567,7 +3656,7 @@ pixel_height_of (GtkText* text, GList* cache_line)
 static gint
 find_char_width (GtkText* text, const GtkPropertyMark *mark, const TabStopMark *tab_mark)
 {
-  gchar ch;
+  GdkWChar ch;
   gint16* char_widths;
   
   if (LAST_INDEX (text, *mark))
@@ -3580,14 +3669,18 @@ find_char_width (GtkText* text, const GtkPropertyMark *mark, const TabStopMark *
     {
       return tab_mark->to_next_tab * char_widths[' '];
     }
+  else if (ch < 256)
+    {
+      return char_widths[ch];
+    }
   else
     {
-      return char_widths[ch & 0xff];
+      return gdk_char_width_wc(MARK_CURRENT_TEXT_FONT(text, mark)->gdk_font, ch);
     }
 }
 
 static void
-advance_tab_mark (GtkText* text, TabStopMark* tab_mark, gchar ch)
+advance_tab_mark (GtkText* text, TabStopMark* tab_mark, GdkWChar ch)
 {
   if (tab_mark->to_next_tab == 1 || ch == '\t')
     {
@@ -3618,7 +3711,7 @@ advance_tab_mark_n (GtkText* text, TabStopMark* tab_mark, gint n)
 static void
 find_cursor_at_line (GtkText* text, const LineParams* start_line, gint pixel_height)
 {
-  gchar ch;
+  GdkWChar ch;
   GtkEditable *editable = (GtkEditable *)text;
   
   GtkPropertyMark mark        = start_line->start;
@@ -3641,30 +3734,32 @@ find_cursor_at_line (GtkText* text, const LineParams* start_line, gint pixel_hei
   ch = LAST_INDEX (text, mark) ? 
     LINE_DELIM : GTK_TEXT_INDEX (text, mark.index);
   
-  if (!isspace(ch))
-    text->cursor_char = ch;
-  else
+  if ((text->use_wchar) ? gdk_iswspace (ch) : isspace (ch))
     text->cursor_char = 0;
-  
+  else
+    text->cursor_char = ch;
+    
 #ifdef USE_XIM
-  if (gdk_im_ready() && editable->ic && 
-      gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION)
+  if (GTK_WIDGET_HAS_FOCUS(text) && gdk_im_ready() && editable->ic && 
+      (gdk_ic_get_style (editable->ic) & GDK_IM_PREEDIT_POSITION))
     {
-      GdkPoint spot;
-      
-      spot.x = text->cursor_pos_x;
-      spot.y = text->cursor_pos_y - text->cursor_char_offset;
+      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
+       = 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);
+
       if (MARK_CURRENT_FONT (text, &mark)->type == GDK_FONT_FONTSET)
-       gdk_ic_set_attr (editable->ic, "preeditAttributes", 
-                        "fontSet", GDK_FONT_XFONT (MARK_CURRENT_FONT (text, &mark)),
-                        NULL);
+       {
+         mask |= GDK_IC_PREEDIT_FONTSET;
+         editable->ic_attr->preedit_fontset = MARK_CURRENT_FONT (text, &mark);
+       }
       
-      gdk_ic_set_attr (editable->ic, "preeditAttributes", 
-                      "spotLocation", &spot,
-                      "lineSpace", LINE_HEIGHT (*start_line),
-                      "foreground", MARK_CURRENT_FORE (text, &mark)->pixel,
-                      "background", MARK_CURRENT_BACK (text, &mark)->pixel,
-                      NULL);
+      gdk_ic_set_attr (editable->ic, editable->ic_attr, mask);
     }
 #endif 
 }
@@ -3700,7 +3795,7 @@ find_mouse_cursor_at_line (GtkText *text, const LineParams* lp,
   
   for (;;)
     {
-      gchar ch = LAST_INDEX (text, mark) ? 
+      GdkWChar ch = LAST_INDEX (text, mark) ? 
        LINE_DELIM : GTK_TEXT_INDEX (text, mark.index);
       
       if (button_x < pixel_width || mark.index == lp->end.index)
@@ -3709,10 +3804,10 @@ find_mouse_cursor_at_line (GtkText *text, const LineParams* lp,
          text->cursor_mark        = mark;
          text->cursor_char_offset = lp->font_descent;
          
-         if (!isspace(ch))
-           text->cursor_char = ch;
-         else
+         if ((text->use_wchar) ? gdk_iswspace (ch) : isspace (ch))
            text->cursor_char = 0;
+         else
+           text->cursor_char = ch;
          
          break;
        }
@@ -3872,7 +3967,8 @@ move_cursor_ver (GtkText *text, int count)
     }
   
   for (i=0; i < text->cursor_virtual_x; i += 1, advance_mark(&mark))
-    if (LAST_INDEX(text, mark) || GTK_TEXT_INDEX(text, mark.index) == LINE_DELIM)
+    if (LAST_INDEX(text, mark) ||
+       GTK_TEXT_INDEX(text, mark.index) == LINE_DELIM)
       break;
   
   undraw_cursor (text, FALSE);
@@ -3979,13 +4075,26 @@ gtk_text_move_forward_word (GtkText *text)
   
   undraw_cursor (text, FALSE);
   
-  while (!LAST_INDEX (text, text->cursor_mark) && 
-        !isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
-    advance_mark (&text->cursor_mark);
-  
-  while (!LAST_INDEX (text, text->cursor_mark) && 
-        isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
-    advance_mark (&text->cursor_mark);
+  if (text->use_wchar)
+    {
+      while (!LAST_INDEX (text, text->cursor_mark) && 
+            !gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
+       advance_mark (&text->cursor_mark);
+      
+      while (!LAST_INDEX (text, text->cursor_mark) && 
+            gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
+       advance_mark (&text->cursor_mark);
+    }
+  else
+    {
+      while (!LAST_INDEX (text, text->cursor_mark) && 
+            !isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
+       advance_mark (&text->cursor_mark);
+      
+      while (!LAST_INDEX (text, text->cursor_mark) && 
+            isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index)))
+       advance_mark (&text->cursor_mark);
+    }
   
   find_cursor (text, TRUE);
   draw_cursor (text, FALSE);
@@ -3998,13 +4107,26 @@ gtk_text_move_backward_word (GtkText *text)
   
   undraw_cursor (text, FALSE);
   
-  while ((text->cursor_mark.index > 0) &&
-        !isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
-    decrement_mark (&text->cursor_mark);
-  
-  while ((text->cursor_mark.index > 0) &&
-        isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
-    decrement_mark (&text->cursor_mark);
+  if (text->use_wchar)
+    {
+      while ((text->cursor_mark.index > 0) &&
+            !gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
+       decrement_mark (&text->cursor_mark);
+      
+      while ((text->cursor_mark.index > 0) &&
+            gdk_iswalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
+       decrement_mark (&text->cursor_mark);
+    }
+  else
+    {
+      while ((text->cursor_mark.index > 0) &&
+            !isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
+       decrement_mark (&text->cursor_mark);
+      
+      while ((text->cursor_mark.index > 0) &&
+            isalnum (GTK_TEXT_INDEX(text, text->cursor_mark.index-1)))
+       decrement_mark (&text->cursor_mark);
+    }
   
   find_cursor (text, TRUE);
   draw_cursor (text, FALSE);
@@ -4544,7 +4666,7 @@ find_line_params (GtkText* text,
   LineParams lp;
   TabStopMark tab_mark = tab_cont->tab_start;
   guint max_display_pixels;
-  gchar ch;
+  GdkWChar ch;
   gint ch_width;
   GdkFont *font;
   
@@ -4626,11 +4748,23 @@ find_line_params (GtkText* text,
                      
                      lp.displayable_chars += 1;
                      
-                     while (!isspace (GTK_TEXT_INDEX (text, lp.end.index)) &&
-                            (lp.end.index > lp.start.index))
+                     if (text->use_wchar)
                        {
-                         decrement_mark (&lp.end);
-                         lp.displayable_chars -= 1;
+                         while (!gdk_iswspace (GTK_TEXT_INDEX (text, lp.end.index)) &&
+                                (lp.end.index > lp.start.index))
+                           {
+                             decrement_mark (&lp.end);
+                             lp.displayable_chars -= 1;
+                           }
+                       }
+                     else
+                       {
+                         while (!isspace(GTK_TEXT_INDEX (text, lp.end.index)) &&
+                                (lp.end.index > lp.start.index))
+                           {
+                             decrement_mark (&lp.end);
+                             lp.displayable_chars -= 1;
+                           }
                        }
                      
                      /* If whole line is one word, revert to char wrapping */
@@ -4689,10 +4823,21 @@ expand_scratch_buffer (GtkText* text, guint len)
       
       while (i <= len && i < MIN_GAP_SIZE) i <<= 1;
       
-      if (text->scratch_buffer)
-       text->scratch_buffer = g_new (guchar, i);
+      if (text->use_wchar)
+        {
+         if (text->scratch_buffer.wc)
+           text->scratch_buffer.wc = g_new (GdkWChar, i);
+         else
+           text->scratch_buffer.wc = g_realloc (text->scratch_buffer.wc,
+                                             i*sizeof (GdkWChar));
+        }
       else
-       text->scratch_buffer = g_realloc (text->scratch_buffer, i);
+        {
+         if (text->scratch_buffer.ch)
+           text->scratch_buffer.ch = g_new (guchar, i);
+         else
+           text->scratch_buffer.ch = g_realloc (text->scratch_buffer.ch, i);
+        }
       
       text->scratch_buffer_len = i;
     }
@@ -4751,7 +4896,7 @@ draw_line (GtkText* text,
   gint i;
   gint len = 0;
   guint running_offset = lp->tab_cont.pixel_offset;
-  guchar* buffer;
+  union { GdkWChar *wc; guchar *ch; } buffer;
   GdkGC *fg_gc;
   
   GtkEditable *editable = GTK_EDITABLE(text);
@@ -4772,17 +4917,35 @@ draw_line (GtkText* text,
     {
       expand_scratch_buffer (text, chars);
       
-      for (i = 0; i < chars; i += 1)
-       text->scratch_buffer[i] = GTK_TEXT_INDEX(text, mark.index + i);
-      
-      buffer = text->scratch_buffer;
+      if (text->use_wchar)
+       {
+         for (i = 0; i < chars; i += 1)
+           text->scratch_buffer.wc[i] = GTK_TEXT_INDEX(text, mark.index + i);
+          buffer.wc = text->scratch_buffer.wc;
+       }
+      else
+       {
+         for (i = 0; i < chars; i += 1)
+           text->scratch_buffer.ch[i] = GTK_TEXT_INDEX(text, mark.index + i);
+         buffer.ch = text->scratch_buffer.ch;
+       }
     }
   else
     {
-      if (mark.index >= text->gap_position)
-       buffer = text->text + mark.index + text->gap_size;
+      if (text->use_wchar)
+       {
+         if (mark.index >= text->gap_position)
+           buffer.wc = text->text.wc + mark.index + text->gap_size;
+         else
+           buffer.wc = text->text.wc + mark.index;
+       }
       else
-       buffer = text->text + mark.index;
+       {
+         if (mark.index >= text->gap_position)
+           buffer.ch = text->text.ch + mark.index + text->gap_size;
+         else
+           buffer.ch = text->text.ch + mark.index;
+       }
     }
   
   
@@ -4792,19 +4955,42 @@ draw_line (GtkText* text,
                    LINE_HEIGHT (*lp), TRUE);
     }
   
-  for (; chars > 0; chars -= len, buffer += len, len = 0)
+  while (chars > 0)
     {
-      if (buffer[0] != '\t')
+      len = 0;
+      if ((text->use_wchar && buffer.wc[0] != '\t') ||
+         (!text->use_wchar && buffer.ch[0] != '\t'))
        {
-         guchar* next_tab = memchr (buffer, '\t', chars);
+         union { GdkWChar *wc; guchar *ch; } next_tab;
          gint pixel_width;
          GdkFont *font;
-         
+
+         next_tab.wc = NULL;
+         if (text->use_wchar)
+           for (i=0; i<chars; i++)
+             {
+               if (buffer.wc[i] == '\t')
+                 {
+                   next_tab.wc = buffer.wc + i;
+                   break;
+                 }
+             }
+         else
+           next_tab.ch = memchr (buffer.ch, '\t', chars);
+
          len = MIN (MARK_CURRENT_PROPERTY (&mark)->length - mark.offset, chars);
          
-         if (next_tab)
-           len = MIN (len, next_tab - buffer);
-         
+         if (text->use_wchar)
+           {
+             if (next_tab.wc)
+               len = MIN (len, next_tab.wc - buffer.wc);
+           }
+         else
+           {
+             if (next_tab.ch)
+               len = MIN (len, next_tab.ch - buffer.ch);
+           }
+
          if (mark.index < selection_start_pos)
            len = MIN (len, selection_start_pos - mark.index);
          else if (mark.index < selection_end_pos)
@@ -4815,11 +5001,20 @@ draw_line (GtkText* text,
            {
              gdk_gc_set_font (text->gc, font);
              gdk_gc_get_values (text->gc, &gc_values);
+             if (text->use_wchar)
+               pixel_width = gdk_text_width_wc (gc_values.font,
+                                                buffer.wc, len);
+             else
              pixel_width = gdk_text_width (gc_values.font,
-                                           (gchar*) buffer, len);
+                                             buffer.ch, len);
            }
          else
-           pixel_width = gdk_text_width (font, (gchar*) buffer, len);
+           {
+             if (text->use_wchar)
+               pixel_width = gdk_text_width_wc (font, buffer.wc, len);
+             else
+               pixel_width = gdk_text_width (font, buffer.ch, len);
+           }
          
          draw_bg_rect (text, &mark, running_offset, pixel_start_height,
                        pixel_width, LINE_HEIGHT (*lp), TRUE);
@@ -4838,12 +5033,20 @@ draw_line (GtkText* text,
              fg_gc = text->gc;
            }
 
-         gdk_draw_text (text->text_area, MARK_CURRENT_FONT (text, &mark),
-                        fg_gc,
-                        running_offset,
-                        pixel_height,
-                        (gchar*) buffer,
-                        len);
+         if (text->use_wchar)
+           gdk_draw_text_wc (text->text_area, MARK_CURRENT_FONT (text, &mark),
+                             fg_gc,
+                             running_offset,
+                             pixel_height,
+                             buffer.wc,
+                             len);
+         else
+           gdk_draw_text (text->text_area, MARK_CURRENT_FONT (text, &mark),
+                          fg_gc,
+                          running_offset,
+                          pixel_height,
+                          buffer.ch,
+                          len);
          
          running_offset += pixel_width;
          
@@ -4875,6 +5078,11 @@ draw_line (GtkText* text,
        }
       
       advance_mark_n (&mark, len);
+      if (text->use_wchar)
+       buffer.wc += len;
+      else
+       buffer.ch += len;
+      chars -= len;
     }
 }
 
@@ -4958,7 +5166,7 @@ undraw_cursor (GtkText* text, gint absolute)
 
          gdk_gc_set_foreground (text->gc, MARK_CURRENT_FORE (text, &text->cursor_mark));
 
-         gdk_draw_text (text->text_area, font,
+         gdk_draw_text_wc (text->text_area, font,
                         text->gc,
                         text->cursor_pos_x,
                         text->cursor_pos_y - text->cursor_char_offset,
index 4ba138614b745728d7002341997a79a00498d50d..f8f35af6c71bbcdabcf7059f657ab0290023581e 100644 (file)
@@ -70,7 +70,7 @@ struct _GtkText
 
   /* The text, a single segment of text a'la emacs, with a gap
    * where insertion occurs. */
-  guchar* text;
+  union { GdkWChar *wc; guchar  *ch; } text;
   /* The allocated length of the text segment. */
   guint text_len;
   /* The gap position, index into address where a char
@@ -94,7 +94,7 @@ struct _GtkText
   /* First visible horizontal pixel. */
   guint first_onscreen_hor_pixel;
   /* First visible vertical pixel. */
- guint first_onscreen_ver_pixel;
 guint first_onscreen_ver_pixel;
 
                             /* FLAGS */
 
@@ -102,6 +102,9 @@ struct _GtkText
    * horizontal scrollbar. */
   guint line_wrap : 1;
   guint word_wrap : 1;
+ /* If a fontset is supplied for the widget, use_wchar become true,
+   * and we use GdkWchar as the encoding of text. */
+  guint use_wchar : 1;
 
   /* Frozen, don't do updates. @@@ fixme */
   guint freeze_count;
@@ -119,7 +122,7 @@ struct _GtkText
 
                          /* SCRATCH AREA */
 
-  guchar* scratch_buffer;
+  union { GdkWChar *wc; guchar *ch; } scratch_buffer;
   guint   scratch_buffer_len;
 
                           /* SCROLLING */
@@ -131,7 +134,7 @@ struct _GtkText
   gint            cursor_pos_x;       /* Position of cursor. */
   gint            cursor_pos_y;       /* Baseline of line cursor is drawn on. */
   GtkPropertyMark cursor_mark;        /* Where it is in the buffer. */
-  gchar           cursor_char;        /* Character to redraw. */
+  GdkWChar        cursor_char;        /* Character to redraw. */
   gchar           cursor_char_offset; /* Distance from baseline of the font. */
   gint            cursor_virtual_x;   /* Where it would be if it could be. */
   gint            cursor_drawn_level; /* How many people have undrawn. */
@@ -192,9 +195,11 @@ gint       gtk_text_backward_delete (GtkText       *text,
 gint       gtk_text_forward_delete  (GtkText       *text,
                                     guint          nchars);
 
-#define GTK_TEXT_INDEX(t, index)  \
-      ((index) < (t)->gap_position ? (t)->text[index] : \
-                                     (t)->text[(index) + (t)->gap_size])
+#define GTK_TEXT_INDEX(t, index)       (((t)->use_wchar) \
+       ? ((index) < (t)->gap_position ? (t)->text.wc[index] : \
+                                       (t)->text.wc[(index)+(t)->gap_size]) \
+       : ((index) < (t)->gap_position ? (t)->text.ch[index] : \
+                                       (t)->text.ch[(index)+(t)->gap_size]))
 
 #ifdef __cplusplus
 }
index ac9786fd92593d5a86456ab4b957f482a92dbd0f..9a400079d267b084f54aa0859698db6d95ab4e76 100644 (file)
@@ -4259,14 +4259,25 @@ gtk_widget_real_unrealize (GtkWidget *widget)
   g_return_if_fail (widget != NULL);
   g_return_if_fail (GTK_IS_WIDGET (widget));
 
-  if (GTK_WIDGET_NO_WINDOW (widget) && GTK_WIDGET_MAPPED (widget))
+  if (GTK_WIDGET_MAPPED (widget))
     gtk_widget_real_unmap (widget);
 
-  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED | GTK_MAPPED);
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_MAPPED);
 
   /* printf ("unrealizing %s\n", gtk_type_name (GTK_OBJECT(widget)->klass->type));
    */
 
+   /* We must do unrealize child widget BEFORE container widget.
+    * gdk_window_destroy() destroys specified xwindow and it's sub-xwindows.
+    * So, unrealizing container widget bofore it's children causes the problem 
+    * (for example, gdk_ic_destroy () with destroyed window causes crash. )
+    */
+
+  if (GTK_IS_CONTAINER (widget))
+    gtk_container_foreach (GTK_CONTAINER (widget),
+                          (GtkCallback) gtk_widget_unrealize,
+                          NULL);
+
   gtk_style_detach (widget->style);
   if (!GTK_WIDGET_NO_WINDOW (widget))
     {
@@ -4280,12 +4291,7 @@ gtk_widget_real_unrealize (GtkWidget *widget)
       widget->window = NULL;
     }
 
-  /* Unrealize afterwards to improve visual effect */
-
-  if (GTK_IS_CONTAINER (widget))
-    gtk_container_forall (GTK_CONTAINER (widget),
-                         (GtkCallback) gtk_widget_unrealize,
-                         NULL);
+  GTK_WIDGET_UNSET_FLAGS (widget, GTK_REALIZED);
 }
 
 /*****************************************
index eb4e6ccba391e567693aaf36afb7d01c1875fc78..4a24d8e03320f84559ed1ffb984129499fd473ae 100644 (file)
@@ -5750,19 +5750,29 @@ create_text (void)
       
       if (infile)
        {
-         char buffer[1024];
-         int nchars;
+         char *buffer;
+         int nbytes_read, nbytes_alloc;
          
+         nbytes_read = 0;
+         nbytes_alloc = 1024;
+         buffer = g_new (char, nbytes_alloc);
          while (1)
            {
-             nchars = fread(buffer, 1, 1024, infile);
-             gtk_text_insert (GTK_TEXT (text), NULL, NULL,
-                              NULL, buffer, nchars);
-             
-             if (nchars < 1024)
+             int len;
+             if (nbytes_alloc < nbytes_read + 1024)
+               {
+                 nbytes_alloc *= 2;
+                 buffer = g_realloc (buffer, nbytes_alloc);
+               }
+             len = fread (buffer + nbytes_read, 1, 1024, infile);
+             nbytes_read += len;
+             if (len < 1024)
                break;
            }
          
+         gtk_text_insert (GTK_TEXT (text), NULL, NULL,
+                          NULL, buffer, nbytes_read);
+         g_free(buffer);
          fclose (infile);
        }
       
index ff0288c6514818669b406c6488e3a6c6802ebd75..065b00cacabc5a6915a3d9c80e450ecdc68daf1f 100644 (file)
@@ -17,8 +17,8 @@ pixmap_path "."
 
 style "defaultfont"
 {
-#  fontset = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*,*"
-  font = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*,*"
+  fontset = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*,*"
+#  font = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*,*"
 }
 
 # common default
index eb4e6ccba391e567693aaf36afb7d01c1875fc78..4a24d8e03320f84559ed1ffb984129499fd473ae 100644 (file)
@@ -5750,19 +5750,29 @@ create_text (void)
       
       if (infile)
        {
-         char buffer[1024];
-         int nchars;
+         char *buffer;
+         int nbytes_read, nbytes_alloc;
          
+         nbytes_read = 0;
+         nbytes_alloc = 1024;
+         buffer = g_new (char, nbytes_alloc);
          while (1)
            {
-             nchars = fread(buffer, 1, 1024, infile);
-             gtk_text_insert (GTK_TEXT (text), NULL, NULL,
-                              NULL, buffer, nchars);
-             
-             if (nchars < 1024)
+             int len;
+             if (nbytes_alloc < nbytes_read + 1024)
+               {
+                 nbytes_alloc *= 2;
+                 buffer = g_realloc (buffer, nbytes_alloc);
+               }
+             len = fread (buffer + nbytes_read, 1, 1024, infile);
+             nbytes_read += len;
+             if (len < 1024)
                break;
            }
          
+         gtk_text_insert (GTK_TEXT (text), NULL, NULL,
+                          NULL, buffer, nbytes_read);
+         g_free(buffer);
          fclose (infile);
        }
       
index ff0288c6514818669b406c6488e3a6c6802ebd75..065b00cacabc5a6915a3d9c80e450ecdc68daf1f 100644 (file)
@@ -17,8 +17,8 @@ pixmap_path "."
 
 style "defaultfont"
 {
-#  fontset = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*,*"
-  font = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*,*"
+  fontset = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*,*"
+#  font = "-adobe-helvetica-medium-r-normal--*-120-*-*-*-*-*-*,*"
 }
 
 # common default