diff options
Diffstat (limited to 'gdk/win32/gdkevents-win32.c')
-rw-r--r-- | gdk/win32/gdkevents-win32.c | 3336 |
1 files changed, 2710 insertions, 626 deletions
diff --git a/gdk/win32/gdkevents-win32.c b/gdk/win32/gdkevents-win32.c index 53097d20b7..7ac8169786 100644 --- a/gdk/win32/gdkevents-win32.c +++ b/gdk/win32/gdkevents-win32.c @@ -27,21 +27,47 @@ #include "config.h" +#define NEW_PROPAGATION_CODE + +#define USE_DISPATCHMESSAGE + +/* Cannot use TrackMouseEvent, as the stupid WM_MOUSELEAVE message + * doesn't tell us where the mouse has gone. Thus we cannot use it to + * generate a correct GdkNotifyType. Pity, as using TrackMouseEvent + * otherwise would make it possible to reliably generate + * GDK_LEAVE_NOTIFY events, which would help get rid of those pesky + * tooltips sometimes popping up in the wrong place. + */ +/* define USE_TRACKMOUSEEVENT */ + #include <stdio.h> +#include <windows.h> + +#ifdef HAVE_WINTAB +#include <wintab.h> +#endif + +#include <objbase.h> +#include <imm.h> + +#ifdef HAVE_DIMM_H +#include <dimm.h> +#else +#include "surrogate-dimm.h" +#endif + #include "gdk.h" -#include "gdkprivate.h" #include "gdkx.h" #include "gdkkeysyms.h" -#ifdef HAVE_WINTAB -#include <wintab.h> -#endif #include "gdkinputprivate.h" #define PING() printf("%s: %d\n",__FILE__,__LINE__),fflush(stdout) +#define WINDOW_PRIVATE(wp) ((GdkWindowPrivate *) (wp)) + typedef struct _GdkIOClosure GdkIOClosure; typedef struct _GdkEventPrivate GdkEventPrivate; @@ -80,10 +106,10 @@ struct _GdkEventPrivate static GdkEvent *gdk_event_new (void); static GdkFilterReturn - gdk_event_apply_filters (MSG *xevent, + gdk_event_apply_filters(MSG *xevent, GdkEvent *event, GList *filters); -static gint gdk_event_translate (GdkEvent *event, +static gboolean gdk_event_translate (GdkEvent *event, MSG *xevent, gboolean *ret_val_flagp, gint *ret_valp); @@ -125,7 +151,7 @@ static GdkWindow *k_grab_window = NULL; /* Window the holds the static GList *client_filters; /* Filters for client messages */ static gboolean p_grab_automatic; -static GdkEventMask p_grab_event_mask; +static GdkEventMask p_grab_mask; static gboolean p_grab_owner_events, k_grab_owner_events; static HCURSOR p_grab_cursor; @@ -158,22 +184,26 @@ static UINT gdk_ping_msg; static gboolean ignore_WM_CHAR = FALSE; static gboolean is_AltGr_key = FALSE; +static IActiveIMMApp *paimmapp = NULL; +static IActiveIMMMessagePumpOwner *paimmmpo = NULL; + LRESULT CALLBACK -gdk_WindowProc(HWND hwnd, - UINT message, - WPARAM wParam, - LPARAM lParam) +gdk_WindowProc (HWND hWnd, + UINT message, + WPARAM wParam, + LPARAM lParam) { GdkEvent event; GdkEvent *eventp; MSG msg; DWORD pos; + LRESULT lres; gint ret_val; gboolean ret_val_flag; - GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x\n", message)); + GDK_NOTE (EVENTS, g_print ("gdk_WindowProc: %#x %#.03x\n", hWnd, message)); - msg.hwnd = hwnd; + msg.hwnd = hWnd; msg.message = message; msg.wParam = wParam; msg.lParam = lParam; @@ -182,12 +212,14 @@ gdk_WindowProc(HWND hwnd, msg.pt.x = LOWORD (pos); msg.pt.y = HIWORD (pos); + ((GdkEventPrivate *)&event)->flags |= GDK_EVENT_PENDING; if (gdk_event_translate (&event, &msg, &ret_val_flag, &ret_val)) { + ((GdkEventPrivate *)&event)->flags &= ~GDK_EVENT_PENDING; #if 1 - /* Compress configure events */ if (event.any.type == GDK_CONFIGURE) { + /* Compress configure events */ GList *list = queued_events; while (list != NULL @@ -203,6 +235,29 @@ gdk_WindowProc(HWND hwnd, return FALSE; } } + else if (event.any.type == GDK_EXPOSE) + { + /* Compress expose events */ + GList *list = queued_events; + + while (list != NULL + && (((GdkEvent *)list->data)->any.type != GDK_EXPOSE + || ((GdkEvent *)list->data)->any.window != event.any.window)) + list = list->next; + if (list != NULL) + { + GdkRectangle u; + + gdk_rectangle_union (&event.expose.area, + &((GdkEvent *)list->data)->expose.area, + &u); + ((GdkEvent *)list->data)->expose.area = u; + gdk_window_unref (event.any.window); + /* Wake up WaitMessage */ + PostMessage (NULL, gdk_ping_msg, 0, 0); + return FALSE; + } + } #endif eventp = gdk_event_new (); *eventp = event; @@ -240,7 +295,13 @@ gdk_WindowProc(HWND hwnd, if (ret_val_flag) return ret_val; else - return DefWindowProc (hwnd, message, wParam, lParam); + { + if (paimmapp == NULL + || (*paimmapp->lpVtbl->OnDefWindowProc) (paimmapp, hWnd, message, wParam, lParam, &lres) == S_FALSE) + return DefWindowProc (hWnd, message, wParam, lParam); + else + return lres; + } } /********************************************* @@ -319,8 +380,18 @@ gdk_event_queue_append (GdkEvent *event) void gdk_events_init (void) { + HRESULT hres; + HMODULE user32; + HINSTANCE commctrl32; + if (g_pipe_readable_msg == 0) g_pipe_readable_msg = RegisterWindowMessage ("g-pipe-readable"); + GDK_NOTE (EVENTS, g_print ("g-pipe-readable = %#.03x\n", + g_pipe_readable_msg)); + + gdk_ping_msg = RegisterWindowMessage ("gdk-ping"); + GDK_NOTE (EVENTS, g_print ("gdk-ping = %#.03x\n", + gdk_ping_msg)); g_source_add (GDK_PRIORITY_EVENTS, TRUE, &event_funcs, NULL, NULL, NULL); @@ -336,7 +407,34 @@ gdk_events_init (void) button_number[0] = -1; button_number[1] = -1; - gdk_ping_msg = RegisterWindowMessage ("gdk-ping"); + hres = CoCreateInstance (&CLSID_CActiveIMM, + NULL, + CLSCTX_ALL, + &IID_IActiveIMMApp, + (LPVOID *) &paimmapp); + + if (hres == S_OK) + { + GDK_NOTE (EVENTS, g_print ("IActiveIMMApp created %#x\n", + paimmapp)); + (*paimmapp->lpVtbl->Activate) (paimmapp, TRUE); + + hres = (*paimmapp->lpVtbl->QueryInterface) (paimmapp, &IID_IActiveIMMMessagePumpOwner, &paimmmpo); + GDK_NOTE (EVENTS, g_print ("IActiveIMMMessagePumpOwner created %#x\n", + paimmmpo)); + (paimmmpo->lpVtbl->Start) (paimmmpo); + } + +#ifdef USE_TRACKMOUSEEVENT + user32 = GetModuleHandle ("user32.dll"); + if ((p_TrackMouseEvent = GetProcAddress (user32, "TrackMouseEvent")) == NULL) + { + if ((commctrl32 = LoadLibrary ("commctrl32.dll")) != NULL) + p_TrackMouseEvent = GetProcAddress (commctrl32, "_TrackMouseEvent"); + } + if (p_TrackMouseEvent != NULL) + GDK_NOTE (EVENTS, g_print ("Using TrackMouseEvent to detect leave events\n")); +#endif } /* @@ -809,12 +907,16 @@ gdk_pointer_grab (GdkWindow * window, { if (!GDK_DRAWABLE_DESTROYED (window)) { - GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x\n", + GDK_NOTE (EVENTS, g_print ("gdk_pointer_grab: %#x %s %#x%s%s\n", xwindow, (owner_events ? "TRUE" : "FALSE"), - xcursor)); - p_grab_event_mask = event_mask; - p_grab_owner_events = owner_events != 0; + xcursor, + (event_mask & GDK_BUTTON_PRESS_MASK) ? + " PRESS" : "", + (event_mask & GDK_BUTTON_RELEASE_MASK) ? + " RELEASE" : "")); + p_grab_mask = event_mask; + p_grab_owner_events = (owner_events != 0); p_grab_automatic = FALSE; #if 0 /* Menus don't work if we use mouse capture. Pity, because many other @@ -1076,15 +1178,1887 @@ gdk_add_client_message_filter (GdkAtom message_type, client_filters = g_list_prepend (client_filters, filter); } +/* Thanks to Markus G. Kuhn <mkuhn@acm.org> for the ksysym<->Unicode + * mapping functions, from the xterm sources. + */ + +struct k2u { + unsigned short keysym; + unsigned short ucs; +} k2utab[] = { + { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */ + { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ + { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */ + { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */ + { 0x01a9, 0x0160 }, /* Scaron Å LATIN CAPITAL LETTER S WITH CARON */ + { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */ + { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */ + { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */ + { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */ + { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */ + { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ + { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */ + { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */ + { 0x01bb, 0x0165 }, /* tcaron Å¥ LATIN SMALL LETTER T WITH CARON */ + { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */ + { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */ + { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */ + { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + { 0x01c8, 0x010c }, /* Ccaron ÄŒ LATIN CAPITAL LETTER C WITH CARON */ + { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */ + { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */ + { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */ + { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */ + { 0x01db, 0x0170 }, /* Udoubleacute Å° LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + { 0x01de, 0x0162 }, /* Tcedilla Å¢ LATIN CAPITAL LETTER T WITH CEDILLA */ + { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */ + { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */ + { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */ + { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */ + { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */ + { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */ + { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */ + { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */ + { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + { 0x01fe, 0x0163 }, /* tcedilla Å£ LATIN SMALL LETTER T WITH CEDILLA */ + { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */ + { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + { 0x02a9, 0x0130 }, /* Iabovedot Ä° LATIN CAPITAL LETTER I WITH DOT ABOVE */ + { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */ + { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + { 0x02b6, 0x0125 }, /* hcircumflex Ä¥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */ + { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + { 0x02d5, 0x0120 }, /* Gabovedot Ä LATIN CAPITAL LETTER G WITH DOT ABOVE */ + { 0x02d8, 0x011c }, /* Gcircumflex Äœ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + { 0x02de, 0x015c }, /* Scircumflex Åœ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */ + { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */ + { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */ + { 0x02fd, 0x016d }, /* ubreve Å LATIN SMALL LETTER U WITH BREVE */ + { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */ + { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ + { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */ + { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */ + { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */ + { 0x03ab, 0x0122 }, /* Gcedilla Ä¢ LATIN CAPITAL LETTER G WITH CEDILLA */ + { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */ + { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */ + { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */ + { 0x03bb, 0x0123 }, /* gcedilla Ä£ LATIN SMALL LETTER G WITH CEDILLA */ + { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */ + { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */ + { 0x03c0, 0x0100 }, /* Amacron Ä€ LATIN CAPITAL LETTER A WITH MACRON */ + { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */ + { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */ + { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */ + { 0x03d2, 0x014c }, /* Omacron ÅŒ LATIN CAPITAL LETTER O WITH MACRON */ + { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */ + { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */ + { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */ + { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */ + { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */ + { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */ + { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */ + { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ + { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */ + { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */ + { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ + { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */ + { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */ + { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */ + { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ + { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */ + { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */ + { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ + { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ + { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ + { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ + { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */ + { 0x04b7, 0x30ad }, /* kana_KI ã‚ KATAKANA LETTER KI */ + { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ + { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ + { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ + { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ + { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */ + { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ + { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */ + { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ + { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */ + { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */ + { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ + { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ + { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ + { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ + { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ + { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ + { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */ + { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ + { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */ + { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ + { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ + { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ + { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ + { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ + { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ + { 0x04d1, 0x30e0 }, /* kana_MU ムKATAKANA LETTER MU */ + { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ + { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ + { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ + { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ + { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ + { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ + { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ + { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ + { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ + { 0x04db, 0x30ed }, /* kana_RO ムKATAKANA LETTER RO */ + { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ + { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ + { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0x04df, 0x309c }, /* semivoicedsound ã‚œ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0x05ac, 0x060c }, /* Arabic_comma ØŒ ARABIC COMMA */ + { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */ + { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */ + { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */ + { 0x05c2, 0x0622 }, /* Arabic_maddaonalef Ø¢ ARABIC LETTER ALEF WITH MADDA ABOVE */ + { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef Ø£ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef Ø¥ ARABIC LETTER ALEF WITH HAMZA BELOW */ + { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ + { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ + { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */ + { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ + { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */ + { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ + { 0x05cd, 0x062d }, /* Arabic_hah Ø ARABIC LETTER HAH */ + { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */ + { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ + { 0x05d0, 0x0630 }, /* Arabic_thal Ø° ARABIC LETTER THAL */ + { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ + { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ + { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ + { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */ + { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ + { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ + { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */ + { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ + { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ + { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */ + { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */ + { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */ + { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */ + { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */ + { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */ + { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */ + { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */ + { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */ + { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */ + { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */ + { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */ + { 0x05ec, 0x064c }, /* Arabic_dammatan ÙŒ ARABIC DAMMATAN */ + { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */ + { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */ + { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */ + { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */ + { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */ + { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */ + { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */ + { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */ + { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */ + { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */ + { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */ + { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */ + { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */ + { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */ + { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */ + { 0x06ac, 0x045c }, /* Macedonia_kje Ñœ CYRILLIC SMALL LETTER KJE */ + { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */ + { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */ + { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */ + { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */ + { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */ + { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + { 0x06bc, 0x040c }, /* Macedonia_KJE ÐŒ CYRILLIC CAPITAL LETTER KJE */ + { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */ + { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */ + { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */ + { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */ + { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */ + { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */ + { 0x06d2, 0x0440 }, /* Cyrillic_er Ñ€ CYRILLIC SMALL LETTER ER */ + { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */ + { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */ + { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + { 0x06d8, 0x044c }, /* Cyrillic_softsign ÑŒ CYRILLIC SMALL LETTER SOFT SIGN */ + { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */ + { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */ + { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */ + { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */ + { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + { 0x06e8, 0x0425 }, /* Cyrillic_HA Ð¥ CYRILLIC CAPITAL LETTER HA */ + { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + { 0x06ed, 0x041c }, /* Cyrillic_EM Ðœ CYRILLIC CAPITAL LETTER EM */ + { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */ + { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + { 0x06f2, 0x0420 }, /* Cyrillic_ER Ð CYRILLIC CAPITAL LETTER ER */ + { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */ + { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + { 0x06fc, 0x042d }, /* Cyrillic_E Ð CYRILLIC CAPITAL LETTER E */ + { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + { 0x07a7, 0x038c }, /* Greek_OMICRONaccent ÎŒ GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */ + { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ + { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x07b2, 0x03ad }, /* Greek_epsilonaccent Î GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + { 0x07b7, 0x03cc }, /* Greek_omicronaccent ÏŒ GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */ + { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + { 0x07cc, 0x039c }, /* Greek_MU Îœ GREEK CAPITAL LETTER MU */ + { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */ + { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + { 0x07d0, 0x03a0 }, /* Greek_PI Î GREEK CAPITAL LETTER PI */ + { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + { 0x07d5, 0x03a5 }, /* Greek_UPSILON Î¥ GREEK CAPITAL LETTER UPSILON */ + { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ + { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ + { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ + { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ + { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ + { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ + { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + { 0x07f0, 0x03c0 }, /* Greek_pi Ï€ GREEK SMALL LETTER PI */ + { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */ + { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */ + { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */ + { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */ + { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ + { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ + { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ +/* 0x08a1 leftradical ? ??? */ +/* 0x08a2 topleftradical ? ??? */ +/* 0x08a3 horizconnector ? ??? */ + { 0x08a4, 0x2320 }, /* topintegral ⌠TOP HALF INTEGRAL */ + { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ +/* 0x08a7 topleftsqbracket ? ??? */ +/* 0x08a8 botleftsqbracket ? ??? */ +/* 0x08a9 toprightsqbracket ? ??? */ +/* 0x08aa botrightsqbracket ? ??? */ +/* 0x08ab topleftparens ? ??? */ +/* 0x08ac botleftparens ? ??? */ +/* 0x08ad toprightparens ? ??? */ +/* 0x08ae botrightparens ? ??? */ +/* 0x08af leftmiddlecurlybrace ? ??? */ +/* 0x08b0 rightmiddlecurlybrace ? ??? */ +/* 0x08b1 topleftsummation ? ??? */ +/* 0x08b2 botleftsummation ? ??? */ +/* 0x08b3 topvertsummationconnector ? ??? */ +/* 0x08b4 botvertsummationconnector ? ??? */ +/* 0x08b5 toprightsummation ? ??? */ +/* 0x08b6 botrightsummation ? ??? */ +/* 0x08b7 rightmiddlesummation ? ??? */ + { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + { 0x08bd, 0x2260 }, /* notequal ≠NOT EQUAL TO */ + { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ + { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ + { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */ + { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ + { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ + { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ +/* 0x08c9 similarequal ? ??? */ + { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ + { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ + { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ + { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ + { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ + { 0x08dd, 0x222a }, /* union ∪ UNION */ + { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ + { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ + { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */ + { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */ + { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ + { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ + { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ + { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */ + { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */ + { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */ + { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */ + { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */ + { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */ + { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */ + { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */ + { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */ + { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */ + { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */ + { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ +/* 0x09ef horizlinescan1 ? ??? */ +/* 0x09f0 horizlinescan3 ? ??? */ + { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ +/* 0x09f2 horizlinescan7 ? ??? */ +/* 0x09f3 horizlinescan9 ? ??? */ + { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ + { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ + { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ + { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ + { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ + { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ + { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ + { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ + { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ + { 0x0aaa, 0x2013 }, /* endash – EN DASH */ +/* 0x0aac signifblank ? ??? */ + { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ +/* 0x0aaf doubbaselinedot ? ??? */ + { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */ + { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */ + { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */ + { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */ + { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */ + { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */ + { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */ + { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */ + { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */ + { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ + { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ + { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ + { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ +/* 0x0abf marker ? ??? */ + { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */ + { 0x0ac4, 0x215c }, /* threeeighths â…œ VULGAR FRACTION THREE EIGHTHS */ + { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */ + { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */ + { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */ + { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ +/* 0x0acb trademarkincircle ? ??? */ + { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */ + { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */ + { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */ + { 0x0acf, 0x25a1 }, /* emopenrectangle â–¡ WHITE SQUARE */ + { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */ + { 0x0ad4, 0x211e }, /* prescription â„ž PRESCRIPTION TAKE */ + { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ + { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ + { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */ +/* 0x0ada hexagram ? ??? */ + { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */ + { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */ + { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */ + { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */ + { 0x0adf, 0x25a0 }, /* emfilledrect â– BLACK SQUARE */ + { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */ + { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */ + { 0x0ae2, 0x25ad }, /* openrectbullet â– WHITE RECTANGLE */ + { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */ + { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */ + { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ + { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ + { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */ + { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */ + { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */ + { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ + { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ + { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ + { 0x0af0, 0x2720 }, /* maltesecross ✠MALTESE CROSS */ + { 0x0af1, 0x2020 }, /* dagger †DAGGER */ + { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ + { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ + { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ + { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ + { 0x0af6, 0x266d }, /* musicalflat â™ MUSIC FLAT SIGN */ + { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ + { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ + { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ + { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */ + { 0x0afc, 0x2038 }, /* caret ‸ CARET */ + { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ +/* 0x0aff cursor ? ??? */ + { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ + { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ + { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ + { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ + { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ + { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ + { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ + { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ + { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ + { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ + { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ + { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ + { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */ + { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ + { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ + { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ + { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ + { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ + { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ + { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */ + { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ + { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */ + { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ + { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */ + { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ + { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */ + { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */ + { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ + { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */ + { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */ + { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ + { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */ + { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ + { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + { 0x0cf0, 0x05e0 }, /* hebrew_nun × HEBREW LETTER NUN */ + { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */ + { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */ + { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ + { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */ + { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ + { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ + { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ + { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ + { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ + { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */ + { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ + { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */ + { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */ + { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */ + { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ + { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ + { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ + { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ + { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */ + { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภTHAI CHARACTER PHO SAMPHAO */ + { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ + { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ + { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ + { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ + { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ + { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ + { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ + { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + { 0x0dcd, 0x0e2d }, /* Thai_oang ภTHAI CHARACTER O ANG */ + { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ + { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ + { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ + { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ + { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ + { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ + { 0x0dde, 0x0e3e }, /* Thai_maihanakat_maitho ฾ ??? */ + { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ + { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */ + { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ + { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */ + { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */ + { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ + { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ + { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ + { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ + { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ + { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ + { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ + { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */ + { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ + { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */ + { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */ + { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */ + { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */ + { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */ + { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */ + { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */ + { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */ + { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */ + { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */ + { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */ + { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */ + { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */ + { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */ + { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */ + { 0x0ebc, 0x314c }, /* Hangul_Tieut ã…Œ HANGUL LETTER THIEUTH */ + { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */ + { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */ + { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */ + { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */ + { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */ + { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */ + { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */ + { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */ + { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */ + { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */ + { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */ + { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */ + { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */ + { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */ + { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */ + { 0x0ecc, 0x315c }, /* Hangul_U ã…œ HANGUL LETTER U */ + { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */ + { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */ + { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */ + { 0x0ed0, 0x3160 }, /* Hangul_YU ã… HANGUL LETTER YU */ + { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */ + { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */ + { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */ + { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆠHANGUL JONGSEONG NIEUN-HIEUH */ + { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */ + { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã… HANGUL LETTER RIEUL-YEORINHIEUH */ + { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */ + { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */ + { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */ +/* 0x0ef3 Hangul_KkogjiDalrinIeung ? ??? */ + { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */ + { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ + { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ +/* 0x0ef9 Hangul_J_KkogjiDalrinIeung ? ??? */ + { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */ + { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */ + { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */ + { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + { 0x20a0, 0x20a0 }, /* EcuSign â‚ EURO-CURRENCY SIGN */ + { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */ + { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */ + { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */ + { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ + { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */ + { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ + { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */ + { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ + { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */ + { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ + { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */ + { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ +}; + +static guint +keyval_to_unicode (guint keysym) +{ + int min = 0; + int max = sizeof(k2utab) / sizeof(k2utab[0]) - 1; + int mid; + + /* First check for Latin-1 characters (1:1 mapping) */ + if ((keysym >= 0x0020 && keysym <= 0x007e) || + (keysym >= 0x00a0 && keysym <= 0x00ff)) + return keysym; + + /* Also check for directly encoded 24-bit UCS characters */ + if ((keysym & 0xff000000) == 0x01000000) + return keysym & 0x00ffffff; + + /* binary search in table */ + while (max >= min) { + mid = (min + max) / 2; + if (k2utab[mid].keysym < keysym) + min = mid + 1; + else if (k2utab[mid].keysym > keysym) + max = mid - 1; + else { + /* found it */ + return k2utab[mid].ucs; + } + } + + /* No matching Unicode value found */ + return -1; +} + +struct u2k { + unsigned short keysym; + unsigned short ucs; +} u2ktab[] = { + { 0x0abd, 0x002e }, /* decimalpoint . FULL STOP */ + { 0x0ba3, 0x003c }, /* leftcaret < LESS-THAN SIGN */ + { 0x0ba6, 0x003e }, /* rightcaret > GREATER-THAN SIGN */ + { 0x0bc6, 0x005f }, /* underbar _ LOW LINE */ + { 0x0bc0, 0x00af }, /* overbar ¯ MACRON */ + { 0x03c0, 0x0100 }, /* Amacron Ä€ LATIN CAPITAL LETTER A WITH MACRON */ + { 0x03e0, 0x0101 }, /* amacron Ä LATIN SMALL LETTER A WITH MACRON */ + { 0x01c3, 0x0102 }, /* Abreve Ä‚ LATIN CAPITAL LETTER A WITH BREVE */ + { 0x01e3, 0x0103 }, /* abreve ă LATIN SMALL LETTER A WITH BREVE */ + { 0x01a1, 0x0104 }, /* Aogonek Ä„ LATIN CAPITAL LETTER A WITH OGONEK */ + { 0x01b1, 0x0105 }, /* aogonek Ä… LATIN SMALL LETTER A WITH OGONEK */ + { 0x01c6, 0x0106 }, /* Cacute Ć LATIN CAPITAL LETTER C WITH ACUTE */ + { 0x01e6, 0x0107 }, /* cacute ć LATIN SMALL LETTER C WITH ACUTE */ + { 0x02c6, 0x0108 }, /* Ccircumflex Ĉ LATIN CAPITAL LETTER C WITH CIRCUMFLEX */ + { 0x02e6, 0x0109 }, /* ccircumflex ĉ LATIN SMALL LETTER C WITH CIRCUMFLEX */ + { 0x02c5, 0x010a }, /* Cabovedot ÄŠ LATIN CAPITAL LETTER C WITH DOT ABOVE */ + { 0x02e5, 0x010b }, /* cabovedot Ä‹ LATIN SMALL LETTER C WITH DOT ABOVE */ + { 0x01c8, 0x010c }, /* Ccaron ÄŒ LATIN CAPITAL LETTER C WITH CARON */ + { 0x01e8, 0x010d }, /* ccaron Ä LATIN SMALL LETTER C WITH CARON */ + { 0x01cf, 0x010e }, /* Dcaron ÄŽ LATIN CAPITAL LETTER D WITH CARON */ + { 0x01ef, 0x010f }, /* dcaron Ä LATIN SMALL LETTER D WITH CARON */ + { 0x01d0, 0x0110 }, /* Dstroke Ä LATIN CAPITAL LETTER D WITH STROKE */ + { 0x01f0, 0x0111 }, /* dstroke Ä‘ LATIN SMALL LETTER D WITH STROKE */ + { 0x03aa, 0x0112 }, /* Emacron Ä’ LATIN CAPITAL LETTER E WITH MACRON */ + { 0x03ba, 0x0113 }, /* emacron Ä“ LATIN SMALL LETTER E WITH MACRON */ + { 0x03cc, 0x0116 }, /* Eabovedot Ä– LATIN CAPITAL LETTER E WITH DOT ABOVE */ + { 0x03ec, 0x0117 }, /* eabovedot Ä— LATIN SMALL LETTER E WITH DOT ABOVE */ + { 0x01ca, 0x0118 }, /* Eogonek Ę LATIN CAPITAL LETTER E WITH OGONEK */ + { 0x01ea, 0x0119 }, /* eogonek Ä™ LATIN SMALL LETTER E WITH OGONEK */ + { 0x01cc, 0x011a }, /* Ecaron Äš LATIN CAPITAL LETTER E WITH CARON */ + { 0x01ec, 0x011b }, /* ecaron Ä› LATIN SMALL LETTER E WITH CARON */ + { 0x02d8, 0x011c }, /* Gcircumflex Äœ LATIN CAPITAL LETTER G WITH CIRCUMFLEX */ + { 0x02f8, 0x011d }, /* gcircumflex Ä LATIN SMALL LETTER G WITH CIRCUMFLEX */ + { 0x02ab, 0x011e }, /* Gbreve Äž LATIN CAPITAL LETTER G WITH BREVE */ + { 0x02bb, 0x011f }, /* gbreve ÄŸ LATIN SMALL LETTER G WITH BREVE */ + { 0x02d5, 0x0120 }, /* Gabovedot Ä LATIN CAPITAL LETTER G WITH DOT ABOVE */ + { 0x02f5, 0x0121 }, /* gabovedot Ä¡ LATIN SMALL LETTER G WITH DOT ABOVE */ + { 0x03ab, 0x0122 }, /* Gcedilla Ä¢ LATIN CAPITAL LETTER G WITH CEDILLA */ + { 0x03bb, 0x0123 }, /* gcedilla Ä£ LATIN SMALL LETTER G WITH CEDILLA */ + { 0x02a6, 0x0124 }, /* Hcircumflex Ĥ LATIN CAPITAL LETTER H WITH CIRCUMFLEX */ + { 0x02b6, 0x0125 }, /* hcircumflex Ä¥ LATIN SMALL LETTER H WITH CIRCUMFLEX */ + { 0x02a1, 0x0126 }, /* Hstroke Ħ LATIN CAPITAL LETTER H WITH STROKE */ + { 0x02b1, 0x0127 }, /* hstroke ħ LATIN SMALL LETTER H WITH STROKE */ + { 0x03a5, 0x0128 }, /* Itilde Ĩ LATIN CAPITAL LETTER I WITH TILDE */ + { 0x03b5, 0x0129 }, /* itilde Ä© LATIN SMALL LETTER I WITH TILDE */ + { 0x03cf, 0x012a }, /* Imacron Ī LATIN CAPITAL LETTER I WITH MACRON */ + { 0x03ef, 0x012b }, /* imacron Ä« LATIN SMALL LETTER I WITH MACRON */ + { 0x03c7, 0x012e }, /* Iogonek Ä® LATIN CAPITAL LETTER I WITH OGONEK */ + { 0x03e7, 0x012f }, /* iogonek į LATIN SMALL LETTER I WITH OGONEK */ + { 0x02a9, 0x0130 }, /* Iabovedot Ä° LATIN CAPITAL LETTER I WITH DOT ABOVE */ + { 0x02b9, 0x0131 }, /* idotless ı LATIN SMALL LETTER DOTLESS I */ + { 0x02ac, 0x0134 }, /* Jcircumflex Ä´ LATIN CAPITAL LETTER J WITH CIRCUMFLEX */ + { 0x02bc, 0x0135 }, /* jcircumflex ĵ LATIN SMALL LETTER J WITH CIRCUMFLEX */ + { 0x03d3, 0x0136 }, /* Kcedilla Ķ LATIN CAPITAL LETTER K WITH CEDILLA */ + { 0x03f3, 0x0137 }, /* kcedilla Ä· LATIN SMALL LETTER K WITH CEDILLA */ + { 0x03a2, 0x0138 }, /* kra ĸ LATIN SMALL LETTER KRA */ + { 0x01c5, 0x0139 }, /* Lacute Ĺ LATIN CAPITAL LETTER L WITH ACUTE */ + { 0x01e5, 0x013a }, /* lacute ĺ LATIN SMALL LETTER L WITH ACUTE */ + { 0x03a6, 0x013b }, /* Lcedilla Ä» LATIN CAPITAL LETTER L WITH CEDILLA */ + { 0x03b6, 0x013c }, /* lcedilla ļ LATIN SMALL LETTER L WITH CEDILLA */ + { 0x01a5, 0x013d }, /* Lcaron Ľ LATIN CAPITAL LETTER L WITH CARON */ + { 0x01b5, 0x013e }, /* lcaron ľ LATIN SMALL LETTER L WITH CARON */ + { 0x01a3, 0x0141 }, /* Lstroke Å LATIN CAPITAL LETTER L WITH STROKE */ + { 0x01b3, 0x0142 }, /* lstroke Å‚ LATIN SMALL LETTER L WITH STROKE */ + { 0x01d1, 0x0143 }, /* Nacute Ń LATIN CAPITAL LETTER N WITH ACUTE */ + { 0x01f1, 0x0144 }, /* nacute Å„ LATIN SMALL LETTER N WITH ACUTE */ + { 0x03d1, 0x0145 }, /* Ncedilla Å… LATIN CAPITAL LETTER N WITH CEDILLA */ + { 0x03f1, 0x0146 }, /* ncedilla ņ LATIN SMALL LETTER N WITH CEDILLA */ + { 0x01d2, 0x0147 }, /* Ncaron Ň LATIN CAPITAL LETTER N WITH CARON */ + { 0x01f2, 0x0148 }, /* ncaron ň LATIN SMALL LETTER N WITH CARON */ + { 0x03bd, 0x014a }, /* ENG ÅŠ LATIN CAPITAL LETTER ENG */ + { 0x03bf, 0x014b }, /* eng Å‹ LATIN SMALL LETTER ENG */ + { 0x03d2, 0x014c }, /* Omacron ÅŒ LATIN CAPITAL LETTER O WITH MACRON */ + { 0x03f2, 0x014d }, /* omacron Å LATIN SMALL LETTER O WITH MACRON */ + { 0x01d5, 0x0150 }, /* Odoubleacute Å LATIN CAPITAL LETTER O WITH DOUBLE ACUTE */ + { 0x01f5, 0x0151 }, /* odoubleacute Å‘ LATIN SMALL LETTER O WITH DOUBLE ACUTE */ + { 0x13bc, 0x0152 }, /* OE Å’ LATIN CAPITAL LIGATURE OE */ + { 0x13bd, 0x0153 }, /* oe Å“ LATIN SMALL LIGATURE OE */ + { 0x01c0, 0x0154 }, /* Racute Å” LATIN CAPITAL LETTER R WITH ACUTE */ + { 0x01e0, 0x0155 }, /* racute Å• LATIN SMALL LETTER R WITH ACUTE */ + { 0x03a3, 0x0156 }, /* Rcedilla Å– LATIN CAPITAL LETTER R WITH CEDILLA */ + { 0x03b3, 0x0157 }, /* rcedilla Å— LATIN SMALL LETTER R WITH CEDILLA */ + { 0x01d8, 0x0158 }, /* Rcaron Ř LATIN CAPITAL LETTER R WITH CARON */ + { 0x01f8, 0x0159 }, /* rcaron Å™ LATIN SMALL LETTER R WITH CARON */ + { 0x01a6, 0x015a }, /* Sacute Åš LATIN CAPITAL LETTER S WITH ACUTE */ + { 0x01b6, 0x015b }, /* sacute Å› LATIN SMALL LETTER S WITH ACUTE */ + { 0x02de, 0x015c }, /* Scircumflex Åœ LATIN CAPITAL LETTER S WITH CIRCUMFLEX */ + { 0x02fe, 0x015d }, /* scircumflex Å LATIN SMALL LETTER S WITH CIRCUMFLEX */ + { 0x01aa, 0x015e }, /* Scedilla Åž LATIN CAPITAL LETTER S WITH CEDILLA */ + { 0x01ba, 0x015f }, /* scedilla ÅŸ LATIN SMALL LETTER S WITH CEDILLA */ + { 0x01a9, 0x0160 }, /* Scaron Å LATIN CAPITAL LETTER S WITH CARON */ + { 0x01b9, 0x0161 }, /* scaron Å¡ LATIN SMALL LETTER S WITH CARON */ + { 0x01de, 0x0162 }, /* Tcedilla Å¢ LATIN CAPITAL LETTER T WITH CEDILLA */ + { 0x01fe, 0x0163 }, /* tcedilla Å£ LATIN SMALL LETTER T WITH CEDILLA */ + { 0x01ab, 0x0164 }, /* Tcaron Ť LATIN CAPITAL LETTER T WITH CARON */ + { 0x01bb, 0x0165 }, /* tcaron Å¥ LATIN SMALL LETTER T WITH CARON */ + { 0x03ac, 0x0166 }, /* Tslash Ŧ LATIN CAPITAL LETTER T WITH STROKE */ + { 0x03bc, 0x0167 }, /* tslash ŧ LATIN SMALL LETTER T WITH STROKE */ + { 0x03dd, 0x0168 }, /* Utilde Ũ LATIN CAPITAL LETTER U WITH TILDE */ + { 0x03fd, 0x0169 }, /* utilde Å© LATIN SMALL LETTER U WITH TILDE */ + { 0x03de, 0x016a }, /* Umacron Ū LATIN CAPITAL LETTER U WITH MACRON */ + { 0x03fe, 0x016b }, /* umacron Å« LATIN SMALL LETTER U WITH MACRON */ + { 0x02dd, 0x016c }, /* Ubreve Ŭ LATIN CAPITAL LETTER U WITH BREVE */ + { 0x02fd, 0x016d }, /* ubreve Å LATIN SMALL LETTER U WITH BREVE */ + { 0x01d9, 0x016e }, /* Uring Å® LATIN CAPITAL LETTER U WITH RING ABOVE */ + { 0x01f9, 0x016f }, /* uring ů LATIN SMALL LETTER U WITH RING ABOVE */ + { 0x01db, 0x0170 }, /* Udoubleacute Å° LATIN CAPITAL LETTER U WITH DOUBLE ACUTE */ + { 0x01fb, 0x0171 }, /* udoubleacute ű LATIN SMALL LETTER U WITH DOUBLE ACUTE */ + { 0x03d9, 0x0172 }, /* Uogonek Ų LATIN CAPITAL LETTER U WITH OGONEK */ + { 0x03f9, 0x0173 }, /* uogonek ų LATIN SMALL LETTER U WITH OGONEK */ + { 0x13be, 0x0178 }, /* Ydiaeresis Ÿ LATIN CAPITAL LETTER Y WITH DIAERESIS */ + { 0x01ac, 0x0179 }, /* Zacute Ź LATIN CAPITAL LETTER Z WITH ACUTE */ + { 0x01bc, 0x017a }, /* zacute ź LATIN SMALL LETTER Z WITH ACUTE */ + { 0x01af, 0x017b }, /* Zabovedot Å» LATIN CAPITAL LETTER Z WITH DOT ABOVE */ + { 0x01bf, 0x017c }, /* zabovedot ż LATIN SMALL LETTER Z WITH DOT ABOVE */ + { 0x01ae, 0x017d }, /* Zcaron Ž LATIN CAPITAL LETTER Z WITH CARON */ + { 0x01be, 0x017e }, /* zcaron ž LATIN SMALL LETTER Z WITH CARON */ + { 0x08f6, 0x0192 }, /* function Æ’ LATIN SMALL LETTER F WITH HOOK */ + { 0x01b7, 0x02c7 }, /* caron ˇ CARON */ + { 0x01a2, 0x02d8 }, /* breve ˘ BREVE */ + { 0x01ff, 0x02d9 }, /* abovedot Ë™ DOT ABOVE */ + { 0x01b2, 0x02db }, /* ogonek Ë› OGONEK */ + { 0x01bd, 0x02dd }, /* doubleacute Ë DOUBLE ACUTE ACCENT */ + { 0x07ae, 0x0385 }, /* Greek_accentdieresis Î… GREEK DIALYTIKA TONOS */ + { 0x07a1, 0x0386 }, /* Greek_ALPHAaccent Ά GREEK CAPITAL LETTER ALPHA WITH TONOS */ + { 0x07a2, 0x0388 }, /* Greek_EPSILONaccent Έ GREEK CAPITAL LETTER EPSILON WITH TONOS */ + { 0x07a3, 0x0389 }, /* Greek_ETAaccent Ή GREEK CAPITAL LETTER ETA WITH TONOS */ + { 0x07a4, 0x038a }, /* Greek_IOTAaccent Ί GREEK CAPITAL LETTER IOTA WITH TONOS */ + { 0x07a7, 0x038c }, /* Greek_OMICRONaccent ÎŒ GREEK CAPITAL LETTER OMICRON WITH TONOS */ + { 0x07a8, 0x038e }, /* Greek_UPSILONaccent ÎŽ GREEK CAPITAL LETTER UPSILON WITH TONOS */ + { 0x07ab, 0x038f }, /* Greek_OMEGAaccent Î GREEK CAPITAL LETTER OMEGA WITH TONOS */ + { 0x07b6, 0x0390 }, /* Greek_iotaaccentdieresis Î GREEK SMALL LETTER IOTA WITH DIALYTIKA AND TONOS */ + { 0x07c1, 0x0391 }, /* Greek_ALPHA Α GREEK CAPITAL LETTER ALPHA */ + { 0x07c2, 0x0392 }, /* Greek_BETA Î’ GREEK CAPITAL LETTER BETA */ + { 0x07c3, 0x0393 }, /* Greek_GAMMA Γ GREEK CAPITAL LETTER GAMMA */ + { 0x07c4, 0x0394 }, /* Greek_DELTA Δ GREEK CAPITAL LETTER DELTA */ + { 0x07c5, 0x0395 }, /* Greek_EPSILON Ε GREEK CAPITAL LETTER EPSILON */ + { 0x07c6, 0x0396 }, /* Greek_ZETA Ζ GREEK CAPITAL LETTER ZETA */ + { 0x07c7, 0x0397 }, /* Greek_ETA Η GREEK CAPITAL LETTER ETA */ + { 0x07c8, 0x0398 }, /* Greek_THETA Θ GREEK CAPITAL LETTER THETA */ + { 0x07c9, 0x0399 }, /* Greek_IOTA Ι GREEK CAPITAL LETTER IOTA */ + { 0x07ca, 0x039a }, /* Greek_KAPPA Κ GREEK CAPITAL LETTER KAPPA */ + { 0x07cb, 0x039b }, /* Greek_LAMBDA Λ GREEK CAPITAL LETTER LAMDA */ + { 0x07cc, 0x039c }, /* Greek_MU Îœ GREEK CAPITAL LETTER MU */ + { 0x07cd, 0x039d }, /* Greek_NU Î GREEK CAPITAL LETTER NU */ + { 0x07ce, 0x039e }, /* Greek_XI Ξ GREEK CAPITAL LETTER XI */ + { 0x07cf, 0x039f }, /* Greek_OMICRON Ο GREEK CAPITAL LETTER OMICRON */ + { 0x07d0, 0x03a0 }, /* Greek_PI Î GREEK CAPITAL LETTER PI */ + { 0x07d1, 0x03a1 }, /* Greek_RHO Ρ GREEK CAPITAL LETTER RHO */ + { 0x07d2, 0x03a3 }, /* Greek_SIGMA Σ GREEK CAPITAL LETTER SIGMA */ + { 0x07d4, 0x03a4 }, /* Greek_TAU Τ GREEK CAPITAL LETTER TAU */ + { 0x07d5, 0x03a5 }, /* Greek_UPSILON Î¥ GREEK CAPITAL LETTER UPSILON */ + { 0x07d6, 0x03a6 }, /* Greek_PHI Φ GREEK CAPITAL LETTER PHI */ + { 0x07d7, 0x03a7 }, /* Greek_CHI Χ GREEK CAPITAL LETTER CHI */ + { 0x07d8, 0x03a8 }, /* Greek_PSI Ψ GREEK CAPITAL LETTER PSI */ + { 0x07d9, 0x03a9 }, /* Greek_OMEGA Ω GREEK CAPITAL LETTER OMEGA */ + { 0x07a5, 0x03aa }, /* Greek_IOTAdiaeresis Ϊ GREEK CAPITAL LETTER IOTA WITH DIALYTIKA */ + { 0x07a9, 0x03ab }, /* Greek_UPSILONdieresis Ϋ GREEK CAPITAL LETTER UPSILON WITH DIALYTIKA */ + { 0x07b1, 0x03ac }, /* Greek_alphaaccent ά GREEK SMALL LETTER ALPHA WITH TONOS */ + { 0x07b2, 0x03ad }, /* Greek_epsilonaccent Î GREEK SMALL LETTER EPSILON WITH TONOS */ + { 0x07b3, 0x03ae }, /* Greek_etaaccent ή GREEK SMALL LETTER ETA WITH TONOS */ + { 0x07b4, 0x03af }, /* Greek_iotaaccent ί GREEK SMALL LETTER IOTA WITH TONOS */ + { 0x07ba, 0x03b0 }, /* Greek_upsilonaccentdieresis ΰ GREEK SMALL LETTER UPSILON WITH DIALYTIKA AND TONOS */ + { 0x07e1, 0x03b1 }, /* Greek_alpha α GREEK SMALL LETTER ALPHA */ + { 0x07e2, 0x03b2 }, /* Greek_beta β GREEK SMALL LETTER BETA */ + { 0x07e3, 0x03b3 }, /* Greek_gamma γ GREEK SMALL LETTER GAMMA */ + { 0x07e4, 0x03b4 }, /* Greek_delta δ GREEK SMALL LETTER DELTA */ + { 0x07e5, 0x03b5 }, /* Greek_epsilon ε GREEK SMALL LETTER EPSILON */ + { 0x07e6, 0x03b6 }, /* Greek_zeta ζ GREEK SMALL LETTER ZETA */ + { 0x07e7, 0x03b7 }, /* Greek_eta η GREEK SMALL LETTER ETA */ + { 0x07e8, 0x03b8 }, /* Greek_theta θ GREEK SMALL LETTER THETA */ + { 0x07e9, 0x03b9 }, /* Greek_iota ι GREEK SMALL LETTER IOTA */ + { 0x07ea, 0x03ba }, /* Greek_kappa κ GREEK SMALL LETTER KAPPA */ + { 0x07eb, 0x03bb }, /* Greek_lambda λ GREEK SMALL LETTER LAMDA */ + { 0x07ec, 0x03bc }, /* Greek_mu μ GREEK SMALL LETTER MU */ + { 0x07ed, 0x03bd }, /* Greek_nu ν GREEK SMALL LETTER NU */ + { 0x07ee, 0x03be }, /* Greek_xi ξ GREEK SMALL LETTER XI */ + { 0x07ef, 0x03bf }, /* Greek_omicron ο GREEK SMALL LETTER OMICRON */ + { 0x07f0, 0x03c0 }, /* Greek_pi Ï€ GREEK SMALL LETTER PI */ + { 0x07f1, 0x03c1 }, /* Greek_rho Ï GREEK SMALL LETTER RHO */ + { 0x07f3, 0x03c2 }, /* Greek_finalsmallsigma Ï‚ GREEK SMALL LETTER FINAL SIGMA */ + { 0x07f2, 0x03c3 }, /* Greek_sigma σ GREEK SMALL LETTER SIGMA */ + { 0x07f4, 0x03c4 }, /* Greek_tau Ï„ GREEK SMALL LETTER TAU */ + { 0x07f5, 0x03c5 }, /* Greek_upsilon Ï… GREEK SMALL LETTER UPSILON */ + { 0x07f6, 0x03c6 }, /* Greek_phi φ GREEK SMALL LETTER PHI */ + { 0x07f7, 0x03c7 }, /* Greek_chi χ GREEK SMALL LETTER CHI */ + { 0x07f8, 0x03c8 }, /* Greek_psi ψ GREEK SMALL LETTER PSI */ + { 0x07f9, 0x03c9 }, /* Greek_omega ω GREEK SMALL LETTER OMEGA */ + { 0x07b5, 0x03ca }, /* Greek_iotadieresis ÏŠ GREEK SMALL LETTER IOTA WITH DIALYTIKA */ + { 0x07b9, 0x03cb }, /* Greek_upsilondieresis Ï‹ GREEK SMALL LETTER UPSILON WITH DIALYTIKA */ + { 0x07b7, 0x03cc }, /* Greek_omicronaccent ÏŒ GREEK SMALL LETTER OMICRON WITH TONOS */ + { 0x07b8, 0x03cd }, /* Greek_upsilonaccent Ï GREEK SMALL LETTER UPSILON WITH TONOS */ + { 0x07bb, 0x03ce }, /* Greek_omegaaccent ÏŽ GREEK SMALL LETTER OMEGA WITH TONOS */ + { 0x06b3, 0x0401 }, /* Cyrillic_IO Ð CYRILLIC CAPITAL LETTER IO */ + { 0x06b1, 0x0402 }, /* Serbian_DJE Ђ CYRILLIC CAPITAL LETTER DJE */ + { 0x06b2, 0x0403 }, /* Macedonia_GJE Ѓ CYRILLIC CAPITAL LETTER GJE */ + { 0x06b4, 0x0404 }, /* Ukrainian_IE Є CYRILLIC CAPITAL LETTER UKRAINIAN IE */ + { 0x06b5, 0x0405 }, /* Macedonia_DSE Ð… CYRILLIC CAPITAL LETTER DZE */ + { 0x06b6, 0x0406 }, /* Ukrainian_I І CYRILLIC CAPITAL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06b7, 0x0407 }, /* Ukrainian_YI Ї CYRILLIC CAPITAL LETTER YI */ + { 0x06b8, 0x0408 }, /* Cyrillic_JE Ј CYRILLIC CAPITAL LETTER JE */ + { 0x06b9, 0x0409 }, /* Cyrillic_LJE Љ CYRILLIC CAPITAL LETTER LJE */ + { 0x06ba, 0x040a }, /* Cyrillic_NJE Њ CYRILLIC CAPITAL LETTER NJE */ + { 0x06bb, 0x040b }, /* Serbian_TSHE Ћ CYRILLIC CAPITAL LETTER TSHE */ + { 0x06bc, 0x040c }, /* Macedonia_KJE ÐŒ CYRILLIC CAPITAL LETTER KJE */ + { 0x06be, 0x040e }, /* Byelorussian_SHORTU ÐŽ CYRILLIC CAPITAL LETTER SHORT U */ + { 0x06bf, 0x040f }, /* Cyrillic_DZHE Ð CYRILLIC CAPITAL LETTER DZHE */ + { 0x06e1, 0x0410 }, /* Cyrillic_A Ð CYRILLIC CAPITAL LETTER A */ + { 0x06e2, 0x0411 }, /* Cyrillic_BE Б CYRILLIC CAPITAL LETTER BE */ + { 0x06f7, 0x0412 }, /* Cyrillic_VE Ð’ CYRILLIC CAPITAL LETTER VE */ + { 0x06e7, 0x0413 }, /* Cyrillic_GHE Г CYRILLIC CAPITAL LETTER GHE */ + { 0x06e4, 0x0414 }, /* Cyrillic_DE Д CYRILLIC CAPITAL LETTER DE */ + { 0x06e5, 0x0415 }, /* Cyrillic_IE Е CYRILLIC CAPITAL LETTER IE */ + { 0x06f6, 0x0416 }, /* Cyrillic_ZHE Ж CYRILLIC CAPITAL LETTER ZHE */ + { 0x06fa, 0x0417 }, /* Cyrillic_ZE З CYRILLIC CAPITAL LETTER ZE */ + { 0x06e9, 0x0418 }, /* Cyrillic_I И CYRILLIC CAPITAL LETTER I */ + { 0x06ea, 0x0419 }, /* Cyrillic_SHORTI Й CYRILLIC CAPITAL LETTER SHORT I */ + { 0x06eb, 0x041a }, /* Cyrillic_KA К CYRILLIC CAPITAL LETTER KA */ + { 0x06ec, 0x041b }, /* Cyrillic_EL Л CYRILLIC CAPITAL LETTER EL */ + { 0x06ed, 0x041c }, /* Cyrillic_EM Ðœ CYRILLIC CAPITAL LETTER EM */ + { 0x06ee, 0x041d }, /* Cyrillic_EN Ð CYRILLIC CAPITAL LETTER EN */ + { 0x06ef, 0x041e }, /* Cyrillic_O О CYRILLIC CAPITAL LETTER O */ + { 0x06f0, 0x041f }, /* Cyrillic_PE П CYRILLIC CAPITAL LETTER PE */ + { 0x06f2, 0x0420 }, /* Cyrillic_ER Ð CYRILLIC CAPITAL LETTER ER */ + { 0x06f3, 0x0421 }, /* Cyrillic_ES С CYRILLIC CAPITAL LETTER ES */ + { 0x06f4, 0x0422 }, /* Cyrillic_TE Т CYRILLIC CAPITAL LETTER TE */ + { 0x06f5, 0x0423 }, /* Cyrillic_U У CYRILLIC CAPITAL LETTER U */ + { 0x06e6, 0x0424 }, /* Cyrillic_EF Ф CYRILLIC CAPITAL LETTER EF */ + { 0x06e8, 0x0425 }, /* Cyrillic_HA Ð¥ CYRILLIC CAPITAL LETTER HA */ + { 0x06e3, 0x0426 }, /* Cyrillic_TSE Ц CYRILLIC CAPITAL LETTER TSE */ + { 0x06fe, 0x0427 }, /* Cyrillic_CHE Ч CYRILLIC CAPITAL LETTER CHE */ + { 0x06fb, 0x0428 }, /* Cyrillic_SHA Ш CYRILLIC CAPITAL LETTER SHA */ + { 0x06fd, 0x0429 }, /* Cyrillic_SHCHA Щ CYRILLIC CAPITAL LETTER SHCHA */ + { 0x06ff, 0x042a }, /* Cyrillic_HARDSIGN Ъ CYRILLIC CAPITAL LETTER HARD SIGN */ + { 0x06f9, 0x042b }, /* Cyrillic_YERU Ы CYRILLIC CAPITAL LETTER YERU */ + { 0x06f8, 0x042c }, /* Cyrillic_SOFTSIGN Ь CYRILLIC CAPITAL LETTER SOFT SIGN */ + { 0x06fc, 0x042d }, /* Cyrillic_E Ð CYRILLIC CAPITAL LETTER E */ + { 0x06e0, 0x042e }, /* Cyrillic_YU Ю CYRILLIC CAPITAL LETTER YU */ + { 0x06f1, 0x042f }, /* Cyrillic_YA Я CYRILLIC CAPITAL LETTER YA */ + { 0x06c1, 0x0430 }, /* Cyrillic_a а CYRILLIC SMALL LETTER A */ + { 0x06c2, 0x0431 }, /* Cyrillic_be б CYRILLIC SMALL LETTER BE */ + { 0x06d7, 0x0432 }, /* Cyrillic_ve в CYRILLIC SMALL LETTER VE */ + { 0x06c7, 0x0433 }, /* Cyrillic_ghe г CYRILLIC SMALL LETTER GHE */ + { 0x06c4, 0x0434 }, /* Cyrillic_de д CYRILLIC SMALL LETTER DE */ + { 0x06c5, 0x0435 }, /* Cyrillic_ie е CYRILLIC SMALL LETTER IE */ + { 0x06d6, 0x0436 }, /* Cyrillic_zhe ж CYRILLIC SMALL LETTER ZHE */ + { 0x06da, 0x0437 }, /* Cyrillic_ze з CYRILLIC SMALL LETTER ZE */ + { 0x06c9, 0x0438 }, /* Cyrillic_i и CYRILLIC SMALL LETTER I */ + { 0x06ca, 0x0439 }, /* Cyrillic_shorti й CYRILLIC SMALL LETTER SHORT I */ + { 0x06cb, 0x043a }, /* Cyrillic_ka к CYRILLIC SMALL LETTER KA */ + { 0x06cc, 0x043b }, /* Cyrillic_el л CYRILLIC SMALL LETTER EL */ + { 0x06cd, 0x043c }, /* Cyrillic_em м CYRILLIC SMALL LETTER EM */ + { 0x06ce, 0x043d }, /* Cyrillic_en н CYRILLIC SMALL LETTER EN */ + { 0x06cf, 0x043e }, /* Cyrillic_o о CYRILLIC SMALL LETTER O */ + { 0x06d0, 0x043f }, /* Cyrillic_pe п CYRILLIC SMALL LETTER PE */ + { 0x06d2, 0x0440 }, /* Cyrillic_er Ñ€ CYRILLIC SMALL LETTER ER */ + { 0x06d3, 0x0441 }, /* Cyrillic_es Ñ CYRILLIC SMALL LETTER ES */ + { 0x06d4, 0x0442 }, /* Cyrillic_te Ñ‚ CYRILLIC SMALL LETTER TE */ + { 0x06d5, 0x0443 }, /* Cyrillic_u у CYRILLIC SMALL LETTER U */ + { 0x06c6, 0x0444 }, /* Cyrillic_ef Ñ„ CYRILLIC SMALL LETTER EF */ + { 0x06c8, 0x0445 }, /* Cyrillic_ha Ñ… CYRILLIC SMALL LETTER HA */ + { 0x06c3, 0x0446 }, /* Cyrillic_tse ц CYRILLIC SMALL LETTER TSE */ + { 0x06de, 0x0447 }, /* Cyrillic_che ч CYRILLIC SMALL LETTER CHE */ + { 0x06db, 0x0448 }, /* Cyrillic_sha ш CYRILLIC SMALL LETTER SHA */ + { 0x06dd, 0x0449 }, /* Cyrillic_shcha щ CYRILLIC SMALL LETTER SHCHA */ + { 0x06df, 0x044a }, /* Cyrillic_hardsign ÑŠ CYRILLIC SMALL LETTER HARD SIGN */ + { 0x06d9, 0x044b }, /* Cyrillic_yeru Ñ‹ CYRILLIC SMALL LETTER YERU */ + { 0x06d8, 0x044c }, /* Cyrillic_softsign ÑŒ CYRILLIC SMALL LETTER SOFT SIGN */ + { 0x06dc, 0x044d }, /* Cyrillic_e Ñ CYRILLIC SMALL LETTER E */ + { 0x06c0, 0x044e }, /* Cyrillic_yu ÑŽ CYRILLIC SMALL LETTER YU */ + { 0x06d1, 0x044f }, /* Cyrillic_ya Ñ CYRILLIC SMALL LETTER YA */ + { 0x06a3, 0x0451 }, /* Cyrillic_io Ñ‘ CYRILLIC SMALL LETTER IO */ + { 0x06a1, 0x0452 }, /* Serbian_dje Ñ’ CYRILLIC SMALL LETTER DJE */ + { 0x06a2, 0x0453 }, /* Macedonia_gje Ñ“ CYRILLIC SMALL LETTER GJE */ + { 0x06a4, 0x0454 }, /* Ukrainian_ie Ñ” CYRILLIC SMALL LETTER UKRAINIAN IE */ + { 0x06a5, 0x0455 }, /* Macedonia_dse Ñ• CYRILLIC SMALL LETTER DZE */ + { 0x06a6, 0x0456 }, /* Ukrainian_i Ñ– CYRILLIC SMALL LETTER BYELORUSSIAN-UKRAINIAN I */ + { 0x06a7, 0x0457 }, /* Ukrainian_yi Ñ— CYRILLIC SMALL LETTER YI */ + { 0x06a8, 0x0458 }, /* Cyrillic_je ј CYRILLIC SMALL LETTER JE */ + { 0x06a9, 0x0459 }, /* Cyrillic_lje Ñ™ CYRILLIC SMALL LETTER LJE */ + { 0x06aa, 0x045a }, /* Cyrillic_nje Ñš CYRILLIC SMALL LETTER NJE */ + { 0x06ab, 0x045b }, /* Serbian_tshe Ñ› CYRILLIC SMALL LETTER TSHE */ + { 0x06ac, 0x045c }, /* Macedonia_kje Ñœ CYRILLIC SMALL LETTER KJE */ + { 0x06ae, 0x045e }, /* Byelorussian_shortu Ñž CYRILLIC SMALL LETTER SHORT U */ + { 0x06af, 0x045f }, /* Cyrillic_dzhe ÑŸ CYRILLIC SMALL LETTER DZHE */ + { 0x0ce0, 0x05d0 }, /* hebrew_aleph × HEBREW LETTER ALEF */ + { 0x0ce1, 0x05d1 }, /* hebrew_bet ב HEBREW LETTER BET */ + { 0x0ce2, 0x05d2 }, /* hebrew_gimel ×’ HEBREW LETTER GIMEL */ + { 0x0ce3, 0x05d3 }, /* hebrew_dalet ד HEBREW LETTER DALET */ + { 0x0ce4, 0x05d4 }, /* hebrew_he ×” HEBREW LETTER HE */ + { 0x0ce5, 0x05d5 }, /* hebrew_waw ו HEBREW LETTER VAV */ + { 0x0ce6, 0x05d6 }, /* hebrew_zain ×– HEBREW LETTER ZAYIN */ + { 0x0ce7, 0x05d7 }, /* hebrew_chet ×— HEBREW LETTER HET */ + { 0x0ce8, 0x05d8 }, /* hebrew_tet ט HEBREW LETTER TET */ + { 0x0ce9, 0x05d9 }, /* hebrew_yod ×™ HEBREW LETTER YOD */ + { 0x0cea, 0x05da }, /* hebrew_finalkaph ך HEBREW LETTER FINAL KAF */ + { 0x0ceb, 0x05db }, /* hebrew_kaph ×› HEBREW LETTER KAF */ + { 0x0cec, 0x05dc }, /* hebrew_lamed ל HEBREW LETTER LAMED */ + { 0x0ced, 0x05dd }, /* hebrew_finalmem × HEBREW LETTER FINAL MEM */ + { 0x0cee, 0x05de }, /* hebrew_mem מ HEBREW LETTER MEM */ + { 0x0cef, 0x05df }, /* hebrew_finalnun ן HEBREW LETTER FINAL NUN */ + { 0x0cf0, 0x05e0 }, /* hebrew_nun × HEBREW LETTER NUN */ + { 0x0cf1, 0x05e1 }, /* hebrew_samech ס HEBREW LETTER SAMEKH */ + { 0x0cf2, 0x05e2 }, /* hebrew_ayin ×¢ HEBREW LETTER AYIN */ + { 0x0cf3, 0x05e3 }, /* hebrew_finalpe ×£ HEBREW LETTER FINAL PE */ + { 0x0cf4, 0x05e4 }, /* hebrew_pe פ HEBREW LETTER PE */ + { 0x0cf5, 0x05e5 }, /* hebrew_finalzade ×¥ HEBREW LETTER FINAL TSADI */ + { 0x0cf6, 0x05e6 }, /* hebrew_zade צ HEBREW LETTER TSADI */ + { 0x0cf7, 0x05e7 }, /* hebrew_qoph ק HEBREW LETTER QOF */ + { 0x0cf8, 0x05e8 }, /* hebrew_resh ר HEBREW LETTER RESH */ + { 0x0cf9, 0x05e9 }, /* hebrew_shin ש HEBREW LETTER SHIN */ + { 0x0cfa, 0x05ea }, /* hebrew_taw ת HEBREW LETTER TAV */ + { 0x05ac, 0x060c }, /* Arabic_comma ØŒ ARABIC COMMA */ + { 0x05bb, 0x061b }, /* Arabic_semicolon Ø› ARABIC SEMICOLON */ + { 0x05bf, 0x061f }, /* Arabic_question_mark ØŸ ARABIC QUESTION MARK */ + { 0x05c1, 0x0621 }, /* Arabic_hamza Ø¡ ARABIC LETTER HAMZA */ + { 0x05c2, 0x0622 }, /* Arabic_maddaonalef Ø¢ ARABIC LETTER ALEF WITH MADDA ABOVE */ + { 0x05c3, 0x0623 }, /* Arabic_hamzaonalef Ø£ ARABIC LETTER ALEF WITH HAMZA ABOVE */ + { 0x05c4, 0x0624 }, /* Arabic_hamzaonwaw ؤ ARABIC LETTER WAW WITH HAMZA ABOVE */ + { 0x05c5, 0x0625 }, /* Arabic_hamzaunderalef Ø¥ ARABIC LETTER ALEF WITH HAMZA BELOW */ + { 0x05c6, 0x0626 }, /* Arabic_hamzaonyeh ئ ARABIC LETTER YEH WITH HAMZA ABOVE */ + { 0x05c7, 0x0627 }, /* Arabic_alef ا ARABIC LETTER ALEF */ + { 0x05c8, 0x0628 }, /* Arabic_beh ب ARABIC LETTER BEH */ + { 0x05c9, 0x0629 }, /* Arabic_tehmarbuta Ø© ARABIC LETTER TEH MARBUTA */ + { 0x05ca, 0x062a }, /* Arabic_teh ت ARABIC LETTER TEH */ + { 0x05cb, 0x062b }, /* Arabic_theh Ø« ARABIC LETTER THEH */ + { 0x05cc, 0x062c }, /* Arabic_jeem ج ARABIC LETTER JEEM */ + { 0x05cd, 0x062d }, /* Arabic_hah Ø ARABIC LETTER HAH */ + { 0x05ce, 0x062e }, /* Arabic_khah Ø® ARABIC LETTER KHAH */ + { 0x05cf, 0x062f }, /* Arabic_dal د ARABIC LETTER DAL */ + { 0x05d0, 0x0630 }, /* Arabic_thal Ø° ARABIC LETTER THAL */ + { 0x05d1, 0x0631 }, /* Arabic_ra ر ARABIC LETTER REH */ + { 0x05d2, 0x0632 }, /* Arabic_zain ز ARABIC LETTER ZAIN */ + { 0x05d3, 0x0633 }, /* Arabic_seen س ARABIC LETTER SEEN */ + { 0x05d4, 0x0634 }, /* Arabic_sheen Ø´ ARABIC LETTER SHEEN */ + { 0x05d5, 0x0635 }, /* Arabic_sad ص ARABIC LETTER SAD */ + { 0x05d6, 0x0636 }, /* Arabic_dad ض ARABIC LETTER DAD */ + { 0x05d7, 0x0637 }, /* Arabic_tah Ø· ARABIC LETTER TAH */ + { 0x05d8, 0x0638 }, /* Arabic_zah ظ ARABIC LETTER ZAH */ + { 0x05d9, 0x0639 }, /* Arabic_ain ع ARABIC LETTER AIN */ + { 0x05da, 0x063a }, /* Arabic_ghain غ ARABIC LETTER GHAIN */ + { 0x05e0, 0x0640 }, /* Arabic_tatweel Ù€ ARABIC TATWEEL */ + { 0x05e1, 0x0641 }, /* Arabic_feh Ù ARABIC LETTER FEH */ + { 0x05e2, 0x0642 }, /* Arabic_qaf Ù‚ ARABIC LETTER QAF */ + { 0x05e3, 0x0643 }, /* Arabic_kaf Ùƒ ARABIC LETTER KAF */ + { 0x05e4, 0x0644 }, /* Arabic_lam Ù„ ARABIC LETTER LAM */ + { 0x05e5, 0x0645 }, /* Arabic_meem Ù… ARABIC LETTER MEEM */ + { 0x05e6, 0x0646 }, /* Arabic_noon Ù† ARABIC LETTER NOON */ + { 0x05e7, 0x0647 }, /* Arabic_ha Ù‡ ARABIC LETTER HEH */ + { 0x05e8, 0x0648 }, /* Arabic_waw Ùˆ ARABIC LETTER WAW */ + { 0x05e9, 0x0649 }, /* Arabic_alefmaksura Ù‰ ARABIC LETTER ALEF MAKSURA */ + { 0x05ea, 0x064a }, /* Arabic_yeh ÙŠ ARABIC LETTER YEH */ + { 0x05eb, 0x064b }, /* Arabic_fathatan Ù‹ ARABIC FATHATAN */ + { 0x05ec, 0x064c }, /* Arabic_dammatan ÙŒ ARABIC DAMMATAN */ + { 0x05ed, 0x064d }, /* Arabic_kasratan Ù ARABIC KASRATAN */ + { 0x05ee, 0x064e }, /* Arabic_fatha ÙŽ ARABIC FATHA */ + { 0x05ef, 0x064f }, /* Arabic_damma Ù ARABIC DAMMA */ + { 0x05f0, 0x0650 }, /* Arabic_kasra Ù ARABIC KASRA */ + { 0x05f1, 0x0651 }, /* Arabic_shadda Ù‘ ARABIC SHADDA */ + { 0x05f2, 0x0652 }, /* Arabic_sukun Ù’ ARABIC SUKUN */ + { 0x0da1, 0x0e01 }, /* Thai_kokai ภTHAI CHARACTER KO KAI */ + { 0x0da2, 0x0e02 }, /* Thai_khokhai ข THAI CHARACTER KHO KHAI */ + { 0x0da3, 0x0e03 }, /* Thai_khokhuat ฃ THAI CHARACTER KHO KHUAT */ + { 0x0da4, 0x0e04 }, /* Thai_khokhwai ค THAI CHARACTER KHO KHWAI */ + { 0x0da5, 0x0e05 }, /* Thai_khokhon ฅ THAI CHARACTER KHO KHON */ + { 0x0da6, 0x0e06 }, /* Thai_khorakhang ฆ THAI CHARACTER KHO RAKHANG */ + { 0x0da7, 0x0e07 }, /* Thai_ngongu ง THAI CHARACTER NGO NGU */ + { 0x0da8, 0x0e08 }, /* Thai_chochan จ THAI CHARACTER CHO CHAN */ + { 0x0da9, 0x0e09 }, /* Thai_choching ฉ THAI CHARACTER CHO CHING */ + { 0x0daa, 0x0e0a }, /* Thai_chochang ช THAI CHARACTER CHO CHANG */ + { 0x0dab, 0x0e0b }, /* Thai_soso ซ THAI CHARACTER SO SO */ + { 0x0dac, 0x0e0c }, /* Thai_chochoe ฌ THAI CHARACTER CHO CHOE */ + { 0x0dad, 0x0e0d }, /* Thai_yoying ภTHAI CHARACTER YO YING */ + { 0x0dae, 0x0e0e }, /* Thai_dochada ฎ THAI CHARACTER DO CHADA */ + { 0x0daf, 0x0e0f }, /* Thai_topatak ภTHAI CHARACTER TO PATAK */ + { 0x0db0, 0x0e10 }, /* Thai_thothan ภTHAI CHARACTER THO THAN */ + { 0x0db1, 0x0e11 }, /* Thai_thonangmontho ฑ THAI CHARACTER THO NANGMONTHO */ + { 0x0db2, 0x0e12 }, /* Thai_thophuthao ฒ THAI CHARACTER THO PHUTHAO */ + { 0x0db3, 0x0e13 }, /* Thai_nonen ณ THAI CHARACTER NO NEN */ + { 0x0db4, 0x0e14 }, /* Thai_dodek ด THAI CHARACTER DO DEK */ + { 0x0db5, 0x0e15 }, /* Thai_totao ต THAI CHARACTER TO TAO */ + { 0x0db6, 0x0e16 }, /* Thai_thothung ถ THAI CHARACTER THO THUNG */ + { 0x0db7, 0x0e17 }, /* Thai_thothahan ท THAI CHARACTER THO THAHAN */ + { 0x0db8, 0x0e18 }, /* Thai_thothong ธ THAI CHARACTER THO THONG */ + { 0x0db9, 0x0e19 }, /* Thai_nonu น THAI CHARACTER NO NU */ + { 0x0dba, 0x0e1a }, /* Thai_bobaimai บ THAI CHARACTER BO BAIMAI */ + { 0x0dbb, 0x0e1b }, /* Thai_popla ป THAI CHARACTER PO PLA */ + { 0x0dbc, 0x0e1c }, /* Thai_phophung ผ THAI CHARACTER PHO PHUNG */ + { 0x0dbd, 0x0e1d }, /* Thai_fofa ภTHAI CHARACTER FO FA */ + { 0x0dbe, 0x0e1e }, /* Thai_phophan พ THAI CHARACTER PHO PHAN */ + { 0x0dbf, 0x0e1f }, /* Thai_fofan ฟ THAI CHARACTER FO FAN */ + { 0x0dc0, 0x0e20 }, /* Thai_phosamphao ภTHAI CHARACTER PHO SAMPHAO */ + { 0x0dc1, 0x0e21 }, /* Thai_moma ม THAI CHARACTER MO MA */ + { 0x0dc2, 0x0e22 }, /* Thai_yoyak ย THAI CHARACTER YO YAK */ + { 0x0dc3, 0x0e23 }, /* Thai_rorua ร THAI CHARACTER RO RUA */ + { 0x0dc4, 0x0e24 }, /* Thai_ru ฤ THAI CHARACTER RU */ + { 0x0dc5, 0x0e25 }, /* Thai_loling ล THAI CHARACTER LO LING */ + { 0x0dc6, 0x0e26 }, /* Thai_lu ฦ THAI CHARACTER LU */ + { 0x0dc7, 0x0e27 }, /* Thai_wowaen ว THAI CHARACTER WO WAEN */ + { 0x0dc8, 0x0e28 }, /* Thai_sosala ศ THAI CHARACTER SO SALA */ + { 0x0dc9, 0x0e29 }, /* Thai_sorusi ษ THAI CHARACTER SO RUSI */ + { 0x0dca, 0x0e2a }, /* Thai_sosua ส THAI CHARACTER SO SUA */ + { 0x0dcb, 0x0e2b }, /* Thai_hohip ห THAI CHARACTER HO HIP */ + { 0x0dcc, 0x0e2c }, /* Thai_lochula ฬ THAI CHARACTER LO CHULA */ + { 0x0dcd, 0x0e2d }, /* Thai_oang ภTHAI CHARACTER O ANG */ + { 0x0dce, 0x0e2e }, /* Thai_honokhuk ฮ THAI CHARACTER HO NOKHUK */ + { 0x0dcf, 0x0e2f }, /* Thai_paiyannoi ฯ THAI CHARACTER PAIYANNOI */ + { 0x0dd0, 0x0e30 }, /* Thai_saraa ะ THAI CHARACTER SARA A */ + { 0x0dd1, 0x0e31 }, /* Thai_maihanakat ั THAI CHARACTER MAI HAN-AKAT */ + { 0x0dd2, 0x0e32 }, /* Thai_saraaa า THAI CHARACTER SARA AA */ + { 0x0dd3, 0x0e33 }, /* Thai_saraam ำ THAI CHARACTER SARA AM */ + { 0x0dd4, 0x0e34 }, /* Thai_sarai ิ THAI CHARACTER SARA I */ + { 0x0dd5, 0x0e35 }, /* Thai_saraii ี THAI CHARACTER SARA II */ + { 0x0dd6, 0x0e36 }, /* Thai_saraue ึ THAI CHARACTER SARA UE */ + { 0x0dd7, 0x0e37 }, /* Thai_sarauee ื THAI CHARACTER SARA UEE */ + { 0x0dd8, 0x0e38 }, /* Thai_sarau ุ THAI CHARACTER SARA U */ + { 0x0dd9, 0x0e39 }, /* Thai_sarauu ู THAI CHARACTER SARA UU */ + { 0x0dda, 0x0e3a }, /* Thai_phinthu ฺ THAI CHARACTER PHINTHU */ + { 0x0ddf, 0x0e3f }, /* Thai_baht ฿ THAI CURRENCY SYMBOL BAHT */ + { 0x0de0, 0x0e40 }, /* Thai_sarae เ THAI CHARACTER SARA E */ + { 0x0de1, 0x0e41 }, /* Thai_saraae ๠THAI CHARACTER SARA AE */ + { 0x0de2, 0x0e42 }, /* Thai_sarao โ THAI CHARACTER SARA O */ + { 0x0de3, 0x0e43 }, /* Thai_saraaimaimuan ใ THAI CHARACTER SARA AI MAIMUAN */ + { 0x0de4, 0x0e44 }, /* Thai_saraaimaimalai ไ THAI CHARACTER SARA AI MAIMALAI */ + { 0x0de5, 0x0e45 }, /* Thai_lakkhangyao ๅ THAI CHARACTER LAKKHANGYAO */ + { 0x0de6, 0x0e46 }, /* Thai_maiyamok ๆ THAI CHARACTER MAIYAMOK */ + { 0x0de7, 0x0e47 }, /* Thai_maitaikhu ็ THAI CHARACTER MAITAIKHU */ + { 0x0de8, 0x0e48 }, /* Thai_maiek ่ THAI CHARACTER MAI EK */ + { 0x0de9, 0x0e49 }, /* Thai_maitho ้ THAI CHARACTER MAI THO */ + { 0x0dea, 0x0e4a }, /* Thai_maitri ๊ THAI CHARACTER MAI TRI */ + { 0x0deb, 0x0e4b }, /* Thai_maichattawa ๋ THAI CHARACTER MAI CHATTAWA */ + { 0x0dec, 0x0e4c }, /* Thai_thanthakhat ์ THAI CHARACTER THANTHAKHAT */ + { 0x0ded, 0x0e4d }, /* Thai_nikhahit ๠THAI CHARACTER NIKHAHIT */ + { 0x0df0, 0x0e50 }, /* Thai_leksun ๠THAI DIGIT ZERO */ + { 0x0df1, 0x0e51 }, /* Thai_leknung ๑ THAI DIGIT ONE */ + { 0x0df2, 0x0e52 }, /* Thai_leksong ๒ THAI DIGIT TWO */ + { 0x0df3, 0x0e53 }, /* Thai_leksam ๓ THAI DIGIT THREE */ + { 0x0df4, 0x0e54 }, /* Thai_leksi ๔ THAI DIGIT FOUR */ + { 0x0df5, 0x0e55 }, /* Thai_lekha ๕ THAI DIGIT FIVE */ + { 0x0df6, 0x0e56 }, /* Thai_lekhok ๖ THAI DIGIT SIX */ + { 0x0df7, 0x0e57 }, /* Thai_lekchet ๗ THAI DIGIT SEVEN */ + { 0x0df8, 0x0e58 }, /* Thai_lekpaet ๘ THAI DIGIT EIGHT */ + { 0x0df9, 0x0e59 }, /* Thai_lekkao ๙ THAI DIGIT NINE */ + { 0x0ed4, 0x11a8 }, /* Hangul_J_Kiyeog ᆨ HANGUL JONGSEONG KIYEOK */ + { 0x0ed5, 0x11a9 }, /* Hangul_J_SsangKiyeog ᆩ HANGUL JONGSEONG SSANGKIYEOK */ + { 0x0ed6, 0x11aa }, /* Hangul_J_KiyeogSios ᆪ HANGUL JONGSEONG KIYEOK-SIOS */ + { 0x0ed7, 0x11ab }, /* Hangul_J_Nieun ᆫ HANGUL JONGSEONG NIEUN */ + { 0x0ed8, 0x11ac }, /* Hangul_J_NieunJieuj ᆬ HANGUL JONGSEONG NIEUN-CIEUC */ + { 0x0ed9, 0x11ad }, /* Hangul_J_NieunHieuh ᆠHANGUL JONGSEONG NIEUN-HIEUH */ + { 0x0eda, 0x11ae }, /* Hangul_J_Dikeud ᆮ HANGUL JONGSEONG TIKEUT */ + { 0x0edb, 0x11af }, /* Hangul_J_Rieul ᆯ HANGUL JONGSEONG RIEUL */ + { 0x0edc, 0x11b0 }, /* Hangul_J_RieulKiyeog ᆰ HANGUL JONGSEONG RIEUL-KIYEOK */ + { 0x0edd, 0x11b1 }, /* Hangul_J_RieulMieum ᆱ HANGUL JONGSEONG RIEUL-MIEUM */ + { 0x0ede, 0x11b2 }, /* Hangul_J_RieulPieub ᆲ HANGUL JONGSEONG RIEUL-PIEUP */ + { 0x0edf, 0x11b3 }, /* Hangul_J_RieulSios ᆳ HANGUL JONGSEONG RIEUL-SIOS */ + { 0x0ee0, 0x11b4 }, /* Hangul_J_RieulTieut ᆴ HANGUL JONGSEONG RIEUL-THIEUTH */ + { 0x0ee1, 0x11b5 }, /* Hangul_J_RieulPhieuf ᆵ HANGUL JONGSEONG RIEUL-PHIEUPH */ + { 0x0ee2, 0x11b6 }, /* Hangul_J_RieulHieuh ᆶ HANGUL JONGSEONG RIEUL-HIEUH */ + { 0x0ee3, 0x11b7 }, /* Hangul_J_Mieum ᆷ HANGUL JONGSEONG MIEUM */ + { 0x0ee4, 0x11b8 }, /* Hangul_J_Pieub ᆸ HANGUL JONGSEONG PIEUP */ + { 0x0ee5, 0x11b9 }, /* Hangul_J_PieubSios ᆹ HANGUL JONGSEONG PIEUP-SIOS */ + { 0x0ee6, 0x11ba }, /* Hangul_J_Sios ᆺ HANGUL JONGSEONG SIOS */ + { 0x0ee7, 0x11bb }, /* Hangul_J_SsangSios ᆻ HANGUL JONGSEONG SSANGSIOS */ + { 0x0ee8, 0x11bc }, /* Hangul_J_Ieung ᆼ HANGUL JONGSEONG IEUNG */ + { 0x0ee9, 0x11bd }, /* Hangul_J_Jieuj ᆽ HANGUL JONGSEONG CIEUC */ + { 0x0eea, 0x11be }, /* Hangul_J_Cieuc ᆾ HANGUL JONGSEONG CHIEUCH */ + { 0x0eeb, 0x11bf }, /* Hangul_J_Khieuq ᆿ HANGUL JONGSEONG KHIEUKH */ + { 0x0eec, 0x11c0 }, /* Hangul_J_Tieut ᇀ HANGUL JONGSEONG THIEUTH */ + { 0x0eed, 0x11c1 }, /* Hangul_J_Phieuf ᇠHANGUL JONGSEONG PHIEUPH */ + { 0x0eee, 0x11c2 }, /* Hangul_J_Hieuh ᇂ HANGUL JONGSEONG HIEUH */ + { 0x0ef8, 0x11eb }, /* Hangul_J_PanSios ᇫ HANGUL JONGSEONG PANSIOS */ + { 0x0efa, 0x11f9 }, /* Hangul_J_YeorinHieuh ᇹ HANGUL JONGSEONG YEORINHIEUH */ + { 0x0aa2, 0x2002 }, /* enspace   EN SPACE */ + { 0x0aa1, 0x2003 }, /* emspace   EM SPACE */ + { 0x0aa3, 0x2004 }, /* em3space   THREE-PER-EM SPACE */ + { 0x0aa4, 0x2005 }, /* em4space   FOUR-PER-EM SPACE */ + { 0x0aa5, 0x2007 }, /* digitspace   FIGURE SPACE */ + { 0x0aa6, 0x2008 }, /* punctspace   PUNCTUATION SPACE */ + { 0x0aa7, 0x2009 }, /* thinspace   THIN SPACE */ + { 0x0aa8, 0x200a }, /* hairspace   HAIR SPACE */ + { 0x0abb, 0x2012 }, /* figdash ‒ FIGURE DASH */ + { 0x0aaa, 0x2013 }, /* endash – EN DASH */ + { 0x0aa9, 0x2014 }, /* emdash — EM DASH */ + { 0x07af, 0x2015 }, /* Greek_horizbar ― HORIZONTAL BAR */ + { 0x0cdf, 0x2017 }, /* hebrew_doublelowline ‗ DOUBLE LOW LINE */ + { 0x0ad0, 0x2018 }, /* leftsinglequotemark ‘ LEFT SINGLE QUOTATION MARK */ + { 0x0ad1, 0x2019 }, /* rightsinglequotemark ’ RIGHT SINGLE QUOTATION MARK */ + { 0x0afd, 0x201a }, /* singlelowquotemark ‚ SINGLE LOW-9 QUOTATION MARK */ + { 0x0ad2, 0x201c }, /* leftdoublequotemark “ LEFT DOUBLE QUOTATION MARK */ + { 0x0ad3, 0x201d }, /* rightdoublequotemark †RIGHT DOUBLE QUOTATION MARK */ + { 0x0afe, 0x201e }, /* doublelowquotemark „ DOUBLE LOW-9 QUOTATION MARK */ + { 0x0af1, 0x2020 }, /* dagger †DAGGER */ + { 0x0af2, 0x2021 }, /* doubledagger ‡ DOUBLE DAGGER */ + { 0x0ae6, 0x2022 }, /* enfilledcircbullet • BULLET */ + { 0x0aae, 0x2026 }, /* ellipsis … HORIZONTAL ELLIPSIS */ + { 0x0ad6, 0x2032 }, /* minutes ′ PRIME */ + { 0x0ad7, 0x2033 }, /* seconds ″ DOUBLE PRIME */ + { 0x0afc, 0x2038 }, /* caret ‸ CARET */ + { 0x047e, 0x203e }, /* overline ‾ OVERLINE */ + { 0x20a0, 0x20a0 }, /* EcuSign â‚ EURO-CURRENCY SIGN */ + { 0x20a1, 0x20a1 }, /* ColonSign â‚¡ COLON SIGN */ + { 0x20a2, 0x20a2 }, /* CruzeiroSign â‚¢ CRUZEIRO SIGN */ + { 0x20a3, 0x20a3 }, /* FFrancSign â‚£ FRENCH FRANC SIGN */ + { 0x20a4, 0x20a4 }, /* LiraSign ₤ LIRA SIGN */ + { 0x20a5, 0x20a5 }, /* MillSign â‚¥ MILL SIGN */ + { 0x20a6, 0x20a6 }, /* NairaSign ₦ NAIRA SIGN */ + { 0x20a7, 0x20a7 }, /* PesetaSign ₧ PESETA SIGN */ + { 0x20a8, 0x20a8 }, /* RupeeSign ₨ RUPEE SIGN */ + { 0x0eff, 0x20a9 }, /* Korean_Won â‚© WON SIGN */ + { 0x20a9, 0x20a9 }, /* WonSign â‚© WON SIGN */ + { 0x20aa, 0x20aa }, /* NewSheqelSign ₪ NEW SHEQEL SIGN */ + { 0x20ab, 0x20ab }, /* DongSign â‚« DONG SIGN */ + { 0x20ac, 0x20ac }, /* EuroSign € EURO SIGN */ + { 0x0ab8, 0x2105 }, /* careof â„… CARE OF */ + { 0x06b0, 0x2116 }, /* numerosign â„– NUMERO SIGN */ + { 0x0afb, 0x2117 }, /* phonographcopyright â„— SOUND RECORDING COPYRIGHT */ + { 0x0ad4, 0x211e }, /* prescription â„ž PRESCRIPTION TAKE */ + { 0x0ac9, 0x2122 }, /* trademark â„¢ TRADE MARK SIGN */ + { 0x0ab0, 0x2153 }, /* onethird â…“ VULGAR FRACTION ONE THIRD */ + { 0x0ab1, 0x2154 }, /* twothirds â…” VULGAR FRACTION TWO THIRDS */ + { 0x0ab2, 0x2155 }, /* onefifth â…• VULGAR FRACTION ONE FIFTH */ + { 0x0ab3, 0x2156 }, /* twofifths â…– VULGAR FRACTION TWO FIFTHS */ + { 0x0ab4, 0x2157 }, /* threefifths â…— VULGAR FRACTION THREE FIFTHS */ + { 0x0ab5, 0x2158 }, /* fourfifths â…˜ VULGAR FRACTION FOUR FIFTHS */ + { 0x0ab6, 0x2159 }, /* onesixth â…™ VULGAR FRACTION ONE SIXTH */ + { 0x0ab7, 0x215a }, /* fivesixths â…š VULGAR FRACTION FIVE SIXTHS */ + { 0x0ac3, 0x215b }, /* oneeighth â…› VULGAR FRACTION ONE EIGHTH */ + { 0x0ac4, 0x215c }, /* threeeighths â…œ VULGAR FRACTION THREE EIGHTHS */ + { 0x0ac5, 0x215d }, /* fiveeighths â… VULGAR FRACTION FIVE EIGHTHS */ + { 0x0ac6, 0x215e }, /* seveneighths â…ž VULGAR FRACTION SEVEN EIGHTHS */ + { 0x08fb, 0x2190 }, /* leftarrow ↠LEFTWARDS ARROW */ + { 0x08fc, 0x2191 }, /* uparrow ↑ UPWARDS ARROW */ + { 0x08fd, 0x2192 }, /* rightarrow → RIGHTWARDS ARROW */ + { 0x08fe, 0x2193 }, /* downarrow ↓ DOWNWARDS ARROW */ + { 0x08ce, 0x21d2 }, /* implies ⇒ RIGHTWARDS DOUBLE ARROW */ + { 0x08cd, 0x21d4 }, /* ifonlyif ⇔ LEFT RIGHT DOUBLE ARROW */ + { 0x08ef, 0x2202 }, /* partialderivative ∂ PARTIAL DIFFERENTIAL */ + { 0x08c5, 0x2207 }, /* nabla ∇ NABLA */ + { 0x0bca, 0x2218 }, /* jot ∘ RING OPERATOR */ + { 0x08d6, 0x221a }, /* radical √ SQUARE ROOT */ + { 0x08c1, 0x221d }, /* variation ∠PROPORTIONAL TO */ + { 0x08c2, 0x221e }, /* infinity ∞ INFINITY */ + { 0x08de, 0x2227 }, /* logicaland ∧ LOGICAL AND */ + { 0x0ba9, 0x2227 }, /* upcaret ∧ LOGICAL AND */ + { 0x08df, 0x2228 }, /* logicalor ∨ LOGICAL OR */ + { 0x0ba8, 0x2228 }, /* downcaret ∨ LOGICAL OR */ + { 0x08dc, 0x2229 }, /* intersection ∩ INTERSECTION */ + { 0x0bc3, 0x2229 }, /* upshoe ∩ INTERSECTION */ + { 0x08dd, 0x222a }, /* union ∪ UNION */ + { 0x0bd6, 0x222a }, /* downshoe ∪ UNION */ + { 0x08bf, 0x222b }, /* integral ∫ INTEGRAL */ + { 0x08c0, 0x2234 }, /* therefore ∴ THEREFORE */ + { 0x08c8, 0x2245 }, /* approximate ≅ APPROXIMATELY EQUAL TO */ + { 0x08bd, 0x2260 }, /* notequal ≠NOT EQUAL TO */ + { 0x08cf, 0x2261 }, /* identical ≡ IDENTICAL TO */ + { 0x08bc, 0x2264 }, /* lessthanequal ≤ LESS-THAN OR EQUAL TO */ + { 0x08be, 0x2265 }, /* greaterthanequal ≥ GREATER-THAN OR EQUAL TO */ + { 0x08da, 0x2282 }, /* includedin ⊂ SUBSET OF */ + { 0x0bda, 0x2282 }, /* leftshoe ⊂ SUBSET OF */ + { 0x08db, 0x2283 }, /* includes ⊃ SUPERSET OF */ + { 0x0bd8, 0x2283 }, /* rightshoe ⊃ SUPERSET OF */ + { 0x0bfc, 0x22a2 }, /* righttack ⊢ RIGHT TACK */ + { 0x0bdc, 0x22a3 }, /* lefttack ⊣ LEFT TACK */ + { 0x0bc2, 0x22a4 }, /* downtack ⊤ DOWN TACK */ + { 0x0bce, 0x22a5 }, /* uptack ⊥ UP TACK */ + { 0x0bd3, 0x2308 }, /* upstile ⌈ LEFT CEILING */ + { 0x0bc4, 0x230a }, /* downstile ⌊ LEFT FLOOR */ + { 0x0afa, 0x2315 }, /* telephonerecorder ⌕ TELEPHONE RECORDER */ + { 0x08a4, 0x2320 }, /* topintegral ⌠TOP HALF INTEGRAL */ + { 0x08a5, 0x2321 }, /* botintegral ⌡ BOTTOM HALF INTEGRAL */ + { 0x0abc, 0x2329 }, /* leftanglebracket 〈 LEFT-POINTING ANGLE BRACKET */ + { 0x0abe, 0x232a }, /* rightanglebracket 〉 RIGHT-POINTING ANGLE BRACKET */ + { 0x0bcc, 0x2395 }, /* quad ⎕ APL FUNCTIONAL SYMBOL QUAD (Unicode 3.0) */ + { 0x09e2, 0x2409 }, /* ht ≠SYMBOL FOR HORIZONTAL TABULATION */ + { 0x09e5, 0x240a }, /* lf ⊠SYMBOL FOR LINE FEED */ + { 0x09e9, 0x240b }, /* vt â‹ SYMBOL FOR VERTICAL TABULATION */ + { 0x09e3, 0x240c }, /* ff ⌠SYMBOL FOR FORM FEED */ + { 0x09e4, 0x240d }, /* cr â SYMBOL FOR CARRIAGE RETURN */ + { 0x09df, 0x2422 }, /* blank ⢠BLANK SYMBOL */ + { 0x09e8, 0x2424 }, /* nl ⤠SYMBOL FOR NEWLINE */ + { 0x09f1, 0x2500 }, /* horizlinescan5 ─ BOX DRAWINGS LIGHT HORIZONTAL */ + { 0x08a6, 0x2502 }, /* vertconnector │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x09f8, 0x2502 }, /* vertbar │ BOX DRAWINGS LIGHT VERTICAL */ + { 0x09ec, 0x250c }, /* upleftcorner ┌ BOX DRAWINGS LIGHT DOWN AND RIGHT */ + { 0x09eb, 0x2510 }, /* uprightcorner â” BOX DRAWINGS LIGHT DOWN AND LEFT */ + { 0x09ed, 0x2514 }, /* lowleftcorner â”” BOX DRAWINGS LIGHT UP AND RIGHT */ + { 0x09ea, 0x2518 }, /* lowrightcorner ┘ BOX DRAWINGS LIGHT UP AND LEFT */ + { 0x09f4, 0x251c }, /* leftt ├ BOX DRAWINGS LIGHT VERTICAL AND RIGHT */ + { 0x09f5, 0x2524 }, /* rightt ┤ BOX DRAWINGS LIGHT VERTICAL AND LEFT */ + { 0x09f7, 0x252c }, /* topt ┬ BOX DRAWINGS LIGHT DOWN AND HORIZONTAL */ + { 0x09f6, 0x2534 }, /* bott â”´ BOX DRAWINGS LIGHT UP AND HORIZONTAL */ + { 0x09ee, 0x253c }, /* crossinglines ┼ BOX DRAWINGS LIGHT VERTICAL AND HORIZONTAL */ + { 0x09e1, 0x2592 }, /* checkerboard â–’ MEDIUM SHADE */ + { 0x0adf, 0x25a0 }, /* emfilledrect â– BLACK SQUARE */ + { 0x0acf, 0x25a1 }, /* emopenrectangle â–¡ WHITE SQUARE */ + { 0x0ae7, 0x25aa }, /* enfilledsqbullet â–ª BLACK SMALL SQUARE */ + { 0x0ae1, 0x25ab }, /* enopensquarebullet â–« WHITE SMALL SQUARE */ + { 0x0adb, 0x25ac }, /* filledrectbullet â–¬ BLACK RECTANGLE */ + { 0x0ae2, 0x25ad }, /* openrectbullet â– WHITE RECTANGLE */ + { 0x0ae8, 0x25b2 }, /* filledtribulletup â–² BLACK UP-POINTING TRIANGLE */ + { 0x0ae3, 0x25b3 }, /* opentribulletup â–³ WHITE UP-POINTING TRIANGLE */ + { 0x0add, 0x25b6 }, /* filledrighttribullet â–¶ BLACK RIGHT-POINTING TRIANGLE */ + { 0x0acd, 0x25b7 }, /* rightopentriangle â–· WHITE RIGHT-POINTING TRIANGLE */ + { 0x0ae9, 0x25bc }, /* filledtribulletdown â–¼ BLACK DOWN-POINTING TRIANGLE */ + { 0x0ae4, 0x25bd }, /* opentribulletdown â–½ WHITE DOWN-POINTING TRIANGLE */ + { 0x0adc, 0x25c0 }, /* filledlefttribullet â—€ BLACK LEFT-POINTING TRIANGLE */ + { 0x0acc, 0x25c1 }, /* leftopentriangle â— WHITE LEFT-POINTING TRIANGLE */ + { 0x09e0, 0x25c6 }, /* soliddiamond â—† BLACK DIAMOND */ + { 0x0ace, 0x25cb }, /* emopencircle â—‹ WHITE CIRCLE */ + { 0x0bcf, 0x25cb }, /* circle â—‹ WHITE CIRCLE */ + { 0x0ade, 0x25cf }, /* emfilledcircle â— BLACK CIRCLE */ + { 0x0ae0, 0x25e6 }, /* enopencircbullet â—¦ WHITE BULLET */ + { 0x0ae5, 0x2606 }, /* openstar ☆ WHITE STAR */ + { 0x0af9, 0x260e }, /* telephone ☎ BLACK TELEPHONE */ + { 0x0aca, 0x2613 }, /* signaturemark ☓ SALTIRE */ + { 0x0aea, 0x261c }, /* leftpointer ☜ WHITE LEFT POINTING INDEX */ + { 0x0aeb, 0x261e }, /* rightpointer ☞ WHITE RIGHT POINTING INDEX */ + { 0x0af8, 0x2640 }, /* femalesymbol ♀ FEMALE SIGN */ + { 0x0af7, 0x2642 }, /* malesymbol ♂ MALE SIGN */ + { 0x0aec, 0x2663 }, /* club ♣ BLACK CLUB SUIT */ + { 0x0aee, 0x2665 }, /* heart ♥ BLACK HEART SUIT */ + { 0x0aed, 0x2666 }, /* diamond ♦ BLACK DIAMOND SUIT */ + { 0x0af6, 0x266d }, /* musicalflat â™ MUSIC FLAT SIGN */ + { 0x0af5, 0x266f }, /* musicalsharp ♯ MUSIC SHARP SIGN */ + { 0x0af3, 0x2713 }, /* checkmark ✓ CHECK MARK */ + { 0x0af4, 0x2717 }, /* ballotcross ✗ BALLOT X */ + { 0x0ad9, 0x271d }, /* latincross ✠LATIN CROSS */ + { 0x0af0, 0x2720 }, /* maltesecross ✠MALTESE CROSS */ + { 0x04a4, 0x3001 }, /* kana_comma 〠IDEOGRAPHIC COMMA */ + { 0x04a1, 0x3002 }, /* kana_fullstop 。 IDEOGRAPHIC FULL STOP */ + { 0x04a2, 0x300c }, /* kana_openingbracket 「 LEFT CORNER BRACKET */ + { 0x04a3, 0x300d }, /* kana_closingbracket 〠RIGHT CORNER BRACKET */ + { 0x04de, 0x309b }, /* voicedsound ã‚› KATAKANA-HIRAGANA VOICED SOUND MARK */ + { 0x04df, 0x309c }, /* semivoicedsound ã‚œ KATAKANA-HIRAGANA SEMI-VOICED SOUND MARK */ + { 0x04a7, 0x30a1 }, /* kana_a ã‚¡ KATAKANA LETTER SMALL A */ + { 0x04b1, 0x30a2 }, /* kana_A ã‚¢ KATAKANA LETTER A */ + { 0x04a8, 0x30a3 }, /* kana_i ã‚£ KATAKANA LETTER SMALL I */ + { 0x04b2, 0x30a4 }, /* kana_I イ KATAKANA LETTER I */ + { 0x04a9, 0x30a5 }, /* kana_u ã‚¥ KATAKANA LETTER SMALL U */ + { 0x04b3, 0x30a6 }, /* kana_U ウ KATAKANA LETTER U */ + { 0x04aa, 0x30a7 }, /* kana_e ェ KATAKANA LETTER SMALL E */ + { 0x04b4, 0x30a8 }, /* kana_E エ KATAKANA LETTER E */ + { 0x04ab, 0x30a9 }, /* kana_o ã‚© KATAKANA LETTER SMALL O */ + { 0x04b5, 0x30aa }, /* kana_O オ KATAKANA LETTER O */ + { 0x04b6, 0x30ab }, /* kana_KA ã‚« KATAKANA LETTER KA */ + { 0x04b7, 0x30ad }, /* kana_KI ã‚ KATAKANA LETTER KI */ + { 0x04b8, 0x30af }, /* kana_KU ク KATAKANA LETTER KU */ + { 0x04b9, 0x30b1 }, /* kana_KE ケ KATAKANA LETTER KE */ + { 0x04ba, 0x30b3 }, /* kana_KO コ KATAKANA LETTER KO */ + { 0x04bb, 0x30b5 }, /* kana_SA サ KATAKANA LETTER SA */ + { 0x04bc, 0x30b7 }, /* kana_SHI ã‚· KATAKANA LETTER SI */ + { 0x04bd, 0x30b9 }, /* kana_SU ス KATAKANA LETTER SU */ + { 0x04be, 0x30bb }, /* kana_SE ã‚» KATAKANA LETTER SE */ + { 0x04bf, 0x30bd }, /* kana_SO ソ KATAKANA LETTER SO */ + { 0x04c0, 0x30bf }, /* kana_TA ã‚¿ KATAKANA LETTER TA */ + { 0x04c1, 0x30c1 }, /* kana_CHI ムKATAKANA LETTER TI */ + { 0x04af, 0x30c3 }, /* kana_tsu ッ KATAKANA LETTER SMALL TU */ + { 0x04c2, 0x30c4 }, /* kana_TSU ツ KATAKANA LETTER TU */ + { 0x04c3, 0x30c6 }, /* kana_TE テ KATAKANA LETTER TE */ + { 0x04c4, 0x30c8 }, /* kana_TO ト KATAKANA LETTER TO */ + { 0x04c5, 0x30ca }, /* kana_NA ナ KATAKANA LETTER NA */ + { 0x04c6, 0x30cb }, /* kana_NI ニ KATAKANA LETTER NI */ + { 0x04c7, 0x30cc }, /* kana_NU ヌ KATAKANA LETTER NU */ + { 0x04c8, 0x30cd }, /* kana_NE ムKATAKANA LETTER NE */ + { 0x04c9, 0x30ce }, /* kana_NO ノ KATAKANA LETTER NO */ + { 0x04ca, 0x30cf }, /* kana_HA ムKATAKANA LETTER HA */ + { 0x04cb, 0x30d2 }, /* kana_HI ヒ KATAKANA LETTER HI */ + { 0x04cc, 0x30d5 }, /* kana_FU フ KATAKANA LETTER HU */ + { 0x04cd, 0x30d8 }, /* kana_HE ヘ KATAKANA LETTER HE */ + { 0x04ce, 0x30db }, /* kana_HO ホ KATAKANA LETTER HO */ + { 0x04cf, 0x30de }, /* kana_MA マ KATAKANA LETTER MA */ + { 0x04d0, 0x30df }, /* kana_MI ミ KATAKANA LETTER MI */ + { 0x04d1, 0x30e0 }, /* kana_MU ムKATAKANA LETTER MU */ + { 0x04d2, 0x30e1 }, /* kana_ME メ KATAKANA LETTER ME */ + { 0x04d3, 0x30e2 }, /* kana_MO モ KATAKANA LETTER MO */ + { 0x04ac, 0x30e3 }, /* kana_ya ャ KATAKANA LETTER SMALL YA */ + { 0x04d4, 0x30e4 }, /* kana_YA ヤ KATAKANA LETTER YA */ + { 0x04ad, 0x30e5 }, /* kana_yu ュ KATAKANA LETTER SMALL YU */ + { 0x04d5, 0x30e6 }, /* kana_YU ユ KATAKANA LETTER YU */ + { 0x04ae, 0x30e7 }, /* kana_yo ョ KATAKANA LETTER SMALL YO */ + { 0x04d6, 0x30e8 }, /* kana_YO ヨ KATAKANA LETTER YO */ + { 0x04d7, 0x30e9 }, /* kana_RA ラ KATAKANA LETTER RA */ + { 0x04d8, 0x30ea }, /* kana_RI リ KATAKANA LETTER RI */ + { 0x04d9, 0x30eb }, /* kana_RU ル KATAKANA LETTER RU */ + { 0x04da, 0x30ec }, /* kana_RE レ KATAKANA LETTER RE */ + { 0x04db, 0x30ed }, /* kana_RO ムKATAKANA LETTER RO */ + { 0x04dc, 0x30ef }, /* kana_WA ワ KATAKANA LETTER WA */ + { 0x04a6, 0x30f2 }, /* kana_WO ヲ KATAKANA LETTER WO */ + { 0x04dd, 0x30f3 }, /* kana_N ン KATAKANA LETTER N */ + { 0x04a5, 0x30fb }, /* kana_conjunctive ・ KATAKANA MIDDLE DOT */ + { 0x04b0, 0x30fc }, /* prolongedsound ー KATAKANA-HIRAGANA PROLONGED SOUND MARK */ + { 0x0ea1, 0x3131 }, /* Hangul_Kiyeog ㄱ HANGUL LETTER KIYEOK */ + { 0x0ea2, 0x3132 }, /* Hangul_SsangKiyeog ㄲ HANGUL LETTER SSANGKIYEOK */ + { 0x0ea3, 0x3133 }, /* Hangul_KiyeogSios ㄳ HANGUL LETTER KIYEOK-SIOS */ + { 0x0ea4, 0x3134 }, /* Hangul_Nieun ã„´ HANGUL LETTER NIEUN */ + { 0x0ea5, 0x3135 }, /* Hangul_NieunJieuj ㄵ HANGUL LETTER NIEUN-CIEUC */ + { 0x0ea6, 0x3136 }, /* Hangul_NieunHieuh ㄶ HANGUL LETTER NIEUN-HIEUH */ + { 0x0ea7, 0x3137 }, /* Hangul_Dikeud ã„· HANGUL LETTER TIKEUT */ + { 0x0ea8, 0x3138 }, /* Hangul_SsangDikeud ㄸ HANGUL LETTER SSANGTIKEUT */ + { 0x0ea9, 0x3139 }, /* Hangul_Rieul ㄹ HANGUL LETTER RIEUL */ + { 0x0eaa, 0x313a }, /* Hangul_RieulKiyeog ㄺ HANGUL LETTER RIEUL-KIYEOK */ + { 0x0eab, 0x313b }, /* Hangul_RieulMieum ã„» HANGUL LETTER RIEUL-MIEUM */ + { 0x0eac, 0x313c }, /* Hangul_RieulPieub ㄼ HANGUL LETTER RIEUL-PIEUP */ + { 0x0ead, 0x313d }, /* Hangul_RieulSios ㄽ HANGUL LETTER RIEUL-SIOS */ + { 0x0eae, 0x313e }, /* Hangul_RieulTieut ㄾ HANGUL LETTER RIEUL-THIEUTH */ + { 0x0eaf, 0x313f }, /* Hangul_RieulPhieuf ã„¿ HANGUL LETTER RIEUL-PHIEUPH */ + { 0x0eb0, 0x3140 }, /* Hangul_RieulHieuh ã…€ HANGUL LETTER RIEUL-HIEUH */ + { 0x0eb1, 0x3141 }, /* Hangul_Mieum ã… HANGUL LETTER MIEUM */ + { 0x0eb2, 0x3142 }, /* Hangul_Pieub ã…‚ HANGUL LETTER PIEUP */ + { 0x0eb3, 0x3143 }, /* Hangul_SsangPieub ã…ƒ HANGUL LETTER SSANGPIEUP */ + { 0x0eb4, 0x3144 }, /* Hangul_PieubSios ã…„ HANGUL LETTER PIEUP-SIOS */ + { 0x0eb5, 0x3145 }, /* Hangul_Sios ã…… HANGUL LETTER SIOS */ + { 0x0eb6, 0x3146 }, /* Hangul_SsangSios ã…† HANGUL LETTER SSANGSIOS */ + { 0x0eb7, 0x3147 }, /* Hangul_Ieung ã…‡ HANGUL LETTER IEUNG */ + { 0x0eb8, 0x3148 }, /* Hangul_Jieuj ã…ˆ HANGUL LETTER CIEUC */ + { 0x0eb9, 0x3149 }, /* Hangul_SsangJieuj ã…‰ HANGUL LETTER SSANGCIEUC */ + { 0x0eba, 0x314a }, /* Hangul_Cieuc ã…Š HANGUL LETTER CHIEUCH */ + { 0x0ebb, 0x314b }, /* Hangul_Khieuq ã…‹ HANGUL LETTER KHIEUKH */ + { 0x0ebc, 0x314c }, /* Hangul_Tieut ã…Œ HANGUL LETTER THIEUTH */ + { 0x0ebd, 0x314d }, /* Hangul_Phieuf ã… HANGUL LETTER PHIEUPH */ + { 0x0ebe, 0x314e }, /* Hangul_Hieuh ã…Ž HANGUL LETTER HIEUH */ + { 0x0ebf, 0x314f }, /* Hangul_A ã… HANGUL LETTER A */ + { 0x0ec0, 0x3150 }, /* Hangul_AE ã… HANGUL LETTER AE */ + { 0x0ec1, 0x3151 }, /* Hangul_YA ã…‘ HANGUL LETTER YA */ + { 0x0ec2, 0x3152 }, /* Hangul_YAE ã…’ HANGUL LETTER YAE */ + { 0x0ec3, 0x3153 }, /* Hangul_EO ã…“ HANGUL LETTER EO */ + { 0x0ec4, 0x3154 }, /* Hangul_E ã…” HANGUL LETTER E */ + { 0x0ec5, 0x3155 }, /* Hangul_YEO ã…• HANGUL LETTER YEO */ + { 0x0ec6, 0x3156 }, /* Hangul_YE ã…– HANGUL LETTER YE */ + { 0x0ec7, 0x3157 }, /* Hangul_O ã…— HANGUL LETTER O */ + { 0x0ec8, 0x3158 }, /* Hangul_WA ã…˜ HANGUL LETTER WA */ + { 0x0ec9, 0x3159 }, /* Hangul_WAE ã…™ HANGUL LETTER WAE */ + { 0x0eca, 0x315a }, /* Hangul_OE ã…š HANGUL LETTER OE */ + { 0x0ecb, 0x315b }, /* Hangul_YO ã…› HANGUL LETTER YO */ + { 0x0ecc, 0x315c }, /* Hangul_U ã…œ HANGUL LETTER U */ + { 0x0ecd, 0x315d }, /* Hangul_WEO ã… HANGUL LETTER WEO */ + { 0x0ece, 0x315e }, /* Hangul_WE ã…ž HANGUL LETTER WE */ + { 0x0ecf, 0x315f }, /* Hangul_WI ã…Ÿ HANGUL LETTER WI */ + { 0x0ed0, 0x3160 }, /* Hangul_YU ã… HANGUL LETTER YU */ + { 0x0ed1, 0x3161 }, /* Hangul_EU ã…¡ HANGUL LETTER EU */ + { 0x0ed2, 0x3162 }, /* Hangul_YI ã…¢ HANGUL LETTER YI */ + { 0x0ed3, 0x3163 }, /* Hangul_I ã…£ HANGUL LETTER I */ + { 0x0eef, 0x316d }, /* Hangul_RieulYeorinHieuh ã… HANGUL LETTER RIEUL-YEORINHIEUH */ + { 0x0ef0, 0x3171 }, /* Hangul_SunkyeongeumMieum ã…± HANGUL LETTER KAPYEOUNMIEUM */ + { 0x0ef1, 0x3178 }, /* Hangul_SunkyeongeumPieub ã…¸ HANGUL LETTER KAPYEOUNPIEUP */ + { 0x0ef2, 0x317f }, /* Hangul_PanSios ã…¿ HANGUL LETTER PANSIOS */ + { 0x0ef4, 0x3184 }, /* Hangul_SunkyeongeumPhieuf ㆄ HANGUL LETTER KAPYEOUNPHIEUPH */ + { 0x0ef5, 0x3186 }, /* Hangul_YeorinHieuh ㆆ HANGUL LETTER YEORINHIEUH */ + { 0x0ef6, 0x318d }, /* Hangul_AraeA ㆠHANGUL LETTER ARAEA */ + { 0x0ef7, 0x318e }, /* Hangul_AraeAE ㆎ HANGUL LETTER ARAEAE */ +}; + +static guint +unicode_to_keyval (wchar_t ucs) +{ + int min = 0; + int max = sizeof(u2ktab) / sizeof(u2ktab[0]) - 1; + int mid; + + /* First check for Latin-1 characters (1:1 mapping) */ + if ((ucs >= 0x0020 && ucs <= 0x007e) || + (ucs >= 0x00a0 && ucs <= 0x00ff)) + return ucs; + + /* Binary search in table */ + while (max >= min) { + mid = (min + max) / 2; + if (u2ktab[mid].ucs < ucs) + min = mid + 1; + else if (u2ktab[mid].ucs > ucs) + max = mid - 1; + else { + /* found it */ + return u2ktab[mid].keysym; + } + } + + /* + * No matching keysym value found, return Unicode value plus 0x01000000 + * (a convention introduced in the UTF-8 work on xterm). + */ + return ucs | 0x01000000; +} + +static void +build_key_event_state (GdkEvent *event) +{ + event->key.state = 0; + if (GetKeyState (VK_SHIFT) < 0) + event->key.state |= GDK_SHIFT_MASK; + if (GetKeyState (VK_CAPITAL) & 0x1) + event->key.state |= GDK_LOCK_MASK; + if (!is_AltGr_key) + { + if (GetKeyState (VK_CONTROL) < 0) + { + event->key.state |= GDK_CONTROL_MASK; + if (event->key.keyval < ' ') + event->key.keyval += '@'; + } + else if (event->key.keyval < ' ') + { + event->key.state |= GDK_CONTROL_MASK; + event->key.keyval += '@'; + } + if (GetKeyState (VK_MENU) < 0) + event->key.state |= GDK_MOD1_MASK; + } +} + +static void +build_keypress_event (GdkWindowPrivate *window_private, + GdkEvent *event, + MSG *xevent) +{ + gint i, bytesleft, bytecount, ucount, ucleft, len; + guchar buf[100], *bp; + wchar_t wbuf[100], *wcp; + + event->key.type = GDK_KEY_PRESS; + event->key.time = xevent->time; + + if (xevent->message == WM_CHAR) + { + bytecount = MIN ((xevent->lParam & 0xFFFF), sizeof (buf)); + for (i = 0; i < bytecount; i++) + buf[i] = xevent->wParam; + } + else + { + /* WM_IME_CHAR */ + event->key.keyval = GDK_VoidSymbol; + if (xevent->wParam & 0xFF00) + { + /* Contrary to the documentation, + * the lead byte is the msb byte. + */ + buf[0] = ((xevent->wParam >> 8) & 0xFF); + buf[1] = (xevent->wParam & 0xFF); + bytecount = 2; + } + else + { + buf[0] = (xevent->wParam & 0xFF); + bytecount = 1; + } + } + + /* Convert from the window's current code page + * to Unicode. Then convert to UTF-8. + * We don't handle the surrogate stuff. Should we? + */ + ucount = MultiByteToWideChar (window_private->charset_info.ciACP, + 0, buf, bytecount, wbuf, 100); + + if (ucount == 0) + event->key.keyval = GDK_VoidSymbol; + else if (xevent->message == WM_CHAR) + if (xevent->wParam < ' ') + event->key.keyval = xevent->wParam + '@'; + else + event->key.keyval = unicode_to_keyval (wbuf[0]); + else + event->key.keyval = GDK_VoidSymbol; + + build_key_event_state (event); + + ucleft = ucount; + len = 0; + wcp = wbuf; + while (ucleft-- > 0) + { + wchar_t c = *wcp++; + + if (c < 0x80) + len += 1; + else if (c < 0x800) + len += 2; + else + len += 3; + } + + event->key.string = g_malloc (len + 1); + event->key.length = len; + + ucleft = ucount; + wcp = wbuf; + bp = event->key.string; + while (ucleft-- > 0) + { + int first; + int i; + wchar_t c = *wcp++; + + if (c < 0x80) + { + first = 0; + len = 1; + } + else if (c < 0x800) + { + first = 0xc0; + len = 2; + } + else + { + first = 0xe0; + len = 3; + } + +#if 1 + /* Woo-hoo! */ + switch (len) + { + case 3: bp[2] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */ + case 2: bp[1] = (c & 0x3f) | 0x80; c >>= 6; /* Fall through */ + case 1: bp[0] = c | first; + } +#else + for (i = len - 1; i > 0; --i) + { + bp[i] = (c & 0x3f) | 0x80; + c >>= 6; + } + bp[0] = c | first; +#endif + + bp += len; + } + *bp = 0; +} + +static void +print_event_state (gint state) +{ + if (state & GDK_SHIFT_MASK) + g_print ("SHIFT "); + if (state & GDK_LOCK_MASK) + g_print ("LOCK "); + if (state & GDK_CONTROL_MASK) + g_print ("CONTROL "); + if (state & GDK_MOD1_MASK) + g_print ("MOD1 "); + if (state & GDK_BUTTON1_MASK) + g_print ("BUTTON1 "); + if (state & GDK_BUTTON2_MASK) + g_print ("BUTTON2 "); + if (state & GDK_BUTTON3_MASK) + g_print ("BUTTON3 "); +} + +static void +print_event (GdkEvent *event) +{ + gchar *escaped, *kvname; + + switch (event->any.type) + { + case GDK_NOTHING: g_print ("GDK_NOTHING "); break; + case GDK_DELETE: g_print ("GDK_DELETE "); break; + case GDK_DESTROY: g_print ("GDK_DESTROY "); break; + case GDK_EXPOSE: g_print ("GDK_EXPOSE "); break; + case GDK_MOTION_NOTIFY: g_print ("GDK_MOTION_NOTIFY "); break; + case GDK_BUTTON_PRESS: g_print ("GDK_BUTTON_PRESS "); break; + case GDK_2BUTTON_PRESS: g_print ("GDK_2BUTTON_PRESS "); break; + case GDK_3BUTTON_PRESS: g_print ("GDK_3BUTTON_PRESS "); break; + case GDK_BUTTON_RELEASE: g_print ("GDK_BUTTON_RELEASE "); break; + case GDK_KEY_PRESS: g_print ("GDK_KEY_PRESS "); break; + case GDK_KEY_RELEASE: g_print ("GDK_KEY_RELEASE "); break; + case GDK_ENTER_NOTIFY: g_print ("GDK_ENTER_NOTIFY "); break; + case GDK_LEAVE_NOTIFY: g_print ("GDK_LEAVE_NOTIFY "); break; + case GDK_FOCUS_CHANGE: g_print ("GDK_FOCUS_CHANGE "); break; + case GDK_CONFIGURE: g_print ("GDK_CONFIGURE "); break; + case GDK_MAP: g_print ("GDK_MAP "); break; + case GDK_UNMAP: g_print ("GDK_UNMAP "); break; + case GDK_PROPERTY_NOTIFY: g_print ("GDK_PROPERTY_NOTIFY "); break; + case GDK_SELECTION_CLEAR: g_print ("GDK_SELECTION_CLEAR "); break; + case GDK_SELECTION_REQUEST: g_print ("GDK_SELECTION_REQUEST "); break; + case GDK_SELECTION_NOTIFY: g_print ("GDK_SELECTION_NOTIFY "); break; + case GDK_PROXIMITY_IN: g_print ("GDK_PROXIMITY_IN "); break; + case GDK_PROXIMITY_OUT: g_print ("GDK_PROXIMITY_OUT "); break; + case GDK_DRAG_ENTER: g_print ("GDK_DRAG_ENTER "); break; + case GDK_DRAG_LEAVE: g_print ("GDK_DRAG_LEAVE "); break; + case GDK_DRAG_MOTION: g_print ("GDK_DRAG_MOTION "); break; + case GDK_DRAG_STATUS: g_print ("GDK_DRAG_STATUS "); break; + case GDK_DROP_START: g_print ("GDK_DROP_START "); break; + case GDK_DROP_FINISHED: g_print ("GDK_DROP_FINISHED "); break; + case GDK_CLIENT_EVENT: g_print ("GDK_CLIENT_EVENT "); break; + case GDK_VISIBILITY_NOTIFY: g_print ("GDK_VISIBILITY_NOTIFY "); break; + case GDK_NO_EXPOSE: g_print ("GDK_NO_EXPOSE "); break; + } + g_print ("%#x ", GDK_DRAWABLE_XID (event->any.window)); + + switch (event->any.type) + { + case GDK_EXPOSE: + g_print ("%dx%d@+%d+%d %d", + event->expose.area.width, + event->expose.area.height, + event->expose.area.x, + event->expose.area.y, + event->expose.count); + break; + case GDK_MOTION_NOTIFY: + print_event_state (event->motion.state); + break; + case GDK_BUTTON_PRESS: + case GDK_BUTTON_RELEASE: + g_print ("%d ", event->button.button); + print_event_state (event->button.state); + break; + case GDK_KEY_PRESS: + case GDK_KEY_RELEASE: + if (event->key.length == 0) + escaped = g_strdup (""); + else + escaped = g_strescape (event->key.string, NULL); + kvname = gdk_keyval_name (event->key.keyval); + g_print ("%s %d:\"%s\" ", + (kvname ? kvname : "??"), + event->key.length, + escaped); + g_free (escaped); + print_event_state (event->key.state); + break; + case GDK_ENTER_NOTIFY: + case GDK_LEAVE_NOTIFY: + g_print (" %s", + (event->crossing.detail == GDK_NOTIFY_INFERIOR ? "INFERIOR" : + (event->crossing.detail == GDK_NOTIFY_ANCESTOR ? "ANCESTOR" : + (event->crossing.detail == GDK_NOTIFY_NONLINEAR ? "NONLINEAR" : + "???")))); + break; + } + g_print ("\n"); +} + static void synthesize_crossing_events (GdkWindow *window, MSG *xevent) { + TRACKMOUSEEVENT tme; GdkEvent *event; - GdkWindowPrivate *window_private = (GdkWindowPrivate *) window; - GdkWindowPrivate *curWnd_private = (GdkWindowPrivate *) curWnd; - if (curWnd && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK)) + /* If we are not using TrackMouseEvent, generate a leave notify + * event if necessary + */ + if (p_TrackMouseEvent == NULL + && curWnd + && (WINDOW_PRIVATE(curWnd)->event_mask & GDK_LEAVE_NOTIFY_MASK)) { GDK_NOTE (EVENTS, g_print ("synthesizing LEAVE_NOTIFY event\n")); @@ -1099,15 +3073,21 @@ synthesize_crossing_events (GdkWindow *window, event->crossing.x_root = curXroot; event->crossing.y_root = curYroot; event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_UNKNOWN; + if (IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window))) + event->crossing.detail = GDK_NOTIFY_INFERIOR; + else if (IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd))) + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + else + event->crossing.detail = GDK_NOTIFY_NONLINEAR; event->crossing.focus = TRUE; /* ??? */ event->crossing.state = 0; /* ??? */ gdk_event_queue_append (event); + GDK_NOTE (EVENTS, print_event (event)); } - if (window_private && (window_private->event_mask & GDK_ENTER_NOTIFY_MASK)) + if (WINDOW_PRIVATE(window)->event_mask & GDK_ENTER_NOTIFY_MASK) { GDK_NOTE (EVENTS, g_print ("synthesizing ENTER_NOTIFY event\n")); @@ -1122,35 +3102,217 @@ synthesize_crossing_events (GdkWindow *window, event->crossing.x_root = (gfloat) xevent->pt.x; event->crossing.y_root = (gfloat) xevent->pt.y; event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_UNKNOWN; + if (curWnd + && IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window))) + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + else if (curWnd + && IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd))) + event->crossing.detail = GDK_NOTIFY_INFERIOR; + else + event->crossing.detail = GDK_NOTIFY_NONLINEAR; event->crossing.focus = TRUE; /* ??? */ event->crossing.state = 0; /* ??? */ gdk_event_queue_append (event); - if (window_private->extension_events != 0 + GDK_NOTE (EVENTS, print_event (event)); + + if (WINDOW_PRIVATE(window)->extension_events != 0 && gdk_input_vtable.enter_event) gdk_input_vtable.enter_event (&event->crossing, window); + } if (curWnd) gdk_window_unref (curWnd); curWnd = window; gdk_window_ref (curWnd); + if (p_TrackMouseEvent != NULL) + { + tme.cbSize = sizeof (TRACKMOUSEEVENT); + tme.dwFlags = TME_LEAVE; + tme.hwndTrack = GDK_DRAWABLE_XID (curWnd); + tme.dwHoverTime = HOVER_DEFAULT; + + (*p_TrackMouseEvent) (&tme); + } +} + +static GdkWindow * +key_propagate (GdkWindow *window, + MSG *xevent) +{ + gdk_window_unref (window); + window = WINDOW_PRIVATE(window)->parent; + gdk_window_ref (window); + GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n", + GDK_DRAWABLE_XID (window))); + + return window; +} + +static GdkWindow * +mouse_propagate (GdkWindow *window, + MSG *xevent) +{ + POINT pt; + + pt.x = LOWORD (xevent->lParam); + pt.y = HIWORD (xevent->lParam); + ClientToScreen (GDK_DRAWABLE_XID (window), &pt); + gdk_window_unref (window); + window = WINDOW_PRIVATE(window)->parent; + gdk_window_ref (window); + ScreenToClient (GDK_DRAWABLE_XID (window), &pt); + xevent->lParam = MAKELPARAM (pt.x, pt.y); + GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n", + GDK_DRAWABLE_XID (window))); + return window; +} + +#ifdef NEW_PROPAGATION_CODE + +static gboolean +propagate (GdkWindow **window, + MSG *xevent, + GdkWindow *grab_window, + gboolean grab_owner_events, + gint grab_mask, + gboolean (*doesnt_want_it) (gint mask, + MSG *xevent), + GdkWindow *(*propagate) (GdkWindow *window, + MSG *xevent)) +{ + if (grab_window != NULL && !grab_owner_events) + { + /* Event source is grabbed with owner_events FALSE */ + GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE, ")); + if ((*doesnt_want_it) (grab_mask, xevent)) + { + GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n")); + return FALSE; + } + else + { + GDK_NOTE (EVENTS, g_print ("...sending to grabber %#x\n", + GDK_DRAWABLE_XID (grab_window))); + gdk_window_unref (*window); + *window = grab_window; + gdk_window_ref (*window); + return TRUE; + } + } + while (TRUE) + { + if ((*doesnt_want_it) (WINDOW_PRIVATE(*window)->event_mask, xevent)) + { + /* Owner doesn't want it, propagate to parent. */ + if (WINDOW_PRIVATE(*window)->parent == (GdkWindow *) gdk_root_parent) + { + /* No parent; check if grabbed */ + if (grab_window != NULL) + { + /* Event source is grabbed with owner_events TRUE */ + GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n")); + if ((*doesnt_want_it) (grab_mask, xevent)) + { + /* Grabber doesn't want it either */ + GDK_NOTE (EVENTS, g_print ("...grabber doesn't want it\n")); + return FALSE; + } + else + { + /* Grabbed! */ + GDK_NOTE (EVENTS, g_print ("...sending to grabber %#x\n", + GDK_DRAWABLE_XID (grab_window))); + gdk_window_unref (*window); + *window = grab_window; + gdk_window_ref (*window); + return TRUE; + } + } + else + { + GDK_NOTE (EVENTS, "...undelivered\n"); + return FALSE; + } + } + else + { + *window = (*propagate) (*window, xevent); + GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n", + GDK_DRAWABLE_XID (*window))); + /* The only branch where we actually continue the loop */ + } + } + else + return TRUE; + } +} + +static gboolean +doesnt_want_key (gint mask, + MSG *xevent) +{ + return (((xevent->message == WM_KEYUP + || xevent->message == WM_SYSKEYUP) + && !(mask & GDK_KEY_RELEASE_MASK)) + || + ((xevent->message == WM_KEYDOWN + || xevent->message == WM_SYSKEYDOWN) + && !(mask & GDK_KEY_PRESS_MASK))); +} + +static gboolean +doesnt_want_char (gint mask, + MSG *xevent) +{ + return !(mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK)); +} + +static gboolean +doesnt_want_button_press (gint mask, + MSG *xevent) +{ + return !(mask & GDK_BUTTON_PRESS_MASK); +} + +static gboolean +doesnt_want_button_release (gint mask, + MSG *xevent) +{ + return !(mask & GDK_BUTTON_RELEASE_MASK); +} + +static gboolean +doesnt_want_button_motion (gint mask, + MSG *xevent) +{ + return !((mask & GDK_POINTER_MOTION_MASK) + || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) + && (mask & GDK_BUTTON_MOTION_MASK)) + || ((xevent->wParam & MK_LBUTTON) + && (mask & GDK_BUTTON1_MOTION_MASK)) + || ((xevent->wParam & MK_MBUTTON) + && (mask & GDK_BUTTON2_MOTION_MASK)) + || ((xevent->wParam & MK_RBUTTON) + && (mask & GDK_BUTTON3_MOTION_MASK))); } -static gint +#endif + +static gboolean gdk_event_translate (GdkEvent *event, MSG *xevent, gboolean *ret_val_flagp, gint *ret_valp) { - GdkWindow *window; - GdkWindowPrivate *window_private; - + GdkWindow *window, *orig_window; GdkColormapPrivate *colormap_private; HWND owner; + DWORD pidActWin; + DWORD pidThis; DWORD dwStyle; PAINTSTRUCT paintstruct; HDC hdc; @@ -1158,7 +3320,6 @@ gdk_event_translate (GdkEvent *event, RECT rect; POINT pt; MINMAXINFO *lpmmi; - GdkWindowPrivate *curWnd_private; GdkEventMask mask; GdkDrawablePrivate *pixmap_private; HDC bgdc; @@ -1166,8 +3327,8 @@ gdk_event_translate (GdkEvent *event, int button; int i, j; gchar buf[256]; - gint charcount; - gint return_val; + gchar *msgname; + gboolean return_val; gboolean flag; return_val = FALSE; @@ -1175,16 +3336,15 @@ gdk_event_translate (GdkEvent *event, if (ret_val_flagp) *ret_val_flagp = FALSE; +#ifndef USE_DISPATCHMESSAGE if (xevent->message == gdk_ping_msg) { /* Messages we post ourselves just to wakeup WaitMessage. */ + GDK_NOTE (EVENTS, g_print ("gdk_ping_msg\n")); + return FALSE; } - - window = gdk_window_lookup (xevent->hwnd); - window_private = (GdkWindowPrivate *) window; - - if (xevent->message == g_pipe_readable_msg) + else if (xevent->message == g_pipe_readable_msg) { GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n", xevent->wParam, xevent->lParam)); @@ -1192,7 +3352,11 @@ gdk_event_translate (GdkEvent *event, g_io_channel_win32_pipe_readable (xevent->wParam, xevent->lParam); return FALSE; } +#endif + window = gdk_window_lookup (xevent->hwnd); + orig_window = window; + if (window != NULL) gdk_window_ref (window); else @@ -1218,18 +3382,12 @@ gdk_event_translate (GdkEvent *event, return FALSE; } - event->any.window = window; - - if (window_private && GDK_DRAWABLE_DESTROYED (window)) - { - } - else + if (!GDK_DRAWABLE_DESTROYED (window)) { /* Check for filters for this window */ GdkFilterReturn result; result = gdk_event_apply_filters - (xevent, event, - window_private ? window_private->filters : gdk_default_filters); + (xevent, event, WINDOW_PRIVATE(window)->filters); if (result != GDK_FILTER_CONTINUE) { @@ -1249,7 +3407,7 @@ gdk_event_translate (GdkEvent *event, event->selection.property = gdk_selection_property; event->selection.time = xevent->time; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = !GDK_DRAWABLE_DESTROYED (window); /* Will pass through switch below without match */ } @@ -1266,7 +3424,7 @@ gdk_event_translate (GdkEvent *event, event->selection.requestor = (guint32) xevent->hwnd; event->selection.time = xevent->time; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = !GDK_DRAWABLE_DESTROYED (window); /* Again, will pass through switch below without match */ } @@ -1280,7 +3438,7 @@ gdk_event_translate (GdkEvent *event, event->selection.selection = xevent->wParam; event->selection.time = xevent->time; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = GDK_DRAWABLE_DESTROYED (window); /* Once again, we will pass through switch below without match */ } @@ -1325,6 +3483,16 @@ gdk_event_translate (GdkEvent *event, switch (xevent->message) { + case WM_INPUTLANGCHANGE: + GDK_NOTE (EVENTS, + g_print ("WM_INPUTLANGCHANGE: %#x charset %d locale %x\n", + xevent->hwnd, xevent->wParam, xevent->lParam)); + WINDOW_PRIVATE(window)->input_locale = (HKL) xevent->lParam; + TranslateCharsetInfo ((DWORD FAR *) xevent->wParam, + &WINDOW_PRIVATE(window)->charset_info, + TCI_SRCCHARSET); + break; + case WM_SYSKEYUP: case WM_SYSKEYDOWN: GDK_NOTE (EVENTS, @@ -1367,50 +3535,57 @@ gdk_event_translate (GdkEvent *event, ignore_WM_CHAR = TRUE; keyup_or_down: + +#ifdef NEW_PROPAGATION_CODE + if (!propagate (&window, xevent, + k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK, + doesnt_want_key, + key_propagate)) + break; + event->key.window = window; +#else if (k_grab_window != NULL && !k_grab_owner_events) { /* Keyboard is grabbed with owner_events FALSE */ - GDK_NOTE (EVENTS, - g_print ("...grabbed, owner_events FALSE, " - "sending to %#x\n", - GDK_DRAWABLE_XID (k_grab_window))); + GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE, " + "sending to %#x\n", + GDK_DRAWABLE_XID (k_grab_window))); event->key.window = k_grab_window; + /* Continue with switch statement below */ } - else if (window_private - && (((xevent->message == WM_KEYUP + else if (((xevent->message == WM_KEYUP || xevent->message == WM_SYSKEYUP) - && !(window_private->event_mask & GDK_KEY_RELEASE_MASK)) + && !(WINDOW_PRIVATE(window)->event_mask & GDK_KEY_RELEASE_MASK)) || ((xevent->message == WM_KEYDOWN || xevent->message == WM_SYSKEYDOWN) - && !(window_private->event_mask & GDK_KEY_PRESS_MASK)))) + && !(WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK))) { - /* Owner window doesn't want it */ - if (k_grab_window != NULL && k_grab_owner_events) + /* Owner doesn't want it, propagate to parent. */ + if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent) { - /* Keyboard is grabbed with owner_events TRUE */ - GDK_NOTE (EVENTS, - g_print ("...grabbed, owner_events TRUE, doesn't want it, " - "sending to %#x\n", - GDK_DRAWABLE_XID (k_grab_window))); - event->key.window = k_grab_window; + /* No parent; check if grabbed */ + if (k_grab_window != NULL) + { + /* Keyboard is grabbed with owner_events TRUE */ + GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n")); + event->key.window = k_grab_window; + /* Continue with switch statement below */ + } + else + break; } else { - /* Owner doesn't want it, neither is it grabbed, so - * propagate to parent. - */ - if (window_private->parent == (GdkWindow *) &gdk_root_parent) - break; - gdk_window_unref (window); - window = window_private->parent; - gdk_window_ref (window); - window_private = (GdkWindowPrivate *) window; - GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n", - GDK_DRAWABLE_XID (window))); + window = key_propagate (window, xevent); + /* Jump back up */ goto keyup_or_down; } } - + else + event->key.window = window; + + g_assert (event->key.window == window); +#endif switch (xevent->wParam) { case VK_LBUTTON: @@ -1505,34 +3680,22 @@ gdk_event_translate (GdkEvent *event, case VK_MULTIPLY: event->key.keyval = GDK_KP_Multiply; break; case VK_ADD: -#if 0 - event->key.keyval = GDK_KP_Add; break; -#else /* Pass it on as an ASCII plus in WM_CHAR. */ ignore_WM_CHAR = FALSE; break; -#endif case VK_SEPARATOR: event->key.keyval = GDK_KP_Separator; break; case VK_SUBTRACT: -#if 0 - event->key.keyval = GDK_KP_Subtract; break; -#else /* Pass it on as an ASCII minus in WM_CHAR. */ ignore_WM_CHAR = FALSE; break; -#endif case VK_DECIMAL: -#if 0 - event->key.keyval = GDK_KP_Decimal; break; -#else /* The keypad decimal key should also be passed on as the decimal * sign ('.' or ',' depending on the Windows locale settings, * apparently). So wait for the WM_CHAR here, also. */ ignore_WM_CHAR = FALSE; break; -#endif case VK_DIVIDE: event->key.keyval = GDK_KP_Divide; break; case VK_F1: @@ -1579,24 +3742,32 @@ gdk_event_translate (GdkEvent *event, case '9': if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0 || GetKeyState (VK_MENU) < 0)) - /* Control- or Alt-digits won't come in as a WM_CHAR */ + /* Control- or Alt-digits won't come in as a WM_CHAR, + * but beware of AltGr-digits, which are used for instance + * on Finnish keyboards. + */ event->key.keyval = GDK_0 + (xevent->wParam - '0'); else - { - ignore_WM_CHAR = FALSE; - event->key.keyval = GDK_VoidSymbol; - } + ignore_WM_CHAR = FALSE; + break; + case VK_OEM_PLUS: /* On my Win98, the '+' key comes in + * as VK_OEM_PLUS + */ + if (!is_AltGr_key && (GetKeyState (VK_CONTROL) < 0 + || GetKeyState (VK_MENU) < 0)) + /* Control- or Alt-plus won't come in as WM_CHAR, + * but beware of AltGr-plus which is backslash on + * Finnish keyboards + */ + event->key.keyval = '+'; + else + ignore_WM_CHAR = FALSE; break; default: if (xevent->message == WM_SYSKEYDOWN || xevent->message == WM_SYSKEYUP) - { - event->key.keyval = xevent->wParam; - } + event->key.keyval = xevent->wParam; else - { - ignore_WM_CHAR = FALSE; - event->key.keyval = GDK_VoidSymbol; - } + ignore_WM_CHAR = FALSE; break; } @@ -1607,7 +3778,6 @@ gdk_event_translate (GdkEvent *event, event->key.type = ((xevent->message == WM_KEYDOWN || xevent->message == WM_SYSKEYDOWN) ? GDK_KEY_PRESS : GDK_KEY_RELEASE); - event->key.window = window; event->key.time = xevent->time; event->key.state = 0; if (GetKeyState (VK_SHIFT) < 0) @@ -1618,17 +3788,21 @@ gdk_event_translate (GdkEvent *event, event->key.state |= GDK_CONTROL_MASK; if (xevent->wParam != VK_MENU && GetKeyState (VK_MENU) < 0) event->key.state |= GDK_MOD1_MASK; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); event->key.string = NULL; event->key.length = 0; + return_val = !GDK_DRAWABLE_DESTROYED (window); break; + case WM_IME_CHAR: + GDK_NOTE (EVENTS, + g_print ("WM_IME_CHAR: %#x bytes: %#.04x\n", + xevent->hwnd, xevent->wParam)); + goto wm_char; + case WM_CHAR: GDK_NOTE (EVENTS, g_print ("WM_CHAR: %#x char: %#x %#.08x %s\n", - xevent->hwnd, - xevent->wParam, - xevent->lParam, + xevent->hwnd, xevent->wParam, xevent->lParam, (ignore_WM_CHAR ? "ignored" : ""))); if (ignore_WM_CHAR) @@ -1638,9 +3812,17 @@ gdk_event_translate (GdkEvent *event, } wm_char: +#ifdef NEW_PROPAGATION_CODE + if (!propagate (&window, xevent, + k_grab_window, k_grab_owner_events, GDK_ALL_EVENTS_MASK, + doesnt_want_char, + key_propagate)) + break; + event->key.window = window; +#else /* This doesn't handle the rather theorethical case that a window * wants key presses but still wants releases to be propagated, - * for instance. + * for instance. Or is that so theorethical? */ if (k_grab_window != NULL && !k_grab_owner_events) { @@ -1651,126 +3833,63 @@ gdk_event_translate (GdkEvent *event, GDK_DRAWABLE_XID (k_grab_window))); event->key.window = k_grab_window; } - else if (window_private - && !(window_private->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK))) + else if (!(WINDOW_PRIVATE(window)->event_mask & (GDK_KEY_PRESS_MASK | GDK_KEY_RELEASE_MASK))) { - /* Owner window doesn't want it */ - if (k_grab_window != NULL && k_grab_owner_events) + /* Owner doesn't want it, propagate to parent. */ + if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent) { - /* Keyboard is grabbed with owner_events TRUE */ - GDK_NOTE (EVENTS, - g_print ("...grabbed, owner_events TRUE, doesn't want it, " - "sending to %#x\n", - GDK_DRAWABLE_XID (k_grab_window))); - event->key.window = k_grab_window; + /* No parent; check if grabbed */ + if (k_grab_window != NULL) + { + GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n")); + event->key.window = k_grab_window; + } + else + break; } else { - /* Owner doesn't want it, neither is it grabbed, so - * propagate to parent. - */ - if (window_private->parent == (GdkWindow *) &gdk_root_parent) - g_assert_not_reached (); /* Should've been handled above */ - - gdk_window_unref (window); - window = window_private->parent; - gdk_window_ref (window); - window_private = (GdkWindowPrivate *) window; - GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n", - GDK_DRAWABLE_XID (window))); + window = key_propagate (window, xevent); + /* Jump back up */ goto wm_char; } } - - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); - if (return_val && (window_private->event_mask & GDK_KEY_RELEASE_MASK)) + else + event->key.window = window; + + g_assert (event->key.window == window); +#endif + return_val = !GDK_DRAWABLE_DESTROYED (window); + if (return_val && (event->key.window == k_grab_window + || (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_RELEASE_MASK))) { - /* Return the release event, and maybe append the press - * event to the queued_events list (from which it will vbe - * fetched before the release event). - */ - event->key.type = GDK_KEY_RELEASE; - event->key.keyval = xevent->wParam; - event->key.window = window; - event->key.time = xevent->time; - event->key.state = 0; - if (GetKeyState (VK_SHIFT) < 0) - event->key.state |= GDK_SHIFT_MASK; - if (GetKeyState (VK_CAPITAL) & 0x1) - event->key.state |= GDK_LOCK_MASK; - if (is_AltGr_key) - ; - else if (GetKeyState (VK_CONTROL) < 0) - { - event->key.state |= GDK_CONTROL_MASK; - if (event->key.keyval < ' ') - event->key.keyval += '@'; - } - else if (event->key.keyval < ' ') - { - event->key.state |= GDK_CONTROL_MASK; - event->key.keyval += '@'; - } - if (!is_AltGr_key && GetKeyState (VK_MENU) < 0) - event->key.state |= GDK_MOD1_MASK; - event->key.string = g_malloc (2); - event->key.length = 1; - event->key.string[0] = xevent->wParam; /* ??? */ - event->key.string[1] = 0; - - if (window_private->event_mask & GDK_KEY_PRESS_MASK) + if (window == k_grab_window + || (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK)) { - /* Append also a GDK_KEY_PRESS event to the pushback list. */ - GdkEvent *event2 = gdk_event_copy (event); - event2->key.type = GDK_KEY_PRESS; - charcount = xevent->lParam & 0xFFFF; - if (charcount > sizeof (buf)- 1) - charcount = sizeof (buf) - 1; - g_free (event2->key.string); - event2->key.string = g_malloc (charcount + 1); - for (i = 0; i < charcount; i++) - event2->key.string[i] = event->key.keyval; - event2->key.string[charcount] = 0; - event2->key.length = charcount; - + /* Append a GDK_KEY_PRESS event to the pushback list + * (from which it will be fetched before the release + * event). + */ + GdkEvent *event2 = gdk_event_new (); + build_keypress_event (WINDOW_PRIVATE(window), event2, xevent); + event2->key.window = window; + gdk_window_ref (window); gdk_event_queue_append (event2); + GDK_NOTE (EVENTS, print_event (event2)); } + /* Return the release event. */ + event->key.type = GDK_KEY_RELEASE; + event->key.keyval = xevent->wParam; + event->key.time = xevent->time; + build_key_event_state (event); + event->key.string = NULL; + event->key.length = 0; } - else if (return_val && (window_private->event_mask & GDK_KEY_PRESS_MASK)) + else if (return_val + && (WINDOW_PRIVATE(window)->event_mask & GDK_KEY_PRESS_MASK)) { /* Return just the GDK_KEY_PRESS event. */ - event->key.type = GDK_KEY_PRESS; - charcount = xevent->lParam & 0xFFFF; - if (charcount > sizeof (buf)- 1) - charcount = sizeof (buf) - 1; - event->key.keyval = xevent->wParam; - event->key.window = window; - event->key.time = xevent->time; - event->key.state = 0; - if (GetKeyState (VK_SHIFT) < 0) - event->key.state |= GDK_SHIFT_MASK; - if (GetKeyState (VK_CAPITAL) & 0x1) - event->key.state |= GDK_LOCK_MASK; - if (is_AltGr_key) - ; - else if (GetKeyState (VK_CONTROL) < 0) - { - event->key.state |= GDK_CONTROL_MASK; - if (event->key.keyval < ' ') - event->key.keyval += '@'; - } - else if (event->key.keyval < ' ') - { - event->key.state |= GDK_CONTROL_MASK; - event->key.keyval += '@'; - } - if (!is_AltGr_key && GetKeyState (VK_MENU) < 0) - event->key.state |= GDK_MOD1_MASK; - event->key.string = g_malloc (charcount + 1); - for (i = 0; i < charcount; i++) - event->key.string[i] = event->key.keyval; - event->key.string[charcount] = 0; - event->key.length = charcount; + build_keypress_event (WINDOW_PRIVATE(window), event, xevent); } else return_val = FALSE; @@ -1799,8 +3918,7 @@ gdk_event_translate (GdkEvent *event, LOWORD (xevent->lParam), HIWORD (xevent->lParam), button)); - if (window_private - && (window_private->extension_events != 0) + if (WINDOW_PRIVATE(window)->extension_events != 0 && gdk_input_ignore_core) { GDK_NOTE (EVENTS, g_print ("...ignored\n")); @@ -1811,18 +3929,23 @@ gdk_event_translate (GdkEvent *event, synthesize_crossing_events (window, xevent); event->button.type = GDK_BUTTON_PRESS; - buttondown: +#ifdef NEW_PROPAGATION_CODE + if (!propagate (&window, xevent, + p_grab_window, p_grab_owner_events, p_grab_mask, + doesnt_want_button_press, + mouse_propagate)) + break; event->button.window = window; - if (window_private) - mask = window_private->event_mask; - else - mask = 0; /* ??? */ +#else + buttondown: + mask = WINDOW_PRIVATE(window)->event_mask; if (p_grab_window != NULL && !p_grab_owner_events) { /* Pointer is grabbed with owner_events FALSE */ GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n")); - mask = p_grab_event_mask; + + mask = p_grab_mask; if (!(mask & GDK_BUTTON_PRESS_MASK)) /* Grabber doesn't want it */ break; @@ -1831,61 +3954,79 @@ gdk_event_translate (GdkEvent *event, GDK_NOTE (EVENTS, g_print ("...sending to %#x\n", GDK_DRAWABLE_XID (p_grab_window))); } - else if (window_private - && !(mask & GDK_BUTTON_PRESS_MASK)) + else if (!(mask & GDK_BUTTON_PRESS_MASK)) { - /* Owner window doesn't want it */ - if (p_grab_window != NULL && p_grab_owner_events) + /* Owner doesn't want it, propagate to parent. */ + if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent) { - /* Pointer is grabbed wíth owner_events TRUE */ - GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n")); - mask = p_grab_event_mask; - if (!(mask & GDK_BUTTON_PRESS_MASK)) - /* Grabber doesn't want it either */ - break; + /* No parent; check if grabbed */ + if (p_grab_window != NULL) + { + /* Pointer is grabbed wíth owner_events TRUE */ + GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n")); + mask = p_grab_mask; + if (!(mask & GDK_BUTTON_PRESS_MASK)) + { + /* Grabber doesn't want it either */ + GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n")); + break; + } + else + event->button.window = p_grab_window; + GDK_NOTE (EVENTS, g_print ("...sending to %#x\n", + GDK_DRAWABLE_XID (p_grab_window))); + } else - event->button.window = p_grab_window; - GDK_NOTE (EVENTS, g_print ("...sending to %#x\n", - GDK_DRAWABLE_XID (p_grab_window))); + break; } else { - /* Owner doesn't want it, neither is it grabbed, so - * propagate to parent. - */ - /* Yes, this code is duplicated twice below. So shoot me. */ - if (window_private->parent == (GdkWindow *) &gdk_root_parent) - break; - pt.x = LOWORD (xevent->lParam); - pt.y = HIWORD (xevent->lParam); - ClientToScreen (GDK_DRAWABLE_XID (window), &pt); - gdk_window_unref (window); - window = window_private->parent; - gdk_window_ref (window); - window_private = (GdkWindowPrivate *) window; - ScreenToClient (GDK_DRAWABLE_XID (window), &pt); - xevent->lParam = MAKELPARAM (pt.x, pt.y); - GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n", - GDK_DRAWABLE_XID (window))); + window = mouse_propagate (window, xevent); + /* Jump back up */ goto buttondown; /* What did Dijkstra say? */ } } + else + event->button.window = window; + g_assert (event->button.window == window); +#endif /* Emulate X11's automatic active grab */ if (!p_grab_window) { /* No explicit active grab, let's start one automatically */ + gint owner_events = + WINDOW_PRIVATE(window)->event_mask + & (GDK_BUTTON_PRESS_MASK|GDK_BUTTON_RELEASE_MASK); + GDK_NOTE (EVENTS, g_print ("...automatic grab started\n")); - gdk_pointer_grab (window, TRUE, window_private->event_mask, + gdk_pointer_grab (window, + owner_events, + WINDOW_PRIVATE(window)->event_mask, NULL, NULL, 0); p_grab_automatic = TRUE; } event->button.time = xevent->time; - event->button.x = LOWORD (xevent->lParam); - event->button.y = HIWORD (xevent->lParam); - event->button.x_root = (gfloat)xevent->pt.x; - event->button.y_root = (gfloat)xevent->pt.y; + if (window == p_grab_window + && p_grab_window != orig_window) + { + /* Translate coordinates to grabber */ + pt.x = LOWORD (xevent->lParam); + pt.y = HIWORD (xevent->lParam); + ClientToScreen (xevent->hwnd, &pt); + ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt); + event->button.x = pt.x; + event->button.y = pt.y; + GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y)); + } + else + { + event->button.x = LOWORD (xevent->lParam); + event->button.y = HIWORD (xevent->lParam); + } + event->button.x_root = xevent->pt.x; + event->button.y_root = xevent->pt.y; event->button.pressure = 0.5; event->button.xtilt = 0; event->button.ytilt = 0; @@ -1943,21 +4084,7 @@ gdk_event_translate (GdkEvent *event, button_number[1] = -1; button_number[0] = event->button.button; } - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); - if (return_val - && p_grab_window != NULL - && event->any.window == p_grab_window - && p_grab_window != window) - { - /* Translate coordinates to grabber */ - pt.x = event->button.x; - pt.y = event->button.y; - ClientToScreen (GDK_DRAWABLE_XID (window), &pt); - ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt); - event->button.x = pt.x; - event->button.y = pt.y; - GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y)); - } + return_val = !GDK_DRAWABLE_DESTROYED (window); break; case WM_LBUTTONUP: @@ -1977,8 +4104,7 @@ gdk_event_translate (GdkEvent *event, LOWORD (xevent->lParam), HIWORD (xevent->lParam), button)); - if (window_private - && (window_private->extension_events != 0) + if (WINDOW_PRIVATE(window)->extension_events != 0 && gdk_input_ignore_core) { GDK_NOTE (EVENTS, g_print ("...ignored\n")); @@ -1989,70 +4115,89 @@ gdk_event_translate (GdkEvent *event, synthesize_crossing_events (window, xevent); event->button.type = GDK_BUTTON_RELEASE; - buttonup: +#ifdef NEW_PROPAGATION_CODE + if (!propagate (&window, xevent, + p_grab_window, p_grab_owner_events, p_grab_mask, + doesnt_want_button_release, + mouse_propagate)) + break; event->button.window = window; - if (window_private) - mask = window_private->event_mask; - else - mask = 0; +#else + buttonup: + mask = WINDOW_PRIVATE(window)->event_mask; if (p_grab_window != NULL && !p_grab_owner_events) { /* Pointer is grabbed with owner_events FALSE */ GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n")); - mask = p_grab_event_mask; + + mask = p_grab_mask; if (!(mask & GDK_BUTTON_RELEASE_MASK)) /* Grabber doesn't want it */ - break; + goto maybe_ungrab; else event->button.window = p_grab_window; GDK_NOTE (EVENTS, g_print ("...sending to %#x\n", GDK_DRAWABLE_XID (p_grab_window))); } - else if (window_private - && !(mask & GDK_BUTTON_RELEASE_MASK)) + else if (!(mask & GDK_BUTTON_RELEASE_MASK)) { - /* Owner window doesn't want it */ - if (p_grab_window != NULL && p_grab_owner_events) + /* Owner doesn't want it, propagate to parent. */ + if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent) { - /* Pointer is grabbed wíth owner_events TRUE */ - GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n")); - mask = p_grab_event_mask; - if (!(mask & GDK_BUTTON_RELEASE_MASK)) - /* Grabber doesn't want it */ - break; + /* No parent; check if grabbed */ + if (p_grab_window != NULL) + { + /* Pointer is grabbed wíth owner_events TRUE */ + GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n")); + mask = p_grab_mask; + if (!(mask & GDK_BUTTON_RELEASE_MASK)) + { + /* Grabber doesn't want it either */ + GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n")); + goto maybe_ungrab; + } + else + event->button.window = p_grab_window; + GDK_NOTE (EVENTS, + g_print ("...sending to %#x\n", + GDK_DRAWABLE_XID (p_grab_window))); + } else - event->button.window = p_grab_window; - GDK_NOTE (EVENTS, g_print ("...sending to %#x\n", - GDK_DRAWABLE_XID (p_grab_window))); + break; } else { - /* Owner doesn't want it, neither is it grabbed, so - * propagate to parent. - */ - if (window_private->parent == (GdkWindow *) &gdk_root_parent) - break; - pt.x = LOWORD (xevent->lParam); - pt.y = HIWORD (xevent->lParam); - ClientToScreen (GDK_DRAWABLE_XID (window), &pt); - gdk_window_unref (window); - window = window_private->parent; - gdk_window_ref (window); - window_private = (GdkWindowPrivate *) window; - ScreenToClient (GDK_DRAWABLE_XID (window), &pt); - xevent->lParam = MAKELPARAM (pt.x, pt.y); - GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n", - GDK_DRAWABLE_XID (window))); + window = mouse_propagate (window, xevent); + /* Jump back up */ goto buttonup; } } + else + event->button.window = window; + g_assert (event->button.window == window); +#endif event->button.time = xevent->time; - event->button.x = LOWORD (xevent->lParam); - event->button.y = HIWORD (xevent->lParam); - event->button.x_root = (gfloat)xevent->pt.x; - event->button.y_root = (gfloat)xevent->pt.y; + if (window == p_grab_window + && p_grab_window != orig_window) + { + /* Translate coordinates to grabber */ + pt.x = LOWORD (xevent->lParam); + pt.y = HIWORD (xevent->lParam); + ClientToScreen (xevent->hwnd, &pt); + ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt); + event->button.x = pt.x; + event->button.y = pt.y; + GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y)); + } + else + { + event->button.x = LOWORD (xevent->lParam); + event->button.y = HIWORD (xevent->lParam); + } + event->button.x_root = xevent->pt.x; + event->button.y_root = xevent->pt.y; event->button.pressure = 0.5; event->button.xtilt = 0; event->button.ytilt = 0; @@ -2067,24 +4212,17 @@ gdk_event_translate (GdkEvent *event, event->button.state |= GDK_BUTTON3_MASK; if (xevent->wParam & MK_SHIFT) event->button.state |= GDK_SHIFT_MASK; + if (GetKeyState (VK_MENU) < 0) + event->button.state |= GDK_MOD1_MASK; + if (GetKeyState (VK_CAPITAL) & 0x1) + event->button.state |= GDK_LOCK_MASK; event->button.button = button; event->button.source = GDK_SOURCE_MOUSE; event->button.deviceid = GDK_CORE_POINTER; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); - if (return_val - && p_grab_window != NULL - && event->any.window == p_grab_window - && p_grab_window != window) - { - /* Translate coordinates to grabber */ - pt.x = event->button.x; - pt.y = event->button.y; - ClientToScreen (GDK_DRAWABLE_XID (window), &pt); - ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt); - event->button.x = pt.x; - event->button.y = pt.y; - GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y)); - } + + return_val = !GDK_DRAWABLE_DESTROYED (window); + + maybe_ungrab: if (p_grab_window != NULL && p_grab_automatic && (event->button.state & (GDK_BUTTON1_MASK | GDK_BUTTON2_MASK | GDK_BUTTON3_MASK)) == 0) @@ -2097,58 +4235,41 @@ gdk_event_translate (GdkEvent *event, xevent->hwnd, xevent->wParam, LOWORD (xevent->lParam), HIWORD (xevent->lParam))); -#if 0 - /* Try hard not to generate events for windows that shouldn't - get any. This is hard because we don't want pushbuttons to - highlight when the cursor moves over them if the window is - inactive. We dont want tooltips windows to be active. OTOH, - also menus are popup windows, but they definitely should - get events. Aw shit. Skip this. - */ - dwStyle = GetWindowLong (xevent->hwnd, GWL_STYLE); - if (active == NULL || - !(active == xevent->hwnd - || (dwStyle & WS_POPUP) - || IsChild (active, xevent->hwnd))) + /* HB: only process mouse move messages if we own the active window. */ + + GetWindowThreadProcessId(GetActiveWindow(), &pidActWin); + GetWindowThreadProcessId(xevent->hwnd, &pidThis); + if (pidActWin != pidThis) break; -#else - { /* HB: only process mouse move messages - * if we own the active window. - */ - DWORD ProcessID_ActWin; - DWORD ProcessID_this; - - GetWindowThreadProcessId(GetActiveWindow(), &ProcessID_ActWin); - GetWindowThreadProcessId(xevent->hwnd, &ProcessID_this); - if (ProcessID_ActWin != ProcessID_this) - break; - } -#endif + if (window != curWnd) synthesize_crossing_events (window, xevent); - if (window_private - && (window_private->extension_events != 0) + if (WINDOW_PRIVATE(window)->extension_events != 0 && gdk_input_ignore_core) { GDK_NOTE (EVENTS, g_print ("...ignored\n")); break; } - mousemotion: event->motion.type = GDK_MOTION_NOTIFY; +#ifdef NEW_PROPAGATION_CODE + if (!propagate (&window, xevent, + p_grab_window, p_grab_owner_events, p_grab_mask, + doesnt_want_button_motion, + mouse_propagate)) + break; event->motion.window = window; - if (window_private) - mask = window_private->event_mask; - else - mask = 0; +#else + mousemotion: + mask = WINDOW_PRIVATE(window)->event_mask; - if (p_grab_window && !p_grab_owner_events) + if (p_grab_window != NULL && !p_grab_owner_events) { /* Pointer is grabbed with owner_events FALSE */ - GDK_NOTE (EVENTS, - g_print ("...grabbed, owner_events FALSE\n")); - mask = p_grab_event_mask; + GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events FALSE\n")); + + mask = p_grab_mask; if (!((mask & GDK_POINTER_MOTION_MASK) || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) && (mask & GDK_BUTTON_MOTION_MASK)) @@ -2158,70 +4279,83 @@ gdk_event_translate (GdkEvent *event, && (mask & GDK_BUTTON2_MOTION_MASK)) || ((xevent->wParam & MK_RBUTTON) && (mask & GDK_BUTTON3_MOTION_MASK)))) + /* Grabber doesn't want it */ break; else event->motion.window = p_grab_window; GDK_NOTE (EVENTS, g_print ("...sending to %#x\n", GDK_DRAWABLE_XID (p_grab_window))); } - else if (window_private - && !((mask & GDK_POINTER_MOTION_MASK) - || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) - && (mask & GDK_BUTTON_MOTION_MASK)) - || ((xevent->wParam & MK_LBUTTON) - && (mask & GDK_BUTTON1_MOTION_MASK)) - || ((xevent->wParam & MK_MBUTTON) - && (mask & GDK_BUTTON2_MOTION_MASK)) - || ((xevent->wParam & MK_RBUTTON) - && (mask & GDK_BUTTON3_MOTION_MASK)))) - { - /* Owner window doesn't want it */ - if (p_grab_window != NULL && p_grab_owner_events) + else if (!((mask & GDK_POINTER_MOTION_MASK) + || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) + && (mask & GDK_BUTTON_MOTION_MASK)) + || ((xevent->wParam & MK_LBUTTON) + && (mask & GDK_BUTTON1_MOTION_MASK)) + || ((xevent->wParam & MK_MBUTTON) + && (mask & GDK_BUTTON2_MOTION_MASK)) + || ((xevent->wParam & MK_RBUTTON) + && (mask & GDK_BUTTON3_MOTION_MASK)))) + { + /* Owner doesn't want it, propagate to parent. */ + if (WINDOW_PRIVATE(window)->parent == (GdkWindow *) gdk_root_parent) { - /* Pointer is grabbed wíth owner_events TRUE */ - GDK_NOTE (EVENTS, g_print ("...grabbed, owner_events TRUE, doesn't want it\n")); - mask = p_grab_event_mask; - if (!((p_grab_event_mask & GDK_POINTER_MOTION_MASK) - || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) - && (mask & GDK_BUTTON_MOTION_MASK)) - || ((xevent->wParam & MK_LBUTTON) - && (mask & GDK_BUTTON1_MOTION_MASK)) - || ((xevent->wParam & MK_MBUTTON) - && (mask & GDK_BUTTON2_MOTION_MASK)) - || ((xevent->wParam & MK_RBUTTON) - && (mask & GDK_BUTTON3_MOTION_MASK)))) - /* Grabber doesn't want it either */ - break; + /* No parent; check if grabbed */ + if (p_grab_window != NULL) + { + /* Pointer is grabbed wíth owner_events TRUE */ + GDK_NOTE (EVENTS, g_print ("...undelivered, but grabbed\n")); + mask = p_grab_mask; + if (!((p_grab_mask & GDK_POINTER_MOTION_MASK) + || ((xevent->wParam & (MK_LBUTTON|MK_MBUTTON|MK_RBUTTON)) + && (mask & GDK_BUTTON_MOTION_MASK)) + || ((xevent->wParam & MK_LBUTTON) + && (mask & GDK_BUTTON1_MOTION_MASK)) + || ((xevent->wParam & MK_MBUTTON) + && (mask & GDK_BUTTON2_MOTION_MASK)) + || ((xevent->wParam & MK_RBUTTON) + && (mask & GDK_BUTTON3_MOTION_MASK)))) + { + /* Grabber doesn't want it either */ + GDK_NOTE (EVENTS, g_print ("...grabber uninterested\n")); + break; + } + else + event->motion.window = p_grab_window; + GDK_NOTE (EVENTS, + g_print ("...sending to %#x\n", + GDK_DRAWABLE_XID (p_grab_window))); + } else - event->motion.window = p_grab_window; - GDK_NOTE (EVENTS, g_print ("...sending to %#x\n", - GDK_DRAWABLE_XID (p_grab_window))); + break; } else { - /* Owner doesn't want it, neither is it grabbed, so - * propagate to parent. - */ - if (window_private->parent == (GdkWindow *) &gdk_root_parent) - break; - pt.x = LOWORD (xevent->lParam); - pt.y = HIWORD (xevent->lParam); - ClientToScreen (GDK_DRAWABLE_XID (window), &pt); - gdk_window_unref (window); - window = window_private->parent; - gdk_window_ref (window); - window_private = (GdkWindowPrivate *) window; - ScreenToClient (GDK_DRAWABLE_XID (window), &pt); - xevent->lParam = MAKELPARAM (pt.x, pt.y); - GDK_NOTE (EVENTS, g_print ("...propagating to %#x\n", - GDK_DRAWABLE_XID (window))); + window = mouse_propagate (window, xevent); + /* Jump back up */ goto mousemotion; } } - + else + event->motion.window = window; +#endif event->motion.time = xevent->time; - event->motion.x = curX = LOWORD (xevent->lParam); - event->motion.y = curY = HIWORD (xevent->lParam); + if (window == p_grab_window + && p_grab_window != orig_window) + { + /* Translate coordinates to grabber */ + pt.x = curX = LOWORD (xevent->lParam); + pt.y = curY = HIWORD (xevent->lParam); + ClientToScreen (xevent->hwnd, &pt); + ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt); + event->motion.x = pt.x; + event->motion.y = pt.y; + GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y)); + } + else + { + event->motion.x = curX = LOWORD (xevent->lParam); + event->motion.y = curY = HIWORD (xevent->lParam); + } event->motion.x_root = xevent->pt.x; event->motion.y_root = xevent->pt.y; curXroot = event->motion.x_root; @@ -2240,6 +4374,10 @@ gdk_event_translate (GdkEvent *event, event->button.state |= GDK_BUTTON3_MASK; if (xevent->wParam & MK_SHIFT) event->button.state |= GDK_SHIFT_MASK; + if (GetKeyState (VK_MENU) < 0) + event->button.state |= GDK_MOD1_MASK; + if (GetKeyState (VK_CAPITAL) & 0x1) + event->button.state |= GDK_LOCK_MASK; if (mask & GDK_POINTER_MOTION_HINT_MASK) event->motion.is_hint = NotifyHint; else @@ -2247,21 +4385,7 @@ gdk_event_translate (GdkEvent *event, event->motion.source = GDK_SOURCE_MOUSE; event->motion.deviceid = GDK_CORE_POINTER; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); - if (return_val - && p_grab_window != NULL - && event->any.window == p_grab_window - && p_grab_window != window) - { - /* Translate coordinates to grabber */ - pt.x = event->motion.x; - pt.y = event->motion.y; - ClientToScreen (GDK_DRAWABLE_XID (window), &pt); - ScreenToClient (GDK_DRAWABLE_XID (p_grab_window), &pt); - event->motion.x = pt.x; - event->motion.y = pt.y; - GDK_NOTE (EVENTS, g_print ("...new coords are +%d+%d\n", pt.x, pt.y)); - } + return_val = !GDK_DRAWABLE_DESTROYED (window); break; case WM_NCMOUSEMOVE: @@ -2269,13 +4393,9 @@ gdk_event_translate (GdkEvent *event, g_print ("WM_NCMOUSEMOVE: %#x x,y: %d %d\n", xevent->hwnd, LOWORD (xevent->lParam), HIWORD (xevent->lParam))); -#if 0 - if (active == NULL || active != xevent->hwnd) - break; -#endif - curWnd_private = (GdkWindowPrivate *) curWnd; - if (curWnd != NULL - && (curWnd_private->event_mask & GDK_LEAVE_NOTIFY_MASK)) + if (p_TrackMouseEvent == NULL + && curWnd != NULL + && (WINDOW_PRIVATE(curWnd)->event_mask & GDK_LEAVE_NOTIFY_MASK)) { GDK_NOTE (EVENTS, g_print ("...synthesizing LEAVE_NOTIFY event\n")); @@ -2288,49 +4408,83 @@ gdk_event_translate (GdkEvent *event, event->crossing.x_root = curXroot; event->crossing.y_root = curYroot; event->crossing.mode = GDK_CROSSING_NORMAL; - event->crossing.detail = GDK_NOTIFY_UNKNOWN; + event->crossing.detail = GDK_NOTIFY_NONLINEAR; event->crossing.focus = TRUE; /* ??? */ event->crossing.state = 0; /* ??? */ + return_val = TRUE; + } + + if (curWnd) + { gdk_window_unref (curWnd); curWnd = NULL; - - return_val = TRUE; } + break; - case WM_SETFOCUS: - case WM_KILLFOCUS: - if (window_private - && !(window_private->event_mask & GDK_FOCUS_CHANGE_MASK)) +#ifdef USE_TRACKMOUSEEVENT + case WM_MOUSELEAVE: + GDK_NOTE (EVENTS, g_print ("WM_MOUSELEAVE: %#x\n", xevent->hwnd)); + + if (!(WINDOW_PRIVATE(window)->event_mask & GDK_LEAVE_NOTIFY_MASK)) break; + event->crossing.type = GDK_LEAVE_NOTIFY; + event->crossing.window = window; + event->crossing.subwindow = NULL; + event->crossing.time = xevent->time; + event->crossing.x = curX; + event->crossing.y = curY; + event->crossing.x_root = curXroot; + event->crossing.y_root = curYroot; + event->crossing.mode = GDK_CROSSING_NORMAL; + if (curWnd + && IsChild (GDK_DRAWABLE_XID (curWnd), GDK_DRAWABLE_XID (window))) + event->crossing.detail = GDK_NOTIFY_INFERIOR; + else if (curWnd + && IsChild (GDK_DRAWABLE_XID (window), GDK_DRAWABLE_XID (curWnd))) + event->crossing.detail = GDK_NOTIFY_ANCESTOR; + else + event->crossing.detail = GDK_NOTIFY_NONLINEAR; + + event->crossing.focus = TRUE; /* ??? */ + event->crossing.state = 0; /* ??? */ + + if (curWnd) + { + gdk_window_unref (curWnd); + curWnd = NULL; + } + + return_val = !GDK_DRAWABLE_DESTROYED (window); + break; +#endif + + case WM_SETFOCUS: + case WM_KILLFOCUS: GDK_NOTE (EVENTS, g_print ("WM_%sFOCUS: %#x\n", - (xevent->message == WM_SETFOCUS ? "SET" : "KILL"), + (xevent->message == WM_SETFOCUS ? + "SET" : "KILL"), xevent->hwnd)); + if (!(WINDOW_PRIVATE(window)->event_mask & GDK_FOCUS_CHANGE_MASK)) + break; + event->focus_change.type = GDK_FOCUS_CHANGE; event->focus_change.window = window; event->focus_change.in = (xevent->message == WM_SETFOCUS); - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = !GDK_DRAWABLE_DESTROYED (window); break; -#if 0 - case WM_ACTIVATE: - GDK_NOTE (EVENTS, g_print ("WM_ACTIVATE: %#x %d\n", - xevent->hwnd, LOWORD (xevent->wParam))); - if (LOWORD (xevent->wParam) == WA_INACTIVE) - active = (HWND) xevent->lParam; - else - active = xevent->hwnd; - break; -#endif + case WM_ERASEBKGND: GDK_NOTE (EVENTS, g_print ("WM_ERASEBKGND: %#x dc %#x\n", xevent->hwnd, xevent->wParam)); - if (!window_private || GDK_DRAWABLE_DESTROYED (window)) + if (GDK_DRAWABLE_DESTROYED (window)) break; - colormap_private = (GdkColormapPrivate *) window_private->drawable.colormap; + + colormap_private = (GdkColormapPrivate *) WINDOW_PRIVATE(window)->drawable.colormap; hdc = (HDC) xevent->wParam; if (colormap_private && colormap_private->xcolormap->rc_palette) @@ -2350,32 +4504,38 @@ gdk_event_translate (GdkEvent *event, *ret_val_flagp = TRUE; *ret_valp = 1; - if (window_private->bg_type == GDK_WIN32_BG_TRANSPARENT) + if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_TRANSPARENT) break; - if (window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE) + if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PARENT_RELATIVE) { /* If this window should have the same background as the * parent, fetch the parent. (And if the same goes for * the parent, fetch the grandparent, etc.) */ - while (window_private - && window_private->bg_type == GDK_WIN32_BG_PARENT_RELATIVE) - window_private = (GdkWindowPrivate *) window_private->parent; + while (window + && WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PARENT_RELATIVE) + { + gdk_window_unref (window); + window = WINDOW_PRIVATE(window)->parent; + gdk_window_ref (window); + } } - if (window_private->bg_type == GDK_WIN32_BG_PIXEL) + if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PIXEL) { COLORREF bg; GetClipBox (hdc, &rect); - GDK_NOTE (EVENTS, g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n", - rect.right - rect.left, - rect.bottom - rect.top, - rect.left, rect.top, - gdk_color_to_string (&window_private->bg_pixel))); - bg = GetNearestColor (hdc, RGB (window_private->bg_pixel.red >> 8, - window_private->bg_pixel.green >> 8, - window_private->bg_pixel.blue >> 8)); + GDK_NOTE (EVENTS, + g_print ("...%dx%d@+%d+%d BG_PIXEL %s\n", + rect.right - rect.left, + rect.bottom - rect.top, + rect.left, rect.top, + gdk_color_to_string (&WINDOW_PRIVATE(window)->bg_pixel))); + bg = GetNearestColor + (hdc, RGB (WINDOW_PRIVATE(window)->bg_pixel.red >> 8, + WINDOW_PRIVATE(window)->bg_pixel.green >> 8, + WINDOW_PRIVATE(window)->bg_pixel.blue >> 8)); hbr = CreateSolidBrush (bg); #if 0 g_print ("...CreateSolidBrush (%.08x) = %.08x\n", bg, hbr); @@ -2384,9 +4544,10 @@ gdk_event_translate (GdkEvent *event, g_warning ("WM_ERASEBKGND: FillRect failed"); DeleteObject (hbr); } - else if (window_private->bg_type == GDK_WIN32_BG_PIXMAP) + else if (WINDOW_PRIVATE(window)->bg_type == GDK_WIN32_BG_PIXMAP) { - pixmap_private = (GdkDrawablePrivate*) window_private->bg_pixmap; + pixmap_private = + (GdkDrawablePrivate*) WINDOW_PRIVATE(window)->bg_pixmap; GetClipBox (hdc, &rect); if (pixmap_private->width <= 8 @@ -2470,8 +4631,7 @@ gdk_event_translate (GdkEvent *event, EndPaint (xevent->hwnd, &paintstruct); - if (window_private - && !(window_private->event_mask & GDK_EXPOSURE_MASK)) + if (!(WINDOW_PRIVATE(window)->event_mask & GDK_EXPOSURE_MASK)) break; event->expose.type = GDK_EXPOSE; @@ -2482,7 +4642,7 @@ gdk_event_translate (GdkEvent *event, event->expose.area.height = paintstruct.rcPaint.bottom - paintstruct.rcPaint.top; event->expose.count = 0; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = !GDK_DRAWABLE_DESTROYED (window); if (return_val) { GList *list = queued_events; @@ -2503,7 +4663,6 @@ gdk_event_translate (GdkEvent *event, xevent->hwnd, LOWORD (xevent->lParam), HIWORD (xevent->lParam))); - return_val = FALSE; if (LOWORD (xevent->lParam) != HTCLIENT) break; if (p_grab_window != NULL && p_grab_cursor != NULL) @@ -2511,44 +4670,27 @@ gdk_event_translate (GdkEvent *event, GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", p_grab_cursor)); SetCursor (p_grab_cursor); } - else if (window_private - && !GDK_DRAWABLE_DESTROYED (window) - && window_private->xcursor) + else if (!GDK_DRAWABLE_DESTROYED (window) + && WINDOW_PRIVATE(window)->xcursor) { GDK_NOTE (EVENTS, g_print ("...SetCursor(%#x)\n", - window_private->xcursor)); - SetCursor (window_private->xcursor); + WINDOW_PRIVATE(window)->xcursor)); + SetCursor (WINDOW_PRIVATE(window)->xcursor); } - *ret_val_flagp = TRUE; - *ret_valp = FALSE; - break; -#if 0 - case WM_QUERYOPEN: - GDK_NOTE (EVENTS, g_print ("WM_QUERYOPEN: %#x\n", - xevent->hwnd)); - *ret_val_flagp = TRUE; - *ret_valp = TRUE; - - if (window_private - && !(window_private->event_mask & GDK_STRUCTURE_MASK)) - break; - - event->any.type = GDK_MAP; - event->any.window = window; + if (window != curWnd) + synthesize_crossing_events (window, xevent); - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + *ret_val_flagp = TRUE; + *ret_valp = FALSE; break; -#endif -#if 1 case WM_SHOWWINDOW: GDK_NOTE (EVENTS, g_print ("WM_SHOWWINDOW: %#x %d\n", xevent->hwnd, xevent->wParam)); - if (window_private - && !(window_private->event_mask & GDK_STRUCTURE_MASK)) + if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK)) break; event->any.type = (xevent->wParam ? GDK_MAP : GDK_UNMAP); @@ -2562,9 +4704,9 @@ gdk_event_translate (GdkEvent *event, && k_grab_window == window) gdk_keyboard_ungrab (xevent->time); - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = !GDK_DRAWABLE_DESTROYED (window); break; -#endif + case WM_SIZE: GDK_NOTE (EVENTS, g_print ("WM_SIZE: %#x %s %dx%d\n", @@ -2576,13 +4718,11 @@ gdk_event_translate (GdkEvent *event, (xevent->wParam == SIZE_RESTORED ? "RESTORED" : "?"))))), LOWORD (xevent->lParam), HIWORD (xevent->lParam))); - if (window_private - && !(window_private->event_mask & GDK_STRUCTURE_MASK)) + if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK)) break; - if (window_private != NULL - && xevent->wParam == SIZE_MINIMIZED) + + if (xevent->wParam == SIZE_MINIMIZED) { -#if 1 event->any.type = GDK_UNMAP; event->any.window = window; @@ -2593,11 +4733,9 @@ gdk_event_translate (GdkEvent *event, gdk_keyboard_ungrab (xevent->time); return_val = !GDK_DRAWABLE_DESTROYED (window); -#endif } - else if (window_private != NULL - && (xevent->wParam == SIZE_RESTORED - || xevent->wParam == SIZE_MAXIMIZED) + else if ((xevent->wParam == SIZE_RESTORED + || xevent->wParam == SIZE_MAXIMIZED) #if 1 && GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD #endif @@ -2615,121 +4753,49 @@ gdk_event_translate (GdkEvent *event, event->configure.y = pt.y; event->configure.width = LOWORD (xevent->lParam); event->configure.height = HIWORD (xevent->lParam); - window_private->x = event->configure.x; - window_private->y = event->configure.y; - window_private->drawable.width = event->configure.width; - window_private->drawable.height = event->configure.height; - if (window_private->resize_count > 1) - window_private->resize_count -= 1; + WINDOW_PRIVATE(window)->x = event->configure.x; + WINDOW_PRIVATE(window)->y = event->configure.y; + WINDOW_PRIVATE(window)->drawable.width = event->configure.width; + WINDOW_PRIVATE(window)->drawable.height = event->configure.height; + if (WINDOW_PRIVATE(window)->resize_count > 1) + WINDOW_PRIVATE(window)->resize_count -= 1; return_val = !GDK_DRAWABLE_DESTROYED (window); if (return_val - && window_private->extension_events != 0 + && WINDOW_PRIVATE(window)->extension_events != 0 && gdk_input_vtable.configure_event) gdk_input_vtable.configure_event (&event->configure, window); } break; -#if 0 /* Bernd Herd suggests responding to WM_GETMINMAXINFO instead, - * which indeed is much easier. - */ - case WM_SIZING: - GDK_NOTE (EVENTS, g_print ("WM_SIZING: %#x\n", xevent->hwnd)); - if (ret_val_flagp == NULL) - g_warning ("ret_val_flagp is NULL but we got a WM_SIZING?"); - else if (window_private != NULL - && window_private->hint_flags & - (GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE)) - { - LPRECT lprc = (LPRECT) xevent->lParam; - - if (window_private->hint_flags & GDK_HINT_MIN_SIZE) - { - gint w = lprc->right - lprc->left; - gint h = lprc->bottom - lprc->top; - - if (w < window_private->hint_min_width) - { - if (xevent->wParam == WMSZ_BOTTOMLEFT - || xevent->wParam == WMSZ_LEFT - || xevent->wParam == WMSZ_TOPLEFT) - lprc->left = lprc->right - window_private->hint_min_width; - else - lprc->right = lprc->left + window_private->hint_min_width; - *ret_val_flagp = TRUE; - *ret_valp = TRUE; - } - if (h < window_private->hint_min_height) - { - if (xevent->wParam == WMSZ_BOTTOMLEFT - || xevent->wParam == WMSZ_BOTTOM - || xevent->wParam == WMSZ_BOTTOMRIGHT) - lprc->bottom = lprc->top + window_private->hint_min_height; - else - lprc->top = lprc->bottom - window_private->hint_min_height; - *ret_val_flagp = TRUE; - *ret_valp = TRUE; - } - } - if (window_private->hint_flags & GDK_HINT_MAX_SIZE) - { - gint w = lprc->right - lprc->left; - gint h = lprc->bottom - lprc->top; - if (w > window_private->hint_max_width) - { - if (xevent->wParam == WMSZ_BOTTOMLEFT - || xevent->wParam == WMSZ_LEFT - || xevent->wParam == WMSZ_TOPLEFT) - lprc->left = lprc->right - window_private->hint_max_width; - else - lprc->right = lprc->left + window_private->hint_max_width; - *ret_val_flagp = TRUE; - *ret_valp = TRUE; - } - if (h > window_private->hint_max_height) - { - if (xevent->wParam == WMSZ_BOTTOMLEFT - || xevent->wParam == WMSZ_BOTTOM - || xevent->wParam == WMSZ_BOTTOMRIGHT) - lprc->bottom = lprc->top + window_private->hint_max_height; - else - lprc->top = lprc->bottom - window_private->hint_max_height; - *ret_val_flagp = TRUE; - *ret_valp = TRUE; - } - } - } - break; -#else case WM_GETMINMAXINFO: GDK_NOTE (EVENTS, g_print ("WM_GETMINMAXINFO: %#x\n", xevent->hwnd)); + lpmmi = (MINMAXINFO*) xevent->lParam; - if (window_private->hint_flags & GDK_HINT_MIN_SIZE) + if (WINDOW_PRIVATE(window)->hint_flags & GDK_HINT_MIN_SIZE) { - lpmmi->ptMinTrackSize.x = window_private->hint_min_width; - lpmmi->ptMinTrackSize.y = window_private->hint_min_height; + lpmmi->ptMinTrackSize.x = WINDOW_PRIVATE(window)->hint_min_width; + lpmmi->ptMinTrackSize.y = WINDOW_PRIVATE(window)->hint_min_height; } - if (window_private->hint_flags & GDK_HINT_MAX_SIZE) + if (WINDOW_PRIVATE(window)->hint_flags & GDK_HINT_MAX_SIZE) { - lpmmi->ptMaxTrackSize.x = window_private->hint_max_width; - lpmmi->ptMaxTrackSize.y = window_private->hint_max_height; + lpmmi->ptMaxTrackSize.x = WINDOW_PRIVATE(window)->hint_max_width; + lpmmi->ptMaxTrackSize.y = WINDOW_PRIVATE(window)->hint_max_height; - lpmmi->ptMaxSize.x = window_private->hint_max_width; - lpmmi->ptMaxSize.y = window_private->hint_max_height; + lpmmi->ptMaxSize.x = WINDOW_PRIVATE(window)->hint_max_width; + lpmmi->ptMaxSize.y = WINDOW_PRIVATE(window)->hint_max_height; } break; -#endif case WM_MOVE: GDK_NOTE (EVENTS, g_print ("WM_MOVE: %#x +%d+%d\n", xevent->hwnd, LOWORD (xevent->lParam), HIWORD (xevent->lParam))); - if (window_private - && !(window_private->event_mask & GDK_STRUCTURE_MASK)) + if (!(WINDOW_PRIVATE(window)->event_mask & GDK_STRUCTURE_MASK)) break; - if (window_private != NULL - && GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD) + + if (GDK_DRAWABLE_TYPE (window) != GDK_WINDOW_CHILD) { event->configure.type = GDK_CONFIGURE; event->configure.window = window; @@ -2738,10 +4804,10 @@ gdk_event_translate (GdkEvent *event, GetClientRect (xevent->hwnd, &rect); event->configure.width = rect.right; event->configure.height = rect.bottom; - window_private->x = event->configure.x; - window_private->y = event->configure.y; - window_private->drawable.width = event->configure.width; - window_private->drawable.height = event->configure.height; + WINDOW_PRIVATE(window)->x = event->configure.x; + WINDOW_PRIVATE(window)->y = event->configure.y; + WINDOW_PRIVATE(window)->drawable.width = event->configure.width; + WINDOW_PRIVATE(window)->drawable.height = event->configure.height; return_val = !GDK_DRAWABLE_DESTROYED (window); } @@ -2749,10 +4815,11 @@ gdk_event_translate (GdkEvent *event, case WM_CLOSE: GDK_NOTE (EVENTS, g_print ("WM_CLOSE: %#x\n", xevent->hwnd)); + event->any.type = GDK_DELETE; event->any.window = window; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = !GDK_DRAWABLE_DESTROYED (window); break; #if 0 @@ -2795,7 +4862,7 @@ gdk_event_translate (GdkEvent *event, event->selection.property = gdk_selection_property; event->selection.requestor = (guint32) xevent->hwnd; event->selection.time = xevent->time; - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = !GDK_DRAWABLE_DESTROYED (window); #else /* Test code, to see if SetClipboardData works when called from * the window procedure. @@ -2817,6 +4884,7 @@ gdk_event_translate (GdkEvent *event, case WM_DESTROY: GDK_NOTE (EVENTS, g_print ("WM_DESTROY: %#x\n", xevent->hwnd)); + event->any.type = GDK_DESTROY; event->any.window = window; if (window != NULL && window == curWnd) @@ -2831,7 +4899,7 @@ gdk_event_translate (GdkEvent *event, if (k_grab_window == window) gdk_keyboard_ungrab (xevent->time); - return_val = window_private && !GDK_DRAWABLE_DESTROYED (window); + return_val = !GDK_DRAWABLE_DESTROYED (window); break; #ifdef HAVE_WINTAB @@ -2871,6 +4939,8 @@ bypass_switch: (event->any.type == GDK_LEAVE_NOTIFY)) && (event->crossing.subwindow != NULL)) gdk_window_ref (event->crossing.subwindow); + + GDK_NOTE (EVENTS, print_event (event)); } else { @@ -2891,17 +4961,31 @@ gdk_events_queue (void) GList *node; GdkEvent *event; MSG msg; - - GDK_NOTE (EVENTS, g_print ("gdk_events_queue: %s\n", - (queued_events ? "yes" : "none"))); + LRESULT lres; while (!gdk_event_queue_find_first() && PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) { - GDK_NOTE (EVENTS, g_print ("gdk_events_queue: PeekMessage: %#x\n", - msg.message)); - TranslateMessage (&msg); + GDK_NOTE (EVENTS, g_print ("PeekMessage: %#x %#x\n", + msg.hwnd, msg.message)); + + if (paimmmpo == NULL + || (paimmmpo->lpVtbl->OnTranslateMessage) (paimmmpo, &msg) != S_OK) + TranslateMessage (&msg); + +#ifdef USE_DISPATCHMESSAGE + if (msg.message == g_pipe_readable_msg) + { + GDK_NOTE (EVENTS, g_print ("g_pipe_readable_msg: %d %d\n", + msg.wParam, msg.lParam)); + g_io_channel_win32_pipe_readable (msg.wParam, msg.lParam); + + continue; + } + + DispatchMessage (&msg); +#else event = gdk_event_new (); event->any.type = GDK_NOTHING; @@ -2914,14 +4998,20 @@ gdk_events_queue (void) node = queued_tail; if (gdk_event_translate (event, &msg, NULL, NULL)) - ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; + ((GdkEventPrivate *)event)->flags &= ~GDK_EVENT_PENDING; else { - DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam); + if (paimmapp == NULL + || (paimmapp->lpVtbl->OnDefWindowProc) (paimmapp, msg.hwnd, + msg.message, + msg.wParam, msg.lParam, + &lres) == S_FALSE) + DefWindowProc (msg.hwnd, msg.message, msg.wParam, msg.lParam); gdk_event_queue_remove_link (node); g_list_free_1 (node); gdk_event_free (event); } +#endif } } @@ -2937,8 +5027,6 @@ gdk_event_prepare (gpointer source_data, *timeout = -1; - GDK_NOTE (EVENTS, g_print ("gdk_event_prepare\n")); - retval = (gdk_event_queue_find_first () != NULL) || PeekMessage (&msg, NULL, 0, 0, PM_NOREMOVE); @@ -2954,8 +5042,6 @@ gdk_event_check (gpointer source_data, MSG msg; gboolean retval; - GDK_NOTE (EVENTS, g_print ("gdk_event_check\n")); - GDK_THREADS_ENTER (); if (event_poll_fd.revents & G_IO_IN) @@ -2994,8 +5080,6 @@ gdk_event_dispatch (gpointer source_data, { GdkEvent *event; - GDK_NOTE (EVENTS, g_print ("gdk_event_dispatch\n")); - GDK_THREADS_ENTER (); gdk_events_queue(); |