diff options
Diffstat (limited to 'win')
-rw-r--r-- | win/tkWinKey.c | 12 | ||||
-rw-r--r-- | win/tkWinX.c | 107 |
2 files changed, 103 insertions, 16 deletions
diff --git a/win/tkWinKey.c b/win/tkWinKey.c index 5591133..a49898f 100644 --- a/win/tkWinKey.c +++ b/win/tkWinKey.c @@ -115,10 +115,18 @@ TkpGetString( } else if (keyEv->send_event == -3) { /* * Special case for WM_UNICHAR. xkey.trans_chars[] already contains a - * UTF-8 char. + * UTF-8 char, except when nbytes == 0 (then it didn't fit there). */ - Tcl_DStringAppend(dsPtr, keyEv->trans_chars, keyEv->nbytes); + if (keyEv->nbytes) { + Tcl_DStringAppend(dsPtr, keyEv->trans_chars, keyEv->nbytes); + } else if (keyEv->keycode > 0xffff) { + char buf[XMaxTransChars]; + Tcl_UniCharToUtf(((keyEv->keycode - 0x10000) >> 10) | 0xd800, buf); + Tcl_DStringAppend(dsPtr, buf, 3); + Tcl_UniCharToUtf(((keyEv->keycode - 0x10000) & 0x3ff) | 0xdc00, buf); + Tcl_DStringAppend(dsPtr, buf, 3); + } } else { /* * This is an event generated from generic code. It has no nchars or diff --git a/win/tkWinX.c b/win/tkWinX.c index 99102cb..f4908e0 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -29,6 +29,8 @@ # pragma comment (lib, "advapi32.lib") #endif +#define USE_EXTRA_EVENTS 0 /* Set this to 1 if you want to generate + additional events for surrogates */ /* * The zmouse.h file includes the definition for WM_MOUSEWHEEL. */ @@ -81,6 +83,7 @@ typedef struct ThreadSpecificData { TkDisplay *winDisplay; /* TkDisplay structure that represents Windows * screen. */ int updatingClipboard; /* If 1, we are updating the clipboard. */ + int surrogateBuffer; /* Buffer for first of surrogate pair. */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -911,15 +914,24 @@ Tk_TranslateWinEvent( Tk_PointerEvent(hwnd, (short) LOWORD(lParam), (short) HIWORD(lParam)); return 1; + case WM_SYSKEYDOWN: + case WM_KEYDOWN: + if (wParam == VK_PACKET) { + /* + * This will trigger WM_CHAR event(s) with unicode data. + */ + *resultPtr = + PostMessageW(hwnd, message, HIWORD(lParam), LOWORD(lParam)); + return 1; + } + /* else fall through */ case WM_CLOSE: case WM_SETFOCUS: case WM_KILLFOCUS: case WM_DESTROYCLIPBOARD: case WM_UNICHAR: case WM_CHAR: - case WM_SYSKEYDOWN: case WM_SYSKEYUP: - case WM_KEYDOWN: case WM_KEYUP: case WM_MOUSEWHEEL: GenerateXEvent(hwnd, message, wParam, lParam); @@ -1197,17 +1209,58 @@ GenerateXEvent( event.type = KeyPress; event.xany.send_event = -1; event.xkey.keycode = 0; - event.xkey.nbytes = 1; - event.xkey.trans_chars[0] = (char) wParam; - - if (IsDBCSLeadByte((BYTE) wParam)) { - MSG msg; + if ((int)wParam & 0xff00) { + int i, ch1 = wParam & 0xffff; + char buffer[XMaxTransChars]; - if ((PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0) - && (msg.message == WM_CHAR)) { - GetMessage(&msg, NULL, 0, 0); - event.xkey.nbytes = 2; - event.xkey.trans_chars[1] = (char) msg.wParam; + if ((ch1 & 0xfc00) == 0xd800) { + tsdPtr->surrogateBuffer = ch1; + return; + } + if ((ch1 & 0xfc00) == 0xdc00) { + ch1 = ((tsdPtr->surrogateBuffer & 0x3ff) << 10) | + (ch1 & 0x3ff) | 0x10000; + tsdPtr->surrogateBuffer = 0; + } + event.xany.send_event = -3; + event.xkey.nbytes = Tcl_UniCharToUtf(ch1, buffer); + if ((ch1 <= 0xffff) || (event.xkey.nbytes == XMaxTransChars)) { + for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) { + event.xkey.trans_chars[i] = buffer[i]; + } + } else { +#ifdef USE_EXTRA_EVENTS + event.xkey.keycode = ((int)(ch1 - 0x10000)>>10) | 0xd800; + event.xkey.nbytes = Tcl_UniCharToUtf(event.xkey.keycode, buffer); + for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) { + event.xkey.trans_chars[i] = buffer[i]; + } + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + event.type = KeyRelease; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + event.type = KeyPress; + event.xkey.keycode = ((int)(ch1 - 0x10000)&0x3ff) | 0xdc00; + event.xkey.nbytes = Tcl_UniCharToUtf(event.xkey.keycode, buffer); + for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) { + event.xkey.trans_chars[i] = buffer[i]; + } +#else + event.xkey.nbytes = 0; +#endif + } + } else { + event.xkey.nbytes = 1; + event.xkey.trans_chars[0] = (char) wParam; + + if (IsDBCSLeadByte((BYTE) wParam)) { + MSG msg; + + if ((PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE) != 0) + && (msg.message == WM_CHAR)) { + GetMessage(&msg, NULL, 0, 0); + event.xkey.nbytes = 2; + event.xkey.trans_chars[1] = (char) msg.wParam; + } } } Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); @@ -1221,8 +1274,34 @@ GenerateXEvent( event.xany.send_event = -3; event.xkey.keycode = wParam; event.xkey.nbytes = Tcl_UniCharToUtf((int)wParam, buffer); - for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) { - event.xkey.trans_chars[i] = buffer[i]; + if(((int)wParam > 0xffff) && (event.xkey.nbytes < XMaxTransChars)) { +#if USE_EXTRA_EVENTS + /* trans_chars buffer is not big enough to hold 2 surrogate + characters, so split it in two separate events */ + + event.xkey.keycode = ((int)(wParam - 0x10000)>>10) | 0xd800; + event.xkey.nbytes = Tcl_UniCharToUtf(event.xkey.keycode, buffer); + for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) { + event.xkey.trans_chars[i] = buffer[i]; + } + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + event.type = KeyRelease; + Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); + event.type = KeyPress; + event.xkey.keycode = ((int)(wParam - 0x10000)&0x3ff) | 0xdc00; + event.xkey.nbytes = Tcl_UniCharToUtf(event.xkey.keycode, buffer); + for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) { + event.xkey.trans_chars[i] = buffer[i]; + } +#else + /* trans_chars buffer is not big enough to hold 2 surrogate + characters, so don't store anything redundant anyway. */ + event.xkey.nbytes = 0; +#endif + } else { + for (i=0; i<event.xkey.nbytes && i<XMaxTransChars; ++i) { + event.xkey.trans_chars[i] = buffer[i]; + } } Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); event.type = KeyRelease; |