summaryrefslogtreecommitdiffstats
path: root/win
diff options
context:
space:
mode:
Diffstat (limited to 'win')
-rw-r--r--win/tkWinKey.c17
-rw-r--r--win/tkWinX.c58
2 files changed, 54 insertions, 21 deletions
diff --git a/win/tkWinKey.c b/win/tkWinKey.c
index 3d2a16a..2698c4d 100644
--- a/win/tkWinKey.c
+++ b/win/tkWinKey.c
@@ -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
diff --git a/win/tkWinX.c b/win/tkWinX.c
index 1f9ad89..6be54e2 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[XMaxTransChars];
- 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<XMaxTransChars; ++i) {
- event.xkey.trans_chars[i] = buffer[i];
- }
+ event.xkey.nbytes = 0;
Tk_QueueWindowEvent(&event, TCL_QUEUE_TAIL);
event.type = KeyRelease;
break;