diff options
Diffstat (limited to 'win')
-rw-r--r-- | win/Makefile.in | 2 | ||||
-rw-r--r-- | win/rules.vc | 2 | ||||
-rw-r--r-- | win/tkWinFont.c | 2 | ||||
-rw-r--r-- | win/tkWinKey.c | 51 | ||||
-rw-r--r-- | win/tkWinX.c | 64 |
5 files changed, 78 insertions, 43 deletions
diff --git a/win/Makefile.in b/win/Makefile.in index 7b1766d..cc90b71 100644 --- a/win/Makefile.in +++ b/win/Makefile.in @@ -169,7 +169,7 @@ LDFLAGS_OPTIMIZE = @LDFLAGS_OPTIMIZE@ #CFLAGS = $(CFLAGS_DEBUG) #CFLAGS = $(CFLAGS_OPTIMIZE) #CFLAGS = $(CFLAGS_DEBUG) $(CFLAGS_OPTIMIZE) -CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE +CFLAGS = @CFLAGS@ @CFLAGS_DEFAULT@ -DUNICODE -D_UNICODE -D_ATL_XP_TARGETING # Special compiler flags to use when building man2tcl on Windows. MAN2TCLFLAGS = @MAN2TCLFLAGS@ diff --git a/win/rules.vc b/win/rules.vc index 503df50..2cd711b 100644 --- a/win/rules.vc +++ b/win/rules.vc @@ -159,7 +159,7 @@ DEBUGFLAGS = $(DEBUGFLAGS) -RTC1 DEBUGFLAGS = $(DEBUGFLAGS) -GZ
!endif
-COMPILERFLAGS =-W3 -DUNICODE -D_UNICODE -D_USING_V110_SDK71_=1
+COMPILERFLAGS =-W3 /DUNICODE /D_UNICODE /D_ATL_XP_TARGETING
# In v13 -GL and -YX are incompatible.
!if [nmakehlp -c -YX]
diff --git a/win/tkWinFont.c b/win/tkWinFont.c index 9172b00..940bc10 100644 --- a/win/tkWinFont.c +++ b/win/tkWinFont.c @@ -2188,7 +2188,7 @@ FontMapLoadPage( { FontFamily *familyPtr; Tcl_Encoding encoding; - char src[TCL_UTF_MAX], buf[16]; + char src[XMaxTransChars], buf[16]; USHORT *startCount, *endCount; int i, j, bitOffset, end, segCount; diff --git a/win/tkWinKey.c b/win/tkWinKey.c index ed546f7..2698c4d 100644 --- a/win/tkWinKey.c +++ b/win/tkWinKey.c @@ -102,7 +102,7 @@ TkpGetString( */ int unichar; - char buf[TCL_UTF_MAX]; + char buf[XMaxTransChars]; int len; unichar = keyEv->trans_chars[1] & 0xff; @@ -113,12 +113,23 @@ TkpGetString( Tcl_DStringAppend(dsPtr, buf, len); } else if (keyEv->send_event == -3) { + + char buf[XMaxTransChars]; + int len; + /* - * Special case for WM_UNICHAR. xkey.trans_chars[] already contains a - * UTF-8 char. + * Special case for WM_UNICHAR. */ - Tcl_DStringAppend(dsPtr, keyEv->trans_chars, keyEv->nbytes); + len = Tcl_UniCharToUtf(keyEv->keycode, buf); + if ((keyEv->keycode <= 0xffff) || (len == XMaxTransChars)) { + Tcl_DStringAppend(dsPtr, buf, len); + } else { + 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 @@ -129,7 +140,7 @@ TkpGetString( if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256)) || (keysym == XK_Return) || (keysym == XK_Tab)) { - char buf[TCL_UTF_MAX]; + char buf[XMaxTransChars]; int len; len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf); @@ -335,18 +346,24 @@ KeycodeToKeysym( /* * Windows only gives us an undifferentiated VK_CONTROL code (for * example) when either Control key is pressed. To distinguish between - * left and right, we have to query the state of one of the two to - * determine which was actually pressed. So if the keycode indicates - * Control, Shift, or Menu (the key that everybody else calls Alt), do - * this extra test. If the right-side key was pressed, return the - * appropriate keycode. Otherwise, we fall through and rely on the - * keymap table to hold the correct keysym value. + * left and right, we use the Extended flag. Indeed, the right Control + * and Alt (aka Menu) keys are such extended keys (which their left + * counterparts are not). + * Regarding the shift case, Windows does not set the Extended flag for + * the neither the left nor the right shift key. As a consequence another + * way to distinguish between the two keys is to query the state of one + * of the two to determine which was actually pressed. So if the keycode + * indicates Shift, do this extra test. If the right-side key was + * pressed, return the appropriate keycode. Otherwise, we fall through + * and rely on the keymap table to hold the correct keysym value. + * Note: this little trick only works for KeyPress, not for KeyRelease, + * for reasons stated in bug [2945130] */ case VK_CONTROL: - if (GetKeyState(VK_RCONTROL) & 0x80) { - return XK_Control_R; - } + if (state & EXTENDED_MASK) { + return XK_Control_R; + } break; case VK_SHIFT: if (GetKeyState(VK_RSHIFT) & 0x80) { @@ -354,9 +371,9 @@ KeycodeToKeysym( } break; case VK_MENU: - if (GetKeyState(VK_RMENU) & 0x80) { - return XK_Alt_R; - } + if (state & EXTENDED_MASK) { + return XK_Alt_R; + } break; } return keymap[keycode]; diff --git a/win/tkWinX.c b/win/tkWinX.c index 6c44059..bb60a2d 100644 --- a/win/tkWinX.c +++ b/win/tkWinX.c @@ -81,6 +81,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 +912,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 +1207,34 @@ 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 ch1 = wParam & 0xffff; - 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 = 0; + event.xkey.keycode = ch1; + } 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); @@ -1215,15 +1242,10 @@ GenerateXEvent( break; case WM_UNICHAR: { - char buffer[TCL_UTF_MAX+1]; - int i; event.type = KeyPress; 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<TCL_UTF_MAX; ++i) { - event.xkey.trans_chars[i] = buffer[i]; - } + event.xkey.nbytes = 0; Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL); event.type = KeyRelease; break; @@ -1321,11 +1343,7 @@ GetState( state &= ~mask; } if (HIWORD(lParam) & KF_EXTENDED) { - if (message == WM_SYSKEYDOWN || message == WM_KEYDOWN) { - state |= EXTENDED_MASK; - } else { - state &= ~EXTENDED_MASK; - } + state |= EXTENDED_MASK; } } return state; |