summaryrefslogtreecommitdiff
path: root/gdk
diff options
context:
space:
mode:
authorTor Lillqvist <tml@iki.fi>1999-10-31 21:35:39 +0000
committerTor Lillqvist <tml@src.gnome.org>1999-10-31 21:35:39 +0000
commit00c5e838710a01ed97a46d96910b6f118d240b99 (patch)
tree2d8a8d72f6e39231ed9fa72a09069025ff559f64 /gdk
parent241f9c9dabdd3f021adb139b25a455260dc473ae (diff)
downloadgtk+-00c5e838710a01ed97a46d96910b6f118d240b99.tar.gz
Add new keysyms from X11R6.4 (including EuroSign).
1999-10-31 Tor Lillqvist <tml@iki.fi> * gdk/gdkkeysyms.h: Add new keysyms from X11R6.4 (including EuroSign). * gdk/gdktypes.h: Add note about wchar_t not necessarily being the same type as GdkWChar, especially on Win32. * gdk/win32/*.c: Change gdk_root_parent to be a pointer. * gdk/win32/*.c: Assume all strings are UTF-8. Convert to Unicode before passing to Windows GDI for drawing etc. Convert to the system default codepage before passing to Windows as window titles. * gdk/win32/gdkprivate.h: Add more fields to GdkWindowPrivate to support changing input locale on the fly. * gdk/win32/gdkevent.c: Support input language (keyboard locale) on-the-fly changes. Convert incoming characters from the current codepage to Unicode (and then to a UTF-8 multi-byte string) based on the current input language. Use keysym<->Unicode mapping tables and functions borrowed from xterm sources. Support IMEs (Input Method Editors) for CJK languages. On non-CJK editions of Win9x, use the ActiveX-based Active IMM (Input Method Manager) if available. IMEs and the Active IMM are available under the disguise of Chinese, Korean and Japanese support for IE and Outlook Express from "Windows Update" for Win98. On Win2k, the CJK support is present in all editions (as long as you install it). Call DispatchMessage from gdk_events_queue() (and thus gdk_WindowProc()), instead of duplicating the code in gdk_WindowProc(). Reworked the grab handling and propagation code, factored out duplicated code snippets into separate functions. Other cleanups, too. * gdk/win32/surrogate-dimm.h: Provide just the bits we need from the <dimm.h> header describing the Active IMM. * gdk/win32/gdkfont.c: Pretend to support fontsets, but so far just do the same as for "single" fonts. * gdk/win32/gdk.c: Call CoInitialize() (COM initialisation) from gdk_init_check, and CoUninitialize() from gdk_exit_func. Handle the new keysyms from gdkkeysyms.h. * gtk/gtkfontsel.c (Win32): Load the font for the preview as a fontset, so that gtkentry uses wide characters. * gtk/gtkrc.c (Win32): Get the locale with gwin_getlocale(). Call GTk+'s system directory "gtk+", not "gtk".
Diffstat (limited to 'gdk')
-rw-r--r--gdk/gdkkeysyms.h18
-rw-r--r--gdk/gdktypes.h5
-rw-r--r--gdk/win32/gdk.c71
-rw-r--r--gdk/win32/gdkconfig.h1
-rw-r--r--gdk/win32/gdkdnd-win32.c6
-rw-r--r--gdk/win32/gdkdnd.c6
-rw-r--r--gdk/win32/gdkdraw.c138
-rw-r--r--gdk/win32/gdkdrawable-win32.c138
-rw-r--r--gdk/win32/gdkevents-win32.c3336
-rw-r--r--gdk/win32/gdkevents.c3336
-rw-r--r--gdk/win32/gdkfont-win32.c354
-rw-r--r--gdk/win32/gdkfont.c354
-rw-r--r--gdk/win32/gdkgc-win32.c6
-rw-r--r--gdk/win32/gdkgc.c6
-rw-r--r--gdk/win32/gdkglobals-win32.c18
-rw-r--r--gdk/win32/gdkglobals.c18
-rw-r--r--gdk/win32/gdkim-win32.c285
-rw-r--r--gdk/win32/gdkim.c285
-rw-r--r--gdk/win32/gdkinput-win32.c6
-rw-r--r--gdk/win32/gdkinput.c6
-rw-r--r--gdk/win32/gdkmain-win32.c71
-rw-r--r--gdk/win32/gdkpixmap-win32.c8
-rw-r--r--gdk/win32/gdkpixmap.c8
-rw-r--r--gdk/win32/gdkprivate-win32.h26
-rw-r--r--gdk/win32/gdkprivate.h26
-rw-r--r--gdk/win32/gdkselection-win32.c4
-rw-r--r--gdk/win32/gdkselection.c4
-rw-r--r--gdk/win32/gdkwin32.h2
-rw-r--r--gdk/win32/gdkwindow-win32.c136
-rw-r--r--gdk/win32/gdkwindow.c136
-rw-r--r--gdk/win32/gdkx.h2
-rw-r--r--gdk/win32/makefile.cygwin2
-rw-r--r--gdk/win32/surrogate-dimm.h144
33 files changed, 6743 insertions, 2219 deletions
diff --git a/gdk/gdkkeysyms.h b/gdk/gdkkeysyms.h
index cc3ed517e6..56798d4e6c 100644
--- a/gdk/gdkkeysyms.h
+++ b/gdk/gdkkeysyms.h
@@ -10,6 +10,7 @@
#define GDK_Escape 0xFF1B
#define GDK_Delete 0xFFFF
#define GDK_Multi_key 0xFF20
+#define GDK_Codeinput 0xFF37
#define GDK_SingleCandidate 0xFF3C
#define GDK_MultipleCandidate 0xFF3D
#define GDK_PreviousCandidate 0xFF3E
@@ -30,6 +31,7 @@
#define GDK_Kana_Shift 0xFF2E
#define GDK_Eisu_Shift 0xFF2F
#define GDK_Eisu_toggle 0xFF30
+#define GDK_Kanji_Bangou 0xFF37
#define GDK_Zen_Koho 0xFF3D
#define GDK_Mae_Koho 0xFF3E
#define GDK_Home 0xFF50
@@ -608,6 +610,9 @@
#define GDK_uogonek 0x3f9
#define GDK_utilde 0x3fd
#define GDK_umacron 0x3fe
+#define GDK_OE 0x13bc
+#define GDK_oe 0x13bd
+#define GDK_Ydiaeresis 0x13be
#define GDK_overline 0x47e
#define GDK_kana_fullstop 0x4a1
#define GDK_kana_openingbracket 0x4a2
@@ -1315,3 +1320,16 @@
#define GDK_Hangul_J_KkogjiDalrinIeung 0xef9
#define GDK_Hangul_J_YeorinHieuh 0xefa
#define GDK_Korean_Won 0xeff
+#define GDK_EcuSign 0x20a0
+#define GDK_ColonSign 0x20a1
+#define GDK_CruzeiroSign 0x20a2
+#define GDK_FFrancSign 0x20a3
+#define GDK_LiraSign 0x20a4
+#define GDK_MillSign 0x20a5
+#define GDK_NairaSign 0x20a6
+#define GDK_PesetaSign 0x20a7
+#define GDK_RupeeSign 0x20a8
+#define GDK_WonSign 0x20a9
+#define GDK_NewSheqelSign 0x20aa
+#define GDK_DongSign 0x20ab
+#define GDK_EuroSign 0x20ac
diff --git a/gdk/gdktypes.h b/gdk/gdktypes.h
index d96f07386f..de5d6ac8a9 100644
--- a/gdk/gdktypes.h
+++ b/gdk/gdktypes.h
@@ -68,6 +68,11 @@ typedef struct _GdkPoint GdkPoint;
typedef struct _GdkRectangle GdkRectangle;
typedef struct _GdkSegment GdkSegment;
+/*
+ * Note that on some platforms the wchar_t type
+ * is not the same as GdkWChar. For instance
+ * on Win32, wchar_t is unsigned short.
+ */
typedef guint32 GdkWChar;
typedef gulong GdkAtom;
diff --git a/gdk/win32/gdk.c b/gdk/win32/gdk.c
index 5a44835c5d..9e5cb9f0ca 100644
--- a/gdk/win32/gdk.c
+++ b/gdk/win32/gdk.c
@@ -38,11 +38,11 @@
#include "gdkinputprivate.h"
#include "gdkkeysyms.h"
+#include <objbase.h>
+
static void gdkx_XConvertCase (KeySym symbol,
KeySym *lower,
KeySym *upper);
-#define XConvertCase gdkx_XConvertCase
-
static void gdk_exit_func (void);
@@ -234,6 +234,9 @@ gdk_init_check (int *argc,
gdk_ProgInstance = GetModuleHandle (NULL);
gdk_DC = CreateDC ("DISPLAY", NULL, NULL, NULL);
+ gdk_root_window = GetDesktopWindow ();
+
+ CoInitialize (NULL);
gdk_selection_request_msg = RegisterWindowMessage ("gdk-selection-request");
gdk_selection_notify_msg = RegisterWindowMessage ("gdk-selection-notify");
@@ -247,8 +250,6 @@ gdk_init_check (int *argc,
gdk_progclass = g_basename (g_get_prgname ());
gdk_progclass[0] = toupper (gdk_progclass[0]);
- gdk_root_window = HWND_DESKTOP;
-
g_atexit (gdk_exit_func);
gdk_events_init ();
@@ -333,7 +334,7 @@ gdk_screen_width (void)
{
gint return_val;
- return_val = gdk_root_parent.drawable.width;
+ return_val = gdk_root_parent->drawable.width;
return return_val;
}
@@ -358,7 +359,7 @@ gdk_screen_height (void)
{
gint return_val;
- return_val = gdk_root_parent.drawable.height;
+ return_val = gdk_root_parent->drawable.height;
return return_val;
}
@@ -498,6 +499,9 @@ gdk_exit_func (void)
gdk_input_exit ();
gdk_key_repeat_restore ();
gdk_dnd_exit ();
+
+ CoUninitialize ();
+
DeleteDC (gdk_DC);
gdk_DC = NULL;
gdk_initialized = 0;
@@ -1670,6 +1674,22 @@ static struct gdk_key {
{ 0x000ef9, "Hangul_J_KkogjiDalrinIeung" },
{ 0x000efa, "Hangul_J_YeorinHieuh" },
{ 0x000eff, "Korean_Won" },
+ { 0x0013bc, "OE" },
+ { 0x0013bd, "oe" },
+ { 0x0013be, "Ydiaeresis" },
+ { 0x0020a0, "EcuSign" },
+ { 0x0020a1, "ColonSign" },
+ { 0x0020a2, "CruzeiroSign" },
+ { 0x0020a3, "FFrancSign" },
+ { 0x0020a4, "LiraSign" },
+ { 0x0020a5, "MillSign" },
+ { 0x0020a6, "NairaSign" },
+ { 0x0020a7, "PesetaSign" },
+ { 0x0020a8, "RupeeSign" },
+ { 0x0020a9, "WonSign" },
+ { 0x0020aa, "NewSheqelSign" },
+ { 0x0020ab, "DongSign" },
+ { 0x0020ac, "EuroSign" },
{ 0x00fd01, "3270_Duplicate" },
{ 0x00fd02, "3270_FieldMark" },
{ 0x00fd03, "3270_Right2" },
@@ -1826,11 +1846,21 @@ static struct gdk_key {
{ 0x00ff2e, "Kana_Shift" },
{ 0x00ff2f, "Eisu_Shift" },
{ 0x00ff30, "Eisu_toggle" },
+ { 0x00ff31, "Hangul" },
+ { 0x00ff32, "Hangul_Start" },
+ { 0x00ff33, "Hangul_End" },
+ { 0x00ff34, "Hangul_Hanja" },
+ { 0x00ff35, "Hangul_Jamo" },
+ { 0x00ff36, "Hangul_Romaja" },
+ { 0x00ff37, "Codeinput" },
+ { 0x00ff38, "Hangul_Jeonja" },
+ { 0x00ff39, "Hangul_Banja" },
+ { 0x00ff3a, "Hangul_PreHanja" },
+ { 0x00ff3b, "Hangul_PostHanja" },
{ 0x00ff3c, "SingleCandidate" },
{ 0x00ff3d, "MultipleCandidate" },
- { 0x00ff3d, "Zen_Koho" },
- { 0x00ff3e, "Mae_Koho" },
{ 0x00ff3e, "PreviousCandidate" },
+ { 0x00ff3f, "Hangul_Special" },
{ 0x00ff50, "Home" },
{ 0x00ff51, "Left" },
{ 0x00ff52, "Up" },
@@ -1949,21 +1979,6 @@ static struct gdk_key {
{ 0x00ffed, "Hyper_L" },
{ 0x00ffee, "Hyper_R" },
{ 0x00ffff, "Delete" },
- { 0x00ff31, "Hangul" },
- { 0x00ff32, "Hangul_Start" },
- { 0x00ff33, "Hangul_End" },
- { 0x00ff34, "Hangul_Hanja" },
- { 0x00ff35, "Hangul_Jamo" },
- { 0x00ff36, "Hangul_Romaja" },
- { 0x00ff37, "Hangul_Codeinput" },
- { 0x00ff38, "Hangul_Jeonja" },
- { 0x00ff39, "Hangul_Banja" },
- { 0x00ff3a, "Hangul_PreHanja" },
- { 0x00ff3b, "Hangul_PostHanja" },
- { 0x00ff3c, "Hangul_SingleCandidate" },
- { 0x00ff3d, "Hangul_MultipleCandidate" },
- { 0x00ff3e, "Hangul_PreviousCandidate" },
- { 0x00ff3f, "Hangul_Special" },
{ 0xffffff, "VoidSymbol" },
};
@@ -1985,7 +2000,7 @@ gdk_keyval_name (guint keyval)
GDK_NUM_KEYS, sizeof (struct gdk_key),
gdk_keys_keyval_compare);
if (found != NULL)
- return found->name;
+ return (gchar *) found->name;
else
return NULL;
}
@@ -2037,7 +2052,7 @@ gdk_keyval_to_upper (guint keyval)
KeySym lower_val = 0;
KeySym upper_val = 0;
- XConvertCase (keyval, &lower_val, &upper_val);
+ gdkx_XConvertCase (keyval, &lower_val, &upper_val);
return upper_val;
}
return 0;
@@ -2051,7 +2066,7 @@ gdk_keyval_to_lower (guint keyval)
KeySym lower_val = 0;
KeySym upper_val = 0;
- XConvertCase (keyval, &lower_val, &upper_val);
+ gdkx_XConvertCase (keyval, &lower_val, &upper_val);
return lower_val;
}
return 0;
@@ -2065,7 +2080,7 @@ gdk_keyval_is_upper (guint keyval)
KeySym lower_val = 0;
KeySym upper_val = 0;
- XConvertCase (keyval, &lower_val, &upper_val);
+ gdkx_XConvertCase (keyval, &lower_val, &upper_val);
return upper_val == keyval;
}
return TRUE;
@@ -2079,7 +2094,7 @@ gdk_keyval_is_lower (guint keyval)
KeySym lower_val = 0;
KeySym upper_val = 0;
- XConvertCase (keyval, &lower_val, &upper_val);
+ gdkx_XConvertCase (keyval, &lower_val, &upper_val);
return lower_val == keyval;
}
return TRUE;
diff --git a/gdk/win32/gdkconfig.h b/gdk/win32/gdkconfig.h
index ee334e28d5..2fd8ca1b3c 100644
--- a/gdk/win32/gdkconfig.h
+++ b/gdk/win32/gdkconfig.h
@@ -5,3 +5,4 @@
#ifdef _MSC_VER
#define GDK_HAVE_WCTYPE_H 1
#endif
+#define GDK_USE_UTF8_MBS 1
diff --git a/gdk/win32/gdkdnd-win32.c b/gdk/win32/gdkdnd-win32.c
index 5a220c6423..1c7f42a99d 100644
--- a/gdk/win32/gdkdnd-win32.c
+++ b/gdk/win32/gdkdnd-win32.c
@@ -38,6 +38,8 @@
#ifdef OLE2_DND
#include <ole2.h>
+#else
+#include <objbase.h>
#endif
#ifdef _MSC_VER /* These aren't in mingw32 */
@@ -596,7 +598,7 @@ gdk_dropfiles_filter (GdkXEvent *xev,
private = (GdkDragContextPrivate *) context;
context->protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
context->is_source = FALSE;
- context->source_window = (GdkWindow *) &gdk_root_parent;
+ context->source_window = (GdkWindow *) gdk_root_parent;
context->dest_window = event->any.window;
gdk_window_ref (context->dest_window);
/* WM_DROPFILES drops are always file names */
@@ -638,7 +640,7 @@ gdk_dropfiles_filter (GdkXEvent *xev,
}
g_string_append (result, "\015\012");
}
- gdk_sel_prop_store ((GdkWindow *) &gdk_root_parent,
+ gdk_sel_prop_store ((GdkWindow *) gdk_root_parent,
text_uri_list_atom, 8, result->str, result->len + 1);
DragFinish (hdrop);
diff --git a/gdk/win32/gdkdnd.c b/gdk/win32/gdkdnd.c
index 5a220c6423..1c7f42a99d 100644
--- a/gdk/win32/gdkdnd.c
+++ b/gdk/win32/gdkdnd.c
@@ -38,6 +38,8 @@
#ifdef OLE2_DND
#include <ole2.h>
+#else
+#include <objbase.h>
#endif
#ifdef _MSC_VER /* These aren't in mingw32 */
@@ -596,7 +598,7 @@ gdk_dropfiles_filter (GdkXEvent *xev,
private = (GdkDragContextPrivate *) context;
context->protocol = GDK_DRAG_PROTO_WIN32_DROPFILES;
context->is_source = FALSE;
- context->source_window = (GdkWindow *) &gdk_root_parent;
+ context->source_window = (GdkWindow *) gdk_root_parent;
context->dest_window = event->any.window;
gdk_window_ref (context->dest_window);
/* WM_DROPFILES drops are always file names */
@@ -638,7 +640,7 @@ gdk_dropfiles_filter (GdkXEvent *xev,
}
g_string_append (result, "\015\012");
}
- gdk_sel_prop_store ((GdkWindow *) &gdk_root_parent,
+ gdk_sel_prop_store ((GdkWindow *) gdk_root_parent,
text_uri_list_atom, 8, result->str, result->len + 1);
DragFinish (hdrop);
diff --git a/gdk/win32/gdkdraw.c b/gdk/win32/gdkdraw.c
index 593c98cd80..85ca076cce 100644
--- a/gdk/win32/gdkdraw.c
+++ b/gdk/win32/gdkdraw.c
@@ -469,47 +469,35 @@ gdk_draw_text (GdkDrawable *drawable,
if (text_length == 0)
return;
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
drawable_private = (GdkDrawablePrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
- if (font->type == GDK_FONT_FONT)
- {
- hdc = gdk_gc_predraw (drawable_private, gc_private);
- xfont = (HFONT) font_private->xfont;
-
- GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
- "+%d+%d font: %#x \"%.*s\" length: %d\n",
- drawable_private->xwindow,
- gc_private, gc_private->xgc,
- x, y, xfont,
- (text_length > 10 ? 10 : text_length),
- text, text_length));
-
- if ((oldfont = SelectObject (hdc, xfont)) == NULL)
- g_warning ("gdk_draw_text: SelectObject failed");
- if (font_private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
- text, text_length,
- wcstr, text_length)) == 0)
- g_warning ("gdk_draw_text: MultiByteToWideChar failed");
- else if (!TextOutW (hdc, x, y, wcstr, wlen))
- g_warning ("gdk_draw_text: TextOutW failed");
- g_free (wcstr);
- }
- else
- {
- if (!TextOutA (hdc, x, y, text, text_length))
- g_warning ("gdk_draw_text: TextOutA failed");
- }
- if (oldfont != NULL)
- SelectObject (hdc, oldfont);
- gdk_gc_postdraw (drawable_private, gc_private);
- }
- else
- g_error ("undefined font type");
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
+ xfont = (HFONT) font_private->xfont;
+
+ GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
+ "+%d+%d font: %#x \"%.*s\" length: %d\n",
+ drawable_private->xwindow,
+ gc_private, gc_private->xgc,
+ x, y, xfont,
+ (text_length > 10 ? 10 : text_length),
+ text, text_length));
+
+ if ((oldfont = SelectObject (hdc, xfont)) == NULL)
+ g_warning ("gdk_draw_text: SelectObject failed");
+
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = gdk_nmbstowchar_ts (wcstr, text, text_length, text_length)) == -1)
+ g_warning ("gdk_draw_text: gdk_nmbstowchar_ts failed");
+ else if (!TextOutW (hdc, x, y, wcstr, wlen))
+ g_warning ("gdk_draw_text: TextOutW failed");
+ g_free (wcstr);
+ if (oldfont != NULL)
+ SelectObject (hdc, oldfont);
+ gdk_gc_postdraw (drawable_private, gc_private);
}
void
@@ -521,6 +509,8 @@ gdk_draw_text_wc (GdkDrawable *drawable,
const GdkWChar *text,
gint text_length)
{
+ HDC hdc;
+ HGDIOBJ oldfont;
GdkDrawablePrivate *drawable_private;
GdkFontPrivate *font_private;
GdkGCPrivate *gc_private;
@@ -539,68 +529,40 @@ gdk_draw_text_wc (GdkDrawable *drawable,
if (text_length == 0)
return;
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
drawable_private = (GdkDrawablePrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
- if (font->type == GDK_FONT_FONT)
- {
- HDC hdc;
- HFONT xfont;
- HGDIOBJ oldfont;
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
- hdc = gdk_gc_predraw (drawable_private, gc_private);
- xfont = (HFONT) font_private->xfont;
-
- GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
- "+%d+%d font: %#x length: %d\n",
- drawable_private->xwindow,
- gc_private, gc_private->xgc,
- x, y, xfont,
- text_length));
+ GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
+ "+%d+%d font: %#x length: %d\n",
+ drawable_private->xwindow,
+ gc_private, gc_private->xgc,
+ x, y, font_private->xfont,
+ text_length));
- if ((oldfont = SelectObject (hdc, xfont)) == NULL)
- g_warning ("gdk_draw_text_wc: SelectObject failed");
-#if 0 /* No. Don't use TextOutW directly. Compare to the X11 version,
- * it uses plain XDrawString for GDK_FONT_FONT fonts, too.
- * TextOutW by definition interprets the string as Unicode.
- * We don't have that, but either chars from some single-byte codepage
- * or from a DBCS.
- */
+ if ((oldfont = SelectObject (hdc, font_private->xfont)) == NULL)
+ g_warning ("gdk_draw_text_wc: SelectObject failed");
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
+ {
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
- if (!TextOutW (hdc, x, y, wcstr, text_length))
- g_warning ("gdk_draw_text_wc: TextOutW failed");
- g_free (wcstr);
-#else
- str = g_new (guchar, text_length);
- for (i = 0; i < text_length; i++)
- str[i] = text[i];
- if (font_private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
- str, text_length,
- wcstr, text_length)) == 0)
- g_warning ("gdk_draw_text: MultiByteToWideChar failed");
- else if (!TextOutW (hdc, x, y, wcstr, wlen))
- g_warning ("gdk_draw_text_wc: TextOutW failed");
- g_free (wcstr);
- }
- else
- {
- if (!TextOutA (hdc, x, y, str, text_length))
- g_warning ("gdk_draw_text_wc: TextOutA failed");
- }
- g_free (str);
-#endif
- if (oldfont != NULL)
- SelectObject (hdc, oldfont);
- gdk_gc_postdraw (drawable_private, gc_private);
}
else
- g_error ("undefined font type");
+ wcstr = (wchar_t *) text;
+
+ if (!TextOutW (hdc, x, y, wcstr, text_length))
+ g_warning ("gdk_draw_text_wc: TextOutW failed");
+
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
+ g_free (wcstr);
+ if (oldfont != NULL)
+ SelectObject (hdc, oldfont);
+ gdk_gc_postdraw (drawable_private, gc_private);
}
void
diff --git a/gdk/win32/gdkdrawable-win32.c b/gdk/win32/gdkdrawable-win32.c
index 593c98cd80..85ca076cce 100644
--- a/gdk/win32/gdkdrawable-win32.c
+++ b/gdk/win32/gdkdrawable-win32.c
@@ -469,47 +469,35 @@ gdk_draw_text (GdkDrawable *drawable,
if (text_length == 0)
return;
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
drawable_private = (GdkDrawablePrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
- if (font->type == GDK_FONT_FONT)
- {
- hdc = gdk_gc_predraw (drawable_private, gc_private);
- xfont = (HFONT) font_private->xfont;
-
- GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
- "+%d+%d font: %#x \"%.*s\" length: %d\n",
- drawable_private->xwindow,
- gc_private, gc_private->xgc,
- x, y, xfont,
- (text_length > 10 ? 10 : text_length),
- text, text_length));
-
- if ((oldfont = SelectObject (hdc, xfont)) == NULL)
- g_warning ("gdk_draw_text: SelectObject failed");
- if (font_private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
- text, text_length,
- wcstr, text_length)) == 0)
- g_warning ("gdk_draw_text: MultiByteToWideChar failed");
- else if (!TextOutW (hdc, x, y, wcstr, wlen))
- g_warning ("gdk_draw_text: TextOutW failed");
- g_free (wcstr);
- }
- else
- {
- if (!TextOutA (hdc, x, y, text, text_length))
- g_warning ("gdk_draw_text: TextOutA failed");
- }
- if (oldfont != NULL)
- SelectObject (hdc, oldfont);
- gdk_gc_postdraw (drawable_private, gc_private);
- }
- else
- g_error ("undefined font type");
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
+ xfont = (HFONT) font_private->xfont;
+
+ GDK_NOTE (MISC, g_print ("gdk_draw_text: %#x (%d) %#x "
+ "+%d+%d font: %#x \"%.*s\" length: %d\n",
+ drawable_private->xwindow,
+ gc_private, gc_private->xgc,
+ x, y, xfont,
+ (text_length > 10 ? 10 : text_length),
+ text, text_length));
+
+ if ((oldfont = SelectObject (hdc, xfont)) == NULL)
+ g_warning ("gdk_draw_text: SelectObject failed");
+
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = gdk_nmbstowchar_ts (wcstr, text, text_length, text_length)) == -1)
+ g_warning ("gdk_draw_text: gdk_nmbstowchar_ts failed");
+ else if (!TextOutW (hdc, x, y, wcstr, wlen))
+ g_warning ("gdk_draw_text: TextOutW failed");
+ g_free (wcstr);
+ if (oldfont != NULL)
+ SelectObject (hdc, oldfont);
+ gdk_gc_postdraw (drawable_private, gc_private);
}
void
@@ -521,6 +509,8 @@ gdk_draw_text_wc (GdkDrawable *drawable,
const GdkWChar *text,
gint text_length)
{
+ HDC hdc;
+ HGDIOBJ oldfont;
GdkDrawablePrivate *drawable_private;
GdkFontPrivate *font_private;
GdkGCPrivate *gc_private;
@@ -539,68 +529,40 @@ gdk_draw_text_wc (GdkDrawable *drawable,
if (text_length == 0)
return;
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
drawable_private = (GdkDrawablePrivate*) drawable;
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
- if (font->type == GDK_FONT_FONT)
- {
- HDC hdc;
- HFONT xfont;
- HGDIOBJ oldfont;
+ hdc = gdk_gc_predraw (drawable_private, gc_private);
- hdc = gdk_gc_predraw (drawable_private, gc_private);
- xfont = (HFONT) font_private->xfont;
-
- GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
- "+%d+%d font: %#x length: %d\n",
- drawable_private->xwindow,
- gc_private, gc_private->xgc,
- x, y, xfont,
- text_length));
+ GDK_NOTE (MISC, g_print ("gdk_draw_text_wc: %#x (%d) %#x "
+ "+%d+%d font: %#x length: %d\n",
+ drawable_private->xwindow,
+ gc_private, gc_private->xgc,
+ x, y, font_private->xfont,
+ text_length));
- if ((oldfont = SelectObject (hdc, xfont)) == NULL)
- g_warning ("gdk_draw_text_wc: SelectObject failed");
-#if 0 /* No. Don't use TextOutW directly. Compare to the X11 version,
- * it uses plain XDrawString for GDK_FONT_FONT fonts, too.
- * TextOutW by definition interprets the string as Unicode.
- * We don't have that, but either chars from some single-byte codepage
- * or from a DBCS.
- */
+ if ((oldfont = SelectObject (hdc, font_private->xfont)) == NULL)
+ g_warning ("gdk_draw_text_wc: SelectObject failed");
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
+ {
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
- if (!TextOutW (hdc, x, y, wcstr, text_length))
- g_warning ("gdk_draw_text_wc: TextOutW failed");
- g_free (wcstr);
-#else
- str = g_new (guchar, text_length);
- for (i = 0; i < text_length; i++)
- str[i] = text[i];
- if (font_private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (font_private->codepage, 0,
- str, text_length,
- wcstr, text_length)) == 0)
- g_warning ("gdk_draw_text: MultiByteToWideChar failed");
- else if (!TextOutW (hdc, x, y, wcstr, wlen))
- g_warning ("gdk_draw_text_wc: TextOutW failed");
- g_free (wcstr);
- }
- else
- {
- if (!TextOutA (hdc, x, y, str, text_length))
- g_warning ("gdk_draw_text_wc: TextOutA failed");
- }
- g_free (str);
-#endif
- if (oldfont != NULL)
- SelectObject (hdc, oldfont);
- gdk_gc_postdraw (drawable_private, gc_private);
}
else
- g_error ("undefined font type");
+ wcstr = (wchar_t *) text;
+
+ if (!TextOutW (hdc, x, y, wcstr, text_length))
+ g_warning ("gdk_draw_text_wc: TextOutW failed");
+
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
+ g_free (wcstr);
+ if (oldfont != NULL)
+ SelectObject (hdc, oldfont);
+ gdk_gc_postdraw (drawable_private, gc_private);
}
void
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c
index 53097d20b7..7ac8169786 100644
--- a/gdk/win32/gdkevents-win32.c
+++ b/gdk/win32/gdkevents-win32.c
@@ -27,21 +27,47 @@
#include "config.h"
+#define NEW_PROPAGATION_CODE
+
+#define USE_DISPATCHMESSAGE
+
+/* Cannot use TrackMouseEvent, as the stupid WM_MOUSELEAVE message
+ * doesn't tell us where the mouse has gone. Thus we cannot use it to
+ * generate a correct GdkNotifyType. Pity, as using TrackMouseEvent
+ * otherwise would make it possible to reliably generate
+ * GDK_LEAVE_NOTIFY events, which would help get rid of those pesky
+ * tooltips sometimes popping up in the wrong place.
+ */
+/* define USE_TRACKMOUSEEVENT */
+
#include <stdio.h>
+#include <windows.h>
+
+#ifdef HAVE_WINTAB
+#include <wintab.h>
+#endif
+
+#include <objbase.h>
+#include <imm.h>
+
+#ifdef HAVE_DIMM_H
+#include <dimm.h>
+#else
+#include "surrogate-dimm.h"
+#endif
+
#include "gdk.h"
-#include "gdkprivate.h"
#include "gdkx.h"
#include "gdkkeysyms.h"
-#ifdef HAVE_WINTAB
-#include <wintab.h>
-#endif
#include "gdkinputprivate.h"
#define PING() printf("%s: %d\n",__FILE__,__LINE__),fflush(stdout)
+#define WINDOW_PRIVATE(wp) ((GdkWindowPrivate *) (wp))
+
typedef struct _GdkIOClosure GdkIOClosure;
typedef struct _GdkEventPrivate GdkEventPrivate;
@@ -80,10 +106,10 @@ struct _GdkEventPrivate
static GdkEvent *gdk_event_new (void);
static GdkFilterReturn
- gdk_event_apply_filters (MSG *xevent,
+ gdk_event_apply_filters(MSG *xevent,
GdkEvent *event,
GList *filters);
-static gint gdk_event_translate (GdkEvent *event,
+static gboolean gdk_event_translate (GdkEvent *event,
MSG *xevent,
gboolean *ret_val_flagp,
gint *ret_valp);
@@ -125,7 +151,7 @@ static GdkWindow *k_grab_window = NULL; /* Window the holds the
static GList *client_filters; /* Filters for client messages */
static gboolean p_grab_automatic;
-static GdkEventMask p_grab_event_mask;
+static GdkEventMask p_grab_mask;
static gboolean p_grab_owner_events, k_grab_owner_events;
static HCURSOR p_grab_cursor;
@@ -158,22 +184,26 @@ static UINT gdk_ping_msg;
static gboolean ignore_WM_CHAR = FALSE;
static gboolean is_AltGr_key = FALSE;
+static IActiveIMMApp *paimmapp = NULL;
+static IActiveIMMMessagePumpOwner *paimmmpo = NULL;
+
LRESULT CALLBACK
-gdk_WindowProc(HWND hwnd,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
+gdk_WindowProc (HWND hWnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
GdkEvent event;
GdkEvent *eventp;
MSG msg;
DWORD pos;
+ LRESULT lres;
gint ret_val;
gboolean ret_val_flag;
- GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x\n", message));
+ GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x %#.03x\n", hWnd, message));
- msg.hwnd = hwnd;
+ msg.hwnd = hWnd;
msg.message = message;
msg.wParam = wParam;
msg.lParam = lParam;
@@ -182,12 +212,14 @@ gdk_WindowProc(HWND hwnd,
msg.pt.x = LOWORD (pos);
msg.pt.y = HIWORD (pos);
+ ((GdkEventPrivate *)&event)->flags |= GDK_EVENT_PENDING;
if (gdk_event_translate (&event, &msg, &ret_val_flag, &ret_val))
{
+ ((GdkEventPrivate *)&event)->flags &= ~GDK_EVENT_PENDING;
#if 1
- /* Compress configure events */
if (event.any.type == GDK_CONFIGURE)
{
+ /* Compress configure events */
GList *list = queued_events;
while (list != NULL
@@ -203,6 +235,29 @@ gdk_WindowProc(HWND hwnd,
return FALSE;
}
}
+ else if (event.any.type == GDK_EXPOSE)
+ {
+ /* Compress expose events */
+ GList *list = queued_events;
+
+ while (list != NULL
+ && (((GdkEvent *)list->data)->any.type != GDK_EXPOSE
+ || ((GdkEvent *)list->data)->any.window != event.any.window))
+ list = list->next;
+ if (list != NULL)
+ {
+ GdkRectangle u;
+
+ gdk_rectangle_union (&event.expose.area,
+ &((GdkEvent *)list->data)->expose.area,
+ &u);
+ ((GdkEvent *)list->data)->expose.area = u;
+ gdk_window_unref (event.any.window);
+ /* Wake up WaitMessage */
+ PostMessage (NULL, gdk_ping_msg, 0, 0);
+ return FALSE;
+ }
+ }
#endif
eventp = gdk_event_new ();
*eventp = event;
@@ -240,7 +295,13 @@ gdk_WindowProc(HWND hwnd,
if (ret_val_flag)
return ret_val;
else
- return DefWindowProc (hwnd, message, wParam, lParam);
+ {
+ if (paimmapp == NULL
+ || (*paimmapp->lpVtbl->OnDefWindowProc) (paimmapp, hWnd, message, wParam, lParam, &lres) == S_FALSE)
+ return DefWindowProc (hWnd, message, wParam, lParam);
+ else
+ return lres;
+ }
}
/*********************************************
@@ -319,8 +380,18 @@ gdk_event_queue_append (GdkEvent *event)
void
gdk_events_init (void)
{
+ HRESULT hres;
+ HMODULE user32;
+ HINSTANCE commctrl32;
+
if (g_pipe_readable_msg == 0)
g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
+ GDK_NOTE (EVENTS, g_print ("g-pipe-readable = %#.03x\n",
+ g_pipe_readable_msg));
+
+ gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
+ GDK_NOTE (EVENTS, g_print ("gdk-ping = %#.03x\n",
+ gdk_ping_msg));
g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL);
@@ -336,7 +407,34 @@ gdk_events_init (void)
button_number[0] = -1;
button_number[1] = -1;
- gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
+ hres = CoCreateInstance (&CLSID_CActiveIMM,
+ NULL,
+ CLSCTX_ALL,
+ &IID_IActiveIMMApp,
+ (LPVOID *) &paimmapp);
+
+ if (hres == S_OK)
+ {
+ GDK_NOTE (EVENTS, g_print ("IActiveIMMApp created %#x\n",
+ paimmapp));
+ (*paimmapp->lpVtbl->Activate) (paimmapp, TRUE);
+
+ hres = (*paimmapp->lpVtbl->QueryInterface) (paimmapp, &IID_IActiveIMMMessagePumpOwner, &paimmmpo);
+ GDK_NOTE (EVENTS, g_print ("IActiveIMMMessagePumpOwner created %#x\n",
+ paimmmpo));
+ (paimmmpo->lpVtbl->Start) (paimmmpo);
+ }
+
+#ifdef USE_TRACKMOUSEEVENT
+ user32 = GetModuleHandle ("user32.dll");
+ if ((p_TrackMouseEvent = GetProcAddress (user32, "TrackMouseEvent")) == NULL)
+ {
+ if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL)
+ p_TrackMouseEvent = GetProcAddress (commctrl32, "_TrackMouseEvent");
+ }
+ if (p_TrackMouseEvent != NULL)
+ GDK_NOTE (EVENTS, g_print ("Using TrackMouseEvent to detect leave events\n"));
+#endif
}
/*
@@ -809,12 +907,16 @@ gdk_pointer_grab (GdkWindow * window,
{
if (!GDK_DRAWABLE_DESTROYED (window))
{
- GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x\n",
+ GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x%s%s\n",
xwindow,
(owner_events ? "TRUE" : "FALSE"),
- xcursor));
- p_grab_event_mask = event_mask;
- p_grab_owner_events = owner_events != 0;
+ xcursor,
+ (event_mask & GDK_BUTTON_PRESS_MASK) ?
+ " PRESS" : "",
+ (event_mask & GDK_BUTTON_RELEASE_MASK) ?
+ " RELEASE" : ""));
+ p_grab_mask = event_mask;
+ p_grab_owner_events = (owner_events != 0);
p_grab_automatic = FALSE;
#if 0 /* Menus don't work if we use mouse capture. Pity, because many other
@@ -1076,15 +1178,1887 @@ gdk_add_client_message_filter (GdkAtom message_type,
client_filters = g_list_prepend (client_filters, filter);
}
+/* Thanks to Markus G. Kuhn <mkuhn@acm.org> for the ksysym<->Unicode
+ * mapping functions, from the xterm sources.
+ */
+
+struct k2u {
+ unsigned short keysym;
+ unsigned short ucs;
+} k2utab[] = {
+ { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */
+ { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */
+ { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */
+ { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */
+ { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */
+ { 0x01a9, 0x0160 }, /* Scaron Å  LATIN CAPITAL LETTER S WITH CARON */
+ { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */
+ { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */
+ { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */
+ { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */
+ { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+ { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */
+ { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */
+ { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */
+ { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */
+ { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */
+ { 0x01b7, 0x02c7 }, /* caron ˇ CARON */
+ { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */
+ { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */
+ { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */
+ { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */
+ { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */
+ { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */
+ { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */
+ { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */
+ { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */
+ { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */
+ { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */
+ { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */
+ { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */
+ { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */
+ { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */
+ { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */
+ { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */
+ { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */
+ { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+ { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */
+ { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */
+ { 0x01db, 0x0170 }, /* Udoubleacute Å° LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+ { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */
+ { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */
+ { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */
+ { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */
+ { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */
+ { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */
+ { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */
+ { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */
+ { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */
+ { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */
+ { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */
+ { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */
+ { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+ { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */
+ { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */
+ { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+ { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */
+ { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */
+ { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */
+ { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+ { 0x02a9, 0x0130 }, /* Iabovedot Ä° LATIN CAPITAL LETTER I WITH DOT ABOVE */
+ { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */
+ { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+ { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */
+ { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */
+ { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */
+ { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */
+ { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */
+ { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */
+ { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+ { 0x02d5, 0x0120 }, /* Gabovedot Ä  LATIN CAPITAL LETTER G WITH DOT ABOVE */
+ { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+ { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */
+ { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+ { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */
+ { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */
+ { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */
+ { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */
+ { 0x02fd, 0x016d }, /* ubreve Å­ LATIN SMALL LETTER U WITH BREVE */
+ { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */
+ { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */
+ { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */
+ { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */
+ { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */
+ { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */
+ { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */
+ { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */
+ { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */
+ { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */
+ { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */
+ { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */
+ { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */
+ { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */
+ { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */
+ { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */
+ { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */
+ { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */
+ { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */
+ { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */
+ { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */
+ { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */
+ { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */
+ { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */
+ { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */
+ { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */
+ { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */
+ { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */
+ { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */
+ { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */
+ { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */
+ { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */
+ { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */
+ { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */
+ { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */
+ { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */
+ { 0x047e, 0x203e }, /* overline ‾ OVERLINE */
+ { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
+ { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
+ { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */
+ { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */
+ { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */
+ { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */
+ { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */
+ { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */
+ { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */
+ { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */
+ { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */
+ { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */
+ { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */
+ { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */
+ { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */
+ { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+ { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */
+ { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */
+ { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */
+ { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */
+ { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */
+ { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */
+ { 0x04b7, 0x30ad }, /* kana_KI ã‚­ KATAKANA LETTER KI */
+ { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */
+ { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */
+ { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */
+ { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */
+ { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */
+ { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */
+ { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */
+ { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */
+ { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */
+ { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */
+ { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */
+ { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */
+ { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */
+ { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */
+ { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */
+ { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */
+ { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */
+ { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */
+ { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */
+ { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */
+ { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */
+ { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */
+ { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */
+ { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */
+ { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */
+ { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */
+ { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */
+ { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */
+ { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */
+ { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */
+ { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */
+ { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */
+ { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */
+ { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */
+ { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */
+ { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */
+ { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */
+ { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */
+ { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */
+ { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+ { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */
+ { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */
+ { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */
+ { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */
+ { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */
+ { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */
+ { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */
+ { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */
+ { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */
+ { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */
+ { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */
+ { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */
+ { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */
+ { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */
+ { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */
+ { 0x05cd, 0x062d }, /* Arabic_hah Ø­ ARABIC LETTER HAH */
+ { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */
+ { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */
+ { 0x05d0, 0x0630 }, /* Arabic_thal Ø° ARABIC LETTER THAL */
+ { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */
+ { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */
+ { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */
+ { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */
+ { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */
+ { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */
+ { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */
+ { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */
+ { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */
+ { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */
+ { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */
+ { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */
+ { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */
+ { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */
+ { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */
+ { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */
+ { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */
+ { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */
+ { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */
+ { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */
+ { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */
+ { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */
+ { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */
+ { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */
+ { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */
+ { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */
+ { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */
+ { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */
+ { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */
+ { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */
+ { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */
+ { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */
+ { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */
+ { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */
+ { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */
+ { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */
+ { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */
+ { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */
+ { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */
+ { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */
+ { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */
+ { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */
+ { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */
+ { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */
+ { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */
+ { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */
+ { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+ { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */
+ { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */
+ { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */
+ { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */
+ { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */
+ { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */
+ { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */
+ { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */
+ { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */
+ { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */
+ { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */
+ { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */
+ { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */
+ { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */
+ { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */
+ { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */
+ { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */
+ { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */
+ { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */
+ { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */
+ { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */
+ { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */
+ { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */
+ { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */
+ { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */
+ { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */
+ { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */
+ { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */
+ { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */
+ { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */
+ { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */
+ { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */
+ { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */
+ { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */
+ { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */
+ { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */
+ { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */
+ { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */
+ { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */
+ { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */
+ { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */
+ { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */
+ { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */
+ { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */
+ { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */
+ { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */
+ { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */
+ { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */
+ { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */
+ { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */
+ { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */
+ { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */
+ { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */
+ { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */
+ { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */
+ { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */
+ { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */
+ { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */
+ { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */
+ { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */
+ { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */
+ { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */
+ { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */
+ { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */
+ { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */
+ { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */
+ { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */
+ { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */
+ { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */
+ { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */
+ { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */
+ { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */
+ { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */
+ { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */
+ { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
+ { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
+ { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
+ { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+ { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
+ { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */
+ { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */
+ { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */
+ { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */
+ { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
+ { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
+ { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */
+ { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */
+ { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+ { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+ { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */
+ { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */
+ { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+ { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */
+ { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */
+ { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */
+ { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */
+ { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */
+ { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */
+ { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */
+ { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */
+ { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */
+ { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */
+ { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */
+ { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */
+ { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */
+ { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */
+ { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */
+ { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */
+ { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */
+ { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */
+ { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */
+ { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */
+ { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */
+ { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */
+ { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
+ { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
+ { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
+ { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */
+ { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */
+ { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */
+ { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */
+ { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */
+ { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */
+ { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */
+ { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */
+ { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */
+ { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */
+ { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */
+ { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */
+ { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */
+ { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */
+ { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */
+ { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */
+ { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */
+ { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */
+ { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */
+ { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */
+ { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */
+ { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */
+ { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
+ { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
+ { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
+/* 0x08a1 leftradical ? ??? */
+/* 0x08a2 topleftradical ? ??? */
+/* 0x08a3 horizconnector ? ??? */
+ { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
+ { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
+ { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
+/* 0x08a7 topleftsqbracket ? ??? */
+/* 0x08a8 botleftsqbracket ? ??? */
+/* 0x08a9 toprightsqbracket ? ??? */
+/* 0x08aa botrightsqbracket ? ??? */
+/* 0x08ab topleftparens ? ??? */
+/* 0x08ac botleftparens ? ??? */
+/* 0x08ad toprightparens ? ??? */
+/* 0x08ae botrightparens ? ??? */
+/* 0x08af leftmiddlecurlybrace ? ??? */
+/* 0x08b0 rightmiddlecurlybrace ? ??? */
+/* 0x08b1 topleftsummation ? ??? */
+/* 0x08b2 botleftsummation ? ??? */
+/* 0x08b3 topvertsummationconnector ? ??? */
+/* 0x08b4 botvertsummationconnector ? ??? */
+/* 0x08b5 toprightsummation ? ??? */
+/* 0x08b6 botrightsummation ? ??? */
+/* 0x08b7 rightmiddlesummation ? ??? */
+ { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
+ { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
+ { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */
+ { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
+ { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
+ { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */
+ { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
+ { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
+ { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
+/* 0x08c9 similarequal ? ??? */
+ { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
+ { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
+ { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
+ { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */
+ { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */
+ { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */
+ { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */
+ { 0x08dd, 0x222a }, /* union ∪ UNION */
+ { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */
+ { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */
+ { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */
+ { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */
+ { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */
+ { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
+ { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
+ { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
+ { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */
+ { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */
+ { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */
+ { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */
+ { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */
+ { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */
+ { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */
+ { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */
+ { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */
+ { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */
+ { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */
+ { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
+ { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */
+ { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+/* 0x09ef horizlinescan1 ? ??? */
+/* 0x09f0 horizlinescan3 ? ??? */
+ { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
+/* 0x09f2 horizlinescan7 ? ??? */
+/* 0x09f3 horizlinescan9 ? ??? */
+ { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+ { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+ { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+ { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+ { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */
+ { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */
+ { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */
+ { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */
+ { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */
+ { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */
+ { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */
+ { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */
+ { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */
+ { 0x0aa9, 0x2014 }, /* emdash — EM DASH */
+ { 0x0aaa, 0x2013 }, /* endash – EN DASH */
+/* 0x0aac signifblank ? ??? */
+ { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
+/* 0x0aaf doubbaselinedot ? ??? */
+ { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */
+ { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */
+ { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */
+ { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */
+ { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */
+ { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */
+ { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */
+ { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */
+ { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */
+ { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
+ { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
+ { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
+ { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
+/* 0x0abf marker ? ??? */
+ { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */
+ { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
+ { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */
+ { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */
+ { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */
+ { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */
+/* 0x0acb trademarkincircle ? ??? */
+ { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */
+ { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */
+ { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */
+ { 0x0acf, 0x25a1 }, /* emopenrectangle â–¡ WHITE SQUARE */
+ { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
+ { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
+ { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
+ { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */
+ { 0x0ad4, 0x211e }, /* prescription â„ž PRESCRIPTION TAKE */
+ { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
+ { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
+ { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */
+/* 0x0ada hexagram ? ??? */
+ { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */
+ { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */
+ { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */
+ { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */
+ { 0x0adf, 0x25a0 }, /* emfilledrect â–  BLACK SQUARE */
+ { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */
+ { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */
+ { 0x0ae2, 0x25ad }, /* openrectbullet â–­ WHITE RECTANGLE */
+ { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */
+ { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */
+ { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */
+ { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
+ { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */
+ { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */
+ { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */
+ { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */
+ { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */
+ { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */
+ { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */
+ { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */
+ { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
+ { 0x0af1, 0x2020 }, /* dagger † DAGGER */
+ { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
+ { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */
+ { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
+ { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */
+ { 0x0af6, 0x266d }, /* musicalflat â™­ MUSIC FLAT SIGN */
+ { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */
+ { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */
+ { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */
+ { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
+ { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */
+ { 0x0afc, 0x2038 }, /* caret ‸ CARET */
+ { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */
+ { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */
+/* 0x0aff cursor ? ??? */
+ { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */
+ { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */
+ { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */
+ { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */
+ { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */
+ { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */
+ { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */
+ { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */
+ { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */
+ { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */
+ { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
+ { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */
+ { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */
+ { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */
+ { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
+ { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */
+ { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */
+ { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */
+ { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */
+ { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */
+ { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */
+ { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */
+ { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */
+ { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */
+ { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */
+ { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */
+ { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */
+ { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */
+ { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */
+ { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */
+ { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */
+ { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */
+ { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */
+ { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */
+ { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */
+ { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */
+ { 0x0cf0, 0x05e0 }, /* hebrew_nun ×  HEBREW LETTER NUN */
+ { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */
+ { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */
+ { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */
+ { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */
+ { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */
+ { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */
+ { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */
+ { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */
+ { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */
+ { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */
+ { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */
+ { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */
+ { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */
+ { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */
+ { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */
+ { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */
+ { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */
+ { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */
+ { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */
+ { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */
+ { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */
+ { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */
+ { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */
+ { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */
+ { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */
+ { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */
+ { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */
+ { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */
+ { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */
+ { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */
+ { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */
+ { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */
+ { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */
+ { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */
+ { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */
+ { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */
+ { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */
+ { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */
+ { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */
+ { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */
+ { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */
+ { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */
+ { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */
+ { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */
+ { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */
+ { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */
+ { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */
+ { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */
+ { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */
+ { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */
+ { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */
+ { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */
+ { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */
+ { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */
+ { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */
+ { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */
+ { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */
+ { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */
+ { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */
+ { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */
+ { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */
+ { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */
+ { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */
+ { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */
+ { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */
+ { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */
+ { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */
+ { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */
+ { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */
+ { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */
+ { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */
+ { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */
+ { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */
+ { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */
+ { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */
+ { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */
+ { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */
+ { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */
+ { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */
+ { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */
+ { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */
+ { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */
+ { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */
+ { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */
+ { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */
+ { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */
+ { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */
+ { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */
+ { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */
+ { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */
+ { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */
+ { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */
+ { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */
+ { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */
+ { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */
+ { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */
+ { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */
+ { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */
+ { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */
+ { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */
+ { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */
+ { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */
+ { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */
+ { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */
+ { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */
+ { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */
+ { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */
+ { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */
+ { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */
+ { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */
+ { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */
+ { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */
+ { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */
+ { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */
+ { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */
+ { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */
+ { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */
+ { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */
+ { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */
+ { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */
+ { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */
+ { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */
+ { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */
+ { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */
+ { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */
+ { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */
+ { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */
+ { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */
+ { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */
+ { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */
+ { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */
+ { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */
+ { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */
+ { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */
+ { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */
+ { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */
+ { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */
+ { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */
+ { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */
+ { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */
+ { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */
+ { 0x0ed0, 0x3160 }, /* Hangul_YU ã…  HANGUL LETTER YU */
+ { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */
+ { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */
+ { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */
+ { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */
+ { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */
+ { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */
+ { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */
+ { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */
+ { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */
+ { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */
+ { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */
+ { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */
+ { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */
+ { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */
+ { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */
+ { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */
+ { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */
+ { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */
+ { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */
+ { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */
+ { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */
+ { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */
+ { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */
+ { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */
+ { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */
+ { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */
+ { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */
+ { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */
+ { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */
+ { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
+ { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã…­ HANGUL LETTER RIEUL-YEORINHIEUH */
+ { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */
+ { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */
+ { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */
+/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
+ { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
+ { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
+ { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */
+ { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
+ { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
+/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */
+ { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
+ { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */
+ { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */
+ { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */
+ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ { 0x20a0, 0x20a0 }, /* EcuSign â‚  EURO-CURRENCY SIGN */
+ { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */
+ { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */
+ { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */
+ { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */
+ { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */
+ { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */
+ { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */
+ { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */
+ { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */
+ { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */
+ { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */
+ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */
+};
+
+static guint
+keyval_to_unicode (guint keysym)
+{
+ int min = 0;
+ int max = sizeof(k2utab) / sizeof(k2utab[0]) - 1;
+ int mid;
+
+ /* First check for Latin-1 characters (1:1 mapping) */
+ if ((keysym >= 0x0020 && keysym <= 0x007e) ||
+ (keysym >= 0x00a0 && keysym <= 0x00ff))
+ return keysym;
+
+ /* Also check for directly encoded 24-bit UCS characters */
+ if ((keysym & 0xff000000) == 0x01000000)
+ return keysym & 0x00ffffff;
+
+ /* binary search in table */
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (k2utab[mid].keysym < keysym)
+ min = mid + 1;
+ else if (k2utab[mid].keysym > keysym)
+ max = mid - 1;
+ else {
+ /* found it */
+ return k2utab[mid].ucs;
+ }
+ }
+
+ /* No matching Unicode value found */
+ return -1;
+}
+
+struct u2k {
+ unsigned short keysym;
+ unsigned short ucs;
+} u2ktab[] = {
+ { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
+ { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */
+ { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */
+ { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */
+ { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */
+ { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */
+ { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */
+ { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */
+ { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */
+ { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */
+ { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */
+ { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */
+ { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */
+ { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+ { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */
+ { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */
+ { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */
+ { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */
+ { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */
+ { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */
+ { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */
+ { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */
+ { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */
+ { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */
+ { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */
+ { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */
+ { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */
+ { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */
+ { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */
+ { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */
+ { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */
+ { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+ { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */
+ { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */
+ { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */
+ { 0x02d5, 0x0120 }, /* Gabovedot Ä  LATIN CAPITAL LETTER G WITH DOT ABOVE */
+ { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */
+ { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */
+ { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */
+ { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+ { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */
+ { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */
+ { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */
+ { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */
+ { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */
+ { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */
+ { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */
+ { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */
+ { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */
+ { 0x02a9, 0x0130 }, /* Iabovedot Ä° LATIN CAPITAL LETTER I WITH DOT ABOVE */
+ { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */
+ { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+ { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */
+ { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */
+ { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */
+ { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */
+ { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */
+ { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */
+ { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */
+ { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */
+ { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */
+ { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */
+ { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */
+ { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */
+ { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */
+ { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */
+ { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */
+ { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */
+ { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */
+ { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */
+ { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */
+ { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */
+ { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */
+ { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */
+ { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+ { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+ { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */
+ { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */
+ { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */
+ { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */
+ { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */
+ { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */
+ { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */
+ { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */
+ { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */
+ { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */
+ { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+ { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */
+ { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */
+ { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */
+ { 0x01a9, 0x0160 }, /* Scaron Å  LATIN CAPITAL LETTER S WITH CARON */
+ { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */
+ { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */
+ { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */
+ { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */
+ { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */
+ { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */
+ { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */
+ { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */
+ { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */
+ { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */
+ { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */
+ { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */
+ { 0x02fd, 0x016d }, /* ubreve Å­ LATIN SMALL LETTER U WITH BREVE */
+ { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */
+ { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */
+ { 0x01db, 0x0170 }, /* Udoubleacute Å° LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+ { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+ { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */
+ { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */
+ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */
+ { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */
+ { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+ { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */
+ { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */
+ { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */
+ { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */
+ { 0x01b7, 0x02c7 }, /* caron ˇ CARON */
+ { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */
+ { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */
+ { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */
+ { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */
+ { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */
+ { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */
+ { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
+ { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
+ { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
+ { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
+ { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */
+ { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */
+ { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+ { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */
+ { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */
+ { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */
+ { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */
+ { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */
+ { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */
+ { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */
+ { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */
+ { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */
+ { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */
+ { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */
+ { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */
+ { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */
+ { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */
+ { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */
+ { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */
+ { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */
+ { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */
+ { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */
+ { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */
+ { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */
+ { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
+ { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
+ { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
+ { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+ { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
+ { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
+ { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */
+ { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */
+ { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+ { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */
+ { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */
+ { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */
+ { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */
+ { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */
+ { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */
+ { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */
+ { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */
+ { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */
+ { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */
+ { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */
+ { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */
+ { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */
+ { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */
+ { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */
+ { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */
+ { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */
+ { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */
+ { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */
+ { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */
+ { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */
+ { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */
+ { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
+ { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
+ { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
+ { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+ { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */
+ { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */
+ { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */
+ { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */
+ { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */
+ { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */
+ { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+ { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */
+ { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */
+ { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */
+ { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */
+ { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */
+ { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */
+ { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */
+ { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */
+ { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */
+ { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */
+ { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */
+ { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */
+ { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */
+ { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */
+ { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */
+ { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */
+ { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */
+ { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */
+ { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */
+ { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */
+ { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */
+ { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */
+ { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */
+ { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */
+ { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */
+ { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */
+ { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */
+ { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */
+ { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */
+ { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */
+ { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */
+ { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */
+ { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */
+ { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */
+ { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */
+ { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */
+ { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */
+ { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */
+ { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */
+ { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */
+ { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */
+ { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */
+ { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */
+ { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */
+ { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */
+ { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */
+ { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */
+ { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */
+ { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */
+ { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */
+ { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */
+ { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */
+ { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */
+ { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */
+ { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */
+ { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */
+ { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */
+ { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */
+ { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */
+ { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */
+ { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */
+ { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */
+ { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */
+ { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */
+ { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */
+ { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */
+ { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */
+ { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */
+ { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */
+ { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */
+ { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */
+ { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */
+ { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */
+ { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */
+ { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */
+ { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */
+ { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */
+ { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */
+ { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */
+ { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */
+ { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */
+ { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */
+ { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */
+ { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */
+ { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */
+ { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */
+ { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */
+ { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */
+ { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */
+ { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */
+ { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */
+ { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */
+ { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */
+ { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */
+ { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */
+ { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */
+ { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */
+ { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */
+ { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */
+ { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */
+ { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */
+ { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */
+ { 0x0cf0, 0x05e0 }, /* hebrew_nun ×  HEBREW LETTER NUN */
+ { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */
+ { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */
+ { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */
+ { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */
+ { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */
+ { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */
+ { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */
+ { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */
+ { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */
+ { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */
+ { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */
+ { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */
+ { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */
+ { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */
+ { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */
+ { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */
+ { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */
+ { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */
+ { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */
+ { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */
+ { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */
+ { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */
+ { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */
+ { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */
+ { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */
+ { 0x05cd, 0x062d }, /* Arabic_hah Ø­ ARABIC LETTER HAH */
+ { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */
+ { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */
+ { 0x05d0, 0x0630 }, /* Arabic_thal Ø° ARABIC LETTER THAL */
+ { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */
+ { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */
+ { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */
+ { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */
+ { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */
+ { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */
+ { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */
+ { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */
+ { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */
+ { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */
+ { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */
+ { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */
+ { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */
+ { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */
+ { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */
+ { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */
+ { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */
+ { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */
+ { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */
+ { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */
+ { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */
+ { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */
+ { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */
+ { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */
+ { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */
+ { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */
+ { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */
+ { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */
+ { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */
+ { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */
+ { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */
+ { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */
+ { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */
+ { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */
+ { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */
+ { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */
+ { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */
+ { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */
+ { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */
+ { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */
+ { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */
+ { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */
+ { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */
+ { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */
+ { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */
+ { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */
+ { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */
+ { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */
+ { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */
+ { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */
+ { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */
+ { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */
+ { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */
+ { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */
+ { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */
+ { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */
+ { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */
+ { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */
+ { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */
+ { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */
+ { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */
+ { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */
+ { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */
+ { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */
+ { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */
+ { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */
+ { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */
+ { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */
+ { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */
+ { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */
+ { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */
+ { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */
+ { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */
+ { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */
+ { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */
+ { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */
+ { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */
+ { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */
+ { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */
+ { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */
+ { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */
+ { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */
+ { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */
+ { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */
+ { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */
+ { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */
+ { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */
+ { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */
+ { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */
+ { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */
+ { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */
+ { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */
+ { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */
+ { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */
+ { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */
+ { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */
+ { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */
+ { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */
+ { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */
+ { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */
+ { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */
+ { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */
+ { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */
+ { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */
+ { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */
+ { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */
+ { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */
+ { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */
+ { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */
+ { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */
+ { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */
+ { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */
+ { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */
+ { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */
+ { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */
+ { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */
+ { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */
+ { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */
+ { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */
+ { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */
+ { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */
+ { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */
+ { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */
+ { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */
+ { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */
+ { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */
+ { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */
+ { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */
+ { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */
+ { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */
+ { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */
+ { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */
+ { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */
+ { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */
+ { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */
+ { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */
+ { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */
+ { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */
+ { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
+ { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
+ { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
+ { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */
+ { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */
+ { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */
+ { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */
+ { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */
+ { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */
+ { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */
+ { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */
+ { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
+ { 0x0aaa, 0x2013 }, /* endash – EN DASH */
+ { 0x0aa9, 0x2014 }, /* emdash — EM DASH */
+ { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */
+ { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */
+ { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
+ { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
+ { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */
+ { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
+ { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */
+ { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */
+ { 0x0af1, 0x2020 }, /* dagger † DAGGER */
+ { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
+ { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
+ { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
+ { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
+ { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
+ { 0x0afc, 0x2038 }, /* caret ‸ CARET */
+ { 0x047e, 0x203e }, /* overline ‾ OVERLINE */
+ { 0x20a0, 0x20a0 }, /* EcuSign â‚  EURO-CURRENCY SIGN */
+ { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */
+ { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */
+ { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */
+ { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */
+ { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */
+ { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */
+ { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */
+ { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */
+ { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */
+ { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */
+ { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */
+ { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */
+ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */
+ { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */
+ { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */
+ { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */
+ { 0x0ad4, 0x211e }, /* prescription â„ž PRESCRIPTION TAKE */
+ { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */
+ { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */
+ { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */
+ { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */
+ { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */
+ { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */
+ { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */
+ { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */
+ { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */
+ { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */
+ { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
+ { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */
+ { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */
+ { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */
+ { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
+ { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
+ { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
+ { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
+ { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
+ { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */
+ { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
+ { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */
+ { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */
+ { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */
+ { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
+ { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */
+ { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */
+ { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */
+ { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */
+ { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */
+ { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */
+ { 0x08dd, 0x222a }, /* union ∪ UNION */
+ { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
+ { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
+ { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
+ { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
+ { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
+ { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
+ { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
+ { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */
+ { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */
+ { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */
+ { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */
+ { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */
+ { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */
+ { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */
+ { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */
+ { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */
+ { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */
+ { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */
+ { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
+ { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
+ { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
+ { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
+ { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
+ { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
+ { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */
+ { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */
+ { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */
+ { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */
+ { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */
+ { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */
+ { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */
+ { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
+ { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
+ { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */
+ { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
+ { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */
+ { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */
+ { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */
+ { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+ { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+ { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+ { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+ { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+ { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */
+ { 0x0adf, 0x25a0 }, /* emfilledrect â–  BLACK SQUARE */
+ { 0x0acf, 0x25a1 }, /* emopenrectangle â–¡ WHITE SQUARE */
+ { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */
+ { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */
+ { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */
+ { 0x0ae2, 0x25ad }, /* openrectbullet â–­ WHITE RECTANGLE */
+ { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */
+ { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */
+ { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */
+ { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */
+ { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */
+ { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */
+ { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */
+ { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */
+ { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */
+ { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */
+ { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */
+ { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */
+ { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */
+ { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */
+ { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */
+ { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */
+ { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */
+ { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */
+ { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */
+ { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */
+ { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */
+ { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */
+ { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */
+ { 0x0af6, 0x266d }, /* musicalflat â™­ MUSIC FLAT SIGN */
+ { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */
+ { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */
+ { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
+ { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */
+ { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
+ { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */
+ { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
+ { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
+ { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */
+ { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */
+ { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+ { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */
+ { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */
+ { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */
+ { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */
+ { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */
+ { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */
+ { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */
+ { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */
+ { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */
+ { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */
+ { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */
+ { 0x04b7, 0x30ad }, /* kana_KI ã‚­ KATAKANA LETTER KI */
+ { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */
+ { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */
+ { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */
+ { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */
+ { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */
+ { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */
+ { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */
+ { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */
+ { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */
+ { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */
+ { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */
+ { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */
+ { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */
+ { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */
+ { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */
+ { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */
+ { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */
+ { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */
+ { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */
+ { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */
+ { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */
+ { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */
+ { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */
+ { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */
+ { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */
+ { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */
+ { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */
+ { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */
+ { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */
+ { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */
+ { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */
+ { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */
+ { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */
+ { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */
+ { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */
+ { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */
+ { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */
+ { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */
+ { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */
+ { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */
+ { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */
+ { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */
+ { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */
+ { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */
+ { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+ { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */
+ { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */
+ { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */
+ { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */
+ { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */
+ { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */
+ { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */
+ { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */
+ { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */
+ { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */
+ { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */
+ { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */
+ { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */
+ { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */
+ { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */
+ { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */
+ { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */
+ { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */
+ { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */
+ { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */
+ { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */
+ { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */
+ { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */
+ { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */
+ { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */
+ { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */
+ { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */
+ { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */
+ { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */
+ { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */
+ { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */
+ { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */
+ { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */
+ { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */
+ { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */
+ { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */
+ { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */
+ { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */
+ { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */
+ { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */
+ { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */
+ { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */
+ { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */
+ { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */
+ { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */
+ { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */
+ { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */
+ { 0x0ed0, 0x3160 }, /* Hangul_YU ã…  HANGUL LETTER YU */
+ { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */
+ { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */
+ { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */
+ { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã…­ HANGUL LETTER RIEUL-YEORINHIEUH */
+ { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */
+ { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */
+ { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */
+ { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
+ { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
+ { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */
+ { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
+};
+
+static guint
+unicode_to_keyval (wchar_t ucs)
+{
+ int min = 0;
+ int max = sizeof(u2ktab) / sizeof(u2ktab[0]) - 1;
+ int mid;
+
+ /* First check for Latin-1 characters (1:1 mapping) */
+ if ((ucs >= 0x0020 && ucs <= 0x007e) ||
+ (ucs >= 0x00a0 && ucs <= 0x00ff))
+ return ucs;
+
+ /* Binary search in table */
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (u2ktab[mid].ucs < ucs)
+ min = mid + 1;
+ else if (u2ktab[mid].ucs > ucs)
+ max = mid - 1;
+ else {
+ /* found it */
+ return u2ktab[mid].keysym;
+ }
+ }
+
+ /*
+ * No matching keysym value found, return Unicode value plus 0x01000000
+ * (a convention introduced in the UTF-8 work on xterm).
+ */
+ return ucs | 0x01000000;
+}
+
+static void
+build_key_event_state (GdkEvent *event)
+{
+ event->key.state = 0;
+ if (GetKeyState (VK_SHIFT) < 0)
+ event->key.state |= GDK_SHIFT_MASK;
+ if (GetKeyState (VK_CAPITAL) & 0x1)
+ event->key.state |= GDK_LOCK_MASK;
+ if (!is_AltGr_key)
+ {
+ if (GetKeyState (VK_CONTROL) < 0)
+ {
+ event->key.state |= GDK_CONTROL_MASK;
+ if (event->key.keyval < ' ')
+ event->key.keyval += '@';
+ }
+ else if (event->key.keyval < ' ')
+ {
+ event->key.state |= GDK_CONTROL_MASK;
+ event->key.keyval += '@';
+ }
+ if (GetKeyState (VK_MENU) < 0)
+ event->key.state |= GDK_MOD1_MASK;
+ }
+}
+
+static void
+build_keypress_event (GdkWindowPrivate *window_private,
+ GdkEvent *event,
+ MSG *xevent)
+{
+ gint i, bytesleft, bytecount, ucount, ucleft, len;
+ guchar buf[100], *bp;
+ wchar_t wbuf[100], *wcp;
+
+ event->key.type = GDK_KEY_PRESS;
+ event->key.time = xevent->time;
+
+ if (xevent->message == WM_CHAR)
+ {
+ bytecount = MIN ((xevent->lParam & 0xFFFF), sizeof (buf));
+ for (i = 0; i < bytecount; i++)
+ buf[i] = xevent->wParam;
+ }
+ else
+ {
+ /* WM_IME_CHAR */
+ event->key.keyval = GDK_VoidSymbol;
+ if (xevent->wParam & 0xFF00)
+ {
+ /* Contrary to the documentation,
+ * the lead byte is the msb byte.
+ */
+ buf[0] = ((xevent->wParam >> 8) & 0xFF);
+ buf[1] = (xevent->wParam & 0xFF);
+ bytecount = 2;
+ }
+ else
+ {
+ buf[0] = (xevent->wParam & 0xFF);
+ bytecount = 1;
+ }
+ }
+
+ /* Convert from the window's current code page
+ * to Unicode. Then convert to UTF-8.
+ * We don't handle the surrogate stuff. Should we?
+ */
+ ucount = MultiByteToWideChar (window_private->charset_info.ciACP,
+ 0, buf, bytecount, wbuf, 100);
+
+ if (ucount == 0)
+ event->key.keyval = GDK_VoidSymbol;
+ else if (xevent->message == WM_CHAR)
+ if (xevent->wParam < ' ')
+ event->key.keyval = xevent->wParam + '@';
+ else
+ event->key.keyval = unicode_to_keyval (wbuf[0]);
+ else
+ event->key.keyval = GDK_VoidSymbol;
+
+ build_key_event_state (event);
+
+ ucleft = ucount;
+ len = 0;
+ wcp = wbuf;
+ while (ucleft-- > 0)
+ {
+ wchar_t c = *wcp++;
+
+ if (c < 0x80)
+ len += 1;
+ else if (c < 0x800)
+ len += 2;
+ else
+ len += 3;
+ }
+
+ event->key.string = g_malloc (len + 1);
+ event->key.length = len;
+
+ ucleft = ucount;
+ wcp = wbuf;
+ bp = event->key.string;
+ while (ucleft-- > 0)
+ {
+ int first;
+ int i;
+ wchar_t c = *wcp++;
+
+ if (c < 0x80)
+ {
+ first = 0;
+ len = 1;
+ }
+ else if (c < 0x800)
+ {
+ first = 0xc0;
+ len = 2;
+ }
+ else
+ {
+ first = 0xe0;
+ len = 3;
+ }
+
+#if 1
+ /* Woo-hoo! */
+ switch (len)
+ {
+ case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 1: bp[0] = c | first;
+ }
+#else
+ for (i = len - 1; i > 0; --i)
+ {
+ bp[i] = (c & 0x3f) | 0x80;
+ c >>= 6;
+ }
+ bp[0] = c | first;
+#endif
+
+ bp += len;
+ }
+ *bp = 0;
+}
+
+static void
+print_event_state (gint state)
+{
+ if (state & GDK_SHIFT_MASK)
+ g_print ("SHIFT ");
+ if (state & GDK_LOCK_MASK)
+ g_print ("LOCK ");
+ if (state & GDK_CONTROL_MASK)
+ g_print ("CONTROL ");
+ if (state & GDK_MOD1_MASK)
+ g_print ("MOD1 ");
+ if (state & GDK_BUTTON1_MASK)
+ g_print ("BUTTON1 ");
+ if (state & GDK_BUTTON2_MASK)
+ g_print ("BUTTON2 ");
+ if (state & GDK_BUTTON3_MASK)
+ g_print ("BUTTON3 ");
+}
+
+static void
+print_event (GdkEvent *event)
+{
+ gchar *escaped, *kvname;
+
+ switch (event->any.type)
+ {
+ case GDK_NOTHING: g_print ("GDK_NOTHING "); break;
+ case GDK_DELETE: g_print ("GDK_DELETE "); break;
+ case GDK_DESTROY: g_print ("GDK_DESTROY "); break;
+ case GDK_EXPOSE: g_print ("GDK_EXPOSE "); break;
+ case GDK_MOTION_NOTIFY: g_print ("GDK_MOTION_NOTIFY "); break;
+ case GDK_BUTTON_PRESS: g_print ("GDK_BUTTON_PRESS "); break;
+ case GDK_2BUTTON_PRESS: g_print ("GDK_2BUTTON_PRESS "); break;
+ case GDK_3BUTTON_PRESS: g_print ("GDK_3BUTTON_PRESS "); break;
+ case GDK_BUTTON_RELEASE: g_print ("GDK_BUTTON_RELEASE "); break;
+ case GDK_KEY_PRESS: g_print ("GDK_KEY_PRESS "); break;
+ case GDK_KEY_RELEASE: g_print ("GDK_KEY_RELEASE "); break;
+ case GDK_ENTER_NOTIFY: g_print ("GDK_ENTER_NOTIFY "); break;
+ case GDK_LEAVE_NOTIFY: g_print ("GDK_LEAVE_NOTIFY "); break;
+ case GDK_FOCUS_CHANGE: g_print ("GDK_FOCUS_CHANGE "); break;
+ case GDK_CONFIGURE: g_print ("GDK_CONFIGURE "); break;
+ case GDK_MAP: g_print ("GDK_MAP "); break;
+ case GDK_UNMAP: g_print ("GDK_UNMAP "); break;
+ case GDK_PROPERTY_NOTIFY: g_print ("GDK_PROPERTY_NOTIFY "); break;
+ case GDK_SELECTION_CLEAR: g_print ("GDK_SELECTION_CLEAR "); break;
+ case GDK_SELECTION_REQUEST: g_print ("GDK_SELECTION_REQUEST "); break;
+ case GDK_SELECTION_NOTIFY: g_print ("GDK_SELECTION_NOTIFY "); break;
+ case GDK_PROXIMITY_IN: g_print ("GDK_PROXIMITY_IN "); break;
+ case GDK_PROXIMITY_OUT: g_print ("GDK_PROXIMITY_OUT "); break;
+ case GDK_DRAG_ENTER: g_print ("GDK_DRAG_ENTER "); break;
+ case GDK_DRAG_LEAVE: g_print ("GDK_DRAG_LEAVE "); break;
+ case GDK_DRAG_MOTION: g_print ("GDK_DRAG_MOTION "); break;
+ case GDK_DRAG_STATUS: g_print ("GDK_DRAG_STATUS "); break;
+ case GDK_DROP_START: g_print ("GDK_DROP_START "); break;
+ case GDK_DROP_FINISHED: g_print ("GDK_DROP_FINISHED "); break;
+ case GDK_CLIENT_EVENT: g_print ("GDK_CLIENT_EVENT "); break;
+ case GDK_VISIBILITY_NOTIFY: g_print ("GDK_VISIBILITY_NOTIFY "); break;
+ case GDK_NO_EXPOSE: g_print ("GDK_NO_EXPOSE "); break;
+ }
+ g_print ("%#x ", GDK_DRAWABLE_XID (event->any.window));
+
+ switch (event->any.type)
+ {
+ case GDK_EXPOSE:
+ g_print ("%dx%d@+%d+%d %d",
+ event->expose.area.width,
+ event->expose.area.height,
+ event->expose.area.x,
+ event->expose.area.y,
+ event->expose.count);
+ break;
+ case GDK_MOTION_NOTIFY:
+ print_event_state (event->motion.state);
+ break;
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ g_print ("%d ", event->button.button);
+ print_event_state (event->button.state);
+ break;
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ if (event->key.length == 0)
+ escaped = g_strdup ("");
+ else
+ escaped = g_strescape (event->key.string, NULL);
+ kvname = gdk_keyval_name (event->key.keyval);
+ g_print ("%s %d:\"%s\" ",
+ (kvname ? kvname : "??"),
+ event->key.length,
+ escaped);
+ g_free (escaped);
+ print_event_state (event->key.state);
+ break;
+ case GDK_ENTER_NOTIFY:
+ case GDK_LEAVE_NOTIFY:
+ g_print (" %s",
+ (event->crossing.detail == GDK_NOTIFY_INFERIOR ? "INFERIOR" :
+ (event->crossing.detail == GDK_NOTIFY_ANCESTOR ? "ANCESTOR" :
+ (event->crossing.detail == GDK_NOTIFY_NONLINEAR ? "NONLINEAR" :
+ "???"))));
+ break;
+ }
+ g_print ("\n");
+}
+
static void
synthesize_crossing_events (GdkWindow *window,
MSG *xevent)
{
+ TRACKMOUSEEVENT tme;
GdkEvent *event;
- GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
- GdkWindowPrivate *curWnd_private = (GdkWindowPrivate *) curWnd;
- if (curWnd && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
+ /* If we are not using TrackMouseEvent, generate a leave notify
+ * event if necessary
+ */
+ if (p_TrackMouseEvent == NULL
+ && curWnd
+ && (WINDOW_PRIVATE(curWnd)->event_mask & GDK_LEAVE_NOTIFY_MASK))
{
GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n"));
@@ -1099,15 +3073,21 @@ synthesize_crossing_events (GdkWindow *window,
event->crossing.x_root = curXroot;
event->crossing.y_root = curYroot;
event->crossing.mode = GDK_CROSSING_NORMAL;
- event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+ if (IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ else if (IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ else
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
event->crossing.focus = TRUE; /* ??? */
event->crossing.state = 0; /* ??? */
gdk_event_queue_append (event);
+ GDK_NOTE (EVENTS, print_event (event));
}
- if (window_private && (window_private->event_mask & GDK_ENTER_NOTIFY_MASK))
+ if (WINDOW_PRIVATE(window)->event_mask & GDK_ENTER_NOTIFY_MASK)
{
GDK_NOTE (EVENTS, g_print ("synthesizing ENTER_NOTIFY event\n"));
@@ -1122,35 +3102,217 @@ synthesize_crossing_events (GdkWindow *window,
event->crossing.x_root = (gfloat) xevent->pt.x;
event->crossing.y_root = (gfloat) xevent->pt.y;
event->crossing.mode = GDK_CROSSING_NORMAL;
- event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+ if (curWnd
+ && IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ else if (curWnd
+ && IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ else
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
event->crossing.focus = TRUE; /* ??? */
event->crossing.state = 0; /* ??? */
gdk_event_queue_append (event);
- if (window_private->extension_events != 0
+ GDK_NOTE (EVENTS, print_event (event));
+
+ if (WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_vtable.enter_event)
gdk_input_vtable.enter_event (&event->crossing, window);
+
}
if (curWnd)
gdk_window_unref (curWnd);
curWnd = window;
gdk_window_ref (curWnd);
+ if (p_TrackMouseEvent != NULL)
+ {
+ tme.cbSize = sizeof (TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = GDK_DRAWABLE_XID (curWnd);
+ tme.dwHoverTime = HOVER_DEFAULT;
+
+ (*p_TrackMouseEvent) (&tme);
+ }
+}
+
+static GdkWindow *
+key_propagate (GdkWindow *window,
+ MSG *xevent)
+{
+ gdk_window_unref (window);
+ window = WINDOW_PRIVATE(window)->parent;
+ gdk_window_ref (window);
+ GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
+ GDK_DRAWABLE_XID (window)));
+
+ return window;
+}
+
+static GdkWindow *
+mouse_propagate (GdkWindow *window,
+ MSG *xevent)
+{
+ POINT pt;
+
+ pt.x = LOWORD (xevent->lParam);
+ pt.y = HIWORD (xevent->lParam);
+ ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
+ gdk_window_unref (window);
+ window = WINDOW_PRIVATE(window)->parent;
+ gdk_window_ref (window);
+ ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
+ xevent->lParam = MAKELPARAM (pt.x, pt.y);
+ GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
+ GDK_DRAWABLE_XID (window)));
+ return window;
+}
+
+#ifdef NEW_PROPAGATION_CODE
+
+static gboolean
+propagate (GdkWindow **window,
+ MSG *xevent,
+ GdkWindow *grab_window,
+ gboolean grab_owner_events,
+ gint grab_mask,
+ gboolean (*doesnt_want_it) (gint mask,
+ MSG *xevent),
+ GdkWindow *(*propagate) (GdkWindow *window,
+ MSG *xevent))
+{
+ if (grab_window != NULL && !grab_owner_events)
+ {
+ /* Event source is grabbed with owner_events FALSE */
+ GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE, "));
+ if ((*doesnt_want_it) (grab_mask, xevent))
+ {
+ GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n"));
+ return FALSE;
+ }
+ else
+ {
+ GDK_NOTE (EVENTS, g_print ("...sending to grabber %#x\n",
+ GDK_DRAWABLE_XID (grab_window)));
+ gdk_window_unref (*window);
+ *window = grab_window;
+ gdk_window_ref (*window);
+ return TRUE;
+ }
+ }
+ while (TRUE)
+ {
+ if ((*doesnt_want_it) (WINDOW_PRIVATE(*window)->event_mask, xevent))
+ {
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(*window)->parent == (GdkWindow *) gdk_root_parent)
+ {
+ /* No parent; check if grabbed */
+ if (grab_window != NULL)
+ {
+ /* Event source is grabbed with owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ if ((*doesnt_want_it) (grab_mask, xevent))
+ {
+ /* Grabber doesn't want it either */
+ GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n"));
+ return FALSE;
+ }
+ else
+ {
+ /* Grabbed! */
+ GDK_NOTE (EVENTS, g_print ("...sending to grabber %#x\n",
+ GDK_DRAWABLE_XID (grab_window)));
+ gdk_window_unref (*window);
+ *window = grab_window;
+ gdk_window_ref (*window);
+ return TRUE;
+ }
+ }
+ else
+ {
+ GDK_NOTE (EVENTS, "...undelivered\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ *window = (*propagate) (*window, xevent);
+ GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
+ GDK_DRAWABLE_XID (*window)));
+ /* The only branch where we actually continue the loop */
+ }
+ }
+ else
+ return TRUE;
+ }
+}
+
+static gboolean
+doesnt_want_key (gint mask,
+ MSG *xevent)
+{
+ return (((xevent->message == WM_KEYUP
+ || xevent->message == WM_SYSKEYUP)
+ && !(mask & GDK_KEY_RELEASE_MASK))
+ ||
+ ((xevent->message == WM_KEYDOWN
+ || xevent->message == WM_SYSKEYDOWN)
+ && !(mask & GDK_KEY_PRESS_MASK)));
+}
+
+static gboolean
+doesnt_want_char (gint mask,
+ MSG *xevent)
+{
+ return !(mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK));
+}
+
+static gboolean
+doesnt_want_button_press (gint mask,
+ MSG *xevent)
+{
+ return !(mask & GDK_BUTTON_PRESS_MASK);
+}
+
+static gboolean
+doesnt_want_button_release (gint mask,
+ MSG *xevent)
+{
+ return !(mask & GDK_BUTTON_RELEASE_MASK);
+}
+
+static gboolean
+doesnt_want_button_motion (gint mask,
+ MSG *xevent)
+{
+ return !((mask & GDK_POINTER_MOTION_MASK)
+ || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
+ && (mask & GDK_BUTTON_MOTION_MASK))
+ || ((xevent->wParam & MK_LBUTTON)
+ && (mask & GDK_BUTTON1_MOTION_MASK))
+ || ((xevent->wParam & MK_MBUTTON)
+ && (mask & GDK_BUTTON2_MOTION_MASK))
+ || ((xevent->wParam & MK_RBUTTON)
+ && (mask & GDK_BUTTON3_MOTION_MASK)));
}
-static gint
+#endif
+
+static gboolean
gdk_event_translate (GdkEvent *event,
MSG *xevent,
gboolean *ret_val_flagp,
gint *ret_valp)
{
- GdkWindow *window;
- GdkWindowPrivate *window_private;
-
+ GdkWindow *window, *orig_window;
GdkColormapPrivate *colormap_private;
HWND owner;
+ DWORD pidActWin;
+ DWORD pidThis;
DWORD dwStyle;
PAINTSTRUCT paintstruct;
HDC hdc;
@@ -1158,7 +3320,6 @@ gdk_event_translate (GdkEvent *event,
RECT rect;
POINT pt;
MINMAXINFO *lpmmi;
- GdkWindowPrivate *curWnd_private;
GdkEventMask mask;
GdkDrawablePrivate *pixmap_private;
HDC bgdc;
@@ -1166,8 +3327,8 @@ gdk_event_translate (GdkEvent *event,
int button;
int i, j;
gchar buf[256];
- gint charcount;
- gint return_val;
+ gchar *msgname;
+ gboolean return_val;
gboolean flag;
return_val = FALSE;
@@ -1175,16 +3336,15 @@ gdk_event_translate (GdkEvent *event,
if (ret_val_flagp)
*ret_val_flagp = FALSE;
+#ifndef USE_DISPATCHMESSAGE
if (xevent->message == gdk_ping_msg)
{
/* Messages we post ourselves just to wakeup WaitMessage. */
+ GDK_NOTE (EVENTS, g_print ("gdk_ping_msg\n"));
+
return FALSE;
}
-
- window = gdk_window_lookup (xevent->hwnd);
- window_private = (GdkWindowPrivate *) window;
-
- if (xevent->message == g_pipe_readable_msg)
+ else if (xevent->message == g_pipe_readable_msg)
{
GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
xevent->wParam, xevent->lParam));
@@ -1192,7 +3352,11 @@ gdk_event_translate (GdkEvent *event,
g_io_channel_win32_pipe_readable (xevent->wParam, xevent->lParam);
return FALSE;
}
+#endif
+ window = gdk_window_lookup (xevent->hwnd);
+ orig_window = window;
+
if (window != NULL)
gdk_window_ref (window);
else
@@ -1218,18 +3382,12 @@ gdk_event_translate (GdkEvent *event,
return FALSE;
}
- event->any.window = window;
-
- if (window_private && GDK_DRAWABLE_DESTROYED (window))
- {
- }
- else
+ if (!GDK_DRAWABLE_DESTROYED (window))
{
/* Check for filters for this window */
GdkFilterReturn result;
result = gdk_event_apply_filters
- (xevent, event,
- window_private ? window_private->filters : gdk_default_filters);
+ (xevent, event, WINDOW_PRIVATE(window)->filters);
if (result != GDK_FILTER_CONTINUE)
{
@@ -1249,7 +3407,7 @@ gdk_event_translate (GdkEvent *event,
event->selection.property = gdk_selection_property;
event->selection.time = xevent->time;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
/* Will pass through switch below without match */
}
@@ -1266,7 +3424,7 @@ gdk_event_translate (GdkEvent *event,
event->selection.requestor = (guint32) xevent->hwnd;
event->selection.time = xevent->time;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
/* Again, will pass through switch below without match */
}
@@ -1280,7 +3438,7 @@ gdk_event_translate (GdkEvent *event,
event->selection.selection = xevent->wParam;
event->selection.time = xevent->time;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = GDK_DRAWABLE_DESTROYED (window);
/* Once again, we will pass through switch below without match */
}
@@ -1325,6 +3483,16 @@ gdk_event_translate (GdkEvent *event,
switch (xevent->message)
{
+ case WM_INPUTLANGCHANGE:
+ GDK_NOTE (EVENTS,
+ g_print ("WM_INPUTLANGCHANGE: %#x charset %d locale %x\n",
+ xevent->hwnd, xevent->wParam, xevent->lParam));
+ WINDOW_PRIVATE(window)->input_locale = (HKL) xevent->lParam;
+ TranslateCharsetInfo ((DWORD FAR *) xevent->wParam,
+ &WINDOW_PRIVATE(window)->charset_info,
+ TCI_SRCCHARSET);
+ break;
+
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
GDK_NOTE (EVENTS,
@@ -1367,50 +3535,57 @@ gdk_event_translate (GdkEvent *event,
ignore_WM_CHAR = TRUE;
keyup_or_down:
+
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
+ doesnt_want_key,
+ key_propagate))
+ break;
+ event->key.window = window;
+#else
if (k_grab_window != NULL && !k_grab_owner_events)
{
/* Keyboard is grabbed with owner_events FALSE */
- GDK_NOTE (EVENTS,
- g_print ("...grabbed, owner_events FALSE, "
- "sending to %#x\n",
- GDK_DRAWABLE_XID (k_grab_window)));
+ GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE, "
+ "sending to %#x\n",
+ GDK_DRAWABLE_XID (k_grab_window)));
event->key.window = k_grab_window;
+ /* Continue with switch statement below */
}
- else if (window_private
- && (((xevent->message == WM_KEYUP
+ else if (((xevent->message == WM_KEYUP
|| xevent->message == WM_SYSKEYUP)
- && !(window_private->event_mask & GDK_KEY_RELEASE_MASK))
+ && !(WINDOW_PRIVATE(window)->event_mask & GDK_KEY_RELEASE_MASK))
|| ((xevent->message == WM_KEYDOWN
|| xevent->message == WM_SYSKEYDOWN)
- && !(window_private->event_mask & GDK_KEY_PRESS_MASK))))
+ && !(WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK)))
{
- /* Owner window doesn't want it */
- if (k_grab_window != NULL && k_grab_owner_events)
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Keyboard is grabbed with owner_events TRUE */
- GDK_NOTE (EVENTS,
- g_print ("...grabbed, owner_events TRUE, doesn't want it, "
- "sending to %#x\n",
- GDK_DRAWABLE_XID (k_grab_window)));
- event->key.window = k_grab_window;
+ /* No parent; check if grabbed */
+ if (k_grab_window != NULL)
+ {
+ /* Keyboard is grabbed with owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ event->key.window = k_grab_window;
+ /* Continue with switch statement below */
+ }
+ else
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- break;
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = key_propagate (window, xevent);
+ /* Jump back up */
goto keyup_or_down;
}
}
-
+ else
+ event->key.window = window;
+
+ g_assert (event->key.window == window);
+#endif
switch (xevent->wParam)
{
case VK_LBUTTON:
@@ -1505,34 +3680,22 @@ gdk_event_translate (GdkEvent *event,
case VK_MULTIPLY:
event->key.keyval = GDK_KP_Multiply; break;
case VK_ADD:
-#if 0
- event->key.keyval = GDK_KP_Add; break;
-#else
/* Pass it on as an ASCII plus in WM_CHAR. */
ignore_WM_CHAR = FALSE;
break;
-#endif
case VK_SEPARATOR:
event->key.keyval = GDK_KP_Separator; break;
case VK_SUBTRACT:
-#if 0
- event->key.keyval = GDK_KP_Subtract; break;
-#else
/* Pass it on as an ASCII minus in WM_CHAR. */
ignore_WM_CHAR = FALSE;
break;
-#endif
case VK_DECIMAL:
-#if 0
- event->key.keyval = GDK_KP_Decimal; break;
-#else
/* The keypad decimal key should also be passed on as the decimal
* sign ('.' or ',' depending on the Windows locale settings,
* apparently). So wait for the WM_CHAR here, also.
*/
ignore_WM_CHAR = FALSE;
break;
-#endif
case VK_DIVIDE:
event->key.keyval = GDK_KP_Divide; break;
case VK_F1:
@@ -1579,24 +3742,32 @@ gdk_event_translate (GdkEvent *event,
case '9':
if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0
|| GetKeyState (VK_MENU) < 0))
- /* Control- or Alt-digits won't come in as a WM_CHAR */
+ /* Control- or Alt-digits won't come in as a WM_CHAR,
+ * but beware of AltGr-digits, which are used for instance
+ * on Finnish keyboards.
+ */
event->key.keyval = GDK_0 + (xevent->wParam - '0');
else
- {
- ignore_WM_CHAR = FALSE;
- event->key.keyval = GDK_VoidSymbol;
- }
+ ignore_WM_CHAR = FALSE;
+ break;
+ case VK_OEM_PLUS: /* On my Win98, the '+' key comes in
+ * as VK_OEM_PLUS
+ */
+ if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0
+ || GetKeyState (VK_MENU) < 0))
+ /* Control- or Alt-plus won't come in as WM_CHAR,
+ * but beware of AltGr-plus which is backslash on
+ * Finnish keyboards
+ */
+ event->key.keyval = '+';
+ else
+ ignore_WM_CHAR = FALSE;
break;
default:
if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP)
- {
- event->key.keyval = xevent->wParam;
- }
+ event->key.keyval = xevent->wParam;
else
- {
- ignore_WM_CHAR = FALSE;
- event->key.keyval = GDK_VoidSymbol;
- }
+ ignore_WM_CHAR = FALSE;
break;
}
@@ -1607,7 +3778,6 @@ gdk_event_translate (GdkEvent *event,
event->key.type = ((xevent->message == WM_KEYDOWN
|| xevent->message == WM_SYSKEYDOWN) ?
GDK_KEY_PRESS : GDK_KEY_RELEASE);
- event->key.window = window;
event->key.time = xevent->time;
event->key.state = 0;
if (GetKeyState (VK_SHIFT) < 0)
@@ -1618,17 +3788,21 @@ gdk_event_translate (GdkEvent *event,
event->key.state |= GDK_CONTROL_MASK;
if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
event->key.state |= GDK_MOD1_MASK;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
event->key.string = NULL;
event->key.length = 0;
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
+ case WM_IME_CHAR:
+ GDK_NOTE (EVENTS,
+ g_print ("WM_IME_CHAR: %#x bytes: %#.04x\n",
+ xevent->hwnd, xevent->wParam));
+ goto wm_char;
+
case WM_CHAR:
GDK_NOTE (EVENTS,
g_print ("WM_CHAR: %#x char: %#x %#.08x %s\n",
- xevent->hwnd,
- xevent->wParam,
- xevent->lParam,
+ xevent->hwnd, xevent->wParam, xevent->lParam,
(ignore_WM_CHAR ? "ignored" : "")));
if (ignore_WM_CHAR)
@@ -1638,9 +3812,17 @@ gdk_event_translate (GdkEvent *event,
}
wm_char:
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
+ doesnt_want_char,
+ key_propagate))
+ break;
+ event->key.window = window;
+#else
/* This doesn't handle the rather theorethical case that a window
* wants key presses but still wants releases to be propagated,
- * for instance.
+ * for instance. Or is that so theorethical?
*/
if (k_grab_window != NULL && !k_grab_owner_events)
{
@@ -1651,126 +3833,63 @@ gdk_event_translate (GdkEvent *event,
GDK_DRAWABLE_XID (k_grab_window)));
event->key.window = k_grab_window;
}
- else if (window_private
- && !(window_private->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
+ else if (!(WINDOW_PRIVATE(window)->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
{
- /* Owner window doesn't want it */
- if (k_grab_window != NULL && k_grab_owner_events)
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Keyboard is grabbed with owner_events TRUE */
- GDK_NOTE (EVENTS,
- g_print ("...grabbed, owner_events TRUE, doesn't want it, "
- "sending to %#x\n",
- GDK_DRAWABLE_XID (k_grab_window)));
- event->key.window = k_grab_window;
+ /* No parent; check if grabbed */
+ if (k_grab_window != NULL)
+ {
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ event->key.window = k_grab_window;
+ }
+ else
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- g_assert_not_reached (); /* Should've been handled above */
-
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = key_propagate (window, xevent);
+ /* Jump back up */
goto wm_char;
}
}
-
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
- if (return_val && (window_private->event_mask & GDK_KEY_RELEASE_MASK))
+ else
+ event->key.window = window;
+
+ g_assert (event->key.window == window);
+#endif
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
+ if (return_val && (event->key.window == k_grab_window
+ || (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_RELEASE_MASK)))
{
- /* Return the release event, and maybe append the press
- * event to the queued_events list (from which it will vbe
- * fetched before the release event).
- */
- event->key.type = GDK_KEY_RELEASE;
- event->key.keyval = xevent->wParam;
- event->key.window = window;
- event->key.time = xevent->time;
- event->key.state = 0;
- if (GetKeyState (VK_SHIFT) < 0)
- event->key.state |= GDK_SHIFT_MASK;
- if (GetKeyState (VK_CAPITAL) & 0x1)
- event->key.state |= GDK_LOCK_MASK;
- if (is_AltGr_key)
- ;
- else if (GetKeyState (VK_CONTROL) < 0)
- {
- event->key.state |= GDK_CONTROL_MASK;
- if (event->key.keyval < ' ')
- event->key.keyval += '@';
- }
- else if (event->key.keyval < ' ')
- {
- event->key.state |= GDK_CONTROL_MASK;
- event->key.keyval += '@';
- }
- if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
- event->key.state |= GDK_MOD1_MASK;
- event->key.string = g_malloc (2);
- event->key.length = 1;
- event->key.string[0] = xevent->wParam; /* ??? */
- event->key.string[1] = 0;
-
- if (window_private->event_mask & GDK_KEY_PRESS_MASK)
+ if (window == k_grab_window
+ || (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK))
{
- /* Append also a GDK_KEY_PRESS event to the pushback list. */
- GdkEvent *event2 = gdk_event_copy (event);
- event2->key.type = GDK_KEY_PRESS;
- charcount = xevent->lParam & 0xFFFF;
- if (charcount > sizeof (buf)- 1)
- charcount = sizeof (buf) - 1;
- g_free (event2->key.string);
- event2->key.string = g_malloc (charcount + 1);
- for (i = 0; i < charcount; i++)
- event2->key.string[i] = event->key.keyval;
- event2->key.string[charcount] = 0;
- event2->key.length = charcount;
-
+ /* Append a GDK_KEY_PRESS event to the pushback list
+ * (from which it will be fetched before the release
+ * event).
+ */
+ GdkEvent *event2 = gdk_event_new ();
+ build_keypress_event (WINDOW_PRIVATE(window), event2, xevent);
+ event2->key.window = window;
+ gdk_window_ref (window);
gdk_event_queue_append (event2);
+ GDK_NOTE (EVENTS, print_event (event2));
}
+ /* Return the release event. */
+ event->key.type = GDK_KEY_RELEASE;
+ event->key.keyval = xevent->wParam;
+ event->key.time = xevent->time;
+ build_key_event_state (event);
+ event->key.string = NULL;
+ event->key.length = 0;
}
- else if (return_val && (window_private->event_mask & GDK_KEY_PRESS_MASK))
+ else if (return_val
+ && (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK))
{
/* Return just the GDK_KEY_PRESS event. */
- event->key.type = GDK_KEY_PRESS;
- charcount = xevent->lParam & 0xFFFF;
- if (charcount > sizeof (buf)- 1)
- charcount = sizeof (buf) - 1;
- event->key.keyval = xevent->wParam;
- event->key.window = window;
- event->key.time = xevent->time;
- event->key.state = 0;
- if (GetKeyState (VK_SHIFT) < 0)
- event->key.state |= GDK_SHIFT_MASK;
- if (GetKeyState (VK_CAPITAL) & 0x1)
- event->key.state |= GDK_LOCK_MASK;
- if (is_AltGr_key)
- ;
- else if (GetKeyState (VK_CONTROL) < 0)
- {
- event->key.state |= GDK_CONTROL_MASK;
- if (event->key.keyval < ' ')
- event->key.keyval += '@';
- }
- else if (event->key.keyval < ' ')
- {
- event->key.state |= GDK_CONTROL_MASK;
- event->key.keyval += '@';
- }
- if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
- event->key.state |= GDK_MOD1_MASK;
- event->key.string = g_malloc (charcount + 1);
- for (i = 0; i < charcount; i++)
- event->key.string[i] = event->key.keyval;
- event->key.string[charcount] = 0;
- event->key.length = charcount;
+ build_keypress_event (WINDOW_PRIVATE(window), event, xevent);
}
else
return_val = FALSE;
@@ -1799,8 +3918,7 @@ gdk_event_translate (GdkEvent *event,
LOWORD (xevent->lParam), HIWORD (xevent->lParam),
button));
- if (window_private
- && (window_private->extension_events != 0)
+ if (WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_ignore_core)
{
GDK_NOTE (EVENTS, g_print ("...ignored\n"));
@@ -1811,18 +3929,23 @@ gdk_event_translate (GdkEvent *event,
synthesize_crossing_events (window, xevent);
event->button.type = GDK_BUTTON_PRESS;
- buttondown:
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ p_grab_window, p_grab_owner_events, p_grab_mask,
+ doesnt_want_button_press,
+ mouse_propagate))
+ break;
event->button.window = window;
- if (window_private)
- mask = window_private->event_mask;
- else
- mask = 0; /* ??? */
+#else
+ buttondown:
+ mask = WINDOW_PRIVATE(window)->event_mask;
if (p_grab_window != NULL && !p_grab_owner_events)
{
/* Pointer is grabbed with owner_events FALSE */
GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
- mask = p_grab_event_mask;
+
+ mask = p_grab_mask;
if (!(mask & GDK_BUTTON_PRESS_MASK))
/* Grabber doesn't want it */
break;
@@ -1831,61 +3954,79 @@ gdk_event_translate (GdkEvent *event,
GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
GDK_DRAWABLE_XID (p_grab_window)));
}
- else if (window_private
- && !(mask & GDK_BUTTON_PRESS_MASK))
+ else if (!(mask & GDK_BUTTON_PRESS_MASK))
{
- /* Owner window doesn't want it */
- if (p_grab_window != NULL && p_grab_owner_events)
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Pointer is grabbed wíth owner_events TRUE */
- GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
- mask = p_grab_event_mask;
- if (!(mask & GDK_BUTTON_PRESS_MASK))
- /* Grabber doesn't want it either */
- break;
+ /* No parent; check if grabbed */
+ if (p_grab_window != NULL)
+ {
+ /* Pointer is grabbed wíth owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ mask = p_grab_mask;
+ if (!(mask & GDK_BUTTON_PRESS_MASK))
+ {
+ /* Grabber doesn't want it either */
+ GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n"));
+ break;
+ }
+ else
+ event->button.window = p_grab_window;
+ GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
+ GDK_DRAWABLE_XID (p_grab_window)));
+ }
else
- event->button.window = p_grab_window;
- GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
- GDK_DRAWABLE_XID (p_grab_window)));
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- /* Yes, this code is duplicated twice below. So shoot me. */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- break;
- pt.x = LOWORD (xevent->lParam);
- pt.y = HIWORD (xevent->lParam);
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
- xevent->lParam = MAKELPARAM (pt.x, pt.y);
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = mouse_propagate (window, xevent);
+ /* Jump back up */
goto buttondown; /* What did Dijkstra say? */
}
}
+ else
+ event->button.window = window;
+ g_assert (event->button.window == window);
+#endif
/* Emulate X11's automatic active grab */
if (!p_grab_window)
{
/* No explicit active grab, let's start one automatically */
+ gint owner_events =
+ WINDOW_PRIVATE(window)->event_mask
+ & (GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK);
+
GDK_NOTE (EVENTS, g_print ("...automatic grab started\n"));
- gdk_pointer_grab (window, TRUE, window_private->event_mask,
+ gdk_pointer_grab (window,
+ owner_events,
+ WINDOW_PRIVATE(window)->event_mask,
NULL, NULL, 0);
p_grab_automatic = TRUE;
}
event->button.time = xevent->time;
- event->button.x = LOWORD (xevent->lParam);
- event->button.y = HIWORD (xevent->lParam);
- event->button.x_root = (gfloat)xevent->pt.x;
- event->button.y_root = (gfloat)xevent->pt.y;
+ if (window == p_grab_window
+ && p_grab_window != orig_window)
+ {
+ /* Translate coordinates to grabber */
+ pt.x = LOWORD (xevent->lParam);
+ pt.y = HIWORD (xevent->lParam);
+ ClientToScreen (xevent->hwnd, &pt);
+ ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
+ event->button.x = pt.x;
+ event->button.y = pt.y;
+ GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
+ }
+ else
+ {
+ event->button.x = LOWORD (xevent->lParam);
+ event->button.y = HIWORD (xevent->lParam);
+ }
+ event->button.x_root = xevent->pt.x;
+ event->button.y_root = xevent->pt.y;
event->button.pressure = 0.5;
event->button.xtilt = 0;
event->button.ytilt = 0;
@@ -1943,21 +4084,7 @@ gdk_event_translate (GdkEvent *event,
button_number[1] = -1;
button_number[0] = event->button.button;
}
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
- if (return_val
- && p_grab_window != NULL
- && event->any.window == p_grab_window
- && p_grab_window != window)
- {
- /* Translate coordinates to grabber */
- pt.x = event->button.x;
- pt.y = event->button.y;
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
- event->button.x = pt.x;
- event->button.y = pt.y;
- GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
- }
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
case WM_LBUTTONUP:
@@ -1977,8 +4104,7 @@ gdk_event_translate (GdkEvent *event,
LOWORD (xevent->lParam), HIWORD (xevent->lParam),
button));
- if (window_private
- && (window_private->extension_events != 0)
+ if (WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_ignore_core)
{
GDK_NOTE (EVENTS, g_print ("...ignored\n"));
@@ -1989,70 +4115,89 @@ gdk_event_translate (GdkEvent *event,
synthesize_crossing_events (window, xevent);
event->button.type = GDK_BUTTON_RELEASE;
- buttonup:
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ p_grab_window, p_grab_owner_events, p_grab_mask,
+ doesnt_want_button_release,
+ mouse_propagate))
+ break;
event->button.window = window;
- if (window_private)
- mask = window_private->event_mask;
- else
- mask = 0;
+#else
+ buttonup:
+ mask = WINDOW_PRIVATE(window)->event_mask;
if (p_grab_window != NULL && !p_grab_owner_events)
{
/* Pointer is grabbed with owner_events FALSE */
GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
- mask = p_grab_event_mask;
+
+ mask = p_grab_mask;
if (!(mask & GDK_BUTTON_RELEASE_MASK))
/* Grabber doesn't want it */
- break;
+ goto maybe_ungrab;
else
event->button.window = p_grab_window;
GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
GDK_DRAWABLE_XID (p_grab_window)));
}
- else if (window_private
- && !(mask & GDK_BUTTON_RELEASE_MASK))
+ else if (!(mask & GDK_BUTTON_RELEASE_MASK))
{
- /* Owner window doesn't want it */
- if (p_grab_window != NULL && p_grab_owner_events)
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Pointer is grabbed wíth owner_events TRUE */
- GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
- mask = p_grab_event_mask;
- if (!(mask & GDK_BUTTON_RELEASE_MASK))
- /* Grabber doesn't want it */
- break;
+ /* No parent; check if grabbed */
+ if (p_grab_window != NULL)
+ {
+ /* Pointer is grabbed wíth owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ mask = p_grab_mask;
+ if (!(mask & GDK_BUTTON_RELEASE_MASK))
+ {
+ /* Grabber doesn't want it either */
+ GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n"));
+ goto maybe_ungrab;
+ }
+ else
+ event->button.window = p_grab_window;
+ GDK_NOTE (EVENTS,
+ g_print ("...sending to %#x\n",
+ GDK_DRAWABLE_XID (p_grab_window)));
+ }
else
- event->button.window = p_grab_window;
- GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
- GDK_DRAWABLE_XID (p_grab_window)));
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- break;
- pt.x = LOWORD (xevent->lParam);
- pt.y = HIWORD (xevent->lParam);
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
- xevent->lParam = MAKELPARAM (pt.x, pt.y);
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = mouse_propagate (window, xevent);
+ /* Jump back up */
goto buttonup;
}
}
+ else
+ event->button.window = window;
+ g_assert (event->button.window == window);
+#endif
event->button.time = xevent->time;
- event->button.x = LOWORD (xevent->lParam);
- event->button.y = HIWORD (xevent->lParam);
- event->button.x_root = (gfloat)xevent->pt.x;
- event->button.y_root = (gfloat)xevent->pt.y;
+ if (window == p_grab_window
+ && p_grab_window != orig_window)
+ {
+ /* Translate coordinates to grabber */
+ pt.x = LOWORD (xevent->lParam);
+ pt.y = HIWORD (xevent->lParam);
+ ClientToScreen (xevent->hwnd, &pt);
+ ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
+ event->button.x = pt.x;
+ event->button.y = pt.y;
+ GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
+ }
+ else
+ {
+ event->button.x = LOWORD (xevent->lParam);
+ event->button.y = HIWORD (xevent->lParam);
+ }
+ event->button.x_root = xevent->pt.x;
+ event->button.y_root = xevent->pt.y;
event->button.pressure = 0.5;
event->button.xtilt = 0;
event->button.ytilt = 0;
@@ -2067,24 +4212,17 @@ gdk_event_translate (GdkEvent *event,
event->button.state |= GDK_BUTTON3_MASK;
if (xevent->wParam & MK_SHIFT)
event->button.state |= GDK_SHIFT_MASK;
+ if (GetKeyState (VK_MENU) < 0)
+ event->button.state |= GDK_MOD1_MASK;
+ if (GetKeyState (VK_CAPITAL) & 0x1)
+ event->button.state |= GDK_LOCK_MASK;
event->button.button = button;
event->button.source = GDK_SOURCE_MOUSE;
event->button.deviceid = GDK_CORE_POINTER;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
- if (return_val
- && p_grab_window != NULL
- && event->any.window == p_grab_window
- && p_grab_window != window)
- {
- /* Translate coordinates to grabber */
- pt.x = event->button.x;
- pt.y = event->button.y;
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
- event->button.x = pt.x;
- event->button.y = pt.y;
- GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
- }
+
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
+
+ maybe_ungrab:
if (p_grab_window != NULL
&& p_grab_automatic
&& (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0)
@@ -2097,58 +4235,41 @@ gdk_event_translate (GdkEvent *event,
xevent->hwnd, xevent->wParam,
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
-#if 0
- /* Try hard not to generate events for windows that shouldn't
- get any. This is hard because we don't want pushbuttons to
- highlight when the cursor moves over them if the window is
- inactive. We dont want tooltips windows to be active. OTOH,
- also menus are popup windows, but they definitely should
- get events. Aw shit. Skip this.
- */
- dwStyle = GetWindowLong (xevent->hwnd, GWL_STYLE);
- if (active == NULL ||
- !(active == xevent->hwnd
- || (dwStyle & WS_POPUP)
- || IsChild (active, xevent->hwnd)))
+ /* HB: only process mouse move messages if we own the active window. */
+
+ GetWindowThreadProcessId(GetActiveWindow(), &pidActWin);
+ GetWindowThreadProcessId(xevent->hwnd, &pidThis);
+ if (pidActWin != pidThis)
break;
-#else
- { /* HB: only process mouse move messages
- * if we own the active window.
- */
- DWORD ProcessID_ActWin;
- DWORD ProcessID_this;
-
- GetWindowThreadProcessId(GetActiveWindow(), &ProcessID_ActWin);
- GetWindowThreadProcessId(xevent->hwnd, &ProcessID_this);
- if (ProcessID_ActWin != ProcessID_this)
- break;
- }
-#endif
+
if (window != curWnd)
synthesize_crossing_events (window, xevent);
- if (window_private
- && (window_private->extension_events != 0)
+ if (WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_ignore_core)
{
GDK_NOTE (EVENTS, g_print ("...ignored\n"));
break;
}
- mousemotion:
event->motion.type = GDK_MOTION_NOTIFY;
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ p_grab_window, p_grab_owner_events, p_grab_mask,
+ doesnt_want_button_motion,
+ mouse_propagate))
+ break;
event->motion.window = window;
- if (window_private)
- mask = window_private->event_mask;
- else
- mask = 0;
+#else
+ mousemotion:
+ mask = WINDOW_PRIVATE(window)->event_mask;
- if (p_grab_window && !p_grab_owner_events)
+ if (p_grab_window != NULL && !p_grab_owner_events)
{
/* Pointer is grabbed with owner_events FALSE */
- GDK_NOTE (EVENTS,
- g_print ("...grabbed, owner_events FALSE\n"));
- mask = p_grab_event_mask;
+ GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
+
+ mask = p_grab_mask;
if (!((mask & GDK_POINTER_MOTION_MASK)
|| ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
&& (mask & GDK_BUTTON_MOTION_MASK))
@@ -2158,70 +4279,83 @@ gdk_event_translate (GdkEvent *event,
&& (mask & GDK_BUTTON2_MOTION_MASK))
|| ((xevent->wParam & MK_RBUTTON)
&& (mask & GDK_BUTTON3_MOTION_MASK))))
+ /* Grabber doesn't want it */
break;
else
event->motion.window = p_grab_window;
GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
GDK_DRAWABLE_XID (p_grab_window)));
}
- else if (window_private
- && !((mask & GDK_POINTER_MOTION_MASK)
- || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
- && (mask & GDK_BUTTON_MOTION_MASK))
- || ((xevent->wParam & MK_LBUTTON)
- && (mask & GDK_BUTTON1_MOTION_MASK))
- || ((xevent->wParam & MK_MBUTTON)
- && (mask & GDK_BUTTON2_MOTION_MASK))
- || ((xevent->wParam & MK_RBUTTON)
- && (mask & GDK_BUTTON3_MOTION_MASK))))
- {
- /* Owner window doesn't want it */
- if (p_grab_window != NULL && p_grab_owner_events)
+ else if (!((mask & GDK_POINTER_MOTION_MASK)
+ || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
+ && (mask & GDK_BUTTON_MOTION_MASK))
+ || ((xevent->wParam & MK_LBUTTON)
+ && (mask & GDK_BUTTON1_MOTION_MASK))
+ || ((xevent->wParam & MK_MBUTTON)
+ && (mask & GDK_BUTTON2_MOTION_MASK))
+ || ((xevent->wParam & MK_RBUTTON)
+ && (mask & GDK_BUTTON3_MOTION_MASK))))
+ {
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Pointer is grabbed wíth owner_events TRUE */
- GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
- mask = p_grab_event_mask;
- if (!((p_grab_event_mask & GDK_POINTER_MOTION_MASK)
- || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
- && (mask & GDK_BUTTON_MOTION_MASK))
- || ((xevent->wParam & MK_LBUTTON)
- && (mask & GDK_BUTTON1_MOTION_MASK))
- || ((xevent->wParam & MK_MBUTTON)
- && (mask & GDK_BUTTON2_MOTION_MASK))
- || ((xevent->wParam & MK_RBUTTON)
- && (mask & GDK_BUTTON3_MOTION_MASK))))
- /* Grabber doesn't want it either */
- break;
+ /* No parent; check if grabbed */
+ if (p_grab_window != NULL)
+ {
+ /* Pointer is grabbed wíth owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ mask = p_grab_mask;
+ if (!((p_grab_mask & GDK_POINTER_MOTION_MASK)
+ || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
+ && (mask & GDK_BUTTON_MOTION_MASK))
+ || ((xevent->wParam & MK_LBUTTON)
+ && (mask & GDK_BUTTON1_MOTION_MASK))
+ || ((xevent->wParam & MK_MBUTTON)
+ && (mask & GDK_BUTTON2_MOTION_MASK))
+ || ((xevent->wParam & MK_RBUTTON)
+ && (mask & GDK_BUTTON3_MOTION_MASK))))
+ {
+ /* Grabber doesn't want it either */
+ GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n"));
+ break;
+ }
+ else
+ event->motion.window = p_grab_window;
+ GDK_NOTE (EVENTS,
+ g_print ("...sending to %#x\n",
+ GDK_DRAWABLE_XID (p_grab_window)));
+ }
else
- event->motion.window = p_grab_window;
- GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
- GDK_DRAWABLE_XID (p_grab_window)));
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- break;
- pt.x = LOWORD (xevent->lParam);
- pt.y = HIWORD (xevent->lParam);
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
- xevent->lParam = MAKELPARAM (pt.x, pt.y);
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = mouse_propagate (window, xevent);
+ /* Jump back up */
goto mousemotion;
}
}
-
+ else
+ event->motion.window = window;
+#endif
event->motion.time = xevent->time;
- event->motion.x = curX = LOWORD (xevent->lParam);
- event->motion.y = curY = HIWORD (xevent->lParam);
+ if (window == p_grab_window
+ && p_grab_window != orig_window)
+ {
+ /* Translate coordinates to grabber */
+ pt.x = curX = LOWORD (xevent->lParam);
+ pt.y = curY = HIWORD (xevent->lParam);
+ ClientToScreen (xevent->hwnd, &pt);
+ ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
+ event->motion.x = pt.x;
+ event->motion.y = pt.y;
+ GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
+ }
+ else
+ {
+ event->motion.x = curX = LOWORD (xevent->lParam);
+ event->motion.y = curY = HIWORD (xevent->lParam);
+ }
event->motion.x_root = xevent->pt.x;
event->motion.y_root = xevent->pt.y;
curXroot = event->motion.x_root;
@@ -2240,6 +4374,10 @@ gdk_event_translate (GdkEvent *event,
event->button.state |= GDK_BUTTON3_MASK;
if (xevent->wParam & MK_SHIFT)
event->button.state |= GDK_SHIFT_MASK;
+ if (GetKeyState (VK_MENU) < 0)
+ event->button.state |= GDK_MOD1_MASK;
+ if (GetKeyState (VK_CAPITAL) & 0x1)
+ event->button.state |= GDK_LOCK_MASK;
if (mask & GDK_POINTER_MOTION_HINT_MASK)
event->motion.is_hint = NotifyHint;
else
@@ -2247,21 +4385,7 @@ gdk_event_translate (GdkEvent *event,
event->motion.source = GDK_SOURCE_MOUSE;
event->motion.deviceid = GDK_CORE_POINTER;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
- if (return_val
- && p_grab_window != NULL
- && event->any.window == p_grab_window
- && p_grab_window != window)
- {
- /* Translate coordinates to grabber */
- pt.x = event->motion.x;
- pt.y = event->motion.y;
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
- event->motion.x = pt.x;
- event->motion.y = pt.y;
- GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
- }
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
case WM_NCMOUSEMOVE:
@@ -2269,13 +4393,9 @@ gdk_event_translate (GdkEvent *event,
g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n",
xevent->hwnd,
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
-#if 0
- if (active == NULL || active != xevent->hwnd)
- break;
-#endif
- curWnd_private = (GdkWindowPrivate *) curWnd;
- if (curWnd != NULL
- && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
+ if (p_TrackMouseEvent == NULL
+ && curWnd != NULL
+ && (WINDOW_PRIVATE(curWnd)->event_mask & GDK_LEAVE_NOTIFY_MASK))
{
GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n"));
@@ -2288,49 +4408,83 @@ gdk_event_translate (GdkEvent *event,
event->crossing.x_root = curXroot;
event->crossing.y_root = curYroot;
event->crossing.mode = GDK_CROSSING_NORMAL;
- event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
event->crossing.focus = TRUE; /* ??? */
event->crossing.state = 0; /* ??? */
+ return_val = TRUE;
+ }
+
+ if (curWnd)
+ {
gdk_window_unref (curWnd);
curWnd = NULL;
-
- return_val = TRUE;
}
+
break;
- case WM_SETFOCUS:
- case WM_KILLFOCUS:
- if (window_private
- && !(window_private->event_mask & GDK_FOCUS_CHANGE_MASK))
+#ifdef USE_TRACKMOUSEEVENT
+ case WM_MOUSELEAVE:
+ GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %#x\n", xevent->hwnd));
+
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
break;
+ event->crossing.type = GDK_LEAVE_NOTIFY;
+ event->crossing.window = window;
+ event->crossing.subwindow = NULL;
+ event->crossing.time = xevent->time;
+ event->crossing.x = curX;
+ event->crossing.y = curY;
+ event->crossing.x_root = curXroot;
+ event->crossing.y_root = curYroot;
+ event->crossing.mode = GDK_CROSSING_NORMAL;
+ if (curWnd
+ && IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ else if (curWnd
+ && IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ else
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+
+ event->crossing.focus = TRUE; /* ??? */
+ event->crossing.state = 0; /* ??? */
+
+ if (curWnd)
+ {
+ gdk_window_unref (curWnd);
+ curWnd = NULL;
+ }
+
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
+ break;
+#endif
+
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n",
- (xevent->message == WM_SETFOCUS ? "SET" : "KILL"),
+ (xevent->message == WM_SETFOCUS ?
+ "SET" : "KILL"),
xevent->hwnd));
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_FOCUS_CHANGE_MASK))
+ break;
+
event->focus_change.type = GDK_FOCUS_CHANGE;
event->focus_change.window = window;
event->focus_change.in = (xevent->message == WM_SETFOCUS);
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
-#if 0
- case WM_ACTIVATE:
- GDK_NOTE (EVENTS, g_print ("WM_ACTIVATE: %#x %d\n",
- xevent->hwnd, LOWORD (xevent->wParam)));
- if (LOWORD (xevent->wParam) == WA_INACTIVE)
- active = (HWND) xevent->lParam;
- else
- active = xevent->hwnd;
- break;
-#endif
+
case WM_ERASEBKGND:
GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n",
xevent->hwnd, xevent->wParam));
- if (!window_private || GDK_DRAWABLE_DESTROYED (window))
+ if (GDK_DRAWABLE_DESTROYED (window))
break;
- colormap_private = (GdkColormapPrivate *) window_private->drawable.colormap;
+
+ colormap_private = (GdkColormapPrivate *) WINDOW_PRIVATE(window)->drawable.colormap;
hdc = (HDC) xevent->wParam;
if (colormap_private
&& colormap_private->xcolormap->rc_palette)
@@ -2350,32 +4504,38 @@ gdk_event_translate (GdkEvent *event,
*ret_val_flagp = TRUE;
*ret_valp = 1;
- if (window_private->bg_type == GDK_WIN32_BG_TRANSPARENT)
+ if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_TRANSPARENT)
break;
- if (window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
+ if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
{
/* If this window should have the same background as the
* parent, fetch the parent. (And if the same goes for
* the parent, fetch the grandparent, etc.)
*/
- while (window_private
- && window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
- window_private = (GdkWindowPrivate *) window_private->parent;
+ while (window
+ && WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
+ {
+ gdk_window_unref (window);
+ window = WINDOW_PRIVATE(window)->parent;
+ gdk_window_ref (window);
+ }
}
- if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
+ if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PIXEL)
{
COLORREF bg;
GetClipBox (hdc, &rect);
- GDK_NOTE (EVENTS, g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
- rect.right - rect.left,
- rect.bottom - rect.top,
- rect.left, rect.top,
- gdk_color_to_string (&window_private->bg_pixel)));
- bg = GetNearestColor (hdc, RGB (window_private->bg_pixel.red >> 8,
- window_private->bg_pixel.green >> 8,
- window_private->bg_pixel.blue >> 8));
+ GDK_NOTE (EVENTS,
+ g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ rect.left, rect.top,
+ gdk_color_to_string (&WINDOW_PRIVATE(window)->bg_pixel)));
+ bg = GetNearestColor
+ (hdc, RGB (WINDOW_PRIVATE(window)->bg_pixel.red >> 8,
+ WINDOW_PRIVATE(window)->bg_pixel.green >> 8,
+ WINDOW_PRIVATE(window)->bg_pixel.blue >> 8));
hbr = CreateSolidBrush (bg);
#if 0
g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
@@ -2384,9 +4544,10 @@ gdk_event_translate (GdkEvent *event,
g_warning ("WM_ERASEBKGND: FillRect failed");
DeleteObject (hbr);
}
- else if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
+ else if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PIXMAP)
{
- pixmap_private = (GdkDrawablePrivate*) window_private->bg_pixmap;
+ pixmap_private =
+ (GdkDrawablePrivate*) WINDOW_PRIVATE(window)->bg_pixmap;
GetClipBox (hdc, &rect);
if (pixmap_private->width <= 8
@@ -2470,8 +4631,7 @@ gdk_event_translate (GdkEvent *event,
EndPaint (xevent->hwnd, &paintstruct);
- if (window_private
- && !(window_private->event_mask & GDK_EXPOSURE_MASK))
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_EXPOSURE_MASK))
break;
event->expose.type = GDK_EXPOSE;
@@ -2482,7 +4642,7 @@ gdk_event_translate (GdkEvent *event,
event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
event->expose.count = 0;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
if (return_val)
{
GList *list = queued_events;
@@ -2503,7 +4663,6 @@ gdk_event_translate (GdkEvent *event,
xevent->hwnd,
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
- return_val = FALSE;
if (LOWORD (xevent->lParam) != HTCLIENT)
break;
if (p_grab_window != NULL && p_grab_cursor != NULL)
@@ -2511,44 +4670,27 @@ gdk_event_translate (GdkEvent *event,
GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", p_grab_cursor));
SetCursor (p_grab_cursor);
}
- else if (window_private
- && !GDK_DRAWABLE_DESTROYED (window)
- && window_private->xcursor)
+ else if (!GDK_DRAWABLE_DESTROYED (window)
+ && WINDOW_PRIVATE(window)->xcursor)
{
GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n",
- window_private->xcursor));
- SetCursor (window_private->xcursor);
+ WINDOW_PRIVATE(window)->xcursor));
+ SetCursor (WINDOW_PRIVATE(window)->xcursor);
}
- *ret_val_flagp = TRUE;
- *ret_valp = FALSE;
- break;
-#if 0
- case WM_QUERYOPEN:
- GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n",
- xevent->hwnd));
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
-
- if (window_private
- && !(window_private->event_mask & GDK_STRUCTURE_MASK))
- break;
-
- event->any.type = GDK_MAP;
- event->any.window = window;
+ if (window != curWnd)
+ synthesize_crossing_events (window, xevent);
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ *ret_val_flagp = TRUE;
+ *ret_valp = FALSE;
break;
-#endif
-#if 1
case WM_SHOWWINDOW:
GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
xevent->hwnd,
xevent->wParam));
- if (window_private
- && !(window_private->event_mask & GDK_STRUCTURE_MASK))
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK))
break;
event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
@@ -2562,9 +4704,9 @@ gdk_event_translate (GdkEvent *event,
&& k_grab_window == window)
gdk_keyboard_ungrab (xevent->time);
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
-#endif
+
case WM_SIZE:
GDK_NOTE (EVENTS,
g_print ("WM_SIZE: %#x %s %dx%d\n",
@@ -2576,13 +4718,11 @@ gdk_event_translate (GdkEvent *event,
(xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
- if (window_private
- && !(window_private->event_mask & GDK_STRUCTURE_MASK))
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK))
break;
- if (window_private != NULL
- && xevent->wParam == SIZE_MINIMIZED)
+
+ if (xevent->wParam == SIZE_MINIMIZED)
{
-#if 1
event->any.type = GDK_UNMAP;
event->any.window = window;
@@ -2593,11 +4733,9 @@ gdk_event_translate (GdkEvent *event,
gdk_keyboard_ungrab (xevent->time);
return_val = !GDK_DRAWABLE_DESTROYED (window);
-#endif
}
- else if (window_private != NULL
- && (xevent->wParam == SIZE_RESTORED
- || xevent->wParam == SIZE_MAXIMIZED)
+ else if ((xevent->wParam == SIZE_RESTORED
+ || xevent->wParam == SIZE_MAXIMIZED)
#if 1
&& GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD
#endif
@@ -2615,121 +4753,49 @@ gdk_event_translate (GdkEvent *event,
event->configure.y = pt.y;
event->configure.width = LOWORD (xevent->lParam);
event->configure.height = HIWORD (xevent->lParam);
- window_private->x = event->configure.x;
- window_private->y = event->configure.y;
- window_private->drawable.width = event->configure.width;
- window_private->drawable.height = event->configure.height;
- if (window_private->resize_count > 1)
- window_private->resize_count -= 1;
+ WINDOW_PRIVATE(window)->x = event->configure.x;
+ WINDOW_PRIVATE(window)->y = event->configure.y;
+ WINDOW_PRIVATE(window)->drawable.width = event->configure.width;
+ WINDOW_PRIVATE(window)->drawable.height = event->configure.height;
+ if (WINDOW_PRIVATE(window)->resize_count > 1)
+ WINDOW_PRIVATE(window)->resize_count -= 1;
return_val = !GDK_DRAWABLE_DESTROYED (window);
if (return_val
- && window_private->extension_events != 0
+ && WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_vtable.configure_event)
gdk_input_vtable.configure_event (&event->configure, window);
}
break;
-#if 0 /* Bernd Herd suggests responding to WM_GETMINMAXINFO instead,
- * which indeed is much easier.
- */
- case WM_SIZING:
- GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd));
- if (ret_val_flagp == NULL)
- g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?");
- else if (window_private != NULL
- && window_private->hint_flags &
- (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
- {
- LPRECT lprc = (LPRECT) xevent->lParam;
-
- if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
- {
- gint w = lprc->right - lprc->left;
- gint h = lprc->bottom - lprc->top;
-
- if (w < window_private->hint_min_width)
- {
- if (xevent->wParam == WMSZ_BOTTOMLEFT
- || xevent->wParam == WMSZ_LEFT
- || xevent->wParam == WMSZ_TOPLEFT)
- lprc->left = lprc->right - window_private->hint_min_width;
- else
- lprc->right = lprc->left + window_private->hint_min_width;
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
- }
- if (h < window_private->hint_min_height)
- {
- if (xevent->wParam == WMSZ_BOTTOMLEFT
- || xevent->wParam == WMSZ_BOTTOM
- || xevent->wParam == WMSZ_BOTTOMRIGHT)
- lprc->bottom = lprc->top + window_private->hint_min_height;
- else
- lprc->top = lprc->bottom - window_private->hint_min_height;
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
- }
- }
- if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
- {
- gint w = lprc->right - lprc->left;
- gint h = lprc->bottom - lprc->top;
- if (w > window_private->hint_max_width)
- {
- if (xevent->wParam == WMSZ_BOTTOMLEFT
- || xevent->wParam == WMSZ_LEFT
- || xevent->wParam == WMSZ_TOPLEFT)
- lprc->left = lprc->right - window_private->hint_max_width;
- else
- lprc->right = lprc->left + window_private->hint_max_width;
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
- }
- if (h > window_private->hint_max_height)
- {
- if (xevent->wParam == WMSZ_BOTTOMLEFT
- || xevent->wParam == WMSZ_BOTTOM
- || xevent->wParam == WMSZ_BOTTOMRIGHT)
- lprc->bottom = lprc->top + window_private->hint_max_height;
- else
- lprc->top = lprc->bottom - window_private->hint_max_height;
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
- }
- }
- }
- break;
-#else
case WM_GETMINMAXINFO:
GDK_NOTE (EVENTS, g_print ("WM_GETMINMAXINFO: %#x\n", xevent->hwnd));
+
lpmmi = (MINMAXINFO*) xevent->lParam;
- if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
+ if (WINDOW_PRIVATE(window)->hint_flags & GDK_HINT_MIN_SIZE)
{
- lpmmi->ptMinTrackSize.x = window_private->hint_min_width;
- lpmmi->ptMinTrackSize.y = window_private->hint_min_height;
+ lpmmi->ptMinTrackSize.x = WINDOW_PRIVATE(window)->hint_min_width;
+ lpmmi->ptMinTrackSize.y = WINDOW_PRIVATE(window)->hint_min_height;
}
- if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
+ if (WINDOW_PRIVATE(window)->hint_flags & GDK_HINT_MAX_SIZE)
{
- lpmmi->ptMaxTrackSize.x = window_private->hint_max_width;
- lpmmi->ptMaxTrackSize.y = window_private->hint_max_height;
+ lpmmi->ptMaxTrackSize.x = WINDOW_PRIVATE(window)->hint_max_width;
+ lpmmi->ptMaxTrackSize.y = WINDOW_PRIVATE(window)->hint_max_height;
- lpmmi->ptMaxSize.x = window_private->hint_max_width;
- lpmmi->ptMaxSize.y = window_private->hint_max_height;
+ lpmmi->ptMaxSize.x = WINDOW_PRIVATE(window)->hint_max_width;
+ lpmmi->ptMaxSize.y = WINDOW_PRIVATE(window)->hint_max_height;
}
break;
-#endif
case WM_MOVE:
GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n",
xevent->hwnd,
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
- if (window_private
- && !(window_private->event_mask & GDK_STRUCTURE_MASK))
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK))
break;
- if (window_private != NULL
- && GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD)
+
+ if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD)
{
event->configure.type = GDK_CONFIGURE;
event->configure.window = window;
@@ -2738,10 +4804,10 @@ gdk_event_translate (GdkEvent *event,
GetClientRect (xevent->hwnd, &rect);
event->configure.width = rect.right;
event->configure.height = rect.bottom;
- window_private->x = event->configure.x;
- window_private->y = event->configure.y;
- window_private->drawable.width = event->configure.width;
- window_private->drawable.height = event->configure.height;
+ WINDOW_PRIVATE(window)->x = event->configure.x;
+ WINDOW_PRIVATE(window)->y = event->configure.y;
+ WINDOW_PRIVATE(window)->drawable.width = event->configure.width;
+ WINDOW_PRIVATE(window)->drawable.height = event->configure.height;
return_val = !GDK_DRAWABLE_DESTROYED (window);
}
@@ -2749,10 +4815,11 @@ gdk_event_translate (GdkEvent *event,
case WM_CLOSE:
GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
+
event->any.type = GDK_DELETE;
event->any.window = window;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
#if 0
@@ -2795,7 +4862,7 @@ gdk_event_translate (GdkEvent *event,
event->selection.property = gdk_selection_property;
event->selection.requestor = (guint32) xevent->hwnd;
event->selection.time = xevent->time;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
#else
/* Test code, to see if SetClipboardData works when called from
* the window procedure.
@@ -2817,6 +4884,7 @@ gdk_event_translate (GdkEvent *event,
case WM_DESTROY:
GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
+
event->any.type = GDK_DESTROY;
event->any.window = window;
if (window != NULL && window == curWnd)
@@ -2831,7 +4899,7 @@ gdk_event_translate (GdkEvent *event,
if (k_grab_window == window)
gdk_keyboard_ungrab (xevent->time);
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
#ifdef HAVE_WINTAB
@@ -2871,6 +4939,8 @@ bypass_switch:
(event->any.type == GDK_LEAVE_NOTIFY)) &&
(event->crossing.subwindow != NULL))
gdk_window_ref (event->crossing.subwindow);
+
+ GDK_NOTE (EVENTS, print_event (event));
}
else
{
@@ -2891,17 +4961,31 @@ gdk_events_queue (void)
GList *node;
GdkEvent *event;
MSG msg;
-
- GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n",
- (queued_events ? "yes" : "none")));
+ LRESULT lres;
while (!gdk_event_queue_find_first()
&& PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
- GDK_NOTE (EVENTS, g_print ("gdk_events_queue: PeekMessage: %#x\n",
- msg.message));
- TranslateMessage (&msg);
+ GDK_NOTE (EVENTS, g_print ("PeekMessage: %#x %#x\n",
+ msg.hwnd, msg.message));
+
+ if (paimmmpo == NULL
+ || (paimmmpo->lpVtbl->OnTranslateMessage) (paimmmpo, &msg) != S_OK)
+ TranslateMessage (&msg);
+
+#ifdef USE_DISPATCHMESSAGE
+ if (msg.message == g_pipe_readable_msg)
+ {
+ GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
+ msg.wParam, msg.lParam));
+ g_io_channel_win32_pipe_readable (msg.wParam, msg.lParam);
+
+ continue;
+ }
+
+ DispatchMessage (&msg);
+#else
event = gdk_event_new ();
event->any.type = GDK_NOTHING;
@@ -2914,14 +4998,20 @@ gdk_events_queue (void)
node = queued_tail;
if (gdk_event_translate (event, &msg, NULL, NULL))
- ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
+ ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
else
{
- DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
+ if (paimmapp == NULL
+ || (paimmapp->lpVtbl->OnDefWindowProc) (paimmapp, msg.hwnd,
+ msg.message,
+ msg.wParam, msg.lParam,
+ &lres) == S_FALSE)
+ DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
gdk_event_queue_remove_link (node);
g_list_free_1 (node);
gdk_event_free (event);
}
+#endif
}
}
@@ -2937,8 +5027,6 @@ gdk_event_prepare (gpointer source_data,
*timeout = -1;
- GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n"));
-
retval = (gdk_event_queue_find_first () != NULL)
|| PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
@@ -2954,8 +5042,6 @@ gdk_event_check (gpointer source_data,
MSG msg;
gboolean retval;
- GDK_NOTE (EVENTS, g_print ("gdk_event_check\n"));
-
GDK_THREADS_ENTER ();
if (event_poll_fd.revents & G_IO_IN)
@@ -2994,8 +5080,6 @@ gdk_event_dispatch (gpointer source_data,
{
GdkEvent *event;
- GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n"));
-
GDK_THREADS_ENTER ();
gdk_events_queue();
diff --git a/gdk/win32/gdkevents.c b/gdk/win32/gdkevents.c
index 53097d20b7..7ac8169786 100644
--- a/gdk/win32/gdkevents.c
+++ b/gdk/win32/gdkevents.c
@@ -27,21 +27,47 @@
#include "config.h"
+#define NEW_PROPAGATION_CODE
+
+#define USE_DISPATCHMESSAGE
+
+/* Cannot use TrackMouseEvent, as the stupid WM_MOUSELEAVE message
+ * doesn't tell us where the mouse has gone. Thus we cannot use it to
+ * generate a correct GdkNotifyType. Pity, as using TrackMouseEvent
+ * otherwise would make it possible to reliably generate
+ * GDK_LEAVE_NOTIFY events, which would help get rid of those pesky
+ * tooltips sometimes popping up in the wrong place.
+ */
+/* define USE_TRACKMOUSEEVENT */
+
#include <stdio.h>
+#include <windows.h>
+
+#ifdef HAVE_WINTAB
+#include <wintab.h>
+#endif
+
+#include <objbase.h>
+#include <imm.h>
+
+#ifdef HAVE_DIMM_H
+#include <dimm.h>
+#else
+#include "surrogate-dimm.h"
+#endif
+
#include "gdk.h"
-#include "gdkprivate.h"
#include "gdkx.h"
#include "gdkkeysyms.h"
-#ifdef HAVE_WINTAB
-#include <wintab.h>
-#endif
#include "gdkinputprivate.h"
#define PING() printf("%s: %d\n",__FILE__,__LINE__),fflush(stdout)
+#define WINDOW_PRIVATE(wp) ((GdkWindowPrivate *) (wp))
+
typedef struct _GdkIOClosure GdkIOClosure;
typedef struct _GdkEventPrivate GdkEventPrivate;
@@ -80,10 +106,10 @@ struct _GdkEventPrivate
static GdkEvent *gdk_event_new (void);
static GdkFilterReturn
- gdk_event_apply_filters (MSG *xevent,
+ gdk_event_apply_filters(MSG *xevent,
GdkEvent *event,
GList *filters);
-static gint gdk_event_translate (GdkEvent *event,
+static gboolean gdk_event_translate (GdkEvent *event,
MSG *xevent,
gboolean *ret_val_flagp,
gint *ret_valp);
@@ -125,7 +151,7 @@ static GdkWindow *k_grab_window = NULL; /* Window the holds the
static GList *client_filters; /* Filters for client messages */
static gboolean p_grab_automatic;
-static GdkEventMask p_grab_event_mask;
+static GdkEventMask p_grab_mask;
static gboolean p_grab_owner_events, k_grab_owner_events;
static HCURSOR p_grab_cursor;
@@ -158,22 +184,26 @@ static UINT gdk_ping_msg;
static gboolean ignore_WM_CHAR = FALSE;
static gboolean is_AltGr_key = FALSE;
+static IActiveIMMApp *paimmapp = NULL;
+static IActiveIMMMessagePumpOwner *paimmmpo = NULL;
+
LRESULT CALLBACK
-gdk_WindowProc(HWND hwnd,
- UINT message,
- WPARAM wParam,
- LPARAM lParam)
+gdk_WindowProc (HWND hWnd,
+ UINT message,
+ WPARAM wParam,
+ LPARAM lParam)
{
GdkEvent event;
GdkEvent *eventp;
MSG msg;
DWORD pos;
+ LRESULT lres;
gint ret_val;
gboolean ret_val_flag;
- GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x\n", message));
+ GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x %#.03x\n", hWnd, message));
- msg.hwnd = hwnd;
+ msg.hwnd = hWnd;
msg.message = message;
msg.wParam = wParam;
msg.lParam = lParam;
@@ -182,12 +212,14 @@ gdk_WindowProc(HWND hwnd,
msg.pt.x = LOWORD (pos);
msg.pt.y = HIWORD (pos);
+ ((GdkEventPrivate *)&event)->flags |= GDK_EVENT_PENDING;
if (gdk_event_translate (&event, &msg, &ret_val_flag, &ret_val))
{
+ ((GdkEventPrivate *)&event)->flags &= ~GDK_EVENT_PENDING;
#if 1
- /* Compress configure events */
if (event.any.type == GDK_CONFIGURE)
{
+ /* Compress configure events */
GList *list = queued_events;
while (list != NULL
@@ -203,6 +235,29 @@ gdk_WindowProc(HWND hwnd,
return FALSE;
}
}
+ else if (event.any.type == GDK_EXPOSE)
+ {
+ /* Compress expose events */
+ GList *list = queued_events;
+
+ while (list != NULL
+ && (((GdkEvent *)list->data)->any.type != GDK_EXPOSE
+ || ((GdkEvent *)list->data)->any.window != event.any.window))
+ list = list->next;
+ if (list != NULL)
+ {
+ GdkRectangle u;
+
+ gdk_rectangle_union (&event.expose.area,
+ &((GdkEvent *)list->data)->expose.area,
+ &u);
+ ((GdkEvent *)list->data)->expose.area = u;
+ gdk_window_unref (event.any.window);
+ /* Wake up WaitMessage */
+ PostMessage (NULL, gdk_ping_msg, 0, 0);
+ return FALSE;
+ }
+ }
#endif
eventp = gdk_event_new ();
*eventp = event;
@@ -240,7 +295,13 @@ gdk_WindowProc(HWND hwnd,
if (ret_val_flag)
return ret_val;
else
- return DefWindowProc (hwnd, message, wParam, lParam);
+ {
+ if (paimmapp == NULL
+ || (*paimmapp->lpVtbl->OnDefWindowProc) (paimmapp, hWnd, message, wParam, lParam, &lres) == S_FALSE)
+ return DefWindowProc (hWnd, message, wParam, lParam);
+ else
+ return lres;
+ }
}
/*********************************************
@@ -319,8 +380,18 @@ gdk_event_queue_append (GdkEvent *event)
void
gdk_events_init (void)
{
+ HRESULT hres;
+ HMODULE user32;
+ HINSTANCE commctrl32;
+
if (g_pipe_readable_msg == 0)
g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable");
+ GDK_NOTE (EVENTS, g_print ("g-pipe-readable = %#.03x\n",
+ g_pipe_readable_msg));
+
+ gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
+ GDK_NOTE (EVENTS, g_print ("gdk-ping = %#.03x\n",
+ gdk_ping_msg));
g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL);
@@ -336,7 +407,34 @@ gdk_events_init (void)
button_number[0] = -1;
button_number[1] = -1;
- gdk_ping_msg = RegisterWindowMessage ("gdk-ping");
+ hres = CoCreateInstance (&CLSID_CActiveIMM,
+ NULL,
+ CLSCTX_ALL,
+ &IID_IActiveIMMApp,
+ (LPVOID *) &paimmapp);
+
+ if (hres == S_OK)
+ {
+ GDK_NOTE (EVENTS, g_print ("IActiveIMMApp created %#x\n",
+ paimmapp));
+ (*paimmapp->lpVtbl->Activate) (paimmapp, TRUE);
+
+ hres = (*paimmapp->lpVtbl->QueryInterface) (paimmapp, &IID_IActiveIMMMessagePumpOwner, &paimmmpo);
+ GDK_NOTE (EVENTS, g_print ("IActiveIMMMessagePumpOwner created %#x\n",
+ paimmmpo));
+ (paimmmpo->lpVtbl->Start) (paimmmpo);
+ }
+
+#ifdef USE_TRACKMOUSEEVENT
+ user32 = GetModuleHandle ("user32.dll");
+ if ((p_TrackMouseEvent = GetProcAddress (user32, "TrackMouseEvent")) == NULL)
+ {
+ if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL)
+ p_TrackMouseEvent = GetProcAddress (commctrl32, "_TrackMouseEvent");
+ }
+ if (p_TrackMouseEvent != NULL)
+ GDK_NOTE (EVENTS, g_print ("Using TrackMouseEvent to detect leave events\n"));
+#endif
}
/*
@@ -809,12 +907,16 @@ gdk_pointer_grab (GdkWindow * window,
{
if (!GDK_DRAWABLE_DESTROYED (window))
{
- GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x\n",
+ GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x%s%s\n",
xwindow,
(owner_events ? "TRUE" : "FALSE"),
- xcursor));
- p_grab_event_mask = event_mask;
- p_grab_owner_events = owner_events != 0;
+ xcursor,
+ (event_mask & GDK_BUTTON_PRESS_MASK) ?
+ " PRESS" : "",
+ (event_mask & GDK_BUTTON_RELEASE_MASK) ?
+ " RELEASE" : ""));
+ p_grab_mask = event_mask;
+ p_grab_owner_events = (owner_events != 0);
p_grab_automatic = FALSE;
#if 0 /* Menus don't work if we use mouse capture. Pity, because many other
@@ -1076,15 +1178,1887 @@ gdk_add_client_message_filter (GdkAtom message_type,
client_filters = g_list_prepend (client_filters, filter);
}
+/* Thanks to Markus G. Kuhn <mkuhn@acm.org> for the ksysym<->Unicode
+ * mapping functions, from the xterm sources.
+ */
+
+struct k2u {
+ unsigned short keysym;
+ unsigned short ucs;
+} k2utab[] = {
+ { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */
+ { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */
+ { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */
+ { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */
+ { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */
+ { 0x01a9, 0x0160 }, /* Scaron Å  LATIN CAPITAL LETTER S WITH CARON */
+ { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */
+ { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */
+ { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */
+ { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */
+ { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+ { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */
+ { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */
+ { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */
+ { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */
+ { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */
+ { 0x01b7, 0x02c7 }, /* caron ˇ CARON */
+ { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */
+ { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */
+ { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */
+ { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */
+ { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */
+ { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */
+ { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */
+ { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */
+ { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */
+ { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */
+ { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */
+ { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */
+ { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */
+ { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */
+ { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */
+ { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */
+ { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */
+ { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */
+ { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+ { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */
+ { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */
+ { 0x01db, 0x0170 }, /* Udoubleacute Å° LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+ { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */
+ { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */
+ { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */
+ { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */
+ { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */
+ { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */
+ { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */
+ { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */
+ { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */
+ { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */
+ { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */
+ { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */
+ { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+ { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */
+ { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */
+ { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+ { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */
+ { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */
+ { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */
+ { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+ { 0x02a9, 0x0130 }, /* Iabovedot Ä° LATIN CAPITAL LETTER I WITH DOT ABOVE */
+ { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */
+ { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+ { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */
+ { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */
+ { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */
+ { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */
+ { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */
+ { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */
+ { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+ { 0x02d5, 0x0120 }, /* Gabovedot Ä  LATIN CAPITAL LETTER G WITH DOT ABOVE */
+ { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+ { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */
+ { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+ { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */
+ { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */
+ { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */
+ { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */
+ { 0x02fd, 0x016d }, /* ubreve Å­ LATIN SMALL LETTER U WITH BREVE */
+ { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */
+ { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */
+ { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */
+ { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */
+ { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */
+ { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */
+ { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */
+ { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */
+ { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */
+ { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */
+ { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */
+ { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */
+ { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */
+ { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */
+ { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */
+ { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */
+ { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */
+ { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */
+ { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */
+ { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */
+ { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */
+ { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */
+ { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */
+ { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */
+ { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */
+ { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */
+ { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */
+ { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */
+ { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */
+ { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */
+ { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */
+ { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */
+ { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */
+ { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */
+ { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */
+ { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */
+ { 0x047e, 0x203e }, /* overline ‾ OVERLINE */
+ { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
+ { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
+ { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */
+ { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */
+ { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */
+ { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */
+ { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */
+ { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */
+ { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */
+ { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */
+ { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */
+ { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */
+ { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */
+ { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */
+ { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */
+ { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+ { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */
+ { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */
+ { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */
+ { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */
+ { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */
+ { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */
+ { 0x04b7, 0x30ad }, /* kana_KI ã‚­ KATAKANA LETTER KI */
+ { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */
+ { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */
+ { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */
+ { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */
+ { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */
+ { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */
+ { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */
+ { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */
+ { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */
+ { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */
+ { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */
+ { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */
+ { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */
+ { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */
+ { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */
+ { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */
+ { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */
+ { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */
+ { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */
+ { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */
+ { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */
+ { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */
+ { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */
+ { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */
+ { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */
+ { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */
+ { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */
+ { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */
+ { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */
+ { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */
+ { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */
+ { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */
+ { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */
+ { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */
+ { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */
+ { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */
+ { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */
+ { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */
+ { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */
+ { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+ { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */
+ { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */
+ { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */
+ { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */
+ { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */
+ { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */
+ { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */
+ { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */
+ { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */
+ { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */
+ { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */
+ { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */
+ { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */
+ { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */
+ { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */
+ { 0x05cd, 0x062d }, /* Arabic_hah Ø­ ARABIC LETTER HAH */
+ { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */
+ { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */
+ { 0x05d0, 0x0630 }, /* Arabic_thal Ø° ARABIC LETTER THAL */
+ { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */
+ { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */
+ { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */
+ { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */
+ { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */
+ { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */
+ { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */
+ { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */
+ { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */
+ { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */
+ { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */
+ { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */
+ { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */
+ { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */
+ { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */
+ { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */
+ { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */
+ { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */
+ { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */
+ { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */
+ { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */
+ { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */
+ { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */
+ { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */
+ { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */
+ { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */
+ { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */
+ { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */
+ { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */
+ { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */
+ { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */
+ { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */
+ { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */
+ { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */
+ { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */
+ { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */
+ { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */
+ { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */
+ { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */
+ { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */
+ { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */
+ { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */
+ { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */
+ { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */
+ { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */
+ { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */
+ { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+ { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */
+ { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */
+ { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */
+ { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */
+ { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */
+ { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */
+ { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */
+ { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */
+ { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */
+ { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */
+ { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */
+ { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */
+ { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */
+ { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */
+ { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */
+ { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */
+ { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */
+ { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */
+ { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */
+ { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */
+ { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */
+ { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */
+ { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */
+ { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */
+ { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */
+ { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */
+ { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */
+ { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */
+ { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */
+ { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */
+ { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */
+ { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */
+ { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */
+ { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */
+ { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */
+ { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */
+ { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */
+ { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */
+ { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */
+ { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */
+ { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */
+ { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */
+ { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */
+ { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */
+ { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */
+ { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */
+ { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */
+ { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */
+ { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */
+ { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */
+ { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */
+ { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */
+ { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */
+ { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */
+ { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */
+ { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */
+ { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */
+ { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */
+ { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */
+ { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */
+ { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */
+ { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */
+ { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */
+ { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */
+ { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */
+ { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */
+ { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */
+ { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */
+ { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */
+ { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */
+ { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */
+ { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */
+ { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */
+ { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */
+ { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
+ { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
+ { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
+ { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+ { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
+ { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */
+ { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */
+ { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */
+ { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */
+ { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
+ { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
+ { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */
+ { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */
+ { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+ { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+ { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */
+ { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */
+ { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+ { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */
+ { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */
+ { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */
+ { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */
+ { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */
+ { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */
+ { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */
+ { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */
+ { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */
+ { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */
+ { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */
+ { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */
+ { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */
+ { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */
+ { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */
+ { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */
+ { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */
+ { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */
+ { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */
+ { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */
+ { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */
+ { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */
+ { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
+ { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
+ { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
+ { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */
+ { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */
+ { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */
+ { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */
+ { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */
+ { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */
+ { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */
+ { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */
+ { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */
+ { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */
+ { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */
+ { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */
+ { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */
+ { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */
+ { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */
+ { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */
+ { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */
+ { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */
+ { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */
+ { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */
+ { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */
+ { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */
+ { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
+ { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
+ { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
+/* 0x08a1 leftradical ? ??? */
+/* 0x08a2 topleftradical ? ??? */
+/* 0x08a3 horizconnector ? ??? */
+ { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
+ { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
+ { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
+/* 0x08a7 topleftsqbracket ? ??? */
+/* 0x08a8 botleftsqbracket ? ??? */
+/* 0x08a9 toprightsqbracket ? ??? */
+/* 0x08aa botrightsqbracket ? ??? */
+/* 0x08ab topleftparens ? ??? */
+/* 0x08ac botleftparens ? ??? */
+/* 0x08ad toprightparens ? ??? */
+/* 0x08ae botrightparens ? ??? */
+/* 0x08af leftmiddlecurlybrace ? ??? */
+/* 0x08b0 rightmiddlecurlybrace ? ??? */
+/* 0x08b1 topleftsummation ? ??? */
+/* 0x08b2 botleftsummation ? ??? */
+/* 0x08b3 topvertsummationconnector ? ??? */
+/* 0x08b4 botvertsummationconnector ? ??? */
+/* 0x08b5 toprightsummation ? ??? */
+/* 0x08b6 botrightsummation ? ??? */
+/* 0x08b7 rightmiddlesummation ? ??? */
+ { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
+ { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
+ { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */
+ { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
+ { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
+ { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */
+ { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
+ { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
+ { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
+/* 0x08c9 similarequal ? ??? */
+ { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
+ { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
+ { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
+ { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */
+ { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */
+ { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */
+ { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */
+ { 0x08dd, 0x222a }, /* union ∪ UNION */
+ { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */
+ { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */
+ { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */
+ { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */
+ { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */
+ { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
+ { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
+ { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
+ { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */
+ { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */
+ { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */
+ { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */
+ { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */
+ { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */
+ { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */
+ { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */
+ { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */
+ { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */
+ { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */
+ { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
+ { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */
+ { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+/* 0x09ef horizlinescan1 ? ??? */
+/* 0x09f0 horizlinescan3 ? ??? */
+ { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
+/* 0x09f2 horizlinescan7 ? ??? */
+/* 0x09f3 horizlinescan9 ? ??? */
+ { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+ { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+ { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+ { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+ { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */
+ { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */
+ { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */
+ { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */
+ { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */
+ { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */
+ { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */
+ { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */
+ { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */
+ { 0x0aa9, 0x2014 }, /* emdash — EM DASH */
+ { 0x0aaa, 0x2013 }, /* endash – EN DASH */
+/* 0x0aac signifblank ? ??? */
+ { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
+/* 0x0aaf doubbaselinedot ? ??? */
+ { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */
+ { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */
+ { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */
+ { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */
+ { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */
+ { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */
+ { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */
+ { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */
+ { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */
+ { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
+ { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
+ { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
+ { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
+/* 0x0abf marker ? ??? */
+ { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */
+ { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
+ { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */
+ { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */
+ { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */
+ { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */
+/* 0x0acb trademarkincircle ? ??? */
+ { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */
+ { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */
+ { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */
+ { 0x0acf, 0x25a1 }, /* emopenrectangle â–¡ WHITE SQUARE */
+ { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
+ { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
+ { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
+ { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */
+ { 0x0ad4, 0x211e }, /* prescription â„ž PRESCRIPTION TAKE */
+ { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
+ { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
+ { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */
+/* 0x0ada hexagram ? ??? */
+ { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */
+ { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */
+ { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */
+ { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */
+ { 0x0adf, 0x25a0 }, /* emfilledrect â–  BLACK SQUARE */
+ { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */
+ { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */
+ { 0x0ae2, 0x25ad }, /* openrectbullet â–­ WHITE RECTANGLE */
+ { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */
+ { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */
+ { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */
+ { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
+ { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */
+ { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */
+ { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */
+ { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */
+ { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */
+ { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */
+ { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */
+ { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */
+ { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
+ { 0x0af1, 0x2020 }, /* dagger † DAGGER */
+ { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
+ { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */
+ { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
+ { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */
+ { 0x0af6, 0x266d }, /* musicalflat â™­ MUSIC FLAT SIGN */
+ { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */
+ { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */
+ { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */
+ { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
+ { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */
+ { 0x0afc, 0x2038 }, /* caret ‸ CARET */
+ { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */
+ { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */
+/* 0x0aff cursor ? ??? */
+ { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */
+ { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */
+ { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */
+ { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */
+ { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */
+ { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */
+ { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */
+ { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */
+ { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */
+ { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */
+ { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
+ { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */
+ { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */
+ { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */
+ { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
+ { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */
+ { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */
+ { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */
+ { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */
+ { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */
+ { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */
+ { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */
+ { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */
+ { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */
+ { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */
+ { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */
+ { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */
+ { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */
+ { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */
+ { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */
+ { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */
+ { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */
+ { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */
+ { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */
+ { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */
+ { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */
+ { 0x0cf0, 0x05e0 }, /* hebrew_nun ×  HEBREW LETTER NUN */
+ { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */
+ { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */
+ { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */
+ { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */
+ { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */
+ { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */
+ { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */
+ { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */
+ { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */
+ { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */
+ { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */
+ { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */
+ { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */
+ { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */
+ { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */
+ { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */
+ { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */
+ { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */
+ { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */
+ { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */
+ { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */
+ { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */
+ { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */
+ { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */
+ { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */
+ { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */
+ { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */
+ { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */
+ { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */
+ { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */
+ { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */
+ { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */
+ { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */
+ { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */
+ { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */
+ { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */
+ { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */
+ { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */
+ { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */
+ { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */
+ { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */
+ { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */
+ { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */
+ { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */
+ { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */
+ { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */
+ { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */
+ { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */
+ { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */
+ { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */
+ { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */
+ { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */
+ { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */
+ { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */
+ { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */
+ { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */
+ { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */
+ { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */
+ { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */
+ { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */
+ { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */
+ { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */
+ { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */
+ { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */
+ { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */
+ { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */
+ { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */
+ { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */
+ { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */
+ { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */
+ { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */
+ { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */
+ { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */
+ { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */
+ { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */
+ { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */
+ { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */
+ { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */
+ { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */
+ { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */
+ { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */
+ { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */
+ { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */
+ { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */
+ { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */
+ { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */
+ { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */
+ { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */
+ { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */
+ { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */
+ { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */
+ { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */
+ { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */
+ { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */
+ { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */
+ { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */
+ { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */
+ { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */
+ { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */
+ { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */
+ { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */
+ { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */
+ { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */
+ { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */
+ { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */
+ { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */
+ { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */
+ { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */
+ { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */
+ { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */
+ { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */
+ { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */
+ { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */
+ { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */
+ { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */
+ { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */
+ { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */
+ { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */
+ { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */
+ { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */
+ { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */
+ { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */
+ { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */
+ { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */
+ { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */
+ { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */
+ { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */
+ { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */
+ { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */
+ { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */
+ { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */
+ { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */
+ { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */
+ { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */
+ { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */
+ { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */
+ { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */
+ { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */
+ { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */
+ { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */
+ { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */
+ { 0x0ed0, 0x3160 }, /* Hangul_YU ã…  HANGUL LETTER YU */
+ { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */
+ { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */
+ { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */
+ { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */
+ { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */
+ { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */
+ { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */
+ { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */
+ { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */
+ { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */
+ { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */
+ { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */
+ { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */
+ { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */
+ { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */
+ { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */
+ { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */
+ { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */
+ { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */
+ { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */
+ { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */
+ { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */
+ { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */
+ { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */
+ { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */
+ { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */
+ { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */
+ { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */
+ { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */
+ { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
+ { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã…­ HANGUL LETTER RIEUL-YEORINHIEUH */
+ { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */
+ { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */
+ { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */
+/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */
+ { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
+ { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
+ { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */
+ { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
+ { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
+/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */
+ { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
+ { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */
+ { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */
+ { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */
+ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ { 0x20a0, 0x20a0 }, /* EcuSign â‚  EURO-CURRENCY SIGN */
+ { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */
+ { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */
+ { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */
+ { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */
+ { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */
+ { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */
+ { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */
+ { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */
+ { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */
+ { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */
+ { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */
+ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */
+};
+
+static guint
+keyval_to_unicode (guint keysym)
+{
+ int min = 0;
+ int max = sizeof(k2utab) / sizeof(k2utab[0]) - 1;
+ int mid;
+
+ /* First check for Latin-1 characters (1:1 mapping) */
+ if ((keysym >= 0x0020 && keysym <= 0x007e) ||
+ (keysym >= 0x00a0 && keysym <= 0x00ff))
+ return keysym;
+
+ /* Also check for directly encoded 24-bit UCS characters */
+ if ((keysym & 0xff000000) == 0x01000000)
+ return keysym & 0x00ffffff;
+
+ /* binary search in table */
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (k2utab[mid].keysym < keysym)
+ min = mid + 1;
+ else if (k2utab[mid].keysym > keysym)
+ max = mid - 1;
+ else {
+ /* found it */
+ return k2utab[mid].ucs;
+ }
+ }
+
+ /* No matching Unicode value found */
+ return -1;
+}
+
+struct u2k {
+ unsigned short keysym;
+ unsigned short ucs;
+} u2ktab[] = {
+ { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */
+ { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */
+ { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */
+ { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */
+ { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */
+ { 0x03c0, 0x0100 }, /* Amacron Ā LATIN CAPITAL LETTER A WITH MACRON */
+ { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */
+ { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */
+ { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */
+ { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */
+ { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */
+ { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */
+ { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */
+ { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */
+ { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */
+ { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */
+ { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */
+ { 0x01c8, 0x010c }, /* Ccaron Č LATIN CAPITAL LETTER C WITH CARON */
+ { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */
+ { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */
+ { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */
+ { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */
+ { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */
+ { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */
+ { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */
+ { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */
+ { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */
+ { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */
+ { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */
+ { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */
+ { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */
+ { 0x02d8, 0x011c }, /* Gcircumflex Ĝ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */
+ { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */
+ { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */
+ { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */
+ { 0x02d5, 0x0120 }, /* Gabovedot Ä  LATIN CAPITAL LETTER G WITH DOT ABOVE */
+ { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */
+ { 0x03ab, 0x0122 }, /* Gcedilla Ģ LATIN CAPITAL LETTER G WITH CEDILLA */
+ { 0x03bb, 0x0123 }, /* gcedilla ģ LATIN SMALL LETTER G WITH CEDILLA */
+ { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */
+ { 0x02b6, 0x0125 }, /* hcircumflex ĥ LATIN SMALL LETTER H WITH CIRCUMFLEX */
+ { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */
+ { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */
+ { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */
+ { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */
+ { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */
+ { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */
+ { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */
+ { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */
+ { 0x02a9, 0x0130 }, /* Iabovedot Ä° LATIN CAPITAL LETTER I WITH DOT ABOVE */
+ { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */
+ { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */
+ { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */
+ { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */
+ { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */
+ { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */
+ { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */
+ { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */
+ { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */
+ { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */
+ { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */
+ { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */
+ { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */
+ { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */
+ { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */
+ { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */
+ { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */
+ { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */
+ { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */
+ { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */
+ { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */
+ { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */
+ { 0x03d2, 0x014c }, /* Omacron Ō LATIN CAPITAL LETTER O WITH MACRON */
+ { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */
+ { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */
+ { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */
+ { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */
+ { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */
+ { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */
+ { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */
+ { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */
+ { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */
+ { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */
+ { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */
+ { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */
+ { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */
+ { 0x02de, 0x015c }, /* Scircumflex Ŝ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */
+ { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */
+ { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */
+ { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */
+ { 0x01a9, 0x0160 }, /* Scaron Å  LATIN CAPITAL LETTER S WITH CARON */
+ { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */
+ { 0x01de, 0x0162 }, /* Tcedilla Ţ LATIN CAPITAL LETTER T WITH CEDILLA */
+ { 0x01fe, 0x0163 }, /* tcedilla ţ LATIN SMALL LETTER T WITH CEDILLA */
+ { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */
+ { 0x01bb, 0x0165 }, /* tcaron ť LATIN SMALL LETTER T WITH CARON */
+ { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */
+ { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */
+ { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */
+ { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */
+ { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */
+ { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */
+ { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */
+ { 0x02fd, 0x016d }, /* ubreve Å­ LATIN SMALL LETTER U WITH BREVE */
+ { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */
+ { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */
+ { 0x01db, 0x0170 }, /* Udoubleacute Å° LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */
+ { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */
+ { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */
+ { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */
+ { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */
+ { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */
+ { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */
+ { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */
+ { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */
+ { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */
+ { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */
+ { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */
+ { 0x01b7, 0x02c7 }, /* caron ˇ CARON */
+ { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */
+ { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */
+ { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */
+ { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */
+ { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */
+ { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */
+ { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */
+ { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */
+ { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */
+ { 0x07a7, 0x038c }, /* Greek_OMICRONaccent Ό GREEK CAPITAL LETTER OMICRON WITH TONOS */
+ { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */
+ { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */
+ { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */
+ { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */
+ { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */
+ { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */
+ { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */
+ { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */
+ { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */
+ { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */
+ { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */
+ { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */
+ { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */
+ { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */
+ { 0x07cc, 0x039c }, /* Greek_MU Μ GREEK CAPITAL LETTER MU */
+ { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */
+ { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */
+ { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */
+ { 0x07d0, 0x03a0 }, /* Greek_PI Π GREEK CAPITAL LETTER PI */
+ { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */
+ { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */
+ { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */
+ { 0x07d5, 0x03a5 }, /* Greek_UPSILON Υ GREEK CAPITAL LETTER UPSILON */
+ { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */
+ { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */
+ { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */
+ { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */
+ { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */
+ { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */
+ { 0x07b2, 0x03ad }, /* Greek_epsilonaccent έ GREEK SMALL LETTER EPSILON WITH TONOS */
+ { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */
+ { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */
+ { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */
+ { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */
+ { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */
+ { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */
+ { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */
+ { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */
+ { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */
+ { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */
+ { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */
+ { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */
+ { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */
+ { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */
+ { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */
+ { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */
+ { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */
+ { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */
+ { 0x07f0, 0x03c0 }, /* Greek_pi π GREEK SMALL LETTER PI */
+ { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */
+ { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */
+ { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */
+ { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */
+ { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */
+ { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */
+ { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */
+ { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */
+ { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */
+ { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */
+ { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */
+ { 0x07b7, 0x03cc }, /* Greek_omicronaccent ό GREEK SMALL LETTER OMICRON WITH TONOS */
+ { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */
+ { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */
+ { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */
+ { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */
+ { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */
+ { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */
+ { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */
+ { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */
+ { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */
+ { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */
+ { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */
+ { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */
+ { 0x06bc, 0x040c }, /* Macedonia_KJE Ќ CYRILLIC CAPITAL LETTER KJE */
+ { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */
+ { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */
+ { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */
+ { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */
+ { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */
+ { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */
+ { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */
+ { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */
+ { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */
+ { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */
+ { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */
+ { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */
+ { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */
+ { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */
+ { 0x06ed, 0x041c }, /* Cyrillic_EM М CYRILLIC CAPITAL LETTER EM */
+ { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */
+ { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */
+ { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */
+ { 0x06f2, 0x0420 }, /* Cyrillic_ER Р CYRILLIC CAPITAL LETTER ER */
+ { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */
+ { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */
+ { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */
+ { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */
+ { 0x06e8, 0x0425 }, /* Cyrillic_HA Х CYRILLIC CAPITAL LETTER HA */
+ { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */
+ { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */
+ { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */
+ { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */
+ { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */
+ { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */
+ { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */
+ { 0x06fc, 0x042d }, /* Cyrillic_E Э CYRILLIC CAPITAL LETTER E */
+ { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */
+ { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */
+ { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */
+ { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */
+ { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */
+ { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */
+ { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */
+ { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */
+ { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */
+ { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */
+ { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */
+ { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */
+ { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */
+ { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */
+ { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */
+ { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */
+ { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */
+ { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */
+ { 0x06d2, 0x0440 }, /* Cyrillic_er р CYRILLIC SMALL LETTER ER */
+ { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */
+ { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */
+ { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */
+ { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */
+ { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */
+ { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */
+ { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */
+ { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */
+ { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */
+ { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */
+ { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */
+ { 0x06d8, 0x044c }, /* Cyrillic_softsign ь CYRILLIC SMALL LETTER SOFT SIGN */
+ { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */
+ { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */
+ { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */
+ { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */
+ { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */
+ { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */
+ { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */
+ { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */
+ { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */
+ { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */
+ { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */
+ { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */
+ { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */
+ { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */
+ { 0x06ac, 0x045c }, /* Macedonia_kje ќ CYRILLIC SMALL LETTER KJE */
+ { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */
+ { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */
+ { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */
+ { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */
+ { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */
+ { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */
+ { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */
+ { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */
+ { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */
+ { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */
+ { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */
+ { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */
+ { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */
+ { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */
+ { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */
+ { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */
+ { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */
+ { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */
+ { 0x0cf0, 0x05e0 }, /* hebrew_nun ×  HEBREW LETTER NUN */
+ { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */
+ { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */
+ { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */
+ { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */
+ { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */
+ { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */
+ { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */
+ { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */
+ { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */
+ { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */
+ { 0x05ac, 0x060c }, /* Arabic_comma ، ARABIC COMMA */
+ { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */
+ { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */
+ { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */
+ { 0x05c2, 0x0622 }, /* Arabic_maddaonalef آ ARABIC LETTER ALEF WITH MADDA ABOVE */
+ { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef أ ARABIC LETTER ALEF WITH HAMZA ABOVE */
+ { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */
+ { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef إ ARABIC LETTER ALEF WITH HAMZA BELOW */
+ { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */
+ { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */
+ { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */
+ { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */
+ { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */
+ { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */
+ { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */
+ { 0x05cd, 0x062d }, /* Arabic_hah Ø­ ARABIC LETTER HAH */
+ { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */
+ { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */
+ { 0x05d0, 0x0630 }, /* Arabic_thal Ø° ARABIC LETTER THAL */
+ { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */
+ { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */
+ { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */
+ { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */
+ { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */
+ { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */
+ { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */
+ { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */
+ { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */
+ { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */
+ { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */
+ { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */
+ { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */
+ { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */
+ { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */
+ { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */
+ { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */
+ { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */
+ { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */
+ { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */
+ { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */
+ { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */
+ { 0x05ec, 0x064c }, /* Arabic_dammatan ٌ ARABIC DAMMATAN */
+ { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */
+ { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */
+ { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */
+ { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */
+ { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */
+ { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */
+ { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */
+ { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */
+ { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */
+ { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */
+ { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */
+ { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */
+ { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */
+ { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */
+ { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */
+ { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */
+ { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */
+ { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */
+ { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */
+ { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */
+ { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */
+ { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */
+ { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */
+ { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */
+ { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */
+ { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */
+ { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */
+ { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */
+ { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */
+ { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */
+ { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */
+ { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */
+ { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */
+ { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */
+ { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */
+ { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */
+ { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */
+ { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภ THAI CHARACTER PHO SAMPHAO */
+ { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */
+ { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */
+ { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */
+ { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */
+ { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */
+ { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */
+ { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */
+ { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */
+ { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */
+ { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */
+ { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */
+ { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */
+ { 0x0dcd, 0x0e2d }, /* Thai_oang อ THAI CHARACTER O ANG */
+ { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */
+ { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */
+ { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */
+ { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */
+ { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */
+ { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */
+ { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */
+ { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */
+ { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */
+ { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */
+ { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */
+ { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */
+ { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */
+ { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */
+ { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */
+ { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */
+ { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */
+ { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */
+ { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */
+ { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */
+ { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */
+ { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */
+ { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */
+ { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */
+ { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */
+ { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */
+ { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */
+ { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */
+ { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */
+ { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */
+ { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */
+ { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */
+ { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */
+ { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */
+ { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */
+ { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */
+ { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */
+ { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */
+ { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */
+ { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */
+ { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */
+ { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */
+ { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */
+ { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆭ HANGUL JONGSEONG NIEUN-HIEUH */
+ { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */
+ { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */
+ { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */
+ { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */
+ { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */
+ { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */
+ { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */
+ { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */
+ { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */
+ { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */
+ { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */
+ { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */
+ { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */
+ { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */
+ { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */
+ { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */
+ { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */
+ { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */
+ { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */
+ { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */
+ { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */
+ { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */
+ { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */
+ { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */
+ { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */
+ { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */
+ { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */
+ { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */
+ { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */
+ { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */
+ { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */
+ { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */
+ { 0x0aaa, 0x2013 }, /* endash – EN DASH */
+ { 0x0aa9, 0x2014 }, /* emdash — EM DASH */
+ { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */
+ { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */
+ { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */
+ { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */
+ { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */
+ { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */
+ { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */
+ { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */
+ { 0x0af1, 0x2020 }, /* dagger † DAGGER */
+ { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */
+ { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */
+ { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */
+ { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */
+ { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */
+ { 0x0afc, 0x2038 }, /* caret ‸ CARET */
+ { 0x047e, 0x203e }, /* overline ‾ OVERLINE */
+ { 0x20a0, 0x20a0 }, /* EcuSign â‚  EURO-CURRENCY SIGN */
+ { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */
+ { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */
+ { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */
+ { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */
+ { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */
+ { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */
+ { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */
+ { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */
+ { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */
+ { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */
+ { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */
+ { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */
+ { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */
+ { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */
+ { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */
+ { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */
+ { 0x0ad4, 0x211e }, /* prescription â„ž PRESCRIPTION TAKE */
+ { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */
+ { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */
+ { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */
+ { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */
+ { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */
+ { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */
+ { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */
+ { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */
+ { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */
+ { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */
+ { 0x0ac4, 0x215c }, /* threeeighths ⅜ VULGAR FRACTION THREE EIGHTHS */
+ { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */
+ { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */
+ { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */
+ { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */
+ { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */
+ { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */
+ { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */
+ { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */
+ { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */
+ { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */
+ { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */
+ { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */
+ { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */
+ { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */
+ { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */
+ { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */
+ { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */
+ { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */
+ { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */
+ { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */
+ { 0x08dd, 0x222a }, /* union ∪ UNION */
+ { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */
+ { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */
+ { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */
+ { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */
+ { 0x08bd, 0x2260 }, /* notequal ≠ NOT EQUAL TO */
+ { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */
+ { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */
+ { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */
+ { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */
+ { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */
+ { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */
+ { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */
+ { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */
+ { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */
+ { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */
+ { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */
+ { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */
+ { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */
+ { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */
+ { 0x08a4, 0x2320 }, /* topintegral ⌠ TOP HALF INTEGRAL */
+ { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */
+ { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */
+ { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */
+ { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */
+ { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */
+ { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */
+ { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */
+ { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */
+ { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */
+ { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */
+ { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */
+ { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */
+ { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */
+ { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */
+ { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */
+ { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */
+ { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */
+ { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */
+ { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */
+ { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */
+ { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */
+ { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */
+ { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */
+ { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */
+ { 0x0adf, 0x25a0 }, /* emfilledrect â–  BLACK SQUARE */
+ { 0x0acf, 0x25a1 }, /* emopenrectangle â–¡ WHITE SQUARE */
+ { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */
+ { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */
+ { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */
+ { 0x0ae2, 0x25ad }, /* openrectbullet â–­ WHITE RECTANGLE */
+ { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */
+ { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */
+ { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */
+ { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */
+ { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */
+ { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */
+ { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */
+ { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */
+ { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */
+ { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */
+ { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */
+ { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */
+ { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */
+ { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */
+ { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */
+ { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */
+ { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */
+ { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */
+ { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */
+ { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */
+ { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */
+ { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */
+ { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */
+ { 0x0af6, 0x266d }, /* musicalflat â™­ MUSIC FLAT SIGN */
+ { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */
+ { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */
+ { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */
+ { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */
+ { 0x0af0, 0x2720 }, /* maltesecross ✠ MALTESE CROSS */
+ { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */
+ { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */
+ { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */
+ { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */
+ { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */
+ { 0x04df, 0x309c }, /* semivoicedsound ゜ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */
+ { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */
+ { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */
+ { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */
+ { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */
+ { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */
+ { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */
+ { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */
+ { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */
+ { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */
+ { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */
+ { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */
+ { 0x04b7, 0x30ad }, /* kana_KI ã‚­ KATAKANA LETTER KI */
+ { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */
+ { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */
+ { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */
+ { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */
+ { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */
+ { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */
+ { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */
+ { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */
+ { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */
+ { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */
+ { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */
+ { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */
+ { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */
+ { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */
+ { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */
+ { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */
+ { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */
+ { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */
+ { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */
+ { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */
+ { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */
+ { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */
+ { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */
+ { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */
+ { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */
+ { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */
+ { 0x04d1, 0x30e0 }, /* kana_MU ム KATAKANA LETTER MU */
+ { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */
+ { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */
+ { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */
+ { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */
+ { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */
+ { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */
+ { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */
+ { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */
+ { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */
+ { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */
+ { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */
+ { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */
+ { 0x04db, 0x30ed }, /* kana_RO ロ KATAKANA LETTER RO */
+ { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */
+ { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */
+ { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */
+ { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */
+ { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */
+ { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */
+ { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */
+ { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */
+ { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */
+ { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */
+ { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */
+ { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */
+ { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */
+ { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */
+ { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */
+ { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */
+ { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */
+ { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */
+ { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */
+ { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */
+ { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */
+ { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */
+ { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */
+ { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */
+ { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */
+ { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */
+ { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */
+ { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */
+ { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */
+ { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */
+ { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */
+ { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */
+ { 0x0ebc, 0x314c }, /* Hangul_Tieut ㅌ HANGUL LETTER THIEUTH */
+ { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */
+ { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */
+ { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */
+ { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */
+ { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */
+ { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */
+ { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */
+ { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */
+ { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */
+ { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */
+ { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */
+ { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */
+ { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */
+ { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */
+ { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */
+ { 0x0ecc, 0x315c }, /* Hangul_U ㅜ HANGUL LETTER U */
+ { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */
+ { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */
+ { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */
+ { 0x0ed0, 0x3160 }, /* Hangul_YU ã…  HANGUL LETTER YU */
+ { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */
+ { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */
+ { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */
+ { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã…­ HANGUL LETTER RIEUL-YEORINHIEUH */
+ { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */
+ { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */
+ { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */
+ { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */
+ { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */
+ { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */
+ { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */
+};
+
+static guint
+unicode_to_keyval (wchar_t ucs)
+{
+ int min = 0;
+ int max = sizeof(u2ktab) / sizeof(u2ktab[0]) - 1;
+ int mid;
+
+ /* First check for Latin-1 characters (1:1 mapping) */
+ if ((ucs >= 0x0020 && ucs <= 0x007e) ||
+ (ucs >= 0x00a0 && ucs <= 0x00ff))
+ return ucs;
+
+ /* Binary search in table */
+ while (max >= min) {
+ mid = (min + max) / 2;
+ if (u2ktab[mid].ucs < ucs)
+ min = mid + 1;
+ else if (u2ktab[mid].ucs > ucs)
+ max = mid - 1;
+ else {
+ /* found it */
+ return u2ktab[mid].keysym;
+ }
+ }
+
+ /*
+ * No matching keysym value found, return Unicode value plus 0x01000000
+ * (a convention introduced in the UTF-8 work on xterm).
+ */
+ return ucs | 0x01000000;
+}
+
+static void
+build_key_event_state (GdkEvent *event)
+{
+ event->key.state = 0;
+ if (GetKeyState (VK_SHIFT) < 0)
+ event->key.state |= GDK_SHIFT_MASK;
+ if (GetKeyState (VK_CAPITAL) & 0x1)
+ event->key.state |= GDK_LOCK_MASK;
+ if (!is_AltGr_key)
+ {
+ if (GetKeyState (VK_CONTROL) < 0)
+ {
+ event->key.state |= GDK_CONTROL_MASK;
+ if (event->key.keyval < ' ')
+ event->key.keyval += '@';
+ }
+ else if (event->key.keyval < ' ')
+ {
+ event->key.state |= GDK_CONTROL_MASK;
+ event->key.keyval += '@';
+ }
+ if (GetKeyState (VK_MENU) < 0)
+ event->key.state |= GDK_MOD1_MASK;
+ }
+}
+
+static void
+build_keypress_event (GdkWindowPrivate *window_private,
+ GdkEvent *event,
+ MSG *xevent)
+{
+ gint i, bytesleft, bytecount, ucount, ucleft, len;
+ guchar buf[100], *bp;
+ wchar_t wbuf[100], *wcp;
+
+ event->key.type = GDK_KEY_PRESS;
+ event->key.time = xevent->time;
+
+ if (xevent->message == WM_CHAR)
+ {
+ bytecount = MIN ((xevent->lParam & 0xFFFF), sizeof (buf));
+ for (i = 0; i < bytecount; i++)
+ buf[i] = xevent->wParam;
+ }
+ else
+ {
+ /* WM_IME_CHAR */
+ event->key.keyval = GDK_VoidSymbol;
+ if (xevent->wParam & 0xFF00)
+ {
+ /* Contrary to the documentation,
+ * the lead byte is the msb byte.
+ */
+ buf[0] = ((xevent->wParam >> 8) & 0xFF);
+ buf[1] = (xevent->wParam & 0xFF);
+ bytecount = 2;
+ }
+ else
+ {
+ buf[0] = (xevent->wParam & 0xFF);
+ bytecount = 1;
+ }
+ }
+
+ /* Convert from the window's current code page
+ * to Unicode. Then convert to UTF-8.
+ * We don't handle the surrogate stuff. Should we?
+ */
+ ucount = MultiByteToWideChar (window_private->charset_info.ciACP,
+ 0, buf, bytecount, wbuf, 100);
+
+ if (ucount == 0)
+ event->key.keyval = GDK_VoidSymbol;
+ else if (xevent->message == WM_CHAR)
+ if (xevent->wParam < ' ')
+ event->key.keyval = xevent->wParam + '@';
+ else
+ event->key.keyval = unicode_to_keyval (wbuf[0]);
+ else
+ event->key.keyval = GDK_VoidSymbol;
+
+ build_key_event_state (event);
+
+ ucleft = ucount;
+ len = 0;
+ wcp = wbuf;
+ while (ucleft-- > 0)
+ {
+ wchar_t c = *wcp++;
+
+ if (c < 0x80)
+ len += 1;
+ else if (c < 0x800)
+ len += 2;
+ else
+ len += 3;
+ }
+
+ event->key.string = g_malloc (len + 1);
+ event->key.length = len;
+
+ ucleft = ucount;
+ wcp = wbuf;
+ bp = event->key.string;
+ while (ucleft-- > 0)
+ {
+ int first;
+ int i;
+ wchar_t c = *wcp++;
+
+ if (c < 0x80)
+ {
+ first = 0;
+ len = 1;
+ }
+ else if (c < 0x800)
+ {
+ first = 0xc0;
+ len = 2;
+ }
+ else
+ {
+ first = 0xe0;
+ len = 3;
+ }
+
+#if 1
+ /* Woo-hoo! */
+ switch (len)
+ {
+ case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 1: bp[0] = c | first;
+ }
+#else
+ for (i = len - 1; i > 0; --i)
+ {
+ bp[i] = (c & 0x3f) | 0x80;
+ c >>= 6;
+ }
+ bp[0] = c | first;
+#endif
+
+ bp += len;
+ }
+ *bp = 0;
+}
+
+static void
+print_event_state (gint state)
+{
+ if (state & GDK_SHIFT_MASK)
+ g_print ("SHIFT ");
+ if (state & GDK_LOCK_MASK)
+ g_print ("LOCK ");
+ if (state & GDK_CONTROL_MASK)
+ g_print ("CONTROL ");
+ if (state & GDK_MOD1_MASK)
+ g_print ("MOD1 ");
+ if (state & GDK_BUTTON1_MASK)
+ g_print ("BUTTON1 ");
+ if (state & GDK_BUTTON2_MASK)
+ g_print ("BUTTON2 ");
+ if (state & GDK_BUTTON3_MASK)
+ g_print ("BUTTON3 ");
+}
+
+static void
+print_event (GdkEvent *event)
+{
+ gchar *escaped, *kvname;
+
+ switch (event->any.type)
+ {
+ case GDK_NOTHING: g_print ("GDK_NOTHING "); break;
+ case GDK_DELETE: g_print ("GDK_DELETE "); break;
+ case GDK_DESTROY: g_print ("GDK_DESTROY "); break;
+ case GDK_EXPOSE: g_print ("GDK_EXPOSE "); break;
+ case GDK_MOTION_NOTIFY: g_print ("GDK_MOTION_NOTIFY "); break;
+ case GDK_BUTTON_PRESS: g_print ("GDK_BUTTON_PRESS "); break;
+ case GDK_2BUTTON_PRESS: g_print ("GDK_2BUTTON_PRESS "); break;
+ case GDK_3BUTTON_PRESS: g_print ("GDK_3BUTTON_PRESS "); break;
+ case GDK_BUTTON_RELEASE: g_print ("GDK_BUTTON_RELEASE "); break;
+ case GDK_KEY_PRESS: g_print ("GDK_KEY_PRESS "); break;
+ case GDK_KEY_RELEASE: g_print ("GDK_KEY_RELEASE "); break;
+ case GDK_ENTER_NOTIFY: g_print ("GDK_ENTER_NOTIFY "); break;
+ case GDK_LEAVE_NOTIFY: g_print ("GDK_LEAVE_NOTIFY "); break;
+ case GDK_FOCUS_CHANGE: g_print ("GDK_FOCUS_CHANGE "); break;
+ case GDK_CONFIGURE: g_print ("GDK_CONFIGURE "); break;
+ case GDK_MAP: g_print ("GDK_MAP "); break;
+ case GDK_UNMAP: g_print ("GDK_UNMAP "); break;
+ case GDK_PROPERTY_NOTIFY: g_print ("GDK_PROPERTY_NOTIFY "); break;
+ case GDK_SELECTION_CLEAR: g_print ("GDK_SELECTION_CLEAR "); break;
+ case GDK_SELECTION_REQUEST: g_print ("GDK_SELECTION_REQUEST "); break;
+ case GDK_SELECTION_NOTIFY: g_print ("GDK_SELECTION_NOTIFY "); break;
+ case GDK_PROXIMITY_IN: g_print ("GDK_PROXIMITY_IN "); break;
+ case GDK_PROXIMITY_OUT: g_print ("GDK_PROXIMITY_OUT "); break;
+ case GDK_DRAG_ENTER: g_print ("GDK_DRAG_ENTER "); break;
+ case GDK_DRAG_LEAVE: g_print ("GDK_DRAG_LEAVE "); break;
+ case GDK_DRAG_MOTION: g_print ("GDK_DRAG_MOTION "); break;
+ case GDK_DRAG_STATUS: g_print ("GDK_DRAG_STATUS "); break;
+ case GDK_DROP_START: g_print ("GDK_DROP_START "); break;
+ case GDK_DROP_FINISHED: g_print ("GDK_DROP_FINISHED "); break;
+ case GDK_CLIENT_EVENT: g_print ("GDK_CLIENT_EVENT "); break;
+ case GDK_VISIBILITY_NOTIFY: g_print ("GDK_VISIBILITY_NOTIFY "); break;
+ case GDK_NO_EXPOSE: g_print ("GDK_NO_EXPOSE "); break;
+ }
+ g_print ("%#x ", GDK_DRAWABLE_XID (event->any.window));
+
+ switch (event->any.type)
+ {
+ case GDK_EXPOSE:
+ g_print ("%dx%d@+%d+%d %d",
+ event->expose.area.width,
+ event->expose.area.height,
+ event->expose.area.x,
+ event->expose.area.y,
+ event->expose.count);
+ break;
+ case GDK_MOTION_NOTIFY:
+ print_event_state (event->motion.state);
+ break;
+ case GDK_BUTTON_PRESS:
+ case GDK_BUTTON_RELEASE:
+ g_print ("%d ", event->button.button);
+ print_event_state (event->button.state);
+ break;
+ case GDK_KEY_PRESS:
+ case GDK_KEY_RELEASE:
+ if (event->key.length == 0)
+ escaped = g_strdup ("");
+ else
+ escaped = g_strescape (event->key.string, NULL);
+ kvname = gdk_keyval_name (event->key.keyval);
+ g_print ("%s %d:\"%s\" ",
+ (kvname ? kvname : "??"),
+ event->key.length,
+ escaped);
+ g_free (escaped);
+ print_event_state (event->key.state);
+ break;
+ case GDK_ENTER_NOTIFY:
+ case GDK_LEAVE_NOTIFY:
+ g_print (" %s",
+ (event->crossing.detail == GDK_NOTIFY_INFERIOR ? "INFERIOR" :
+ (event->crossing.detail == GDK_NOTIFY_ANCESTOR ? "ANCESTOR" :
+ (event->crossing.detail == GDK_NOTIFY_NONLINEAR ? "NONLINEAR" :
+ "???"))));
+ break;
+ }
+ g_print ("\n");
+}
+
static void
synthesize_crossing_events (GdkWindow *window,
MSG *xevent)
{
+ TRACKMOUSEEVENT tme;
GdkEvent *event;
- GdkWindowPrivate *window_private = (GdkWindowPrivate *) window;
- GdkWindowPrivate *curWnd_private = (GdkWindowPrivate *) curWnd;
- if (curWnd && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
+ /* If we are not using TrackMouseEvent, generate a leave notify
+ * event if necessary
+ */
+ if (p_TrackMouseEvent == NULL
+ && curWnd
+ && (WINDOW_PRIVATE(curWnd)->event_mask & GDK_LEAVE_NOTIFY_MASK))
{
GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n"));
@@ -1099,15 +3073,21 @@ synthesize_crossing_events (GdkWindow *window,
event->crossing.x_root = curXroot;
event->crossing.y_root = curYroot;
event->crossing.mode = GDK_CROSSING_NORMAL;
- event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+ if (IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ else if (IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ else
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
event->crossing.focus = TRUE; /* ??? */
event->crossing.state = 0; /* ??? */
gdk_event_queue_append (event);
+ GDK_NOTE (EVENTS, print_event (event));
}
- if (window_private && (window_private->event_mask & GDK_ENTER_NOTIFY_MASK))
+ if (WINDOW_PRIVATE(window)->event_mask & GDK_ENTER_NOTIFY_MASK)
{
GDK_NOTE (EVENTS, g_print ("synthesizing ENTER_NOTIFY event\n"));
@@ -1122,35 +3102,217 @@ synthesize_crossing_events (GdkWindow *window,
event->crossing.x_root = (gfloat) xevent->pt.x;
event->crossing.y_root = (gfloat) xevent->pt.y;
event->crossing.mode = GDK_CROSSING_NORMAL;
- event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+ if (curWnd
+ && IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ else if (curWnd
+ && IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ else
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
event->crossing.focus = TRUE; /* ??? */
event->crossing.state = 0; /* ??? */
gdk_event_queue_append (event);
- if (window_private->extension_events != 0
+ GDK_NOTE (EVENTS, print_event (event));
+
+ if (WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_vtable.enter_event)
gdk_input_vtable.enter_event (&event->crossing, window);
+
}
if (curWnd)
gdk_window_unref (curWnd);
curWnd = window;
gdk_window_ref (curWnd);
+ if (p_TrackMouseEvent != NULL)
+ {
+ tme.cbSize = sizeof (TRACKMOUSEEVENT);
+ tme.dwFlags = TME_LEAVE;
+ tme.hwndTrack = GDK_DRAWABLE_XID (curWnd);
+ tme.dwHoverTime = HOVER_DEFAULT;
+
+ (*p_TrackMouseEvent) (&tme);
+ }
+}
+
+static GdkWindow *
+key_propagate (GdkWindow *window,
+ MSG *xevent)
+{
+ gdk_window_unref (window);
+ window = WINDOW_PRIVATE(window)->parent;
+ gdk_window_ref (window);
+ GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
+ GDK_DRAWABLE_XID (window)));
+
+ return window;
+}
+
+static GdkWindow *
+mouse_propagate (GdkWindow *window,
+ MSG *xevent)
+{
+ POINT pt;
+
+ pt.x = LOWORD (xevent->lParam);
+ pt.y = HIWORD (xevent->lParam);
+ ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
+ gdk_window_unref (window);
+ window = WINDOW_PRIVATE(window)->parent;
+ gdk_window_ref (window);
+ ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
+ xevent->lParam = MAKELPARAM (pt.x, pt.y);
+ GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
+ GDK_DRAWABLE_XID (window)));
+ return window;
+}
+
+#ifdef NEW_PROPAGATION_CODE
+
+static gboolean
+propagate (GdkWindow **window,
+ MSG *xevent,
+ GdkWindow *grab_window,
+ gboolean grab_owner_events,
+ gint grab_mask,
+ gboolean (*doesnt_want_it) (gint mask,
+ MSG *xevent),
+ GdkWindow *(*propagate) (GdkWindow *window,
+ MSG *xevent))
+{
+ if (grab_window != NULL && !grab_owner_events)
+ {
+ /* Event source is grabbed with owner_events FALSE */
+ GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE, "));
+ if ((*doesnt_want_it) (grab_mask, xevent))
+ {
+ GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n"));
+ return FALSE;
+ }
+ else
+ {
+ GDK_NOTE (EVENTS, g_print ("...sending to grabber %#x\n",
+ GDK_DRAWABLE_XID (grab_window)));
+ gdk_window_unref (*window);
+ *window = grab_window;
+ gdk_window_ref (*window);
+ return TRUE;
+ }
+ }
+ while (TRUE)
+ {
+ if ((*doesnt_want_it) (WINDOW_PRIVATE(*window)->event_mask, xevent))
+ {
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(*window)->parent == (GdkWindow *) gdk_root_parent)
+ {
+ /* No parent; check if grabbed */
+ if (grab_window != NULL)
+ {
+ /* Event source is grabbed with owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ if ((*doesnt_want_it) (grab_mask, xevent))
+ {
+ /* Grabber doesn't want it either */
+ GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n"));
+ return FALSE;
+ }
+ else
+ {
+ /* Grabbed! */
+ GDK_NOTE (EVENTS, g_print ("...sending to grabber %#x\n",
+ GDK_DRAWABLE_XID (grab_window)));
+ gdk_window_unref (*window);
+ *window = grab_window;
+ gdk_window_ref (*window);
+ return TRUE;
+ }
+ }
+ else
+ {
+ GDK_NOTE (EVENTS, "...undelivered\n");
+ return FALSE;
+ }
+ }
+ else
+ {
+ *window = (*propagate) (*window, xevent);
+ GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
+ GDK_DRAWABLE_XID (*window)));
+ /* The only branch where we actually continue the loop */
+ }
+ }
+ else
+ return TRUE;
+ }
+}
+
+static gboolean
+doesnt_want_key (gint mask,
+ MSG *xevent)
+{
+ return (((xevent->message == WM_KEYUP
+ || xevent->message == WM_SYSKEYUP)
+ && !(mask & GDK_KEY_RELEASE_MASK))
+ ||
+ ((xevent->message == WM_KEYDOWN
+ || xevent->message == WM_SYSKEYDOWN)
+ && !(mask & GDK_KEY_PRESS_MASK)));
+}
+
+static gboolean
+doesnt_want_char (gint mask,
+ MSG *xevent)
+{
+ return !(mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK));
+}
+
+static gboolean
+doesnt_want_button_press (gint mask,
+ MSG *xevent)
+{
+ return !(mask & GDK_BUTTON_PRESS_MASK);
+}
+
+static gboolean
+doesnt_want_button_release (gint mask,
+ MSG *xevent)
+{
+ return !(mask & GDK_BUTTON_RELEASE_MASK);
+}
+
+static gboolean
+doesnt_want_button_motion (gint mask,
+ MSG *xevent)
+{
+ return !((mask & GDK_POINTER_MOTION_MASK)
+ || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
+ && (mask & GDK_BUTTON_MOTION_MASK))
+ || ((xevent->wParam & MK_LBUTTON)
+ && (mask & GDK_BUTTON1_MOTION_MASK))
+ || ((xevent->wParam & MK_MBUTTON)
+ && (mask & GDK_BUTTON2_MOTION_MASK))
+ || ((xevent->wParam & MK_RBUTTON)
+ && (mask & GDK_BUTTON3_MOTION_MASK)));
}
-static gint
+#endif
+
+static gboolean
gdk_event_translate (GdkEvent *event,
MSG *xevent,
gboolean *ret_val_flagp,
gint *ret_valp)
{
- GdkWindow *window;
- GdkWindowPrivate *window_private;
-
+ GdkWindow *window, *orig_window;
GdkColormapPrivate *colormap_private;
HWND owner;
+ DWORD pidActWin;
+ DWORD pidThis;
DWORD dwStyle;
PAINTSTRUCT paintstruct;
HDC hdc;
@@ -1158,7 +3320,6 @@ gdk_event_translate (GdkEvent *event,
RECT rect;
POINT pt;
MINMAXINFO *lpmmi;
- GdkWindowPrivate *curWnd_private;
GdkEventMask mask;
GdkDrawablePrivate *pixmap_private;
HDC bgdc;
@@ -1166,8 +3327,8 @@ gdk_event_translate (GdkEvent *event,
int button;
int i, j;
gchar buf[256];
- gint charcount;
- gint return_val;
+ gchar *msgname;
+ gboolean return_val;
gboolean flag;
return_val = FALSE;
@@ -1175,16 +3336,15 @@ gdk_event_translate (GdkEvent *event,
if (ret_val_flagp)
*ret_val_flagp = FALSE;
+#ifndef USE_DISPATCHMESSAGE
if (xevent->message == gdk_ping_msg)
{
/* Messages we post ourselves just to wakeup WaitMessage. */
+ GDK_NOTE (EVENTS, g_print ("gdk_ping_msg\n"));
+
return FALSE;
}
-
- window = gdk_window_lookup (xevent->hwnd);
- window_private = (GdkWindowPrivate *) window;
-
- if (xevent->message == g_pipe_readable_msg)
+ else if (xevent->message == g_pipe_readable_msg)
{
GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
xevent->wParam, xevent->lParam));
@@ -1192,7 +3352,11 @@ gdk_event_translate (GdkEvent *event,
g_io_channel_win32_pipe_readable (xevent->wParam, xevent->lParam);
return FALSE;
}
+#endif
+ window = gdk_window_lookup (xevent->hwnd);
+ orig_window = window;
+
if (window != NULL)
gdk_window_ref (window);
else
@@ -1218,18 +3382,12 @@ gdk_event_translate (GdkEvent *event,
return FALSE;
}
- event->any.window = window;
-
- if (window_private && GDK_DRAWABLE_DESTROYED (window))
- {
- }
- else
+ if (!GDK_DRAWABLE_DESTROYED (window))
{
/* Check for filters for this window */
GdkFilterReturn result;
result = gdk_event_apply_filters
- (xevent, event,
- window_private ? window_private->filters : gdk_default_filters);
+ (xevent, event, WINDOW_PRIVATE(window)->filters);
if (result != GDK_FILTER_CONTINUE)
{
@@ -1249,7 +3407,7 @@ gdk_event_translate (GdkEvent *event,
event->selection.property = gdk_selection_property;
event->selection.time = xevent->time;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
/* Will pass through switch below without match */
}
@@ -1266,7 +3424,7 @@ gdk_event_translate (GdkEvent *event,
event->selection.requestor = (guint32) xevent->hwnd;
event->selection.time = xevent->time;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
/* Again, will pass through switch below without match */
}
@@ -1280,7 +3438,7 @@ gdk_event_translate (GdkEvent *event,
event->selection.selection = xevent->wParam;
event->selection.time = xevent->time;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = GDK_DRAWABLE_DESTROYED (window);
/* Once again, we will pass through switch below without match */
}
@@ -1325,6 +3483,16 @@ gdk_event_translate (GdkEvent *event,
switch (xevent->message)
{
+ case WM_INPUTLANGCHANGE:
+ GDK_NOTE (EVENTS,
+ g_print ("WM_INPUTLANGCHANGE: %#x charset %d locale %x\n",
+ xevent->hwnd, xevent->wParam, xevent->lParam));
+ WINDOW_PRIVATE(window)->input_locale = (HKL) xevent->lParam;
+ TranslateCharsetInfo ((DWORD FAR *) xevent->wParam,
+ &WINDOW_PRIVATE(window)->charset_info,
+ TCI_SRCCHARSET);
+ break;
+
case WM_SYSKEYUP:
case WM_SYSKEYDOWN:
GDK_NOTE (EVENTS,
@@ -1367,50 +3535,57 @@ gdk_event_translate (GdkEvent *event,
ignore_WM_CHAR = TRUE;
keyup_or_down:
+
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
+ doesnt_want_key,
+ key_propagate))
+ break;
+ event->key.window = window;
+#else
if (k_grab_window != NULL && !k_grab_owner_events)
{
/* Keyboard is grabbed with owner_events FALSE */
- GDK_NOTE (EVENTS,
- g_print ("...grabbed, owner_events FALSE, "
- "sending to %#x\n",
- GDK_DRAWABLE_XID (k_grab_window)));
+ GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE, "
+ "sending to %#x\n",
+ GDK_DRAWABLE_XID (k_grab_window)));
event->key.window = k_grab_window;
+ /* Continue with switch statement below */
}
- else if (window_private
- && (((xevent->message == WM_KEYUP
+ else if (((xevent->message == WM_KEYUP
|| xevent->message == WM_SYSKEYUP)
- && !(window_private->event_mask & GDK_KEY_RELEASE_MASK))
+ && !(WINDOW_PRIVATE(window)->event_mask & GDK_KEY_RELEASE_MASK))
|| ((xevent->message == WM_KEYDOWN
|| xevent->message == WM_SYSKEYDOWN)
- && !(window_private->event_mask & GDK_KEY_PRESS_MASK))))
+ && !(WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK)))
{
- /* Owner window doesn't want it */
- if (k_grab_window != NULL && k_grab_owner_events)
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Keyboard is grabbed with owner_events TRUE */
- GDK_NOTE (EVENTS,
- g_print ("...grabbed, owner_events TRUE, doesn't want it, "
- "sending to %#x\n",
- GDK_DRAWABLE_XID (k_grab_window)));
- event->key.window = k_grab_window;
+ /* No parent; check if grabbed */
+ if (k_grab_window != NULL)
+ {
+ /* Keyboard is grabbed with owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ event->key.window = k_grab_window;
+ /* Continue with switch statement below */
+ }
+ else
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- break;
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = key_propagate (window, xevent);
+ /* Jump back up */
goto keyup_or_down;
}
}
-
+ else
+ event->key.window = window;
+
+ g_assert (event->key.window == window);
+#endif
switch (xevent->wParam)
{
case VK_LBUTTON:
@@ -1505,34 +3680,22 @@ gdk_event_translate (GdkEvent *event,
case VK_MULTIPLY:
event->key.keyval = GDK_KP_Multiply; break;
case VK_ADD:
-#if 0
- event->key.keyval = GDK_KP_Add; break;
-#else
/* Pass it on as an ASCII plus in WM_CHAR. */
ignore_WM_CHAR = FALSE;
break;
-#endif
case VK_SEPARATOR:
event->key.keyval = GDK_KP_Separator; break;
case VK_SUBTRACT:
-#if 0
- event->key.keyval = GDK_KP_Subtract; break;
-#else
/* Pass it on as an ASCII minus in WM_CHAR. */
ignore_WM_CHAR = FALSE;
break;
-#endif
case VK_DECIMAL:
-#if 0
- event->key.keyval = GDK_KP_Decimal; break;
-#else
/* The keypad decimal key should also be passed on as the decimal
* sign ('.' or ',' depending on the Windows locale settings,
* apparently). So wait for the WM_CHAR here, also.
*/
ignore_WM_CHAR = FALSE;
break;
-#endif
case VK_DIVIDE:
event->key.keyval = GDK_KP_Divide; break;
case VK_F1:
@@ -1579,24 +3742,32 @@ gdk_event_translate (GdkEvent *event,
case '9':
if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0
|| GetKeyState (VK_MENU) < 0))
- /* Control- or Alt-digits won't come in as a WM_CHAR */
+ /* Control- or Alt-digits won't come in as a WM_CHAR,
+ * but beware of AltGr-digits, which are used for instance
+ * on Finnish keyboards.
+ */
event->key.keyval = GDK_0 + (xevent->wParam - '0');
else
- {
- ignore_WM_CHAR = FALSE;
- event->key.keyval = GDK_VoidSymbol;
- }
+ ignore_WM_CHAR = FALSE;
+ break;
+ case VK_OEM_PLUS: /* On my Win98, the '+' key comes in
+ * as VK_OEM_PLUS
+ */
+ if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0
+ || GetKeyState (VK_MENU) < 0))
+ /* Control- or Alt-plus won't come in as WM_CHAR,
+ * but beware of AltGr-plus which is backslash on
+ * Finnish keyboards
+ */
+ event->key.keyval = '+';
+ else
+ ignore_WM_CHAR = FALSE;
break;
default:
if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP)
- {
- event->key.keyval = xevent->wParam;
- }
+ event->key.keyval = xevent->wParam;
else
- {
- ignore_WM_CHAR = FALSE;
- event->key.keyval = GDK_VoidSymbol;
- }
+ ignore_WM_CHAR = FALSE;
break;
}
@@ -1607,7 +3778,6 @@ gdk_event_translate (GdkEvent *event,
event->key.type = ((xevent->message == WM_KEYDOWN
|| xevent->message == WM_SYSKEYDOWN) ?
GDK_KEY_PRESS : GDK_KEY_RELEASE);
- event->key.window = window;
event->key.time = xevent->time;
event->key.state = 0;
if (GetKeyState (VK_SHIFT) < 0)
@@ -1618,17 +3788,21 @@ gdk_event_translate (GdkEvent *event,
event->key.state |= GDK_CONTROL_MASK;
if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0)
event->key.state |= GDK_MOD1_MASK;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
event->key.string = NULL;
event->key.length = 0;
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
+ case WM_IME_CHAR:
+ GDK_NOTE (EVENTS,
+ g_print ("WM_IME_CHAR: %#x bytes: %#.04x\n",
+ xevent->hwnd, xevent->wParam));
+ goto wm_char;
+
case WM_CHAR:
GDK_NOTE (EVENTS,
g_print ("WM_CHAR: %#x char: %#x %#.08x %s\n",
- xevent->hwnd,
- xevent->wParam,
- xevent->lParam,
+ xevent->hwnd, xevent->wParam, xevent->lParam,
(ignore_WM_CHAR ? "ignored" : "")));
if (ignore_WM_CHAR)
@@ -1638,9 +3812,17 @@ gdk_event_translate (GdkEvent *event,
}
wm_char:
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK,
+ doesnt_want_char,
+ key_propagate))
+ break;
+ event->key.window = window;
+#else
/* This doesn't handle the rather theorethical case that a window
* wants key presses but still wants releases to be propagated,
- * for instance.
+ * for instance. Or is that so theorethical?
*/
if (k_grab_window != NULL && !k_grab_owner_events)
{
@@ -1651,126 +3833,63 @@ gdk_event_translate (GdkEvent *event,
GDK_DRAWABLE_XID (k_grab_window)));
event->key.window = k_grab_window;
}
- else if (window_private
- && !(window_private->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
+ else if (!(WINDOW_PRIVATE(window)->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)))
{
- /* Owner window doesn't want it */
- if (k_grab_window != NULL && k_grab_owner_events)
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Keyboard is grabbed with owner_events TRUE */
- GDK_NOTE (EVENTS,
- g_print ("...grabbed, owner_events TRUE, doesn't want it, "
- "sending to %#x\n",
- GDK_DRAWABLE_XID (k_grab_window)));
- event->key.window = k_grab_window;
+ /* No parent; check if grabbed */
+ if (k_grab_window != NULL)
+ {
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ event->key.window = k_grab_window;
+ }
+ else
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- g_assert_not_reached (); /* Should've been handled above */
-
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = key_propagate (window, xevent);
+ /* Jump back up */
goto wm_char;
}
}
-
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
- if (return_val && (window_private->event_mask & GDK_KEY_RELEASE_MASK))
+ else
+ event->key.window = window;
+
+ g_assert (event->key.window == window);
+#endif
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
+ if (return_val && (event->key.window == k_grab_window
+ || (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_RELEASE_MASK)))
{
- /* Return the release event, and maybe append the press
- * event to the queued_events list (from which it will vbe
- * fetched before the release event).
- */
- event->key.type = GDK_KEY_RELEASE;
- event->key.keyval = xevent->wParam;
- event->key.window = window;
- event->key.time = xevent->time;
- event->key.state = 0;
- if (GetKeyState (VK_SHIFT) < 0)
- event->key.state |= GDK_SHIFT_MASK;
- if (GetKeyState (VK_CAPITAL) & 0x1)
- event->key.state |= GDK_LOCK_MASK;
- if (is_AltGr_key)
- ;
- else if (GetKeyState (VK_CONTROL) < 0)
- {
- event->key.state |= GDK_CONTROL_MASK;
- if (event->key.keyval < ' ')
- event->key.keyval += '@';
- }
- else if (event->key.keyval < ' ')
- {
- event->key.state |= GDK_CONTROL_MASK;
- event->key.keyval += '@';
- }
- if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
- event->key.state |= GDK_MOD1_MASK;
- event->key.string = g_malloc (2);
- event->key.length = 1;
- event->key.string[0] = xevent->wParam; /* ??? */
- event->key.string[1] = 0;
-
- if (window_private->event_mask & GDK_KEY_PRESS_MASK)
+ if (window == k_grab_window
+ || (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK))
{
- /* Append also a GDK_KEY_PRESS event to the pushback list. */
- GdkEvent *event2 = gdk_event_copy (event);
- event2->key.type = GDK_KEY_PRESS;
- charcount = xevent->lParam & 0xFFFF;
- if (charcount > sizeof (buf)- 1)
- charcount = sizeof (buf) - 1;
- g_free (event2->key.string);
- event2->key.string = g_malloc (charcount + 1);
- for (i = 0; i < charcount; i++)
- event2->key.string[i] = event->key.keyval;
- event2->key.string[charcount] = 0;
- event2->key.length = charcount;
-
+ /* Append a GDK_KEY_PRESS event to the pushback list
+ * (from which it will be fetched before the release
+ * event).
+ */
+ GdkEvent *event2 = gdk_event_new ();
+ build_keypress_event (WINDOW_PRIVATE(window), event2, xevent);
+ event2->key.window = window;
+ gdk_window_ref (window);
gdk_event_queue_append (event2);
+ GDK_NOTE (EVENTS, print_event (event2));
}
+ /* Return the release event. */
+ event->key.type = GDK_KEY_RELEASE;
+ event->key.keyval = xevent->wParam;
+ event->key.time = xevent->time;
+ build_key_event_state (event);
+ event->key.string = NULL;
+ event->key.length = 0;
}
- else if (return_val && (window_private->event_mask & GDK_KEY_PRESS_MASK))
+ else if (return_val
+ && (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK))
{
/* Return just the GDK_KEY_PRESS event. */
- event->key.type = GDK_KEY_PRESS;
- charcount = xevent->lParam & 0xFFFF;
- if (charcount > sizeof (buf)- 1)
- charcount = sizeof (buf) - 1;
- event->key.keyval = xevent->wParam;
- event->key.window = window;
- event->key.time = xevent->time;
- event->key.state = 0;
- if (GetKeyState (VK_SHIFT) < 0)
- event->key.state |= GDK_SHIFT_MASK;
- if (GetKeyState (VK_CAPITAL) & 0x1)
- event->key.state |= GDK_LOCK_MASK;
- if (is_AltGr_key)
- ;
- else if (GetKeyState (VK_CONTROL) < 0)
- {
- event->key.state |= GDK_CONTROL_MASK;
- if (event->key.keyval < ' ')
- event->key.keyval += '@';
- }
- else if (event->key.keyval < ' ')
- {
- event->key.state |= GDK_CONTROL_MASK;
- event->key.keyval += '@';
- }
- if (!is_AltGr_key && GetKeyState (VK_MENU) < 0)
- event->key.state |= GDK_MOD1_MASK;
- event->key.string = g_malloc (charcount + 1);
- for (i = 0; i < charcount; i++)
- event->key.string[i] = event->key.keyval;
- event->key.string[charcount] = 0;
- event->key.length = charcount;
+ build_keypress_event (WINDOW_PRIVATE(window), event, xevent);
}
else
return_val = FALSE;
@@ -1799,8 +3918,7 @@ gdk_event_translate (GdkEvent *event,
LOWORD (xevent->lParam), HIWORD (xevent->lParam),
button));
- if (window_private
- && (window_private->extension_events != 0)
+ if (WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_ignore_core)
{
GDK_NOTE (EVENTS, g_print ("...ignored\n"));
@@ -1811,18 +3929,23 @@ gdk_event_translate (GdkEvent *event,
synthesize_crossing_events (window, xevent);
event->button.type = GDK_BUTTON_PRESS;
- buttondown:
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ p_grab_window, p_grab_owner_events, p_grab_mask,
+ doesnt_want_button_press,
+ mouse_propagate))
+ break;
event->button.window = window;
- if (window_private)
- mask = window_private->event_mask;
- else
- mask = 0; /* ??? */
+#else
+ buttondown:
+ mask = WINDOW_PRIVATE(window)->event_mask;
if (p_grab_window != NULL && !p_grab_owner_events)
{
/* Pointer is grabbed with owner_events FALSE */
GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
- mask = p_grab_event_mask;
+
+ mask = p_grab_mask;
if (!(mask & GDK_BUTTON_PRESS_MASK))
/* Grabber doesn't want it */
break;
@@ -1831,61 +3954,79 @@ gdk_event_translate (GdkEvent *event,
GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
GDK_DRAWABLE_XID (p_grab_window)));
}
- else if (window_private
- && !(mask & GDK_BUTTON_PRESS_MASK))
+ else if (!(mask & GDK_BUTTON_PRESS_MASK))
{
- /* Owner window doesn't want it */
- if (p_grab_window != NULL && p_grab_owner_events)
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Pointer is grabbed wíth owner_events TRUE */
- GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
- mask = p_grab_event_mask;
- if (!(mask & GDK_BUTTON_PRESS_MASK))
- /* Grabber doesn't want it either */
- break;
+ /* No parent; check if grabbed */
+ if (p_grab_window != NULL)
+ {
+ /* Pointer is grabbed wíth owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ mask = p_grab_mask;
+ if (!(mask & GDK_BUTTON_PRESS_MASK))
+ {
+ /* Grabber doesn't want it either */
+ GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n"));
+ break;
+ }
+ else
+ event->button.window = p_grab_window;
+ GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
+ GDK_DRAWABLE_XID (p_grab_window)));
+ }
else
- event->button.window = p_grab_window;
- GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
- GDK_DRAWABLE_XID (p_grab_window)));
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- /* Yes, this code is duplicated twice below. So shoot me. */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- break;
- pt.x = LOWORD (xevent->lParam);
- pt.y = HIWORD (xevent->lParam);
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
- xevent->lParam = MAKELPARAM (pt.x, pt.y);
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = mouse_propagate (window, xevent);
+ /* Jump back up */
goto buttondown; /* What did Dijkstra say? */
}
}
+ else
+ event->button.window = window;
+ g_assert (event->button.window == window);
+#endif
/* Emulate X11's automatic active grab */
if (!p_grab_window)
{
/* No explicit active grab, let's start one automatically */
+ gint owner_events =
+ WINDOW_PRIVATE(window)->event_mask
+ & (GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK);
+
GDK_NOTE (EVENTS, g_print ("...automatic grab started\n"));
- gdk_pointer_grab (window, TRUE, window_private->event_mask,
+ gdk_pointer_grab (window,
+ owner_events,
+ WINDOW_PRIVATE(window)->event_mask,
NULL, NULL, 0);
p_grab_automatic = TRUE;
}
event->button.time = xevent->time;
- event->button.x = LOWORD (xevent->lParam);
- event->button.y = HIWORD (xevent->lParam);
- event->button.x_root = (gfloat)xevent->pt.x;
- event->button.y_root = (gfloat)xevent->pt.y;
+ if (window == p_grab_window
+ && p_grab_window != orig_window)
+ {
+ /* Translate coordinates to grabber */
+ pt.x = LOWORD (xevent->lParam);
+ pt.y = HIWORD (xevent->lParam);
+ ClientToScreen (xevent->hwnd, &pt);
+ ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
+ event->button.x = pt.x;
+ event->button.y = pt.y;
+ GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
+ }
+ else
+ {
+ event->button.x = LOWORD (xevent->lParam);
+ event->button.y = HIWORD (xevent->lParam);
+ }
+ event->button.x_root = xevent->pt.x;
+ event->button.y_root = xevent->pt.y;
event->button.pressure = 0.5;
event->button.xtilt = 0;
event->button.ytilt = 0;
@@ -1943,21 +4084,7 @@ gdk_event_translate (GdkEvent *event,
button_number[1] = -1;
button_number[0] = event->button.button;
}
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
- if (return_val
- && p_grab_window != NULL
- && event->any.window == p_grab_window
- && p_grab_window != window)
- {
- /* Translate coordinates to grabber */
- pt.x = event->button.x;
- pt.y = event->button.y;
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
- event->button.x = pt.x;
- event->button.y = pt.y;
- GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
- }
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
case WM_LBUTTONUP:
@@ -1977,8 +4104,7 @@ gdk_event_translate (GdkEvent *event,
LOWORD (xevent->lParam), HIWORD (xevent->lParam),
button));
- if (window_private
- && (window_private->extension_events != 0)
+ if (WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_ignore_core)
{
GDK_NOTE (EVENTS, g_print ("...ignored\n"));
@@ -1989,70 +4115,89 @@ gdk_event_translate (GdkEvent *event,
synthesize_crossing_events (window, xevent);
event->button.type = GDK_BUTTON_RELEASE;
- buttonup:
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ p_grab_window, p_grab_owner_events, p_grab_mask,
+ doesnt_want_button_release,
+ mouse_propagate))
+ break;
event->button.window = window;
- if (window_private)
- mask = window_private->event_mask;
- else
- mask = 0;
+#else
+ buttonup:
+ mask = WINDOW_PRIVATE(window)->event_mask;
if (p_grab_window != NULL && !p_grab_owner_events)
{
/* Pointer is grabbed with owner_events FALSE */
GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
- mask = p_grab_event_mask;
+
+ mask = p_grab_mask;
if (!(mask & GDK_BUTTON_RELEASE_MASK))
/* Grabber doesn't want it */
- break;
+ goto maybe_ungrab;
else
event->button.window = p_grab_window;
GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
GDK_DRAWABLE_XID (p_grab_window)));
}
- else if (window_private
- && !(mask & GDK_BUTTON_RELEASE_MASK))
+ else if (!(mask & GDK_BUTTON_RELEASE_MASK))
{
- /* Owner window doesn't want it */
- if (p_grab_window != NULL && p_grab_owner_events)
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Pointer is grabbed wíth owner_events TRUE */
- GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
- mask = p_grab_event_mask;
- if (!(mask & GDK_BUTTON_RELEASE_MASK))
- /* Grabber doesn't want it */
- break;
+ /* No parent; check if grabbed */
+ if (p_grab_window != NULL)
+ {
+ /* Pointer is grabbed wíth owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ mask = p_grab_mask;
+ if (!(mask & GDK_BUTTON_RELEASE_MASK))
+ {
+ /* Grabber doesn't want it either */
+ GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n"));
+ goto maybe_ungrab;
+ }
+ else
+ event->button.window = p_grab_window;
+ GDK_NOTE (EVENTS,
+ g_print ("...sending to %#x\n",
+ GDK_DRAWABLE_XID (p_grab_window)));
+ }
else
- event->button.window = p_grab_window;
- GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
- GDK_DRAWABLE_XID (p_grab_window)));
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- break;
- pt.x = LOWORD (xevent->lParam);
- pt.y = HIWORD (xevent->lParam);
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
- xevent->lParam = MAKELPARAM (pt.x, pt.y);
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = mouse_propagate (window, xevent);
+ /* Jump back up */
goto buttonup;
}
}
+ else
+ event->button.window = window;
+ g_assert (event->button.window == window);
+#endif
event->button.time = xevent->time;
- event->button.x = LOWORD (xevent->lParam);
- event->button.y = HIWORD (xevent->lParam);
- event->button.x_root = (gfloat)xevent->pt.x;
- event->button.y_root = (gfloat)xevent->pt.y;
+ if (window == p_grab_window
+ && p_grab_window != orig_window)
+ {
+ /* Translate coordinates to grabber */
+ pt.x = LOWORD (xevent->lParam);
+ pt.y = HIWORD (xevent->lParam);
+ ClientToScreen (xevent->hwnd, &pt);
+ ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
+ event->button.x = pt.x;
+ event->button.y = pt.y;
+ GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
+ }
+ else
+ {
+ event->button.x = LOWORD (xevent->lParam);
+ event->button.y = HIWORD (xevent->lParam);
+ }
+ event->button.x_root = xevent->pt.x;
+ event->button.y_root = xevent->pt.y;
event->button.pressure = 0.5;
event->button.xtilt = 0;
event->button.ytilt = 0;
@@ -2067,24 +4212,17 @@ gdk_event_translate (GdkEvent *event,
event->button.state |= GDK_BUTTON3_MASK;
if (xevent->wParam & MK_SHIFT)
event->button.state |= GDK_SHIFT_MASK;
+ if (GetKeyState (VK_MENU) < 0)
+ event->button.state |= GDK_MOD1_MASK;
+ if (GetKeyState (VK_CAPITAL) & 0x1)
+ event->button.state |= GDK_LOCK_MASK;
event->button.button = button;
event->button.source = GDK_SOURCE_MOUSE;
event->button.deviceid = GDK_CORE_POINTER;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
- if (return_val
- && p_grab_window != NULL
- && event->any.window == p_grab_window
- && p_grab_window != window)
- {
- /* Translate coordinates to grabber */
- pt.x = event->button.x;
- pt.y = event->button.y;
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
- event->button.x = pt.x;
- event->button.y = pt.y;
- GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
- }
+
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
+
+ maybe_ungrab:
if (p_grab_window != NULL
&& p_grab_automatic
&& (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0)
@@ -2097,58 +4235,41 @@ gdk_event_translate (GdkEvent *event,
xevent->hwnd, xevent->wParam,
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
-#if 0
- /* Try hard not to generate events for windows that shouldn't
- get any. This is hard because we don't want pushbuttons to
- highlight when the cursor moves over them if the window is
- inactive. We dont want tooltips windows to be active. OTOH,
- also menus are popup windows, but they definitely should
- get events. Aw shit. Skip this.
- */
- dwStyle = GetWindowLong (xevent->hwnd, GWL_STYLE);
- if (active == NULL ||
- !(active == xevent->hwnd
- || (dwStyle & WS_POPUP)
- || IsChild (active, xevent->hwnd)))
+ /* HB: only process mouse move messages if we own the active window. */
+
+ GetWindowThreadProcessId(GetActiveWindow(), &pidActWin);
+ GetWindowThreadProcessId(xevent->hwnd, &pidThis);
+ if (pidActWin != pidThis)
break;
-#else
- { /* HB: only process mouse move messages
- * if we own the active window.
- */
- DWORD ProcessID_ActWin;
- DWORD ProcessID_this;
-
- GetWindowThreadProcessId(GetActiveWindow(), &ProcessID_ActWin);
- GetWindowThreadProcessId(xevent->hwnd, &ProcessID_this);
- if (ProcessID_ActWin != ProcessID_this)
- break;
- }
-#endif
+
if (window != curWnd)
synthesize_crossing_events (window, xevent);
- if (window_private
- && (window_private->extension_events != 0)
+ if (WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_ignore_core)
{
GDK_NOTE (EVENTS, g_print ("...ignored\n"));
break;
}
- mousemotion:
event->motion.type = GDK_MOTION_NOTIFY;
+#ifdef NEW_PROPAGATION_CODE
+ if (!propagate (&window, xevent,
+ p_grab_window, p_grab_owner_events, p_grab_mask,
+ doesnt_want_button_motion,
+ mouse_propagate))
+ break;
event->motion.window = window;
- if (window_private)
- mask = window_private->event_mask;
- else
- mask = 0;
+#else
+ mousemotion:
+ mask = WINDOW_PRIVATE(window)->event_mask;
- if (p_grab_window && !p_grab_owner_events)
+ if (p_grab_window != NULL && !p_grab_owner_events)
{
/* Pointer is grabbed with owner_events FALSE */
- GDK_NOTE (EVENTS,
- g_print ("...grabbed, owner_events FALSE\n"));
- mask = p_grab_event_mask;
+ GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n"));
+
+ mask = p_grab_mask;
if (!((mask & GDK_POINTER_MOTION_MASK)
|| ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
&& (mask & GDK_BUTTON_MOTION_MASK))
@@ -2158,70 +4279,83 @@ gdk_event_translate (GdkEvent *event,
&& (mask & GDK_BUTTON2_MOTION_MASK))
|| ((xevent->wParam & MK_RBUTTON)
&& (mask & GDK_BUTTON3_MOTION_MASK))))
+ /* Grabber doesn't want it */
break;
else
event->motion.window = p_grab_window;
GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
GDK_DRAWABLE_XID (p_grab_window)));
}
- else if (window_private
- && !((mask & GDK_POINTER_MOTION_MASK)
- || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
- && (mask & GDK_BUTTON_MOTION_MASK))
- || ((xevent->wParam & MK_LBUTTON)
- && (mask & GDK_BUTTON1_MOTION_MASK))
- || ((xevent->wParam & MK_MBUTTON)
- && (mask & GDK_BUTTON2_MOTION_MASK))
- || ((xevent->wParam & MK_RBUTTON)
- && (mask & GDK_BUTTON3_MOTION_MASK))))
- {
- /* Owner window doesn't want it */
- if (p_grab_window != NULL && p_grab_owner_events)
+ else if (!((mask & GDK_POINTER_MOTION_MASK)
+ || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
+ && (mask & GDK_BUTTON_MOTION_MASK))
+ || ((xevent->wParam & MK_LBUTTON)
+ && (mask & GDK_BUTTON1_MOTION_MASK))
+ || ((xevent->wParam & MK_MBUTTON)
+ && (mask & GDK_BUTTON2_MOTION_MASK))
+ || ((xevent->wParam & MK_RBUTTON)
+ && (mask & GDK_BUTTON3_MOTION_MASK))))
+ {
+ /* Owner doesn't want it, propagate to parent. */
+ if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent)
{
- /* Pointer is grabbed wíth owner_events TRUE */
- GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n"));
- mask = p_grab_event_mask;
- if (!((p_grab_event_mask & GDK_POINTER_MOTION_MASK)
- || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
- && (mask & GDK_BUTTON_MOTION_MASK))
- || ((xevent->wParam & MK_LBUTTON)
- && (mask & GDK_BUTTON1_MOTION_MASK))
- || ((xevent->wParam & MK_MBUTTON)
- && (mask & GDK_BUTTON2_MOTION_MASK))
- || ((xevent->wParam & MK_RBUTTON)
- && (mask & GDK_BUTTON3_MOTION_MASK))))
- /* Grabber doesn't want it either */
- break;
+ /* No parent; check if grabbed */
+ if (p_grab_window != NULL)
+ {
+ /* Pointer is grabbed wíth owner_events TRUE */
+ GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n"));
+ mask = p_grab_mask;
+ if (!((p_grab_mask & GDK_POINTER_MOTION_MASK)
+ || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON))
+ && (mask & GDK_BUTTON_MOTION_MASK))
+ || ((xevent->wParam & MK_LBUTTON)
+ && (mask & GDK_BUTTON1_MOTION_MASK))
+ || ((xevent->wParam & MK_MBUTTON)
+ && (mask & GDK_BUTTON2_MOTION_MASK))
+ || ((xevent->wParam & MK_RBUTTON)
+ && (mask & GDK_BUTTON3_MOTION_MASK))))
+ {
+ /* Grabber doesn't want it either */
+ GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n"));
+ break;
+ }
+ else
+ event->motion.window = p_grab_window;
+ GDK_NOTE (EVENTS,
+ g_print ("...sending to %#x\n",
+ GDK_DRAWABLE_XID (p_grab_window)));
+ }
else
- event->motion.window = p_grab_window;
- GDK_NOTE (EVENTS, g_print ("...sending to %#x\n",
- GDK_DRAWABLE_XID (p_grab_window)));
+ break;
}
else
{
- /* Owner doesn't want it, neither is it grabbed, so
- * propagate to parent.
- */
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
- break;
- pt.x = LOWORD (xevent->lParam);
- pt.y = HIWORD (xevent->lParam);
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- gdk_window_unref (window);
- window = window_private->parent;
- gdk_window_ref (window);
- window_private = (GdkWindowPrivate *) window;
- ScreenToClient (GDK_DRAWABLE_XID (window), &pt);
- xevent->lParam = MAKELPARAM (pt.x, pt.y);
- GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n",
- GDK_DRAWABLE_XID (window)));
+ window = mouse_propagate (window, xevent);
+ /* Jump back up */
goto mousemotion;
}
}
-
+ else
+ event->motion.window = window;
+#endif
event->motion.time = xevent->time;
- event->motion.x = curX = LOWORD (xevent->lParam);
- event->motion.y = curY = HIWORD (xevent->lParam);
+ if (window == p_grab_window
+ && p_grab_window != orig_window)
+ {
+ /* Translate coordinates to grabber */
+ pt.x = curX = LOWORD (xevent->lParam);
+ pt.y = curY = HIWORD (xevent->lParam);
+ ClientToScreen (xevent->hwnd, &pt);
+ ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
+ event->motion.x = pt.x;
+ event->motion.y = pt.y;
+ GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
+ }
+ else
+ {
+ event->motion.x = curX = LOWORD (xevent->lParam);
+ event->motion.y = curY = HIWORD (xevent->lParam);
+ }
event->motion.x_root = xevent->pt.x;
event->motion.y_root = xevent->pt.y;
curXroot = event->motion.x_root;
@@ -2240,6 +4374,10 @@ gdk_event_translate (GdkEvent *event,
event->button.state |= GDK_BUTTON3_MASK;
if (xevent->wParam & MK_SHIFT)
event->button.state |= GDK_SHIFT_MASK;
+ if (GetKeyState (VK_MENU) < 0)
+ event->button.state |= GDK_MOD1_MASK;
+ if (GetKeyState (VK_CAPITAL) & 0x1)
+ event->button.state |= GDK_LOCK_MASK;
if (mask & GDK_POINTER_MOTION_HINT_MASK)
event->motion.is_hint = NotifyHint;
else
@@ -2247,21 +4385,7 @@ gdk_event_translate (GdkEvent *event,
event->motion.source = GDK_SOURCE_MOUSE;
event->motion.deviceid = GDK_CORE_POINTER;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
- if (return_val
- && p_grab_window != NULL
- && event->any.window == p_grab_window
- && p_grab_window != window)
- {
- /* Translate coordinates to grabber */
- pt.x = event->motion.x;
- pt.y = event->motion.y;
- ClientToScreen (GDK_DRAWABLE_XID (window), &pt);
- ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt);
- event->motion.x = pt.x;
- event->motion.y = pt.y;
- GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y));
- }
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
case WM_NCMOUSEMOVE:
@@ -2269,13 +4393,9 @@ gdk_event_translate (GdkEvent *event,
g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n",
xevent->hwnd,
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
-#if 0
- if (active == NULL || active != xevent->hwnd)
- break;
-#endif
- curWnd_private = (GdkWindowPrivate *) curWnd;
- if (curWnd != NULL
- && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK))
+ if (p_TrackMouseEvent == NULL
+ && curWnd != NULL
+ && (WINDOW_PRIVATE(curWnd)->event_mask & GDK_LEAVE_NOTIFY_MASK))
{
GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n"));
@@ -2288,49 +4408,83 @@ gdk_event_translate (GdkEvent *event,
event->crossing.x_root = curXroot;
event->crossing.y_root = curYroot;
event->crossing.mode = GDK_CROSSING_NORMAL;
- event->crossing.detail = GDK_NOTIFY_UNKNOWN;
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
event->crossing.focus = TRUE; /* ??? */
event->crossing.state = 0; /* ??? */
+ return_val = TRUE;
+ }
+
+ if (curWnd)
+ {
gdk_window_unref (curWnd);
curWnd = NULL;
-
- return_val = TRUE;
}
+
break;
- case WM_SETFOCUS:
- case WM_KILLFOCUS:
- if (window_private
- && !(window_private->event_mask & GDK_FOCUS_CHANGE_MASK))
+#ifdef USE_TRACKMOUSEEVENT
+ case WM_MOUSELEAVE:
+ GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %#x\n", xevent->hwnd));
+
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_LEAVE_NOTIFY_MASK))
break;
+ event->crossing.type = GDK_LEAVE_NOTIFY;
+ event->crossing.window = window;
+ event->crossing.subwindow = NULL;
+ event->crossing.time = xevent->time;
+ event->crossing.x = curX;
+ event->crossing.y = curY;
+ event->crossing.x_root = curXroot;
+ event->crossing.y_root = curYroot;
+ event->crossing.mode = GDK_CROSSING_NORMAL;
+ if (curWnd
+ && IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window)))
+ event->crossing.detail = GDK_NOTIFY_INFERIOR;
+ else if (curWnd
+ && IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd)))
+ event->crossing.detail = GDK_NOTIFY_ANCESTOR;
+ else
+ event->crossing.detail = GDK_NOTIFY_NONLINEAR;
+
+ event->crossing.focus = TRUE; /* ??? */
+ event->crossing.state = 0; /* ??? */
+
+ if (curWnd)
+ {
+ gdk_window_unref (curWnd);
+ curWnd = NULL;
+ }
+
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
+ break;
+#endif
+
+ case WM_SETFOCUS:
+ case WM_KILLFOCUS:
GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n",
- (xevent->message == WM_SETFOCUS ? "SET" : "KILL"),
+ (xevent->message == WM_SETFOCUS ?
+ "SET" : "KILL"),
xevent->hwnd));
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_FOCUS_CHANGE_MASK))
+ break;
+
event->focus_change.type = GDK_FOCUS_CHANGE;
event->focus_change.window = window;
event->focus_change.in = (xevent->message == WM_SETFOCUS);
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
-#if 0
- case WM_ACTIVATE:
- GDK_NOTE (EVENTS, g_print ("WM_ACTIVATE: %#x %d\n",
- xevent->hwnd, LOWORD (xevent->wParam)));
- if (LOWORD (xevent->wParam) == WA_INACTIVE)
- active = (HWND) xevent->lParam;
- else
- active = xevent->hwnd;
- break;
-#endif
+
case WM_ERASEBKGND:
GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n",
xevent->hwnd, xevent->wParam));
- if (!window_private || GDK_DRAWABLE_DESTROYED (window))
+ if (GDK_DRAWABLE_DESTROYED (window))
break;
- colormap_private = (GdkColormapPrivate *) window_private->drawable.colormap;
+
+ colormap_private = (GdkColormapPrivate *) WINDOW_PRIVATE(window)->drawable.colormap;
hdc = (HDC) xevent->wParam;
if (colormap_private
&& colormap_private->xcolormap->rc_palette)
@@ -2350,32 +4504,38 @@ gdk_event_translate (GdkEvent *event,
*ret_val_flagp = TRUE;
*ret_valp = 1;
- if (window_private->bg_type == GDK_WIN32_BG_TRANSPARENT)
+ if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_TRANSPARENT)
break;
- if (window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
+ if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
{
/* If this window should have the same background as the
* parent, fetch the parent. (And if the same goes for
* the parent, fetch the grandparent, etc.)
*/
- while (window_private
- && window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
- window_private = (GdkWindowPrivate *) window_private->parent;
+ while (window
+ && WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PARENT_RELATIVE)
+ {
+ gdk_window_unref (window);
+ window = WINDOW_PRIVATE(window)->parent;
+ gdk_window_ref (window);
+ }
}
- if (window_private->bg_type == GDK_WIN32_BG_PIXEL)
+ if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PIXEL)
{
COLORREF bg;
GetClipBox (hdc, &rect);
- GDK_NOTE (EVENTS, g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
- rect.right - rect.left,
- rect.bottom - rect.top,
- rect.left, rect.top,
- gdk_color_to_string (&window_private->bg_pixel)));
- bg = GetNearestColor (hdc, RGB (window_private->bg_pixel.red >> 8,
- window_private->bg_pixel.green >> 8,
- window_private->bg_pixel.blue >> 8));
+ GDK_NOTE (EVENTS,
+ g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n",
+ rect.right - rect.left,
+ rect.bottom - rect.top,
+ rect.left, rect.top,
+ gdk_color_to_string (&WINDOW_PRIVATE(window)->bg_pixel)));
+ bg = GetNearestColor
+ (hdc, RGB (WINDOW_PRIVATE(window)->bg_pixel.red >> 8,
+ WINDOW_PRIVATE(window)->bg_pixel.green >> 8,
+ WINDOW_PRIVATE(window)->bg_pixel.blue >> 8));
hbr = CreateSolidBrush (bg);
#if 0
g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr);
@@ -2384,9 +4544,10 @@ gdk_event_translate (GdkEvent *event,
g_warning ("WM_ERASEBKGND: FillRect failed");
DeleteObject (hbr);
}
- else if (window_private->bg_type == GDK_WIN32_BG_PIXMAP)
+ else if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PIXMAP)
{
- pixmap_private = (GdkDrawablePrivate*) window_private->bg_pixmap;
+ pixmap_private =
+ (GdkDrawablePrivate*) WINDOW_PRIVATE(window)->bg_pixmap;
GetClipBox (hdc, &rect);
if (pixmap_private->width <= 8
@@ -2470,8 +4631,7 @@ gdk_event_translate (GdkEvent *event,
EndPaint (xevent->hwnd, &paintstruct);
- if (window_private
- && !(window_private->event_mask & GDK_EXPOSURE_MASK))
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_EXPOSURE_MASK))
break;
event->expose.type = GDK_EXPOSE;
@@ -2482,7 +4642,7 @@ gdk_event_translate (GdkEvent *event,
event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top;
event->expose.count = 0;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
if (return_val)
{
GList *list = queued_events;
@@ -2503,7 +4663,6 @@ gdk_event_translate (GdkEvent *event,
xevent->hwnd,
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
- return_val = FALSE;
if (LOWORD (xevent->lParam) != HTCLIENT)
break;
if (p_grab_window != NULL && p_grab_cursor != NULL)
@@ -2511,44 +4670,27 @@ gdk_event_translate (GdkEvent *event,
GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", p_grab_cursor));
SetCursor (p_grab_cursor);
}
- else if (window_private
- && !GDK_DRAWABLE_DESTROYED (window)
- && window_private->xcursor)
+ else if (!GDK_DRAWABLE_DESTROYED (window)
+ && WINDOW_PRIVATE(window)->xcursor)
{
GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n",
- window_private->xcursor));
- SetCursor (window_private->xcursor);
+ WINDOW_PRIVATE(window)->xcursor));
+ SetCursor (WINDOW_PRIVATE(window)->xcursor);
}
- *ret_val_flagp = TRUE;
- *ret_valp = FALSE;
- break;
-#if 0
- case WM_QUERYOPEN:
- GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n",
- xevent->hwnd));
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
-
- if (window_private
- && !(window_private->event_mask & GDK_STRUCTURE_MASK))
- break;
-
- event->any.type = GDK_MAP;
- event->any.window = window;
+ if (window != curWnd)
+ synthesize_crossing_events (window, xevent);
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ *ret_val_flagp = TRUE;
+ *ret_valp = FALSE;
break;
-#endif
-#if 1
case WM_SHOWWINDOW:
GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n",
xevent->hwnd,
xevent->wParam));
- if (window_private
- && !(window_private->event_mask & GDK_STRUCTURE_MASK))
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK))
break;
event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP);
@@ -2562,9 +4704,9 @@ gdk_event_translate (GdkEvent *event,
&& k_grab_window == window)
gdk_keyboard_ungrab (xevent->time);
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
-#endif
+
case WM_SIZE:
GDK_NOTE (EVENTS,
g_print ("WM_SIZE: %#x %s %dx%d\n",
@@ -2576,13 +4718,11 @@ gdk_event_translate (GdkEvent *event,
(xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))),
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
- if (window_private
- && !(window_private->event_mask & GDK_STRUCTURE_MASK))
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK))
break;
- if (window_private != NULL
- && xevent->wParam == SIZE_MINIMIZED)
+
+ if (xevent->wParam == SIZE_MINIMIZED)
{
-#if 1
event->any.type = GDK_UNMAP;
event->any.window = window;
@@ -2593,11 +4733,9 @@ gdk_event_translate (GdkEvent *event,
gdk_keyboard_ungrab (xevent->time);
return_val = !GDK_DRAWABLE_DESTROYED (window);
-#endif
}
- else if (window_private != NULL
- && (xevent->wParam == SIZE_RESTORED
- || xevent->wParam == SIZE_MAXIMIZED)
+ else if ((xevent->wParam == SIZE_RESTORED
+ || xevent->wParam == SIZE_MAXIMIZED)
#if 1
&& GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD
#endif
@@ -2615,121 +4753,49 @@ gdk_event_translate (GdkEvent *event,
event->configure.y = pt.y;
event->configure.width = LOWORD (xevent->lParam);
event->configure.height = HIWORD (xevent->lParam);
- window_private->x = event->configure.x;
- window_private->y = event->configure.y;
- window_private->drawable.width = event->configure.width;
- window_private->drawable.height = event->configure.height;
- if (window_private->resize_count > 1)
- window_private->resize_count -= 1;
+ WINDOW_PRIVATE(window)->x = event->configure.x;
+ WINDOW_PRIVATE(window)->y = event->configure.y;
+ WINDOW_PRIVATE(window)->drawable.width = event->configure.width;
+ WINDOW_PRIVATE(window)->drawable.height = event->configure.height;
+ if (WINDOW_PRIVATE(window)->resize_count > 1)
+ WINDOW_PRIVATE(window)->resize_count -= 1;
return_val = !GDK_DRAWABLE_DESTROYED (window);
if (return_val
- && window_private->extension_events != 0
+ && WINDOW_PRIVATE(window)->extension_events != 0
&& gdk_input_vtable.configure_event)
gdk_input_vtable.configure_event (&event->configure, window);
}
break;
-#if 0 /* Bernd Herd suggests responding to WM_GETMINMAXINFO instead,
- * which indeed is much easier.
- */
- case WM_SIZING:
- GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd));
- if (ret_val_flagp == NULL)
- g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?");
- else if (window_private != NULL
- && window_private->hint_flags &
- (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE))
- {
- LPRECT lprc = (LPRECT) xevent->lParam;
-
- if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
- {
- gint w = lprc->right - lprc->left;
- gint h = lprc->bottom - lprc->top;
-
- if (w < window_private->hint_min_width)
- {
- if (xevent->wParam == WMSZ_BOTTOMLEFT
- || xevent->wParam == WMSZ_LEFT
- || xevent->wParam == WMSZ_TOPLEFT)
- lprc->left = lprc->right - window_private->hint_min_width;
- else
- lprc->right = lprc->left + window_private->hint_min_width;
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
- }
- if (h < window_private->hint_min_height)
- {
- if (xevent->wParam == WMSZ_BOTTOMLEFT
- || xevent->wParam == WMSZ_BOTTOM
- || xevent->wParam == WMSZ_BOTTOMRIGHT)
- lprc->bottom = lprc->top + window_private->hint_min_height;
- else
- lprc->top = lprc->bottom - window_private->hint_min_height;
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
- }
- }
- if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
- {
- gint w = lprc->right - lprc->left;
- gint h = lprc->bottom - lprc->top;
- if (w > window_private->hint_max_width)
- {
- if (xevent->wParam == WMSZ_BOTTOMLEFT
- || xevent->wParam == WMSZ_LEFT
- || xevent->wParam == WMSZ_TOPLEFT)
- lprc->left = lprc->right - window_private->hint_max_width;
- else
- lprc->right = lprc->left + window_private->hint_max_width;
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
- }
- if (h > window_private->hint_max_height)
- {
- if (xevent->wParam == WMSZ_BOTTOMLEFT
- || xevent->wParam == WMSZ_BOTTOM
- || xevent->wParam == WMSZ_BOTTOMRIGHT)
- lprc->bottom = lprc->top + window_private->hint_max_height;
- else
- lprc->top = lprc->bottom - window_private->hint_max_height;
- *ret_val_flagp = TRUE;
- *ret_valp = TRUE;
- }
- }
- }
- break;
-#else
case WM_GETMINMAXINFO:
GDK_NOTE (EVENTS, g_print ("WM_GETMINMAXINFO: %#x\n", xevent->hwnd));
+
lpmmi = (MINMAXINFO*) xevent->lParam;
- if (window_private->hint_flags & GDK_HINT_MIN_SIZE)
+ if (WINDOW_PRIVATE(window)->hint_flags & GDK_HINT_MIN_SIZE)
{
- lpmmi->ptMinTrackSize.x = window_private->hint_min_width;
- lpmmi->ptMinTrackSize.y = window_private->hint_min_height;
+ lpmmi->ptMinTrackSize.x = WINDOW_PRIVATE(window)->hint_min_width;
+ lpmmi->ptMinTrackSize.y = WINDOW_PRIVATE(window)->hint_min_height;
}
- if (window_private->hint_flags & GDK_HINT_MAX_SIZE)
+ if (WINDOW_PRIVATE(window)->hint_flags & GDK_HINT_MAX_SIZE)
{
- lpmmi->ptMaxTrackSize.x = window_private->hint_max_width;
- lpmmi->ptMaxTrackSize.y = window_private->hint_max_height;
+ lpmmi->ptMaxTrackSize.x = WINDOW_PRIVATE(window)->hint_max_width;
+ lpmmi->ptMaxTrackSize.y = WINDOW_PRIVATE(window)->hint_max_height;
- lpmmi->ptMaxSize.x = window_private->hint_max_width;
- lpmmi->ptMaxSize.y = window_private->hint_max_height;
+ lpmmi->ptMaxSize.x = WINDOW_PRIVATE(window)->hint_max_width;
+ lpmmi->ptMaxSize.y = WINDOW_PRIVATE(window)->hint_max_height;
}
break;
-#endif
case WM_MOVE:
GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n",
xevent->hwnd,
LOWORD (xevent->lParam), HIWORD (xevent->lParam)));
- if (window_private
- && !(window_private->event_mask & GDK_STRUCTURE_MASK))
+ if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK))
break;
- if (window_private != NULL
- && GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD)
+
+ if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD)
{
event->configure.type = GDK_CONFIGURE;
event->configure.window = window;
@@ -2738,10 +4804,10 @@ gdk_event_translate (GdkEvent *event,
GetClientRect (xevent->hwnd, &rect);
event->configure.width = rect.right;
event->configure.height = rect.bottom;
- window_private->x = event->configure.x;
- window_private->y = event->configure.y;
- window_private->drawable.width = event->configure.width;
- window_private->drawable.height = event->configure.height;
+ WINDOW_PRIVATE(window)->x = event->configure.x;
+ WINDOW_PRIVATE(window)->y = event->configure.y;
+ WINDOW_PRIVATE(window)->drawable.width = event->configure.width;
+ WINDOW_PRIVATE(window)->drawable.height = event->configure.height;
return_val = !GDK_DRAWABLE_DESTROYED (window);
}
@@ -2749,10 +4815,11 @@ gdk_event_translate (GdkEvent *event,
case WM_CLOSE:
GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd));
+
event->any.type = GDK_DELETE;
event->any.window = window;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
#if 0
@@ -2795,7 +4862,7 @@ gdk_event_translate (GdkEvent *event,
event->selection.property = gdk_selection_property;
event->selection.requestor = (guint32) xevent->hwnd;
event->selection.time = xevent->time;
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
#else
/* Test code, to see if SetClipboardData works when called from
* the window procedure.
@@ -2817,6 +4884,7 @@ gdk_event_translate (GdkEvent *event,
case WM_DESTROY:
GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd));
+
event->any.type = GDK_DESTROY;
event->any.window = window;
if (window != NULL && window == curWnd)
@@ -2831,7 +4899,7 @@ gdk_event_translate (GdkEvent *event,
if (k_grab_window == window)
gdk_keyboard_ungrab (xevent->time);
- return_val = window_private && !GDK_DRAWABLE_DESTROYED (window);
+ return_val = !GDK_DRAWABLE_DESTROYED (window);
break;
#ifdef HAVE_WINTAB
@@ -2871,6 +4939,8 @@ bypass_switch:
(event->any.type == GDK_LEAVE_NOTIFY)) &&
(event->crossing.subwindow != NULL))
gdk_window_ref (event->crossing.subwindow);
+
+ GDK_NOTE (EVENTS, print_event (event));
}
else
{
@@ -2891,17 +4961,31 @@ gdk_events_queue (void)
GList *node;
GdkEvent *event;
MSG msg;
-
- GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n",
- (queued_events ? "yes" : "none")));
+ LRESULT lres;
while (!gdk_event_queue_find_first()
&& PeekMessage (&msg, NULL, 0, 0, PM_REMOVE))
{
- GDK_NOTE (EVENTS, g_print ("gdk_events_queue: PeekMessage: %#x\n",
- msg.message));
- TranslateMessage (&msg);
+ GDK_NOTE (EVENTS, g_print ("PeekMessage: %#x %#x\n",
+ msg.hwnd, msg.message));
+
+ if (paimmmpo == NULL
+ || (paimmmpo->lpVtbl->OnTranslateMessage) (paimmmpo, &msg) != S_OK)
+ TranslateMessage (&msg);
+
+#ifdef USE_DISPATCHMESSAGE
+ if (msg.message == g_pipe_readable_msg)
+ {
+ GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n",
+ msg.wParam, msg.lParam));
+ g_io_channel_win32_pipe_readable (msg.wParam, msg.lParam);
+
+ continue;
+ }
+
+ DispatchMessage (&msg);
+#else
event = gdk_event_new ();
event->any.type = GDK_NOTHING;
@@ -2914,14 +4998,20 @@ gdk_events_queue (void)
node = queued_tail;
if (gdk_event_translate (event, &msg, NULL, NULL))
- ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
+ ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING;
else
{
- DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
+ if (paimmapp == NULL
+ || (paimmapp->lpVtbl->OnDefWindowProc) (paimmapp, msg.hwnd,
+ msg.message,
+ msg.wParam, msg.lParam,
+ &lres) == S_FALSE)
+ DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam);
gdk_event_queue_remove_link (node);
g_list_free_1 (node);
gdk_event_free (event);
}
+#endif
}
}
@@ -2937,8 +5027,6 @@ gdk_event_prepare (gpointer source_data,
*timeout = -1;
- GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n"));
-
retval = (gdk_event_queue_find_first () != NULL)
|| PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE);
@@ -2954,8 +5042,6 @@ gdk_event_check (gpointer source_data,
MSG msg;
gboolean retval;
- GDK_NOTE (EVENTS, g_print ("gdk_event_check\n"));
-
GDK_THREADS_ENTER ();
if (event_poll_fd.revents & G_IO_IN)
@@ -2994,8 +5080,6 @@ gdk_event_dispatch (gpointer source_data,
{
GdkEvent *event;
- GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n"));
-
GDK_THREADS_ENTER ();
gdk_events_queue();
diff --git a/gdk/win32/gdkfont-win32.c b/gdk/win32/gdkfont-win32.c
index d28c1f77c0..5c85d476a1 100644
--- a/gdk/win32/gdkfont-win32.c
+++ b/gdk/win32/gdkfont-win32.c
@@ -117,7 +117,8 @@ charset_name (DWORD charset)
}
GdkFont*
-gdk_font_load (const gchar *font_name)
+gdk_font_load_internal (GdkFontType type,
+ const gchar *font_name)
{
GdkFont *font;
GdkFontPrivate *private;
@@ -142,9 +143,9 @@ gdk_font_load (const gchar *font_name)
g_return_val_if_fail (font_name != NULL, NULL);
- GDK_NOTE (MISC, g_print ("gdk_font_load: %s\n", font_name));
+ GDK_NOTE (MISC, g_print ("gdk_font_load_internal: %s\n", font_name));
- font = gdk_font_hash_lookup (GDK_FONT_FONT, font_name);
+ font = gdk_font_hash_lookup (type, font_name);
if (font)
return font;
@@ -417,7 +418,6 @@ gdk_font_load (const gchar *font_name)
private->xfont = hfont;
private->ref_count = 1;
private->names = NULL;
- font->type = GDK_FONT_FONT;
GetObject (private->xfont, sizeof (logfont), &logfont);
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextMetrics (gdk_DC, &textmetric);
@@ -426,6 +426,7 @@ gdk_font_load (const gchar *font_name)
TranslateCharsetInfo ((DWORD *) private->charset, &csi, TCI_SRCCHARSET);
private->codepage = csi.ciACP;
GetCPInfo (private->codepage, &private->cpinfo);
+ font->type = type;
font->ascent = textmetric.tmAscent;
font->descent = textmetric.tmDescent;
@@ -442,17 +443,21 @@ gdk_font_load (const gchar *font_name)
*f = (HANDLE) ((guint) private->xfont + HFONT_DITHER);
gdk_xid_table_insert (f, font);
- gdk_font_hash_insert (GDK_FONT_FONT, font, font_name);
+ gdk_font_hash_insert (type, font, font_name);
return font;
}
GdkFont*
-gdk_fontset_load (gchar *fontset_name)
+gdk_font_load (const gchar *font_name)
{
- g_warning ("gdk_fontset_load: Not implemented");
+ return gdk_font_load_internal (GDK_FONT_FONT, font_name);
+}
- return NULL;
+GdkFont*
+gdk_fontset_load (gchar *fontset_name)
+{
+ return gdk_font_load_internal (GDK_FONT_FONTSET, fontset_name);
}
GdkFont*
@@ -493,6 +498,7 @@ gdk_font_unref (GdkFont *font)
switch (font->type)
{
case GDK_FONT_FONT:
+ case GDK_FONT_FONTSET: /* XXX */
gdk_xid_table_remove ((HANDLE) ((guint) private->xfont + HFONT_DITHER));
DeleteObject (private->xfont);
break;
@@ -515,9 +521,8 @@ gdk_font_id (const GdkFont *font)
if (font->type == GDK_FONT_FONT)
return (gint) font_private->xfont;
-
- g_assert_not_reached ();
- return 0;
+ else
+ return 0;
}
gint
@@ -535,9 +540,10 @@ gdk_font_equal (const GdkFont *fonta,
if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
return (privatea->xfont == privateb->xfont);
-
- g_assert_not_reached ();
- return 0;
+ else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
+ return (privatea->xfont == privateb->xfont);
+ else
+ return 0;
}
gint
@@ -547,55 +553,59 @@ gdk_string_width (GdkFont *font,
return gdk_text_width (font, string, strlen (string));
}
-gint
-gdk_text_width (GdkFont *font,
- const gchar *text,
- gint text_length)
+static gboolean
+gdk_text_size (GdkFont *font,
+ const gchar *text,
+ gint text_length,
+ SIZE *sizep)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
- SIZE size;
- gint width, wlen;
+ gint wlen;
wchar_t *wcstr;
- g_return_val_if_fail (font != NULL, -1);
- g_return_val_if_fail (text != NULL, -1);
+ g_return_val_if_fail (font != NULL, FALSE);
+ g_return_val_if_fail (text != NULL, FALSE);
if (text_length == 0)
return 0;
private = (GdkFontPrivate*) font;
- switch (font->type)
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
+ if ((oldfont = SelectObject (gdk_DC, private->xfont)) == NULL)
{
- case GDK_FONT_FONT:
- oldfont = SelectObject (gdk_DC, private->xfont);
- if (private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (private->codepage, 0,
- text, text_length,
- wcstr, text_length)) == 0)
- {
- g_warning ("gdk_text_width: MultiByteToWideChar failed");
- size.cx = 0;
- }
- else
- GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
- g_free (wcstr);
- }
- else
- {
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
- }
- SelectObject (gdk_DC, oldfont);
- width = size.cx;
- break;
+ g_warning ("gdk_text_width: SelectObject failed");
+ return FALSE;
+ }
- default:
- g_assert_not_reached ();
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = gdk_nmbstowchar_ts (wcstr, text, text_length, text_length)) == -1)
+ {
+ g_warning ("gdk_text_size: gdk_nmbstowchar_ts failed");
+ return FALSE;
}
- return width;
+
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, sizep);
+
+ g_free (wcstr);
+ SelectObject (gdk_DC, oldfont);
+
+ return TRUE;
+}
+
+gint
+gdk_text_width (GdkFont *font,
+ const gchar *text,
+ gint text_length)
+{
+ SIZE size;
+
+ if (!gdk_text_size (font, text, text_length, &size))
+ return -1;
+
+ return size.cx;
}
gint
@@ -608,7 +618,7 @@ gdk_text_width_wc (GdkFont *font,
SIZE size;
wchar_t *wcstr;
guchar *str;
- gint i, width, wlen;
+ gint i;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
@@ -616,58 +626,44 @@ gdk_text_width_wc (GdkFont *font,
if (text_length == 0)
return 0;
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
private = (GdkFontPrivate*) font;
- switch (font->type)
+ if ((oldfont = SelectObject (gdk_DC, private->xfont)) == NULL)
+
+ g_warning ("gdk_text_width_wc: SelectObject failed");
+
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
{
- case GDK_FONT_FONT:
- oldfont = SelectObject (gdk_DC, private->xfont);
-#if 0 /* No. Don't assume Unicode here either.
- * (Read the comments in gdk_draw_text_wc.)
- */
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
- GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
- g_free (wcstr);
-#else
- str = g_new (guchar, text_length);
- for (i = 0; i < text_length; i++)
- str[i] = text[i];
- if (private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (private->codepage, 0,
- str, text_length,
- wcstr, text_length)) == 0)
- {
- g_warning ("gdk_text_width_wc: MultiByteToWideChar failed");
- size.cx = 0;
- }
- else
- GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
- g_free (wcstr);
- }
- else
- {
- GetTextExtentPoint32A (gdk_DC, str, text_length, &size);
- }
- g_free (str);
-#endif
- SelectObject (gdk_DC, oldfont);
- width = size.cx;
- break;
-
- default:
- width = 0;
}
- return width;
+ else
+ wcstr = (wchar_t *) text;
+
+ GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
+
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
+ g_free (wcstr);
+
+ if (oldfont != NULL)
+ SelectObject (gdk_DC, oldfont);
+
+ return size.cx;
}
gint
gdk_char_width (GdkFont *font,
gchar character)
{
+ if (((guchar) character) >= 128)
+ {
+ /* gtktext calls us with non-ASCII characters, sigh */
+ GdkWChar wc = (guchar) character;
+ return gdk_text_width_wc (font, &wc, 1);
+ }
return gdk_text_width (font, &character, 1);
}
@@ -722,48 +718,37 @@ gdk_text_extents (GdkFont *font,
return;
}
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
private = (GdkFontPrivate*) font;
- switch (font->type)
- {
- case GDK_FONT_FONT:
- oldfont = SelectObject (gdk_DC, private->xfont);
- if (private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (private->codepage, 0,
- text, text_length,
- wcstr, text_length)) == 0)
- {
- g_warning ("gdk_text_extents: MultiByteToWideChar failed");
- size.cx = 0;
- size.cy = 0;
- }
- else
- GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
- g_free (wcstr);
- }
- else
- {
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
- }
- SelectObject (gdk_DC, oldfont);
- /* XXX This is all quite bogus */
- if (lbearing)
- *lbearing = 0;
- if (rbearing)
- *rbearing = 0;
- if (width)
- *width = size.cx;
- if (ascent)
- *ascent = size.cy + 1;
- if (descent)
- *descent = font->descent + 1;
- break;
+ if ((oldfont = SelectObject (gdk_DC, private->xfont)) == NULL)
+ g_warning ("gdk_text_extents: SelectObject failed");
- default:
- g_assert_not_reached ();
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = gdk_nmbstowchar_ts (wcstr, text, text_length, text_length)) == -1)
+ {
+ g_warning ("gdk_text_extents: gdk_nmbstowchar_ts failed");
+ size.cx = 0;
+ size.cy = 0;
}
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+
+ if (oldfont != NULL)
+ SelectObject (gdk_DC, oldfont);
+
+ /* XXX This is all quite bogus */
+ if (lbearing)
+ *lbearing = 0;
+ if (rbearing)
+ *rbearing = 0;
+ if (width)
+ *width = size.cx;
+ if (ascent)
+ *ascent = size.cy + 1;
+ if (descent)
+ *descent = font->descent + 1;
}
void
@@ -800,35 +785,41 @@ gdk_text_extents_wc (GdkFont *font,
return;
}
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
private = (GdkFontPrivate*) font;
- switch (font->type)
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
{
- case GDK_FONT_FONT:
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
- oldfont = SelectObject (gdk_DC, private->xfont);
- GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
- g_free (wcstr);
- SelectObject (gdk_DC, oldfont);
-
- /* XXX This is all quite bogus */
- if (lbearing)
- *lbearing = 0;
- if (rbearing)
- *rbearing = 0;
- if (width)
- *width = size.cx;
- if (ascent)
- *ascent = size.cy + 1;
- if (descent)
- *descent = font->descent + 1;
- break;
-
- default:
- g_assert_not_reached ();
}
+ else
+ wcstr = (wchar_t *) text;
+
+ if ((oldfont = SelectObject (gdk_DC, private->xfont)) == NULL)
+ g_warning ("gdk_text_extents_wc: SelectObject failed");
+
+ GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
+
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
+ g_free (wcstr);
+
+ if (oldfont != NULL)
+ SelectObject (gdk_DC, oldfont);
+
+ /* XXX This is all quite bogus */
+ if (lbearing)
+ *lbearing = 0;
+ if (rbearing)
+ *rbearing = 0;
+ if (width)
+ *width = size.cx;
+ if (ascent)
+ *ascent = size.cy + 1;
+ if (descent)
+ *descent = font->descent + 1;
}
void
@@ -853,24 +844,7 @@ gdk_text_measure (GdkFont *font,
const gchar *text,
gint text_length)
{
- GdkFontPrivate *private;
- gint width;
-
- 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:
- return gdk_text_width (font, text, text_length); /* ??? */
- break;
-
- default:
- g_assert_not_reached ();
- }
- return 0;
+ return gdk_text_width (font, text, text_length); /* ??? */
}
gint
@@ -895,52 +869,12 @@ gdk_text_height (GdkFont *font,
const gchar *text,
gint text_length)
{
- GdkFontPrivate *private;
- HGDIOBJ oldfont;
SIZE size;
- gint height, wlen;
- wchar_t *wcstr;
-
- g_return_val_if_fail (font != NULL, -1);
- g_return_val_if_fail (text != NULL, -1);
-
- if (text_length == 0)
- return 0;
- private = (GdkFontPrivate*) font;
-
- switch (font->type)
- {
- case GDK_FONT_FONT:
- oldfont = SelectObject (gdk_DC, private->xfont);
- if (private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (private->codepage, 0,
- text, text_length,
- wcstr, text_length)) == 0)
- {
- g_warning ("gdk_text_height: MultiByteToWideChar failed "
- "text = %.*s (%d)",
- text_length, text, text_length);
- size.cy = 0;
- }
- else
- GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
- g_free (wcstr);
- }
- else
- {
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
- }
- SelectObject (gdk_DC, oldfont);
- height = size.cy;
- break;
+ if (!gdk_text_size (font, text, text_length, &size))
+ return -1;
- default:
- g_error ("font->type = %d", font->type);
- }
- return height;
+ return size.cy;
}
gint
diff --git a/gdk/win32/gdkfont.c b/gdk/win32/gdkfont.c
index d28c1f77c0..5c85d476a1 100644
--- a/gdk/win32/gdkfont.c
+++ b/gdk/win32/gdkfont.c
@@ -117,7 +117,8 @@ charset_name (DWORD charset)
}
GdkFont*
-gdk_font_load (const gchar *font_name)
+gdk_font_load_internal (GdkFontType type,
+ const gchar *font_name)
{
GdkFont *font;
GdkFontPrivate *private;
@@ -142,9 +143,9 @@ gdk_font_load (const gchar *font_name)
g_return_val_if_fail (font_name != NULL, NULL);
- GDK_NOTE (MISC, g_print ("gdk_font_load: %s\n", font_name));
+ GDK_NOTE (MISC, g_print ("gdk_font_load_internal: %s\n", font_name));
- font = gdk_font_hash_lookup (GDK_FONT_FONT, font_name);
+ font = gdk_font_hash_lookup (type, font_name);
if (font)
return font;
@@ -417,7 +418,6 @@ gdk_font_load (const gchar *font_name)
private->xfont = hfont;
private->ref_count = 1;
private->names = NULL;
- font->type = GDK_FONT_FONT;
GetObject (private->xfont, sizeof (logfont), &logfont);
oldfont = SelectObject (gdk_DC, private->xfont);
GetTextMetrics (gdk_DC, &textmetric);
@@ -426,6 +426,7 @@ gdk_font_load (const gchar *font_name)
TranslateCharsetInfo ((DWORD *) private->charset, &csi, TCI_SRCCHARSET);
private->codepage = csi.ciACP;
GetCPInfo (private->codepage, &private->cpinfo);
+ font->type = type;
font->ascent = textmetric.tmAscent;
font->descent = textmetric.tmDescent;
@@ -442,17 +443,21 @@ gdk_font_load (const gchar *font_name)
*f = (HANDLE) ((guint) private->xfont + HFONT_DITHER);
gdk_xid_table_insert (f, font);
- gdk_font_hash_insert (GDK_FONT_FONT, font, font_name);
+ gdk_font_hash_insert (type, font, font_name);
return font;
}
GdkFont*
-gdk_fontset_load (gchar *fontset_name)
+gdk_font_load (const gchar *font_name)
{
- g_warning ("gdk_fontset_load: Not implemented");
+ return gdk_font_load_internal (GDK_FONT_FONT, font_name);
+}
- return NULL;
+GdkFont*
+gdk_fontset_load (gchar *fontset_name)
+{
+ return gdk_font_load_internal (GDK_FONT_FONTSET, fontset_name);
}
GdkFont*
@@ -493,6 +498,7 @@ gdk_font_unref (GdkFont *font)
switch (font->type)
{
case GDK_FONT_FONT:
+ case GDK_FONT_FONTSET: /* XXX */
gdk_xid_table_remove ((HANDLE) ((guint) private->xfont + HFONT_DITHER));
DeleteObject (private->xfont);
break;
@@ -515,9 +521,8 @@ gdk_font_id (const GdkFont *font)
if (font->type == GDK_FONT_FONT)
return (gint) font_private->xfont;
-
- g_assert_not_reached ();
- return 0;
+ else
+ return 0;
}
gint
@@ -535,9 +540,10 @@ gdk_font_equal (const GdkFont *fonta,
if (fonta->type == GDK_FONT_FONT && fontb->type == GDK_FONT_FONT)
return (privatea->xfont == privateb->xfont);
-
- g_assert_not_reached ();
- return 0;
+ else if (fonta->type == GDK_FONT_FONTSET && fontb->type == GDK_FONT_FONTSET)
+ return (privatea->xfont == privateb->xfont);
+ else
+ return 0;
}
gint
@@ -547,55 +553,59 @@ gdk_string_width (GdkFont *font,
return gdk_text_width (font, string, strlen (string));
}
-gint
-gdk_text_width (GdkFont *font,
- const gchar *text,
- gint text_length)
+static gboolean
+gdk_text_size (GdkFont *font,
+ const gchar *text,
+ gint text_length,
+ SIZE *sizep)
{
GdkFontPrivate *private;
HGDIOBJ oldfont;
- SIZE size;
- gint width, wlen;
+ gint wlen;
wchar_t *wcstr;
- g_return_val_if_fail (font != NULL, -1);
- g_return_val_if_fail (text != NULL, -1);
+ g_return_val_if_fail (font != NULL, FALSE);
+ g_return_val_if_fail (text != NULL, FALSE);
if (text_length == 0)
return 0;
private = (GdkFontPrivate*) font;
- switch (font->type)
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
+ if ((oldfont = SelectObject (gdk_DC, private->xfont)) == NULL)
{
- case GDK_FONT_FONT:
- oldfont = SelectObject (gdk_DC, private->xfont);
- if (private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (private->codepage, 0,
- text, text_length,
- wcstr, text_length)) == 0)
- {
- g_warning ("gdk_text_width: MultiByteToWideChar failed");
- size.cx = 0;
- }
- else
- GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
- g_free (wcstr);
- }
- else
- {
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
- }
- SelectObject (gdk_DC, oldfont);
- width = size.cx;
- break;
+ g_warning ("gdk_text_width: SelectObject failed");
+ return FALSE;
+ }
- default:
- g_assert_not_reached ();
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = gdk_nmbstowchar_ts (wcstr, text, text_length, text_length)) == -1)
+ {
+ g_warning ("gdk_text_size: gdk_nmbstowchar_ts failed");
+ return FALSE;
}
- return width;
+
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, sizep);
+
+ g_free (wcstr);
+ SelectObject (gdk_DC, oldfont);
+
+ return TRUE;
+}
+
+gint
+gdk_text_width (GdkFont *font,
+ const gchar *text,
+ gint text_length)
+{
+ SIZE size;
+
+ if (!gdk_text_size (font, text, text_length, &size))
+ return -1;
+
+ return size.cx;
}
gint
@@ -608,7 +618,7 @@ gdk_text_width_wc (GdkFont *font,
SIZE size;
wchar_t *wcstr;
guchar *str;
- gint i, width, wlen;
+ gint i;
g_return_val_if_fail (font != NULL, -1);
g_return_val_if_fail (text != NULL, -1);
@@ -616,58 +626,44 @@ gdk_text_width_wc (GdkFont *font,
if (text_length == 0)
return 0;
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
private = (GdkFontPrivate*) font;
- switch (font->type)
+ if ((oldfont = SelectObject (gdk_DC, private->xfont)) == NULL)
+
+ g_warning ("gdk_text_width_wc: SelectObject failed");
+
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
{
- case GDK_FONT_FONT:
- oldfont = SelectObject (gdk_DC, private->xfont);
-#if 0 /* No. Don't assume Unicode here either.
- * (Read the comments in gdk_draw_text_wc.)
- */
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
- GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
- g_free (wcstr);
-#else
- str = g_new (guchar, text_length);
- for (i = 0; i < text_length; i++)
- str[i] = text[i];
- if (private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (private->codepage, 0,
- str, text_length,
- wcstr, text_length)) == 0)
- {
- g_warning ("gdk_text_width_wc: MultiByteToWideChar failed");
- size.cx = 0;
- }
- else
- GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
- g_free (wcstr);
- }
- else
- {
- GetTextExtentPoint32A (gdk_DC, str, text_length, &size);
- }
- g_free (str);
-#endif
- SelectObject (gdk_DC, oldfont);
- width = size.cx;
- break;
-
- default:
- width = 0;
}
- return width;
+ else
+ wcstr = (wchar_t *) text;
+
+ GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
+
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
+ g_free (wcstr);
+
+ if (oldfont != NULL)
+ SelectObject (gdk_DC, oldfont);
+
+ return size.cx;
}
gint
gdk_char_width (GdkFont *font,
gchar character)
{
+ if (((guchar) character) >= 128)
+ {
+ /* gtktext calls us with non-ASCII characters, sigh */
+ GdkWChar wc = (guchar) character;
+ return gdk_text_width_wc (font, &wc, 1);
+ }
return gdk_text_width (font, &character, 1);
}
@@ -722,48 +718,37 @@ gdk_text_extents (GdkFont *font,
return;
}
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
private = (GdkFontPrivate*) font;
- switch (font->type)
- {
- case GDK_FONT_FONT:
- oldfont = SelectObject (gdk_DC, private->xfont);
- if (private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (private->codepage, 0,
- text, text_length,
- wcstr, text_length)) == 0)
- {
- g_warning ("gdk_text_extents: MultiByteToWideChar failed");
- size.cx = 0;
- size.cy = 0;
- }
- else
- GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
- g_free (wcstr);
- }
- else
- {
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
- }
- SelectObject (gdk_DC, oldfont);
- /* XXX This is all quite bogus */
- if (lbearing)
- *lbearing = 0;
- if (rbearing)
- *rbearing = 0;
- if (width)
- *width = size.cx;
- if (ascent)
- *ascent = size.cy + 1;
- if (descent)
- *descent = font->descent + 1;
- break;
+ if ((oldfont = SelectObject (gdk_DC, private->xfont)) == NULL)
+ g_warning ("gdk_text_extents: SelectObject failed");
- default:
- g_assert_not_reached ();
+ wcstr = g_new (wchar_t, text_length);
+ if ((wlen = gdk_nmbstowchar_ts (wcstr, text, text_length, text_length)) == -1)
+ {
+ g_warning ("gdk_text_extents: gdk_nmbstowchar_ts failed");
+ size.cx = 0;
+ size.cy = 0;
}
+ else
+ GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
+
+ if (oldfont != NULL)
+ SelectObject (gdk_DC, oldfont);
+
+ /* XXX This is all quite bogus */
+ if (lbearing)
+ *lbearing = 0;
+ if (rbearing)
+ *rbearing = 0;
+ if (width)
+ *width = size.cx;
+ if (ascent)
+ *ascent = size.cy + 1;
+ if (descent)
+ *descent = font->descent + 1;
}
void
@@ -800,35 +785,41 @@ gdk_text_extents_wc (GdkFont *font,
return;
}
+ g_assert (font->type == GDK_FONT_FONT || font->type == GDK_FONT_FONTSET);
+
private = (GdkFontPrivate*) font;
- switch (font->type)
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
{
- case GDK_FONT_FONT:
wcstr = g_new (wchar_t, text_length);
for (i = 0; i < text_length; i++)
wcstr[i] = text[i];
- oldfont = SelectObject (gdk_DC, private->xfont);
- GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
- g_free (wcstr);
- SelectObject (gdk_DC, oldfont);
-
- /* XXX This is all quite bogus */
- if (lbearing)
- *lbearing = 0;
- if (rbearing)
- *rbearing = 0;
- if (width)
- *width = size.cx;
- if (ascent)
- *ascent = size.cy + 1;
- if (descent)
- *descent = font->descent + 1;
- break;
-
- default:
- g_assert_not_reached ();
}
+ else
+ wcstr = (wchar_t *) text;
+
+ if ((oldfont = SelectObject (gdk_DC, private->xfont)) == NULL)
+ g_warning ("gdk_text_extents_wc: SelectObject failed");
+
+ GetTextExtentPoint32W (gdk_DC, wcstr, text_length, &size);
+
+ if (sizeof (wchar_t) != sizeof (GdkWChar))
+ g_free (wcstr);
+
+ if (oldfont != NULL)
+ SelectObject (gdk_DC, oldfont);
+
+ /* XXX This is all quite bogus */
+ if (lbearing)
+ *lbearing = 0;
+ if (rbearing)
+ *rbearing = 0;
+ if (width)
+ *width = size.cx;
+ if (ascent)
+ *ascent = size.cy + 1;
+ if (descent)
+ *descent = font->descent + 1;
}
void
@@ -853,24 +844,7 @@ gdk_text_measure (GdkFont *font,
const gchar *text,
gint text_length)
{
- GdkFontPrivate *private;
- gint width;
-
- 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:
- return gdk_text_width (font, text, text_length); /* ??? */
- break;
-
- default:
- g_assert_not_reached ();
- }
- return 0;
+ return gdk_text_width (font, text, text_length); /* ??? */
}
gint
@@ -895,52 +869,12 @@ gdk_text_height (GdkFont *font,
const gchar *text,
gint text_length)
{
- GdkFontPrivate *private;
- HGDIOBJ oldfont;
SIZE size;
- gint height, wlen;
- wchar_t *wcstr;
-
- g_return_val_if_fail (font != NULL, -1);
- g_return_val_if_fail (text != NULL, -1);
-
- if (text_length == 0)
- return 0;
- private = (GdkFontPrivate*) font;
-
- switch (font->type)
- {
- case GDK_FONT_FONT:
- oldfont = SelectObject (gdk_DC, private->xfont);
- if (private->cpinfo.MaxCharSize > 1)
- {
- wcstr = g_new (wchar_t, text_length);
- if ((wlen = MultiByteToWideChar (private->codepage, 0,
- text, text_length,
- wcstr, text_length)) == 0)
- {
- g_warning ("gdk_text_height: MultiByteToWideChar failed "
- "text = %.*s (%d)",
- text_length, text, text_length);
- size.cy = 0;
- }
- else
- GetTextExtentPoint32W (gdk_DC, wcstr, wlen, &size);
- g_free (wcstr);
- }
- else
- {
- GetTextExtentPoint32A (gdk_DC, text, text_length, &size);
- }
- SelectObject (gdk_DC, oldfont);
- height = size.cy;
- break;
+ if (!gdk_text_size (font, text, text_length, &size))
+ return -1;
- default:
- g_error ("font->type = %d", font->type);
- }
- return height;
+ return size.cy;
}
gint
diff --git a/gdk/win32/gdkgc-win32.c b/gdk/win32/gdkgc-win32.c
index e1cbf8552b..fb59c593f9 100644
--- a/gdk/win32/gdkgc-win32.c
+++ b/gdk/win32/gdkgc-win32.c
@@ -87,7 +87,8 @@ gdk_gc_new_with_values (GdkWindow *window,
else
private->background = white;
- if ((values_mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT))
+ if ((values_mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT
+ || values->font->type == GDK_FONT_FONTSET))
{
private->font = (HFONT) ((GdkFontPrivate*) values->font)->xfont;
GDK_NOTE (MISC, g_print (" font=%#x", private->font));
@@ -480,7 +481,8 @@ gdk_gc_set_font (GdkGC *gc,
g_return_if_fail (gc != NULL);
g_return_if_fail (font != NULL);
- if (font->type == GDK_FONT_FONT)
+ if (font->type == GDK_FONT_FONT
+ || font->type == GDK_FONT_FONTSET)
{
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
diff --git a/gdk/win32/gdkgc.c b/gdk/win32/gdkgc.c
index e1cbf8552b..fb59c593f9 100644
--- a/gdk/win32/gdkgc.c
+++ b/gdk/win32/gdkgc.c
@@ -87,7 +87,8 @@ gdk_gc_new_with_values (GdkWindow *window,
else
private->background = white;
- if ((values_mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT))
+ if ((values_mask & GDK_GC_FONT) && (values->font->type == GDK_FONT_FONT
+ || values->font->type == GDK_FONT_FONTSET))
{
private->font = (HFONT) ((GdkFontPrivate*) values->font)->xfont;
GDK_NOTE (MISC, g_print (" font=%#x", private->font));
@@ -480,7 +481,8 @@ gdk_gc_set_font (GdkGC *gc,
g_return_if_fail (gc != NULL);
g_return_if_fail (font != NULL);
- if (font->type == GDK_FONT_FONT)
+ if (font->type == GDK_FONT_FONT
+ || font->type == GDK_FONT_FONTSET)
{
gc_private = (GdkGCPrivate*) gc;
font_private = (GdkFontPrivate*) font;
diff --git a/gdk/win32/gdkglobals-win32.c b/gdk/win32/gdkglobals-win32.c
index cf16cf717c..3aa73b6076 100644
--- a/gdk/win32/gdkglobals-win32.c
+++ b/gdk/win32/gdkglobals-win32.c
@@ -28,9 +28,9 @@
#include "gdkprivate.h"
guint gdk_debug_flags = 0;
-HWND gdk_root_window;
+HWND gdk_root_window = NULL;
HWND gdk_leader_window;
-GDKVAR GdkWindowPrivate gdk_root_parent = { { NULL, }, NULL, };
+GDKVAR GdkWindowPrivate *gdk_root_parent = NULL;
HDC gdk_DC;
HINSTANCE gdk_DLLInstance;
HINSTANCE gdk_ProgInstance;
@@ -45,18 +45,8 @@ gchar *gdk_progclass = NULL;
gint gdk_error_code;
gint gdk_error_warnings = TRUE;
gint gdk_null_window_warnings = TRUE;
-GList *gdk_default_filters = NULL;
-
-gboolean gdk_xim_using; /* using XIM Protocol if TRUE */
-GdkWindow *gdk_xim_window; /* currently using Widow */
-
-GdkWindowPrivate *gdk_xgrab_window = NULL; /* Window that currently holds the
- * x pointer grab
- */
GMutex *gdk_threads_mutex = NULL; /* Global GDK lock */
-#ifdef USE_XIM
-GdkICPrivate *gdk_xim_ic; /* currently using IC */
-GdkWindow *gdk_xim_window; /* currently using Window */
-#endif
+BOOL (WINAPI *p_TrackMouseEvent) (TRACKMOUSEEVENT *tme) = NULL;
+
diff --git a/gdk/win32/gdkglobals.c b/gdk/win32/gdkglobals.c
index cf16cf717c..3aa73b6076 100644
--- a/gdk/win32/gdkglobals.c
+++ b/gdk/win32/gdkglobals.c
@@ -28,9 +28,9 @@
#include "gdkprivate.h"
guint gdk_debug_flags = 0;
-HWND gdk_root_window;
+HWND gdk_root_window = NULL;
HWND gdk_leader_window;
-GDKVAR GdkWindowPrivate gdk_root_parent = { { NULL, }, NULL, };
+GDKVAR GdkWindowPrivate *gdk_root_parent = NULL;
HDC gdk_DC;
HINSTANCE gdk_DLLInstance;
HINSTANCE gdk_ProgInstance;
@@ -45,18 +45,8 @@ gchar *gdk_progclass = NULL;
gint gdk_error_code;
gint gdk_error_warnings = TRUE;
gint gdk_null_window_warnings = TRUE;
-GList *gdk_default_filters = NULL;
-
-gboolean gdk_xim_using; /* using XIM Protocol if TRUE */
-GdkWindow *gdk_xim_window; /* currently using Widow */
-
-GdkWindowPrivate *gdk_xgrab_window = NULL; /* Window that currently holds the
- * x pointer grab
- */
GMutex *gdk_threads_mutex = NULL; /* Global GDK lock */
-#ifdef USE_XIM
-GdkICPrivate *gdk_xim_ic; /* currently using IC */
-GdkWindow *gdk_xim_window; /* currently using Window */
-#endif
+BOOL (WINAPI *p_TrackMouseEvent) (TRACKMOUSEEVENT *tme) = NULL;
+
diff --git a/gdk/win32/gdkim-win32.c b/gdk/win32/gdkim-win32.c
index 35ea6b5683..0d55317655 100644
--- a/gdk/win32/gdkim-win32.c
+++ b/gdk/win32/gdkim-win32.c
@@ -37,12 +37,6 @@
#include "gdki18n.h"
#include "gdkx.h"
-/* If this variable is FALSE, it indicates that we should
- * avoid trying to use multibyte conversion functions and
- * assume everything is 1-byte per character
- */
-static gboolean gdk_use_mb;
-
/*
*--------------------------------------------------------------
* gdk_set_locale
@@ -59,22 +53,13 @@ static gboolean gdk_use_mb;
gchar*
gdk_set_locale (void)
{
- wchar_t result;
gchar *current_locale;
- gdk_use_mb = FALSE;
-
if (!setlocale (LC_ALL,""))
g_warning ("locale not supported by C library");
current_locale = setlocale (LC_ALL, NULL);
- if (MB_CUR_MAX > 1)
- gdk_use_mb = TRUE;
-
- GDK_NOTE (XIM, g_message ("%s multi-byte string functions.",
- gdk_use_mb ? "Using" : "Not using"));
-
return current_locale;
}
@@ -158,50 +143,91 @@ gdk_ic_get_events (GdkIC *ic)
* of wide characters. The string is newly allocated. The array of
* wide characters must be null-terminated. If the conversion is
* failed, it returns NULL.
+ *
+ * On Win32, we always use UTF-8.
*/
gchar *
gdk_wcstombs (const GdkWChar *src)
{
- gchar *mbstr;
+ gint len;
+ const GdkWChar *wcp;
+ guchar *mbstr, *bp;
- if (gdk_use_mb)
+ wcp = src;
+ len = 0;
+ while (*wcp)
{
- gint i, wcsl, mbsl;
- wchar_t *src_alt;
-
- for (wcsl = 0; src[wcsl]; wcsl++)
- ;
- src_alt = g_new (wchar_t, wcsl+1);
- for (i = wcsl; i >= 0; i--)
- src_alt[i] = src[i];
- mbsl = WideCharToMultiByte (CP_OEMCP, 0, src_alt, wcsl,
- NULL, 0, NULL, NULL);
- mbstr = g_new (guchar, mbsl + 1);
- if (!WideCharToMultiByte (CP_OEMCP, 0, src_alt, wcsl,
- mbstr, mbsl, NULL, NULL))
- {
- g_warning ("gdk_wcstombs: WideCharToMultiByte failed");
- g_free (mbstr);
- g_free (src_alt);
- return NULL;
- }
- mbstr[mbsl] = '\0';
- g_free (src_alt);
+ const GdkWChar c = *wcp++;
+
+ if (c < 0x80)
+ len += 1;
+ else if (c < 0x800)
+ len += 2;
+ else if (c < 0x10000)
+ len += 3;
+ else if (c < 0x200000)
+ len += 4;
+ else if (c < 0x4000000)
+ len += 5;
+ else
+ len += 6;
}
- else
+
+ mbstr = g_malloc (len + 1);
+
+ wcp = src;
+ bp = mbstr;
+ while (*wcp)
{
- gint length = 0;
- gint i;
+ int first;
+ int i;
+ GdkWChar c = *wcp++;
- while (src[length] != 0)
- length++;
+ if (c < 0x80)
+ {
+ first = 0;
+ len = 1;
+ }
+ else if (c < 0x800)
+ {
+ first = 0xc0;
+ len = 2;
+ }
+ else if (c < 0x10000)
+ {
+ first = 0xe0;
+ len = 3;
+ }
+ else if (c < 0x200000)
+ {
+ first = 0xf0;
+ len = 4;
+ }
+ else if (c < 0x4000000)
+ {
+ first = 0xf8;
+ len = 5;
+ }
+ else
+ {
+ first = 0xfc;
+ len = 6;
+ }
- mbstr = g_new (gchar, length + 1);
+ /* Woo-hoo! */
+ switch (len)
+ {
+ case 6: bp[5] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 5: bp[4] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 4: bp[3] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 1: bp[0] = c | first;
+ }
- for (i=0; i<length+1; i++)
- mbstr[i] = src[i];
+ bp += len;
}
-
+ *bp = 0;
return mbstr;
}
@@ -209,41 +235,158 @@ gdk_wcstombs (const GdkWChar *src)
/*
* gdk_mbstowcs
*
- * Converts the specified string into wide characters, and, returns the
- * number of wide characters written. The string 'src' must be
- * null-terminated. If the conversion is failed, it returns -1.
+ * Converts the specified string into GDK wide characters, and,
+ * returns the number of wide characters written. The string 'src'
+ * must be null-terminated. If the conversion is failed, it returns
+ * -1.
+ *
+ * On Win32, thr string is assumed to be in UTF-8. Also note that
+ * GdkWChar is 32 bits, while wchar_t, and the wide characters the
+ * Windows API uses, are 16 bits!
*/
+
+/* First a helper function for not zero-terminated strings */
gint
-gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
+gdk_nmbstowcs (GdkWChar *dest,
+ const gchar *src,
+ gint src_len,
+ gint dest_max)
{
- if (gdk_use_mb)
+ guchar *cp, *end;
+ gint n;
+
+ cp = (guchar *) src;
+ end = cp + src_len;
+ n = 0;
+ while (cp != end && dest != dest + dest_max)
{
- gint i, wcsl;
- wchar_t *wcstr;
+ gint i, mask = 0, len;
+ guchar c = *cp;
+
+ if (c < 0x80)
+ {
+ len = 1;
+ mask = 0x7f;
+ }
+ else if ((c & 0xe0) == 0xc0)
+ {
+ len = 2;
+ mask = 0x1f;
+ }
+ else if ((c & 0xf0) == 0xe0)
+ {
+ len = 3;
+ mask = 0x0f;
+ }
+ else if ((c & 0xf8) == 0xf0)
+ {
+ len = 4;
+ mask = 0x07;
+ }
+ else if ((c & 0xfc) == 0xf8)
+ {
+ len = 5;
+ mask = 0x03;
+ }
+ else if ((c & 0xfc) == 0xfc)
+ {
+ len = 6;
+ mask = 0x01;
+ }
+ else
+ return -1;
+
+ if (cp + len > end)
+ return -1;
- wcsl = MultiByteToWideChar (CP_OEMCP, 0, src, -1, NULL, 0);
- wcstr = g_new (wchar_t, wcsl);
- if (!MultiByteToWideChar (CP_OEMCP, 0, src, -1, wcstr, wcsl))
+ *dest = (cp[0] & mask);
+ for (i = 1; i < len; i++)
{
- g_warning ("gdk_mbstowcs: MultiByteToWideChar failed");
- g_free (wcstr);
- return -1;
+ if ((cp[i] & 0xc0) != 0x80)
+ return -1;
+ *dest <<= 6;
+ *dest |= (cp[i] & 0x3f);
}
- if (wcsl > dest_max)
- wcsl = dest_max;
- for (i = 0; i < wcsl && wcstr[i]; i++)
- dest[i] = wcstr[i];
- g_free (wcstr);
+ if (*dest == -1)
+ return -1;
- return i;
+ cp += len;
+ dest++;
+ n++;
}
- else
+ if (cp != end)
+ return -1;
+
+ return n;
+}
+
+gint
+gdk_mbstowcs (GdkWChar *dest,
+ const gchar *src,
+ gint dest_max)
+{
+ return gdk_nmbstowcs (dest, src, strlen (src), dest_max);
+}
+
+
+/* A version that converts to wchar_t wide chars */
+
+gint
+gdk_nmbstowchar_ts (wchar_t *dest,
+ const gchar *src,
+ gint src_len,
+ gint dest_max)
+{
+ guchar *cp, *end;
+ gint n;
+
+ cp = (guchar *) src;
+ end = cp + src_len;
+ n = 0;
+ while (cp != end && dest != dest + dest_max)
{
- gint i;
+ gint i, mask = 0, len;
+ guchar c = *cp;
+
+ if (c < 0x80)
+ {
+ len = 1;
+ mask = 0x7f;
+ }
+ else if ((c & 0xe0) == 0xc0)
+ {
+ len = 2;
+ mask = 0x1f;
+ }
+ else if ((c & 0xf0) == 0xe0)
+ {
+ len = 3;
+ mask = 0x0f;
+ }
+ else /* Other lengths are not possible with 16-bit wchar_t! */
+ return -1;
+
+ if (cp + len > end)
+ return -1;
- for (i=0; i<dest_max && src[i]; i++)
- dest[i] = src[i];
+ *dest = (cp[0] & mask);
+ for (i = 1; i < len; i++)
+ {
+ if ((cp[i] & 0xc0) != 0x80)
+ return -1;
+ *dest <<= 6;
+ *dest |= (cp[i] & 0x3f);
+ }
+ if (*dest == 0xFFFF)
+ return -1;
- return i;
+ cp += len;
+ dest++;
+ n++;
}
+ if (cp != end)
+ return -1;
+
+ return n;
}
+
diff --git a/gdk/win32/gdkim.c b/gdk/win32/gdkim.c
index 35ea6b5683..0d55317655 100644
--- a/gdk/win32/gdkim.c
+++ b/gdk/win32/gdkim.c
@@ -37,12 +37,6 @@
#include "gdki18n.h"
#include "gdkx.h"
-/* If this variable is FALSE, it indicates that we should
- * avoid trying to use multibyte conversion functions and
- * assume everything is 1-byte per character
- */
-static gboolean gdk_use_mb;
-
/*
*--------------------------------------------------------------
* gdk_set_locale
@@ -59,22 +53,13 @@ static gboolean gdk_use_mb;
gchar*
gdk_set_locale (void)
{
- wchar_t result;
gchar *current_locale;
- gdk_use_mb = FALSE;
-
if (!setlocale (LC_ALL,""))
g_warning ("locale not supported by C library");
current_locale = setlocale (LC_ALL, NULL);
- if (MB_CUR_MAX > 1)
- gdk_use_mb = TRUE;
-
- GDK_NOTE (XIM, g_message ("%s multi-byte string functions.",
- gdk_use_mb ? "Using" : "Not using"));
-
return current_locale;
}
@@ -158,50 +143,91 @@ gdk_ic_get_events (GdkIC *ic)
* of wide characters. The string is newly allocated. The array of
* wide characters must be null-terminated. If the conversion is
* failed, it returns NULL.
+ *
+ * On Win32, we always use UTF-8.
*/
gchar *
gdk_wcstombs (const GdkWChar *src)
{
- gchar *mbstr;
+ gint len;
+ const GdkWChar *wcp;
+ guchar *mbstr, *bp;
- if (gdk_use_mb)
+ wcp = src;
+ len = 0;
+ while (*wcp)
{
- gint i, wcsl, mbsl;
- wchar_t *src_alt;
-
- for (wcsl = 0; src[wcsl]; wcsl++)
- ;
- src_alt = g_new (wchar_t, wcsl+1);
- for (i = wcsl; i >= 0; i--)
- src_alt[i] = src[i];
- mbsl = WideCharToMultiByte (CP_OEMCP, 0, src_alt, wcsl,
- NULL, 0, NULL, NULL);
- mbstr = g_new (guchar, mbsl + 1);
- if (!WideCharToMultiByte (CP_OEMCP, 0, src_alt, wcsl,
- mbstr, mbsl, NULL, NULL))
- {
- g_warning ("gdk_wcstombs: WideCharToMultiByte failed");
- g_free (mbstr);
- g_free (src_alt);
- return NULL;
- }
- mbstr[mbsl] = '\0';
- g_free (src_alt);
+ const GdkWChar c = *wcp++;
+
+ if (c < 0x80)
+ len += 1;
+ else if (c < 0x800)
+ len += 2;
+ else if (c < 0x10000)
+ len += 3;
+ else if (c < 0x200000)
+ len += 4;
+ else if (c < 0x4000000)
+ len += 5;
+ else
+ len += 6;
}
- else
+
+ mbstr = g_malloc (len + 1);
+
+ wcp = src;
+ bp = mbstr;
+ while (*wcp)
{
- gint length = 0;
- gint i;
+ int first;
+ int i;
+ GdkWChar c = *wcp++;
- while (src[length] != 0)
- length++;
+ if (c < 0x80)
+ {
+ first = 0;
+ len = 1;
+ }
+ else if (c < 0x800)
+ {
+ first = 0xc0;
+ len = 2;
+ }
+ else if (c < 0x10000)
+ {
+ first = 0xe0;
+ len = 3;
+ }
+ else if (c < 0x200000)
+ {
+ first = 0xf0;
+ len = 4;
+ }
+ else if (c < 0x4000000)
+ {
+ first = 0xf8;
+ len = 5;
+ }
+ else
+ {
+ first = 0xfc;
+ len = 6;
+ }
- mbstr = g_new (gchar, length + 1);
+ /* Woo-hoo! */
+ switch (len)
+ {
+ case 6: bp[5] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 5: bp[4] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 4: bp[3] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */
+ case 1: bp[0] = c | first;
+ }
- for (i=0; i<length+1; i++)
- mbstr[i] = src[i];
+ bp += len;
}
-
+ *bp = 0;
return mbstr;
}
@@ -209,41 +235,158 @@ gdk_wcstombs (const GdkWChar *src)
/*
* gdk_mbstowcs
*
- * Converts the specified string into wide characters, and, returns the
- * number of wide characters written. The string 'src' must be
- * null-terminated. If the conversion is failed, it returns -1.
+ * Converts the specified string into GDK wide characters, and,
+ * returns the number of wide characters written. The string 'src'
+ * must be null-terminated. If the conversion is failed, it returns
+ * -1.
+ *
+ * On Win32, thr string is assumed to be in UTF-8. Also note that
+ * GdkWChar is 32 bits, while wchar_t, and the wide characters the
+ * Windows API uses, are 16 bits!
*/
+
+/* First a helper function for not zero-terminated strings */
gint
-gdk_mbstowcs (GdkWChar *dest, const gchar *src, gint dest_max)
+gdk_nmbstowcs (GdkWChar *dest,
+ const gchar *src,
+ gint src_len,
+ gint dest_max)
{
- if (gdk_use_mb)
+ guchar *cp, *end;
+ gint n;
+
+ cp = (guchar *) src;
+ end = cp + src_len;
+ n = 0;
+ while (cp != end && dest != dest + dest_max)
{
- gint i, wcsl;
- wchar_t *wcstr;
+ gint i, mask = 0, len;
+ guchar c = *cp;
+
+ if (c < 0x80)
+ {
+ len = 1;
+ mask = 0x7f;
+ }
+ else if ((c & 0xe0) == 0xc0)
+ {
+ len = 2;
+ mask = 0x1f;
+ }
+ else if ((c & 0xf0) == 0xe0)
+ {
+ len = 3;
+ mask = 0x0f;
+ }
+ else if ((c & 0xf8) == 0xf0)
+ {
+ len = 4;
+ mask = 0x07;
+ }
+ else if ((c & 0xfc) == 0xf8)
+ {
+ len = 5;
+ mask = 0x03;
+ }
+ else if ((c & 0xfc) == 0xfc)
+ {
+ len = 6;
+ mask = 0x01;
+ }
+ else
+ return -1;
+
+ if (cp + len > end)
+ return -1;
- wcsl = MultiByteToWideChar (CP_OEMCP, 0, src, -1, NULL, 0);
- wcstr = g_new (wchar_t, wcsl);
- if (!MultiByteToWideChar (CP_OEMCP, 0, src, -1, wcstr, wcsl))
+ *dest = (cp[0] & mask);
+ for (i = 1; i < len; i++)
{
- g_warning ("gdk_mbstowcs: MultiByteToWideChar failed");
- g_free (wcstr);
- return -1;
+ if ((cp[i] & 0xc0) != 0x80)
+ return -1;
+ *dest <<= 6;
+ *dest |= (cp[i] & 0x3f);
}
- if (wcsl > dest_max)
- wcsl = dest_max;
- for (i = 0; i < wcsl && wcstr[i]; i++)
- dest[i] = wcstr[i];
- g_free (wcstr);
+ if (*dest == -1)
+ return -1;
- return i;
+ cp += len;
+ dest++;
+ n++;
}
- else
+ if (cp != end)
+ return -1;
+
+ return n;
+}
+
+gint
+gdk_mbstowcs (GdkWChar *dest,
+ const gchar *src,
+ gint dest_max)
+{
+ return gdk_nmbstowcs (dest, src, strlen (src), dest_max);
+}
+
+
+/* A version that converts to wchar_t wide chars */
+
+gint
+gdk_nmbstowchar_ts (wchar_t *dest,
+ const gchar *src,
+ gint src_len,
+ gint dest_max)
+{
+ guchar *cp, *end;
+ gint n;
+
+ cp = (guchar *) src;
+ end = cp + src_len;
+ n = 0;
+ while (cp != end && dest != dest + dest_max)
{
- gint i;
+ gint i, mask = 0, len;
+ guchar c = *cp;
+
+ if (c < 0x80)
+ {
+ len = 1;
+ mask = 0x7f;
+ }
+ else if ((c & 0xe0) == 0xc0)
+ {
+ len = 2;
+ mask = 0x1f;
+ }
+ else if ((c & 0xf0) == 0xe0)
+ {
+ len = 3;
+ mask = 0x0f;
+ }
+ else /* Other lengths are not possible with 16-bit wchar_t! */
+ return -1;
+
+ if (cp + len > end)
+ return -1;
- for (i=0; i<dest_max && src[i]; i++)
- dest[i] = src[i];
+ *dest = (cp[0] & mask);
+ for (i = 1; i < len; i++)
+ {
+ if ((cp[i] & 0xc0) != 0x80)
+ return -1;
+ *dest <<= 6;
+ *dest |= (cp[i] & 0x3f);
+ }
+ if (*dest == 0xFFFF)
+ return -1;
- return i;
+ cp += len;
+ dest++;
+ n++;
}
+ if (cp != end)
+ return -1;
+
+ return n;
}
+
diff --git a/gdk/win32/gdkinput-win32.c b/gdk/win32/gdkinput-win32.c
index 4a864c7eaa..2335e989c5 100644
--- a/gdk/win32/gdkinput-win32.c
+++ b/gdk/win32/gdkinput-win32.c
@@ -1006,7 +1006,7 @@ gdk_input_win32_other_event (GdkEvent *event,
#if USE_SYSCONTEXT
window = gdk_window_at_pointer (&x, &y);
if (window == NULL)
- window = (GdkWindow *) &gdk_root_parent;
+ window = (GdkWindow *) gdk_root_parent;
gdk_window_ref (window);
@@ -1036,7 +1036,7 @@ gdk_input_win32_other_event (GdkEvent *event,
switch (xevent->message)
{
case WT_PACKET:
- if (window_private == &gdk_root_parent)
+ if (window_private == gdk_root_parent)
{
GDK_NOTE (EVENTS, g_print ("...is root\n"));
return FALSE;
@@ -1104,7 +1104,7 @@ gdk_input_win32_other_event (GdkEvent *event,
{
GDK_NOTE (EVENTS, g_print ("...not selected\n"));
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
+ if (window_private->parent == (GdkWindow *) gdk_root_parent)
return FALSE;
pt.x = x;
diff --git a/gdk/win32/gdkinput.c b/gdk/win32/gdkinput.c
index 4a864c7eaa..2335e989c5 100644
--- a/gdk/win32/gdkinput.c
+++ b/gdk/win32/gdkinput.c
@@ -1006,7 +1006,7 @@ gdk_input_win32_other_event (GdkEvent *event,
#if USE_SYSCONTEXT
window = gdk_window_at_pointer (&x, &y);
if (window == NULL)
- window = (GdkWindow *) &gdk_root_parent;
+ window = (GdkWindow *) gdk_root_parent;
gdk_window_ref (window);
@@ -1036,7 +1036,7 @@ gdk_input_win32_other_event (GdkEvent *event,
switch (xevent->message)
{
case WT_PACKET:
- if (window_private == &gdk_root_parent)
+ if (window_private == gdk_root_parent)
{
GDK_NOTE (EVENTS, g_print ("...is root\n"));
return FALSE;
@@ -1104,7 +1104,7 @@ gdk_input_win32_other_event (GdkEvent *event,
{
GDK_NOTE (EVENTS, g_print ("...not selected\n"));
- if (window_private->parent == (GdkWindow *) &gdk_root_parent)
+ if (window_private->parent == (GdkWindow *) gdk_root_parent)
return FALSE;
pt.x = x;
diff --git a/gdk/win32/gdkmain-win32.c b/gdk/win32/gdkmain-win32.c
index 5a44835c5d..9e5cb9f0ca 100644
--- a/gdk/win32/gdkmain-win32.c
+++ b/gdk/win32/gdkmain-win32.c
@@ -38,11 +38,11 @@
#include "gdkinputprivate.h"
#include "gdkkeysyms.h"
+#include <objbase.h>
+
static void gdkx_XConvertCase (KeySym symbol,
KeySym *lower,
KeySym *upper);
-#define XConvertCase gdkx_XConvertCase
-
static void gdk_exit_func (void);
@@ -234,6 +234,9 @@ gdk_init_check (int *argc,
gdk_ProgInstance = GetModuleHandle (NULL);
gdk_DC = CreateDC ("DISPLAY", NULL, NULL, NULL);
+ gdk_root_window = GetDesktopWindow ();
+
+ CoInitialize (NULL);
gdk_selection_request_msg = RegisterWindowMessage ("gdk-selection-request");
gdk_selection_notify_msg = RegisterWindowMessage ("gdk-selection-notify");
@@ -247,8 +250,6 @@ gdk_init_check (int *argc,
gdk_progclass = g_basename (g_get_prgname ());
gdk_progclass[0] = toupper (gdk_progclass[0]);
- gdk_root_window = HWND_DESKTOP;
-
g_atexit (gdk_exit_func);
gdk_events_init ();
@@ -333,7 +334,7 @@ gdk_screen_width (void)
{
gint return_val;
- return_val = gdk_root_parent.drawable.width;
+ return_val = gdk_root_parent->drawable.width;
return return_val;
}
@@ -358,7 +359,7 @@ gdk_screen_height (void)
{
gint return_val;
- return_val = gdk_root_parent.drawable.height;
+ return_val = gdk_root_parent->drawable.height;
return return_val;
}
@@ -498,6 +499,9 @@ gdk_exit_func (void)
gdk_input_exit ();
gdk_key_repeat_restore ();
gdk_dnd_exit ();
+
+ CoUninitialize ();
+
DeleteDC (gdk_DC);
gdk_DC = NULL;
gdk_initialized = 0;
@@ -1670,6 +1674,22 @@ static struct gdk_key {
{ 0x000ef9, "Hangul_J_KkogjiDalrinIeung" },
{ 0x000efa, "Hangul_J_YeorinHieuh" },
{ 0x000eff, "Korean_Won" },
+ { 0x0013bc, "OE" },
+ { 0x0013bd, "oe" },
+ { 0x0013be, "Ydiaeresis" },
+ { 0x0020a0, "EcuSign" },
+ { 0x0020a1, "ColonSign" },
+ { 0x0020a2, "CruzeiroSign" },
+ { 0x0020a3, "FFrancSign" },
+ { 0x0020a4, "LiraSign" },
+ { 0x0020a5, "MillSign" },
+ { 0x0020a6, "NairaSign" },
+ { 0x0020a7, "PesetaSign" },
+ { 0x0020a8, "RupeeSign" },
+ { 0x0020a9, "WonSign" },
+ { 0x0020aa, "NewSheqelSign" },
+ { 0x0020ab, "DongSign" },
+ { 0x0020ac, "EuroSign" },
{ 0x00fd01, "3270_Duplicate" },
{ 0x00fd02, "3270_FieldMark" },
{ 0x00fd03, "3270_Right2" },
@@ -1826,11 +1846,21 @@ static struct gdk_key {
{ 0x00ff2e, "Kana_Shift" },
{ 0x00ff2f, "Eisu_Shift" },
{ 0x00ff30, "Eisu_toggle" },
+ { 0x00ff31, "Hangul" },
+ { 0x00ff32, "Hangul_Start" },
+ { 0x00ff33, "Hangul_End" },
+ { 0x00ff34, "Hangul_Hanja" },
+ { 0x00ff35, "Hangul_Jamo" },
+ { 0x00ff36, "Hangul_Romaja" },
+ { 0x00ff37, "Codeinput" },
+ { 0x00ff38, "Hangul_Jeonja" },
+ { 0x00ff39, "Hangul_Banja" },
+ { 0x00ff3a, "Hangul_PreHanja" },
+ { 0x00ff3b, "Hangul_PostHanja" },
{ 0x00ff3c, "SingleCandidate" },
{ 0x00ff3d, "MultipleCandidate" },
- { 0x00ff3d, "Zen_Koho" },
- { 0x00ff3e, "Mae_Koho" },
{ 0x00ff3e, "PreviousCandidate" },
+ { 0x00ff3f, "Hangul_Special" },
{ 0x00ff50, "Home" },
{ 0x00ff51, "Left" },
{ 0x00ff52, "Up" },
@@ -1949,21 +1979,6 @@ static struct gdk_key {
{ 0x00ffed, "Hyper_L" },
{ 0x00ffee, "Hyper_R" },
{ 0x00ffff, "Delete" },
- { 0x00ff31, "Hangul" },
- { 0x00ff32, "Hangul_Start" },
- { 0x00ff33, "Hangul_End" },
- { 0x00ff34, "Hangul_Hanja" },
- { 0x00ff35, "Hangul_Jamo" },
- { 0x00ff36, "Hangul_Romaja" },
- { 0x00ff37, "Hangul_Codeinput" },
- { 0x00ff38, "Hangul_Jeonja" },
- { 0x00ff39, "Hangul_Banja" },
- { 0x00ff3a, "Hangul_PreHanja" },
- { 0x00ff3b, "Hangul_PostHanja" },
- { 0x00ff3c, "Hangul_SingleCandidate" },
- { 0x00ff3d, "Hangul_MultipleCandidate" },
- { 0x00ff3e, "Hangul_PreviousCandidate" },
- { 0x00ff3f, "Hangul_Special" },
{ 0xffffff, "VoidSymbol" },
};
@@ -1985,7 +2000,7 @@ gdk_keyval_name (guint keyval)
GDK_NUM_KEYS, sizeof (struct gdk_key),
gdk_keys_keyval_compare);
if (found != NULL)
- return found->name;
+ return (gchar *) found->name;
else
return NULL;
}
@@ -2037,7 +2052,7 @@ gdk_keyval_to_upper (guint keyval)
KeySym lower_val = 0;
KeySym upper_val = 0;
- XConvertCase (keyval, &lower_val, &upper_val);
+ gdkx_XConvertCase (keyval, &lower_val, &upper_val);
return upper_val;
}
return 0;
@@ -2051,7 +2066,7 @@ gdk_keyval_to_lower (guint keyval)
KeySym lower_val = 0;
KeySym upper_val = 0;
- XConvertCase (keyval, &lower_val, &upper_val);
+ gdkx_XConvertCase (keyval, &lower_val, &upper_val);
return lower_val;
}
return 0;
@@ -2065,7 +2080,7 @@ gdk_keyval_is_upper (guint keyval)
KeySym lower_val = 0;
KeySym upper_val = 0;
- XConvertCase (keyval, &lower_val, &upper_val);
+ gdkx_XConvertCase (keyval, &lower_val, &upper_val);
return upper_val == keyval;
}
return TRUE;
@@ -2079,7 +2094,7 @@ gdk_keyval_is_lower (guint keyval)
KeySym lower_val = 0;
KeySym upper_val = 0;
- XConvertCase (keyval, &lower_val, &upper_val);
+ gdkx_XConvertCase (keyval, &lower_val, &upper_val);
return lower_val == keyval;
}
return TRUE;
diff --git a/gdk/win32/gdkpixmap-win32.c b/gdk/win32/gdkpixmap-win32.c
index 8e4e027813..a78fca9355 100644
--- a/gdk/win32/gdkpixmap-win32.c
+++ b/gdk/win32/gdkpixmap-win32.c
@@ -77,7 +77,7 @@ gdk_pixmap_new (GdkWindow *window,
g_return_val_if_fail ((width != 0) && (height != 0), NULL);
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = (GdkWindow*) gdk_root_parent;
if (GDK_DRAWABLE_DESTROYED (window))
return NULL;
@@ -287,7 +287,7 @@ gdk_bitmap_create_from_data (GdkWindow *window,
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = (GdkWindow*) gdk_root_parent;
if (GDK_DRAWABLE_DESTROYED (window))
return NULL;
@@ -616,7 +616,7 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
g_warning ("Creating pixmap from xpm with NULL window and colormap");
if (window == NULL)
- window = (GdkWindow *)&gdk_root_parent;
+ window = (GdkWindow *) gdk_root_parent;
if (colormap == NULL)
{
@@ -929,7 +929,7 @@ gdk_pixmap_foreign_new (guint32 anid)
/* set the pixmap to the passed in value */
xpixmap = (HBITMAP) anid;
/* get the root window */
- window_private = &gdk_root_parent;
+ window_private = gdk_root_parent;
/* get information about the BITMAP to fill in the structure for
the gdk window */
diff --git a/gdk/win32/gdkpixmap.c b/gdk/win32/gdkpixmap.c
index 8e4e027813..a78fca9355 100644
--- a/gdk/win32/gdkpixmap.c
+++ b/gdk/win32/gdkpixmap.c
@@ -77,7 +77,7 @@ gdk_pixmap_new (GdkWindow *window,
g_return_val_if_fail ((width != 0) && (height != 0), NULL);
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = (GdkWindow*) gdk_root_parent;
if (GDK_DRAWABLE_DESTROYED (window))
return NULL;
@@ -287,7 +287,7 @@ gdk_bitmap_create_from_data (GdkWindow *window,
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = (GdkWindow*) gdk_root_parent;
if (GDK_DRAWABLE_DESTROYED (window))
return NULL;
@@ -616,7 +616,7 @@ _gdk_pixmap_create_from_xpm (GdkWindow *window,
g_warning ("Creating pixmap from xpm with NULL window and colormap");
if (window == NULL)
- window = (GdkWindow *)&gdk_root_parent;
+ window = (GdkWindow *) gdk_root_parent;
if (colormap == NULL)
{
@@ -929,7 +929,7 @@ gdk_pixmap_foreign_new (guint32 anid)
/* set the pixmap to the passed in value */
xpixmap = (HBITMAP) anid;
/* get the root window */
- window_private = &gdk_root_parent;
+ window_private = gdk_root_parent;
/* get information about the BITMAP to fill in the structure for
the gdk window */
diff --git a/gdk/win32/gdkprivate-win32.h b/gdk/win32/gdkprivate-win32.h
index a45044d8e6..25ed2e071f 100644
--- a/gdk/win32/gdkprivate-win32.h
+++ b/gdk/win32/gdkprivate-win32.h
@@ -50,10 +50,8 @@
#define VIETNAMESE_CHARSET 163
#endif
-/* MB_CUR_MAX is missing */
-#ifndef MB_CUR_MAX
-extern int *__imp___mb_cur_max;
-#define MB_CUR_MAX (*__imp___mb_cur_max)
+#ifndef VM_OEM_PLUS
+#define VK_OEM_PLUS 0xBB
#endif
#include <time.h>
@@ -217,6 +215,9 @@ struct _GdkWindowPrivate
GList *filters;
GList *children;
+
+ HKL input_locale;
+ CHARSETINFO charset_info;
};
struct _GdkImagePrivate
@@ -304,6 +305,9 @@ struct _GdkVisualPrivate
struct _GdkFontPrivate
{
GdkFont font;
+ /* For now, both GDK_FONT_FONT and GDK_FONT_FONTSET fonts
+ * just have one Windows font loaded. This will change.
+ */
HFONT xfont;
guint ref_count;
@@ -382,6 +386,15 @@ void gdk_sel_prop_store (GdkWindow *owner,
void gdk_event_queue_append (GdkEvent *event);
+gint gdk_nmbstowcs (GdkWChar *dest,
+ const gchar *src,
+ gint src_len,
+ gint dest_max);
+gint gdk_nmbstowchar_ts (wchar_t *dest,
+ const gchar *src,
+ gint src_len,
+ gint dest_max);
+
/* Please see gdkwindow.c for comments on how to use */
HWND gdk_window_xid_at(HWND base, gint bx, gint by, gint x, gint y, GList *excludes, gboolean excl_child);
HWND gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child);
@@ -391,14 +404,12 @@ extern gint gdk_show_events;
extern gint gdk_stack_trace;
extern HWND gdk_root_window;
extern HWND gdk_leader_window;
-GDKVAR GdkWindowPrivate gdk_root_parent;
+GDKVAR GdkWindowPrivate *gdk_root_parent;
GDKVAR Atom gdk_selection_property;
-extern GdkWindow *selection_owner[];
GDKVAR gchar *gdk_progclass;
GDKVAR gint gdk_error_code;
GDKVAR gint gdk_error_warnings;
GDKVAR gint gdk_null_window_warnings;
-extern GList *gdk_default_filters;
extern gint gdk_event_func_from_window_proc;
extern HDC gdk_DC;
@@ -411,6 +422,7 @@ extern UINT gdk_selection_clear_msg;
extern GdkAtom gdk_clipboard_atom;
extern GdkAtom gdk_win32_dropfiles_atom;
extern GdkAtom gdk_ole2_dnd_atom;
+extern BOOL (WINAPI *p_TrackMouseEvent) (TRACKMOUSEEVENT *tme);
extern LRESULT CALLBACK gdk_WindowProc (HWND, UINT, WPARAM, LPARAM);
diff --git a/gdk/win32/gdkprivate.h b/gdk/win32/gdkprivate.h
index a45044d8e6..25ed2e071f 100644
--- a/gdk/win32/gdkprivate.h
+++ b/gdk/win32/gdkprivate.h
@@ -50,10 +50,8 @@
#define VIETNAMESE_CHARSET 163
#endif
-/* MB_CUR_MAX is missing */
-#ifndef MB_CUR_MAX
-extern int *__imp___mb_cur_max;
-#define MB_CUR_MAX (*__imp___mb_cur_max)
+#ifndef VM_OEM_PLUS
+#define VK_OEM_PLUS 0xBB
#endif
#include <time.h>
@@ -217,6 +215,9 @@ struct _GdkWindowPrivate
GList *filters;
GList *children;
+
+ HKL input_locale;
+ CHARSETINFO charset_info;
};
struct _GdkImagePrivate
@@ -304,6 +305,9 @@ struct _GdkVisualPrivate
struct _GdkFontPrivate
{
GdkFont font;
+ /* For now, both GDK_FONT_FONT and GDK_FONT_FONTSET fonts
+ * just have one Windows font loaded. This will change.
+ */
HFONT xfont;
guint ref_count;
@@ -382,6 +386,15 @@ void gdk_sel_prop_store (GdkWindow *owner,
void gdk_event_queue_append (GdkEvent *event);
+gint gdk_nmbstowcs (GdkWChar *dest,
+ const gchar *src,
+ gint src_len,
+ gint dest_max);
+gint gdk_nmbstowchar_ts (wchar_t *dest,
+ const gchar *src,
+ gint src_len,
+ gint dest_max);
+
/* Please see gdkwindow.c for comments on how to use */
HWND gdk_window_xid_at(HWND base, gint bx, gint by, gint x, gint y, GList *excludes, gboolean excl_child);
HWND gdk_window_xid_at_coords(gint x, gint y, GList *excludes, gboolean excl_child);
@@ -391,14 +404,12 @@ extern gint gdk_show_events;
extern gint gdk_stack_trace;
extern HWND gdk_root_window;
extern HWND gdk_leader_window;
-GDKVAR GdkWindowPrivate gdk_root_parent;
+GDKVAR GdkWindowPrivate *gdk_root_parent;
GDKVAR Atom gdk_selection_property;
-extern GdkWindow *selection_owner[];
GDKVAR gchar *gdk_progclass;
GDKVAR gint gdk_error_code;
GDKVAR gint gdk_error_warnings;
GDKVAR gint gdk_null_window_warnings;
-extern GList *gdk_default_filters;
extern gint gdk_event_func_from_window_proc;
extern HDC gdk_DC;
@@ -411,6 +422,7 @@ extern UINT gdk_selection_clear_msg;
extern GdkAtom gdk_clipboard_atom;
extern GdkAtom gdk_win32_dropfiles_atom;
extern GdkAtom gdk_ole2_dnd_atom;
+extern BOOL (WINAPI *p_TrackMouseEvent) (TRACKMOUSEEVENT *tme);
extern LRESULT CALLBACK gdk_WindowProc (HWND, UINT, WPARAM, LPARAM);
diff --git a/gdk/win32/gdkselection-win32.c b/gdk/win32/gdkselection-win32.c
index 782c39da25..0338672893 100644
--- a/gdk/win32/gdkselection-win32.c
+++ b/gdk/win32/gdkselection-win32.c
@@ -257,11 +257,11 @@ gdk_selection_convert (GdkWindow *requestor,
*/
GdkSelProp *prop;
- prop = g_hash_table_lookup (sel_prop_table, &gdk_root_parent.drawable.xwindow);
+ prop = g_hash_table_lookup (sel_prop_table, &gdk_root_parent->drawable.xwindow);
if (prop != NULL)
{
- g_hash_table_remove (sel_prop_table, &gdk_root_parent.drawable.xwindow);
+ g_hash_table_remove (sel_prop_table, &gdk_root_parent->drawable.xwindow);
gdk_sel_prop_store (requestor, prop->type, prop->format,
prop->data, prop->length);
g_free (prop);
diff --git a/gdk/win32/gdkselection.c b/gdk/win32/gdkselection.c
index 782c39da25..0338672893 100644
--- a/gdk/win32/gdkselection.c
+++ b/gdk/win32/gdkselection.c
@@ -257,11 +257,11 @@ gdk_selection_convert (GdkWindow *requestor,
*/
GdkSelProp *prop;
- prop = g_hash_table_lookup (sel_prop_table, &gdk_root_parent.drawable.xwindow);
+ prop = g_hash_table_lookup (sel_prop_table, &gdk_root_parent->drawable.xwindow);
if (prop != NULL)
{
- g_hash_table_remove (sel_prop_table, &gdk_root_parent.drawable.xwindow);
+ g_hash_table_remove (sel_prop_table, &gdk_root_parent->drawable.xwindow);
gdk_sel_prop_store (requestor, prop->type, prop->format,
prop->data, prop->length);
g_free (prop);
diff --git a/gdk/win32/gdkwin32.h b/gdk/win32/gdkwin32.h
index 7e8f8aded0..092765b89e 100644
--- a/gdk/win32/gdkwin32.h
+++ b/gdk/win32/gdkwin32.h
@@ -34,7 +34,7 @@
#include <locale.h>
#define GDK_ROOT_WINDOW() ((guint32) HWND_DESKTOP)
-#define GDK_ROOT_PARENT() ((GdkWindow *)&gdk_root_parent)
+#define GDK_ROOT_PARENT() ((GdkWindow *) gdk_root_parent)
#define GDK_DISPLAY() NULL
#define GDK_DRAWABLE_XDISPLAY(win) NULL
#define GDK_DRAWABLE_XID(win) (((GdkDrawablePrivate*) win)->xwindow)
diff --git a/gdk/win32/gdkwindow-win32.c b/gdk/win32/gdkwindow-win32.c
index d76694dbaa..0d2a5b056e 100644
--- a/gdk/win32/gdkwindow-win32.c
+++ b/gdk/win32/gdkwindow-win32.c
@@ -105,29 +105,25 @@ gdk_window_xid_at_coords (gint x,
void
gdk_window_init (void)
{
- unsigned int width;
- unsigned int height;
-#if 0
- width = GetSystemMetrics (SM_CXSCREEN);
- height = GetSystemMetrics (SM_CYSCREEN);
-#else
- { RECT r; /* //HB: don't obscure tray window (task bar) */
- SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
- width = r.right - r.left;
- height = r.bottom - r.top;
- }
-#endif
+ RECT r;
+ guint width;
+ guint height;
+
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+ width = r.right - r.left;
+ height = r.bottom - r.top;
- gdk_root_parent.drawable.xwindow = gdk_root_window;
- gdk_root_parent.drawable.window_type = GDK_WINDOW_ROOT;
- gdk_root_parent.drawable.drawable.user_data = NULL;
- gdk_root_parent.drawable.width = width;
- gdk_root_parent.drawable.height = height;
- gdk_root_parent.drawable.ref_count = 1;
- gdk_root_parent.drawable.colormap = NULL;
- gdk_root_parent.children = NULL;
+ gdk_root_parent = g_new (GdkWindowPrivate, 1);
+ gdk_root_parent->drawable.xwindow = gdk_root_window;
+ gdk_root_parent->drawable.window_type = GDK_WINDOW_ROOT;
+ gdk_root_parent->drawable.drawable.user_data = NULL;
+ gdk_root_parent->drawable.width = width;
+ gdk_root_parent->drawable.height = height;
+ gdk_root_parent->drawable.ref_count = 1;
+ gdk_root_parent->drawable.colormap = NULL;
+ gdk_root_parent->children = NULL;
- gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
+ gdk_xid_table_insert (&gdk_root_window, gdk_root_parent);
}
/* RegisterGdkClass
@@ -258,14 +254,19 @@ gdk_window_new (GdkWindow *parent,
ATOM klass = 0;
DWORD dwStyle, dwExStyle;
RECT rect;
+ UINT acp;
int width, height;
int x, y;
char *title;
+ gint titlelen;
+ wchar_t *wctitle;
+ gint wlen;
+ char *mbtitle;
g_return_val_if_fail (attributes != NULL, NULL);
if (!parent)
- parent = (GdkWindow*) &gdk_root_parent;
+ parent = (GdkWindow*) gdk_root_parent;
parent_private = (GdkWindowPrivate*) parent;
if (GDK_DRAWABLE_DESTROYED (parent))
@@ -413,10 +414,23 @@ gdk_window_new (GdkWindow *parent,
height = private->drawable.height;
}
+ acp = GetACP ();
+ private->input_locale = GetKeyboardLayout (0);
+ TranslateCharsetInfo ((DWORD FAR *) acp,
+ &private->charset_info,
+ TCI_SRCCODEPAGE);
+
+ titlelen = strlen (title);
+ wctitle = g_new (wchar_t, titlelen);
+ mbtitle = g_new (char, 3*titlelen + 1);
+ wlen = gdk_nmbstowchar_ts (wctitle, title, titlelen, titlelen);
+ WideCharToMultiByte (GetACP (), 0, wctitle, wlen,
+ mbtitle, 3*titlelen, NULL, NULL);
+
private->drawable.xwindow =
CreateWindowEx (dwExStyle,
MAKEINTRESOURCE(klass),
- title,
+ mbtitle,
dwStyle,
x, y,
width, height,
@@ -424,19 +438,31 @@ gdk_window_new (GdkWindow *parent,
NULL,
gdk_ProgInstance,
NULL);
+
+ g_free (mbtitle);
+ g_free (wctitle);
+
+ if (private->drawable.xwindow == NULL)
+ {
+ g_warning ("gdk_window_create: CreateWindowEx failed");
+ g_free (private);
+ return NULL;
+ }
+
GDK_NOTE (MISC,
- g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
+ g_print ("gdk_window_create: %s %s %dx%d@+%d+%d %#x = %#x\n"
+ "...locale %#x codepage %d\n",
(private->drawable.window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
(private->drawable.window_type == GDK_WINDOW_CHILD ? "CHILD" :
(private->drawable.window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
(private->drawable.window_type == GDK_WINDOW_TEMP ? "TEMP" :
"???")))),
title,
- dwStyle,
- private->event_mask,
width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
xparent,
- private->drawable.xwindow));
+ private->drawable.xwindow,
+ private->input_locale,
+ private->charset_info.ciACP));
gdk_window_ref (window);
gdk_xid_table_insert (&private->drawable.xwindow, window);
@@ -477,7 +503,7 @@ gdk_window_foreign_new (guint32 anid)
point.x = rect.left;
point.y = rect.right;
ClientToScreen ((HWND) anid, &point);
- if (parent != HWND_DESKTOP)
+ if (parent != GetDesktopWindow ())
ScreenToClient (parent, &point);
private->x = point.x;
private->y = point.y;
@@ -727,6 +753,7 @@ gdk_window_show (GdkWindow *window)
ShowWindow (private->drawable.xwindow, SW_SHOWNORMAL);
ShowWindow (private->drawable.xwindow, SW_RESTORE);
SetForegroundWindow (private->drawable.xwindow);
+ BringWindowToTop (private->drawable.xwindow);
#if 0
ShowOwnedPopups (private->drawable.xwindow, TRUE);
#endif
@@ -991,7 +1018,7 @@ gdk_window_reparent (GdkWindow *window,
g_return_if_fail (window != NULL);
if (!new_parent)
- new_parent = (GdkWindow*) &gdk_root_parent;
+ new_parent = (GdkWindow*) gdk_root_parent;
window_private = (GdkWindowPrivate*) window;
old_parent_private = (GdkWindowPrivate*)window_private->parent;
@@ -1370,6 +1397,11 @@ void
gdk_window_set_title (GdkWindow *window,
const gchar *title)
{
+ gint titlelen;
+ wchar_t *wcstr;
+ gint wlen;
+ char *mbstr;
+
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
@@ -1377,8 +1409,21 @@ gdk_window_set_title (GdkWindow *window,
GDK_DRAWABLE_XID (window), title));
if (!GDK_DRAWABLE_DESTROYED (window))
{
- if (!SetWindowText (GDK_DRAWABLE_XID (window), title))
+ /* As the title most is in UTF-8 we must translate it
+ * to the system codepage.
+ */
+ titlelen = strlen (title);
+ wcstr = g_new (wchar_t, titlelen);
+ mbstr = g_new (char, 3*titlelen + 1);
+ wlen = gdk_nmbstowchar_ts (wcstr, title, titlelen, titlelen);
+ WideCharToMultiByte (GetACP (), 0, wcstr, wlen,
+ mbstr, 3*titlelen, NULL, NULL);
+
+ if (!SetWindowText (GDK_DRAWABLE_XID (window), mbstr))
g_warning ("gdk_window_set_title: SetWindowText failed");
+
+ g_free (mbstr);
+ g_free (wcstr);
}
}
@@ -1527,7 +1572,7 @@ gdk_window_get_geometry (GdkWindow *window,
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = (GdkWindow*) gdk_root_parent;
if (!GDK_DRAWABLE_DESTROYED (window))
{
@@ -1660,7 +1705,7 @@ gdk_window_get_pointer (GdkWindow *window,
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = (GdkWindow*) gdk_root_parent;
return_val = NULL;
GetCursorPos (&pointc);
@@ -1724,7 +1769,7 @@ gdk_window_at_pointer (gint *win_x,
if (hwnd == NULL)
{
- window = (GdkWindow *) &gdk_root_parent;
+ window = (GdkWindow *) gdk_root_parent;
if (win_x)
*win_x = pointc.x;
if (win_y)
@@ -1902,10 +1947,7 @@ gdk_window_add_filter (GdkWindow *window,
if (private && GDK_DRAWABLE_DESTROYED (window))
return;
- if (private)
- tmp_list = private->filters;
- else
- tmp_list = gdk_default_filters;
+ tmp_list = private->filters;
while (tmp_list)
{
@@ -1919,10 +1961,7 @@ gdk_window_add_filter (GdkWindow *window,
filter->function = function;
filter->data = data;
- if (private)
- private->filters = g_list_append (private->filters, filter);
- else
- gdk_default_filters = g_list_append (gdk_default_filters, filter);
+ private->filters = g_list_append (private->filters, filter);
}
void
@@ -1939,10 +1978,7 @@ gdk_window_remove_filter (GdkWindow *window,
private = (GdkWindowPrivate*) window;
- if (private)
- tmp_list = private->filters;
- else
- tmp_list = gdk_default_filters;
+ tmp_list = private->filters;
while (tmp_list)
{
@@ -1952,10 +1988,8 @@ gdk_window_remove_filter (GdkWindow *window,
if ((filter->function == function) && (filter->data == data))
{
- if (private)
- private->filters = g_list_remove_link (private->filters, node);
- else
- gdk_default_filters = g_list_remove_link (gdk_default_filters, node);
+ private->filters = g_list_remove_link (private->filters, node);
+
g_list_free_1 (node);
g_free (filter);
@@ -2091,7 +2125,7 @@ gdk_window_get_toplevels (void)
GList *new_list = NULL;
GList *tmp_list;
- tmp_list = gdk_root_parent.children;
+ tmp_list = gdk_root_parent->children;
while (tmp_list)
{
new_list = g_list_prepend (new_list, tmp_list->data);
@@ -2244,7 +2278,7 @@ gdk_window_is_viewable (GdkWindow *window)
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
while (private &&
- (private != &gdk_root_parent) &&
+ (private != gdk_root_parent) &&
(private->drawable.window_type != GDK_WINDOW_FOREIGN))
{
if (!private->mapped)
diff --git a/gdk/win32/gdkwindow.c b/gdk/win32/gdkwindow.c
index d76694dbaa..0d2a5b056e 100644
--- a/gdk/win32/gdkwindow.c
+++ b/gdk/win32/gdkwindow.c
@@ -105,29 +105,25 @@ gdk_window_xid_at_coords (gint x,
void
gdk_window_init (void)
{
- unsigned int width;
- unsigned int height;
-#if 0
- width = GetSystemMetrics (SM_CXSCREEN);
- height = GetSystemMetrics (SM_CYSCREEN);
-#else
- { RECT r; /* //HB: don't obscure tray window (task bar) */
- SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
- width = r.right - r.left;
- height = r.bottom - r.top;
- }
-#endif
+ RECT r;
+ guint width;
+ guint height;
+
+ SystemParametersInfo(SPI_GETWORKAREA, 0, &r, 0);
+ width = r.right - r.left;
+ height = r.bottom - r.top;
- gdk_root_parent.drawable.xwindow = gdk_root_window;
- gdk_root_parent.drawable.window_type = GDK_WINDOW_ROOT;
- gdk_root_parent.drawable.drawable.user_data = NULL;
- gdk_root_parent.drawable.width = width;
- gdk_root_parent.drawable.height = height;
- gdk_root_parent.drawable.ref_count = 1;
- gdk_root_parent.drawable.colormap = NULL;
- gdk_root_parent.children = NULL;
+ gdk_root_parent = g_new (GdkWindowPrivate, 1);
+ gdk_root_parent->drawable.xwindow = gdk_root_window;
+ gdk_root_parent->drawable.window_type = GDK_WINDOW_ROOT;
+ gdk_root_parent->drawable.drawable.user_data = NULL;
+ gdk_root_parent->drawable.width = width;
+ gdk_root_parent->drawable.height = height;
+ gdk_root_parent->drawable.ref_count = 1;
+ gdk_root_parent->drawable.colormap = NULL;
+ gdk_root_parent->children = NULL;
- gdk_xid_table_insert (&gdk_root_window, &gdk_root_parent);
+ gdk_xid_table_insert (&gdk_root_window, gdk_root_parent);
}
/* RegisterGdkClass
@@ -258,14 +254,19 @@ gdk_window_new (GdkWindow *parent,
ATOM klass = 0;
DWORD dwStyle, dwExStyle;
RECT rect;
+ UINT acp;
int width, height;
int x, y;
char *title;
+ gint titlelen;
+ wchar_t *wctitle;
+ gint wlen;
+ char *mbtitle;
g_return_val_if_fail (attributes != NULL, NULL);
if (!parent)
- parent = (GdkWindow*) &gdk_root_parent;
+ parent = (GdkWindow*) gdk_root_parent;
parent_private = (GdkWindowPrivate*) parent;
if (GDK_DRAWABLE_DESTROYED (parent))
@@ -413,10 +414,23 @@ gdk_window_new (GdkWindow *parent,
height = private->drawable.height;
}
+ acp = GetACP ();
+ private->input_locale = GetKeyboardLayout (0);
+ TranslateCharsetInfo ((DWORD FAR *) acp,
+ &private->charset_info,
+ TCI_SRCCODEPAGE);
+
+ titlelen = strlen (title);
+ wctitle = g_new (wchar_t, titlelen);
+ mbtitle = g_new (char, 3*titlelen + 1);
+ wlen = gdk_nmbstowchar_ts (wctitle, title, titlelen, titlelen);
+ WideCharToMultiByte (GetACP (), 0, wctitle, wlen,
+ mbtitle, 3*titlelen, NULL, NULL);
+
private->drawable.xwindow =
CreateWindowEx (dwExStyle,
MAKEINTRESOURCE(klass),
- title,
+ mbtitle,
dwStyle,
x, y,
width, height,
@@ -424,19 +438,31 @@ gdk_window_new (GdkWindow *parent,
NULL,
gdk_ProgInstance,
NULL);
+
+ g_free (mbtitle);
+ g_free (wctitle);
+
+ if (private->drawable.xwindow == NULL)
+ {
+ g_warning ("gdk_window_create: CreateWindowEx failed");
+ g_free (private);
+ return NULL;
+ }
+
GDK_NOTE (MISC,
- g_print ("gdk_window_create: %s %s %#x %#x %dx%d@+%d+%d %#x = %#x\n",
+ g_print ("gdk_window_create: %s %s %dx%d@+%d+%d %#x = %#x\n"
+ "...locale %#x codepage %d\n",
(private->drawable.window_type == GDK_WINDOW_TOPLEVEL ? "TOPLEVEL" :
(private->drawable.window_type == GDK_WINDOW_CHILD ? "CHILD" :
(private->drawable.window_type == GDK_WINDOW_DIALOG ? "DIALOG" :
(private->drawable.window_type == GDK_WINDOW_TEMP ? "TEMP" :
"???")))),
title,
- dwStyle,
- private->event_mask,
width, height, (x == CW_USEDEFAULT ? -9999 : x), y,
xparent,
- private->drawable.xwindow));
+ private->drawable.xwindow,
+ private->input_locale,
+ private->charset_info.ciACP));
gdk_window_ref (window);
gdk_xid_table_insert (&private->drawable.xwindow, window);
@@ -477,7 +503,7 @@ gdk_window_foreign_new (guint32 anid)
point.x = rect.left;
point.y = rect.right;
ClientToScreen ((HWND) anid, &point);
- if (parent != HWND_DESKTOP)
+ if (parent != GetDesktopWindow ())
ScreenToClient (parent, &point);
private->x = point.x;
private->y = point.y;
@@ -727,6 +753,7 @@ gdk_window_show (GdkWindow *window)
ShowWindow (private->drawable.xwindow, SW_SHOWNORMAL);
ShowWindow (private->drawable.xwindow, SW_RESTORE);
SetForegroundWindow (private->drawable.xwindow);
+ BringWindowToTop (private->drawable.xwindow);
#if 0
ShowOwnedPopups (private->drawable.xwindow, TRUE);
#endif
@@ -991,7 +1018,7 @@ gdk_window_reparent (GdkWindow *window,
g_return_if_fail (window != NULL);
if (!new_parent)
- new_parent = (GdkWindow*) &gdk_root_parent;
+ new_parent = (GdkWindow*) gdk_root_parent;
window_private = (GdkWindowPrivate*) window;
old_parent_private = (GdkWindowPrivate*)window_private->parent;
@@ -1370,6 +1397,11 @@ void
gdk_window_set_title (GdkWindow *window,
const gchar *title)
{
+ gint titlelen;
+ wchar_t *wcstr;
+ gint wlen;
+ char *mbstr;
+
g_return_if_fail (window != NULL);
g_return_if_fail (GDK_IS_WINDOW (window));
@@ -1377,8 +1409,21 @@ gdk_window_set_title (GdkWindow *window,
GDK_DRAWABLE_XID (window), title));
if (!GDK_DRAWABLE_DESTROYED (window))
{
- if (!SetWindowText (GDK_DRAWABLE_XID (window), title))
+ /* As the title most is in UTF-8 we must translate it
+ * to the system codepage.
+ */
+ titlelen = strlen (title);
+ wcstr = g_new (wchar_t, titlelen);
+ mbstr = g_new (char, 3*titlelen + 1);
+ wlen = gdk_nmbstowchar_ts (wcstr, title, titlelen, titlelen);
+ WideCharToMultiByte (GetACP (), 0, wcstr, wlen,
+ mbstr, 3*titlelen, NULL, NULL);
+
+ if (!SetWindowText (GDK_DRAWABLE_XID (window), mbstr))
g_warning ("gdk_window_set_title: SetWindowText failed");
+
+ g_free (mbstr);
+ g_free (wcstr);
}
}
@@ -1527,7 +1572,7 @@ gdk_window_get_geometry (GdkWindow *window,
g_return_if_fail (window == NULL || GDK_IS_WINDOW (window));
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = (GdkWindow*) gdk_root_parent;
if (!GDK_DRAWABLE_DESTROYED (window))
{
@@ -1660,7 +1705,7 @@ gdk_window_get_pointer (GdkWindow *window,
g_return_val_if_fail (window == NULL || GDK_IS_WINDOW (window), NULL);
if (!window)
- window = (GdkWindow*) &gdk_root_parent;
+ window = (GdkWindow*) gdk_root_parent;
return_val = NULL;
GetCursorPos (&pointc);
@@ -1724,7 +1769,7 @@ gdk_window_at_pointer (gint *win_x,
if (hwnd == NULL)
{
- window = (GdkWindow *) &gdk_root_parent;
+ window = (GdkWindow *) gdk_root_parent;
if (win_x)
*win_x = pointc.x;
if (win_y)
@@ -1902,10 +1947,7 @@ gdk_window_add_filter (GdkWindow *window,
if (private && GDK_DRAWABLE_DESTROYED (window))
return;
- if (private)
- tmp_list = private->filters;
- else
- tmp_list = gdk_default_filters;
+ tmp_list = private->filters;
while (tmp_list)
{
@@ -1919,10 +1961,7 @@ gdk_window_add_filter (GdkWindow *window,
filter->function = function;
filter->data = data;
- if (private)
- private->filters = g_list_append (private->filters, filter);
- else
- gdk_default_filters = g_list_append (gdk_default_filters, filter);
+ private->filters = g_list_append (private->filters, filter);
}
void
@@ -1939,10 +1978,7 @@ gdk_window_remove_filter (GdkWindow *window,
private = (GdkWindowPrivate*) window;
- if (private)
- tmp_list = private->filters;
- else
- tmp_list = gdk_default_filters;
+ tmp_list = private->filters;
while (tmp_list)
{
@@ -1952,10 +1988,8 @@ gdk_window_remove_filter (GdkWindow *window,
if ((filter->function == function) && (filter->data == data))
{
- if (private)
- private->filters = g_list_remove_link (private->filters, node);
- else
- gdk_default_filters = g_list_remove_link (gdk_default_filters, node);
+ private->filters = g_list_remove_link (private->filters, node);
+
g_list_free_1 (node);
g_free (filter);
@@ -2091,7 +2125,7 @@ gdk_window_get_toplevels (void)
GList *new_list = NULL;
GList *tmp_list;
- tmp_list = gdk_root_parent.children;
+ tmp_list = gdk_root_parent->children;
while (tmp_list)
{
new_list = g_list_prepend (new_list, tmp_list->data);
@@ -2244,7 +2278,7 @@ gdk_window_is_viewable (GdkWindow *window)
g_return_val_if_fail (GDK_IS_WINDOW (window), FALSE);
while (private &&
- (private != &gdk_root_parent) &&
+ (private != gdk_root_parent) &&
(private->drawable.window_type != GDK_WINDOW_FOREIGN))
{
if (!private->mapped)
diff --git a/gdk/win32/gdkx.h b/gdk/win32/gdkx.h
index 7e8f8aded0..092765b89e 100644
--- a/gdk/win32/gdkx.h
+++ b/gdk/win32/gdkx.h
@@ -34,7 +34,7 @@
#include <locale.h>
#define GDK_ROOT_WINDOW() ((guint32) HWND_DESKTOP)
-#define GDK_ROOT_PARENT() ((GdkWindow *)&gdk_root_parent)
+#define GDK_ROOT_PARENT() ((GdkWindow *) gdk_root_parent)
#define GDK_DISPLAY() NULL
#define GDK_DRAWABLE_XDISPLAY(win) NULL
#define GDK_DRAWABLE_XID(win) (((GdkDrawablePrivate*) win)->xwindow)
diff --git a/gdk/win32/makefile.cygwin b/gdk/win32/makefile.cygwin
index 77429ca2e8..e067af15c6 100644
--- a/gdk/win32/makefile.cygwin
+++ b/gdk/win32/makefile.cygwin
@@ -88,7 +88,7 @@ gdkres.o : rc/gdk.rc
windres --include-dir rc rc/gdk.rc gdkres.o
gdk-$(GTK_VER).dll : $(gdk_OBJECTS) gdk.def gdkres.o libwntab32x.a
- $(GLIB)/build-dll gdk $(GTK_VER) gdk.def $(gdk_OBJECTS) -L $(GLIB) -lglib-$(GLIB_VER) -L . -lwntab32x -lgdi32 -luser32 -lshell32 -lole32 -luuid $(LDFLAGS) gdkres.o
+ $(GLIB)/build-dll gdk $(GTK_VER) gdk.def $(gdk_OBJECTS) -L $(GLIB) -lglib-$(GLIB_VER) -L . -lwntab32x -lgdi32 -luser32 -limm32 -lshell32 -lole32 -luuid $(LDFLAGS) gdkres.o
libwntab32x.a : $(WTKIT)/lib/i386/wntab32x.lib
cp $(WTKIT)/lib/i386/wntab32x.lib libwntab32x.a
diff --git a/gdk/win32/surrogate-dimm.h b/gdk/win32/surrogate-dimm.h
new file mode 100644
index 0000000000..3cc50be34c
--- /dev/null
+++ b/gdk/win32/surrogate-dimm.h
@@ -0,0 +1,144 @@
+#ifndef __SURROGATE_DIMM_H__
+#define __SURROGATE_DIMM_H__
+
+/* The Win32api headers doesn't include <dimm.h>, thus we need
+ * this file, which coverr just the stuff we need from <dimm.h>.
+ */
+
+typedef struct IActiveIMMApp IActiveIMMApp;
+typedef struct IActiveIMMMessagePumpOwner IActiveIMMMessagePumpOwner;
+
+/* Dummy vtable structs that contain real names and prototypes for
+ * only those methods we need.
+ */
+typedef struct {
+ HRESULT (__stdcall *QueryInterface) (IActiveIMMApp *This,
+ REFIID riid,
+ void *ppvObject);
+ /* Dummy method prototypes for those we don't use */
+ ULONG (__stdcall *dummy_AddRef)();
+ ULONG (__stdcall *dummy_Release)();
+ HRESULT (__stdcall *dummy_AssociateContext)();
+ HRESULT (__stdcall *dummy_ConfigureIMEA)();
+ HRESULT (__stdcall *dummy_ConfigureIMEW)();
+ HRESULT (__stdcall *dummy_CreateContext)();
+ HRESULT (__stdcall *dummy_DestroyContext)();
+ HRESULT (__stdcall *dummy_EnumRegisterWordA)();
+ HRESULT (__stdcall *dummy_EnumRegisterWordW)();
+ HRESULT (__stdcall *dummy_EscapeA)();
+ HRESULT (__stdcall *dummy_EscapeW)();
+ HRESULT (__stdcall *dummy_GetCandidateListA)();
+ HRESULT (__stdcall *dummy_GetCandidateListW)();
+ HRESULT (__stdcall *dummy_GetCandidateListCountA)();
+ HRESULT (__stdcall *dummy_GetCandidateListCountW)();
+ HRESULT (__stdcall *dummy_GetCandidateWindow)();
+ HRESULT (__stdcall *dummy_GetCompositionFontA)();
+ HRESULT (__stdcall *dummy_GetCompositionFontW)();
+ HRESULT (__stdcall *dummy_GetCompositionStringA)();
+ HRESULT (__stdcall *dummy_GetCompositionStringW)();
+ HRESULT (__stdcall *dummy_GetCompositionWindow)();
+ HRESULT (__stdcall *dummy_GetContext)();
+ HRESULT (__stdcall *dummy_GetConversionListA)();
+ HRESULT (__stdcall *dummy_GetConversionListW)();
+ HRESULT (__stdcall *dummy_GetConversionStatus)();
+
+ HRESULT (__stdcall *GetDefaultIMEWnd)(IActiveIMMApp *This,
+ HWND hWnd,
+ HWND *phDefWnd);
+
+ HRESULT (__stdcall *dummy_GetDescriptionA)();
+ HRESULT (__stdcall *dummy_GetDescriptionW)();
+ HRESULT (__stdcall *dummy_GetGuideLineA)();
+ HRESULT (__stdcall *dummy_GetGuideLineW)();
+ HRESULT (__stdcall *dummy_GetIMEFileNameA)();
+ HRESULT (__stdcall *dummy_GetIMEFileNameW)();
+ HRESULT (__stdcall *dummy_GetOpenStatus)();
+ HRESULT (__stdcall *dummy_GetProperty)();
+ HRESULT (__stdcall *dummy_GetRegisterWordStyleA)();
+ HRESULT (__stdcall *dummy_GetRegisterWordStyleW)();
+ HRESULT (__stdcall *dummy_GetStatusWindowPos)();
+ HRESULT (__stdcall *dummy_GetVirtualKey)();
+ HRESULT (__stdcall *dummy_InstallIMEA)();
+ HRESULT (__stdcall *dummy_InstallIMEW)();
+
+ HRESULT (__stdcall *IsIME)(IActiveIMMApp *This,
+ HKL hKL);
+ HRESULT (__stdcall *IsUIMessageA )(IActiveIMMApp *This,
+ HWND hWndIME,
+ UINT msg,
+ WPARAM wParam,
+ LPARAM lParam);
+ HRESULT (__stdcall *dummy_IsUIMessageW)();
+ HRESULT (__stdcall *dummy_NotifyIME)();
+ HRESULT (__stdcall *dummy_RegisterWordA)();
+ HRESULT (__stdcall *dummy_RegisterWordW)();
+ HRESULT (__stdcall *dummy_ReleaseContext)();
+ HRESULT (__stdcall *dummy_SetCandidateWindow)();
+ HRESULT (__stdcall *dummy_SetCompositionFontA)();
+ HRESULT (__stdcall *dummy_SetCompositionFontW)();
+ HRESULT (__stdcall *dummy_SetCompositionStringA)();
+ HRESULT (__stdcall *dummy_SetCompositionStringW)();
+ HRESULT (__stdcall *dummy_SetCompositionWindow)();
+ HRESULT (__stdcall *dummy_SetConversionStatus)();
+ HRESULT (__stdcall *dummy_SetOpenStatus)();
+ HRESULT (__stdcall *dummy_SetStatusWindowPos)();
+ HRESULT (__stdcall *dummy_SimulateHotKey)();
+ HRESULT (__stdcall *dummy_UnregisterWordA)();
+ HRESULT (__stdcall *dummy_UnregisterWordW)();
+
+ HRESULT (__stdcall *Activate)(IActiveIMMApp *This,
+ BOOL restore);
+ HRESULT (__stdcall *Deactivate)(IActiveIMMApp *This);
+ HRESULT (__stdcall *OnDefWindowProc)(IActiveIMMApp *This,
+ HWND hWnd,
+ UINT Msg,
+ WPARAM wParam,
+ LPARAM lParam,
+ LRESULT *plResult);
+
+ HRESULT (__stdcall *dummy_FilterClientWindows)();
+
+ HRESULT (__stdcall *GetCodePageA)(IActiveIMMApp *This,
+ HKL hKL,
+ UINT *uCodePage);
+ HRESULT (__stdcall *GetLangId)(IActiveIMMApp *This,
+ HKL hKL,
+ LANGID *plid);
+
+ HRESULT (__stdcall *dummy_AssociateContextEx)();
+ HRESULT (__stdcall *dummy_DisableIME)();
+ HRESULT (__stdcall *dummy_GetImeMenuItemsA)();
+ HRESULT (__stdcall *dummy_GetImeMenuItemsW)();
+ HRESULT (__stdcall *dummy_EnumInputContext)();
+} IActiveIMMAppVtbl;
+
+struct IActiveIMMApp {
+ IActiveIMMAppVtbl *lpVtbl;
+};
+
+typedef struct {
+ HRESULT (__stdcall *dummy_QueryInterface)();
+ ULONG (__stdcall *dummy_AddRef)();
+ ULONG (__stdcall *dummy_Release)();
+
+ HRESULT (__stdcall *Start)(IActiveIMMMessagePumpOwner *This);
+ HRESULT (__stdcall *End)(IActiveIMMMessagePumpOwner *This);
+ HRESULT (__stdcall *OnTranslateMessage)(IActiveIMMMessagePumpOwner *This,
+ MSG *pMSG);
+
+ HRESULT (__stdcall *dummy_Pause)();
+ HRESULT (__stdcall *dummy_Resume)();
+} IActiveIMMMessagePumpOwnerVtbl;
+
+struct IActiveIMMMessagePumpOwner {
+ IActiveIMMMessagePumpOwnerVtbl *lpVtbl;
+};
+
+static UUID CLSID_CActiveIMM = {
+ 0x4955DD33, 0xB159, 0x11d0, { 0x8F,0xCF,0x00,0xAA,0x00,0x6B,0xCC,0x59 } };
+static IID IID_IActiveIMMApp = {
+ 0x08C0E040, 0x62D1, 0x11D1, { 0x93,0x26,0x00,0x60,0xB0,0x67,0xB8,0x6E } };
+static IID IID_IActiveIMMMessagePumpOwner = {
+ 0xB5CF2CFA, 0x8AEB, 0x11D1, { 0x93,0x64,0x00,0x60,0xB0,0x67,0xB8,0x6E } };
+
+#endif /* __SURROGATE_DIMM_H__ */