diff options
Diffstat (limited to 'gdk/win32')
31 files changed, 6720 insertions, 2219 deletions
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__ */ |