diff options
Diffstat (limited to 'win/tkWinKey.c')
-rw-r--r-- | win/tkWinKey.c | 97 |
1 files changed, 43 insertions, 54 deletions
diff --git a/win/tkWinKey.c b/win/tkWinKey.c index ed546f7..1ebf312 100644 --- a/win/tkWinKey.c +++ b/win/tkWinKey.c @@ -88,6 +88,8 @@ TkpGetString( * result. */ { XKeyEvent *keyEv = &eventPtr->xkey; + char buf[6]; + int len; Tcl_DStringInit(dsPtr); if (keyEv->send_event == -1) { @@ -95,30 +97,14 @@ TkpGetString( Tcl_ExternalToUtfDString(TkWinGetKeyInputEncoding(), keyEv->trans_chars, keyEv->nbytes, dsPtr); } - } else if (keyEv->send_event == -2) { - /* - * Special case for win2000 multi-lingal IME input. xkey.trans_chars[] - * already contains a UNICODE char. - */ - - int unichar; - char buf[TCL_UTF_MAX]; - int len; - - unichar = keyEv->trans_chars[1] & 0xff; - unichar <<= 8; - unichar |= keyEv->trans_chars[0] & 0xff; - - len = Tcl_UniCharToUtf((Tcl_UniChar) unichar, buf); - - Tcl_DStringAppend(dsPtr, buf, len); } else if (keyEv->send_event == -3) { + /* - * Special case for WM_UNICHAR. xkey.trans_chars[] already contains a - * UTF-8 char. + * Special case for WM_UNICHAR and win2000 multi-lingal IME input */ - Tcl_DStringAppend(dsPtr, keyEv->trans_chars, keyEv->nbytes); + len = TkUniCharToUtf(keyEv->keycode, buf); + Tcl_DStringAppend(dsPtr, buf, len); } else { /* * This is an event generated from generic code. It has no nchars or @@ -129,9 +115,6 @@ TkpGetString( if (((keysym != NoSymbol) && (keysym > 0) && (keysym < 256)) || (keysym == XK_Return) || (keysym == XK_Tab)) { - char buf[TCL_UTF_MAX]; - int len; - len = Tcl_UniCharToUtf((Tcl_UniChar) (keysym & 255), buf); Tcl_DStringAppend(dsPtr, buf, len); } @@ -196,18 +179,18 @@ KeycodeToKeysym( { BYTE keys[256]; int result, deadkey, shift; - char buf[4]; + TCHAR buf[4]; unsigned int scancode = MapVirtualKey(keycode, 0); /* - * Do not run keycodes of lock keys through ToAscii(). One of ToAscii()'s + * Do not run keycodes of lock keys through ToUnicode(). One of ToUnicode()'s * side effects is to handle the lights on the keyboard, and we don't want * to mess that up. */ if (noascii || keycode == VK_CAPITAL || keycode == VK_SCROLL || keycode == VK_NUMLOCK) { - goto skipToAscii; + goto skipToUnicode; } /* @@ -248,24 +231,24 @@ KeycodeToKeysym( keys[VK_NUMLOCK] = 1; } - result = ToAscii(keycode, scancode, keys, (LPWORD) buf, 0); + result = ToUnicode(keycode, scancode, keys, buf, 4, 0); if (result < 0) { /* * Win95/98: This was a dead char, which is now remembered by the - * keyboard. Call ToAscii() again to forget it. + * keyboard. Call ToUnicode() again to forget it. * WinNT: This was a dead char, overwriting any previously remembered - * key. Calling ToAscii() again does not affect anything. + * key. Calling ToUnicode() again does not affect anything. */ - ToAscii(keycode, scancode, keys, (LPWORD) buf, 0); + ToUnicode(keycode, scancode, keys, buf, 4, 0); return XK_Multi_key; } if (result == 2) { /* * This was a dead char, and there were one previously remembered by - * the keyboard. Call ToAscii() again with proper parameters to + * the keyboard. Call ToUnicode() again with proper parameters to * restore it. * * Get information about the old char @@ -290,26 +273,26 @@ KeycodeToKeysym( if (shift & 4) { keys[VK_MENU] = 0x80; } - ToAscii(deadkey, scancode, keys, (LPWORD) buf, 0); + ToUnicode(deadkey, scancode, keys, buf, 4, 0); return XK_Multi_key; } /* - * Keycode mapped to a valid Latin-1 character. Since the keysyms for - * alphanumeric characters map onto Latin-1, we just return it. + * Keycode mapped to a valid Unicode character. Since the keysyms for + * alphanumeric characters map onto Unicode, we just return it. * * We treat 0x7F as a special case mostly for backwards compatibility. In * versions of Tk<=8.2, Control-Backspace returned "XK_BackSpace" as the X * Keysym. This was due to the fact that we did not initialize the keys - * array properly when we passed it to ToAscii, above. We had previously + * array properly when we passed it to ToUnicode, above. We had previously * not been setting the state bit for the Control key. When we fixed that, * we found that Control-Backspace on Windows is interpreted as ASCII-127 * (0x7F), which corresponds to the Delete key. * * Upon discovering this, we realized we had two choices: return XK_Delete * or return XK_BackSpace. If we returned XK_Delete, that could be - * considered "more correct" (although the correctness would be dependant - * on whether you believe that ToAscii is doing the right thing in that + * considered "more correct" (although the correctness would be dependent + * on whether you believe that ToUnicode is doing the right thing in that * case); however, this would break backwards compatibility, and worse, it * would limit application programmers; they would effectively be unable * to bind to <Control-Backspace> on Windows. We therefore chose instead @@ -319,15 +302,15 @@ KeycodeToKeysym( * XK_BackSpace). */ - if (result == 1 && UCHAR(buf[0]) >= 0x20 && UCHAR(buf[0]) != 0x7F) { - return (KeySym) UCHAR(buf[0]); + if (result == 1 && buf[0] >= 0x20 && buf[0] != 0x7F) { + return (KeySym) buf[0]; } /* * Keycode is a non-alphanumeric key, so we have to do the lookup. */ - skipToAscii: + skipToUnicode: if (keycode > MAX_KEYCODE) { return NoSymbol; } @@ -335,18 +318,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 +343,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]; @@ -576,7 +565,7 @@ TkpSetKeycodeAndState( } } if (keySym >= 0x20) { - result = VkKeyScan((char) keySym); + result = VkKeyScan((TCHAR) keySym); if (result != -1) { shift = result >> 8; if (shift & 1) @@ -629,7 +618,7 @@ XKeysymToKeycode( } } if (keysym >= 0x20) { - result = VkKeyScan((char) keysym); + result = VkKeyScan((TCHAR) keysym); if (result != -1) { return (KeyCode) (result & 0xff); } |