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