summaryrefslogtreecommitdiffstats
path: root/win/tkWinKey.c
diff options
context:
space:
mode:
Diffstat (limited to 'win/tkWinKey.c')
-rw-r--r--win/tkWinKey.c97
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);
}