diff options
author | Tor Lillqvist <tml@iki.fi> | 1999-10-31 21:35:39 +0000 |
---|---|---|
committer | Tor Lillqvist <tml@src.gnome.org> | 1999-10-31 21:35:39 +0000 |
commit | 00c5e838710a01ed97a46d96910b6f118d240b99 (patch) | |
tree | 2d8a8d72f6e39231ed9fa72a09069025ff559f64 /gdk/win32/gdkevents.c | |
parent | 241f9c9dabdd3f021adb139b25a455260dc473ae (diff) | |
download | gdk-pixbuf-00c5e838710a01ed97a46d96910b6f118d240b99.tar.gz |
Add new keysyms from X11R6.4 (including EuroSign).
1999-10-31 Tor Lillqvist <tml@iki.fi>
* gdk/gdkkeysyms.h: Add new keysyms from X11R6.4 (including
EuroSign).
* gdk/gdktypes.h: Add note about wchar_t not necessarily being the
same type as GdkWChar, especially on Win32.
* gdk/win32/*.c: Change gdk_root_parent to be a pointer.
* gdk/win32/*.c: Assume all strings are UTF-8. Convert to Unicode
before passing to Windows GDI for drawing etc. Convert to the
system default codepage before passing to Windows as window
titles.
* gdk/win32/gdkprivate.h: Add more fields to GdkWindowPrivate to
support changing input locale on the fly.
* gdk/win32/gdkevent.c: Support input language (keyboard locale)
on-the-fly changes. Convert incoming characters from the current
codepage to Unicode (and then to a UTF-8 multi-byte string) based
on the current input language. Use keysym<->Unicode mapping tables
and functions borrowed from xterm sources.
Support IMEs (Input Method Editors) for CJK languages. On non-CJK
editions of Win9x, use the ActiveX-based Active IMM (Input Method
Manager) if available. IMEs and the Active IMM are available under
the disguise of Chinese, Korean and Japanese support for IE and
Outlook Express from "Windows Update" for Win98. On Win2k, the CJK
support is present in all editions (as long as you install it).
Call DispatchMessage from gdk_events_queue() (and thus
gdk_WindowProc()), instead of duplicating the code in
gdk_WindowProc().
Reworked the grab handling and propagation code, factored out
duplicated code snippets into separate functions. Other cleanups,
too.
* gdk/win32/surrogate-dimm.h: Provide just the bits we need from
the <dimm.h> header describing the Active IMM.
* gdk/win32/gdkfont.c: Pretend to support fontsets, but so far
just do the same as for "single" fonts.
* gdk/win32/gdk.c: Call CoInitialize() (COM initialisation) from
gdk_init_check, and CoUninitialize() from gdk_exit_func. Handle
the new keysyms from gdkkeysyms.h.
* gtk/gtkfontsel.c (Win32): Load the font for the preview as a
fontset, so that gtkentry uses wide characters.
* gtk/gtkrc.c (Win32): Get the locale with gwin_getlocale(). Call
GTk+'s system directory "gtk+", not "gtk".
Diffstat (limited to 'gdk/win32/gdkevents.c')
-rw-r--r-- | gdk/win32/gdkevents.c | 3336 |
1 files changed, 2710 insertions, 626 deletions
diff --git a/gdk/win32/gdkevents.c b/gdk/win32/gdkevents.c index 53097d20b..7ac816978 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 wth 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 wth 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 wth 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 wth 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 wth 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 wth 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(); |