aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJason Rumney <[email protected]>2008-01-17 11:38:45 +0000
committerJason Rumney <[email protected]>2008-01-17 11:38:45 +0000
commit602e142f5cddd7b199abb16ee9db1aeaa6e01ea6 (patch)
tree28713adfefb8158eec4b71b90a789292b0a299d4 /src
parenteddedb1594409e2eb4dc42840a72023190d0e716 (diff)
(w32_read_socket) <WM_CHAR>: Decode characters outside
the unicode range available in MULE by locale-coding-system. Improve dbcs lead byte detection. Set event timestamp and modifiers earlier.
Diffstat (limited to 'src')
-rw-r--r--src/ChangeLog7
-rw-r--r--src/w32term.c86
2 files changed, 75 insertions, 18 deletions
diff --git a/src/ChangeLog b/src/ChangeLog
index ceea594199..a2cb8c490a 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2008-01-17 Jason Rumney <[email protected]>
+
+ * w32term.c (w32_read_socket) <WM_CHAR>: Decode characters outside
+ the unicode range available in MULE by locale-coding-system.
+ Improve dbcs lead byte detection. Set event timestamp and modifiers
+ earlier.
+
2008-01-17 Glenn Morris <[email protected]>
* m/ibms390x.h (START_FILES, LIB_STANDARD): Adjust value according
diff --git a/src/w32term.c b/src/w32term.c
index a85715dbfb..23b7900840 100644
--- a/src/w32term.c
+++ b/src/w32term.c
@@ -4290,6 +4290,10 @@ w32_read_socket (sd, expected, hold_quit)
temp_index = 0;
temp_buffer[temp_index++] = msg.msg.wParam;
+ inev.modifiers = msg.dwModifiers;
+ XSETFRAME (inev.frame_or_window, f);
+ inev.timestamp = msg.msg.time;
+
if (msg.msg.wParam < 128 && !dbcs_lead)
{
inev.kind = ASCII_KEYSTROKE_EVENT;
@@ -4298,20 +4302,14 @@ w32_read_socket (sd, expected, hold_quit)
else if (msg.msg.wParam < 256)
{
wchar_t code;
-
+ char dbcs[2];
inev.kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
+ dbcs[0] = 0;
+ dbcs[1] = (char) msg.msg.wParam;
- if (IsDBCSLeadByteEx(CP_ACP, (BYTE) msg.msg.wParam))
- {
- dbcs_lead = (char) msg.msg.wParam;
- inev.kind = NO_EVENT;
- break;
- }
- else if (dbcs_lead)
+ if (dbcs_lead)
{
- char dbcs[2];
dbcs[0] = dbcs_lead;
- dbcs[1] = (char) msg.msg.wParam;
dbcs_lead = 0;
if (!MultiByteToWideChar(CP_ACP, 0, dbcs, 2, &code, 1))
{
@@ -4322,14 +4320,19 @@ w32_read_socket (sd, expected, hold_quit)
break;
}
}
+ else if (IsDBCSLeadByteEx(CP_ACP, (BYTE) msg.msg.wParam))
+ {
+ dbcs_lead = (char) msg.msg.wParam;
+ inev.kind = NO_EVENT;
+ break;
+ }
else
{
- char single_byte = (char) msg.msg.wParam;
- if (!MultiByteToWideChar(CP_ACP, 0, &single_byte, 1,
+ if (!MultiByteToWideChar(CP_ACP, 0, &dbcs[1], 1,
&code, 1))
{
/* What to do with garbage? */
- DebPrint (("Invalid character: %d\n", single_byte));
+ DebPrint (("Invalid character: %d\n", dbcs[1]));
inev.kind = NO_EVENT;
break;
}
@@ -4355,17 +4358,67 @@ w32_read_socket (sd, expected, hold_quit)
charset_id = charset_mule_unicode_0100_24ff;
code -= 0x100;
}
- else if (code < 0xE000)
+ else if (code < 0x3400)
{
charset_id = charset_mule_unicode_2500_33ff;
code -= 0x2500;
}
- else
+ else if (code >= 0xE000)
{
charset_id = charset_mule_unicode_e000_ffff;
code -= 0xE000;
}
+ else
+ {
+ /* Not in the unicode range that we can handle in
+ Emacs-22, so decode the original character
+ using the locale */
+ int nbytes, nchars, require, i, len;
+ unsigned char *dest;
+ struct coding_system coding;
+
+ if (dbcs[0] == 0)
+ {
+ nbytes = 1;
+ dbcs[0] = dbcs[1];
+ }
+ else
+ nbytes = 2;
+
+ setup_coding_system (Vlocale_coding_system, &coding);
+ coding.src_multibyte = 0;
+ coding.dst_multibyte = 1;
+ coding.composing = COMPOSITION_DISABLED;
+ require = decoding_buffer_size (&coding, nbytes);
+ dest = (unsigned char *) alloca (require);
+ coding.mode |= CODING_MODE_LAST_BLOCK;
+
+ decode_coding (&coding, dbcs, dest, nbytes, require);
+ nbytes = coding.produced;
+ nchars = coding.produced_char;
+
+ for (i = 0; i < nbytes; i += len)
+ {
+ if (nchars == nbytes)
+ {
+ inev.code = dest[i];
+ len = 1;
+ }
+ else
+ inev.code = STRING_CHAR_AND_LENGTH (dest + i,
+ nbytes - 1,
+ len);
+ inev.kind = (SINGLE_BYTE_CHAR_P (inev.code)
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+ count++;
+ }
+ inev.kind = NO_EVENT; /* Already handled */
+ break;
+ }
+ /* Unicode characters from above. */
c1 = (code / 96) + 32;
c2 = (code % 96) + 32;
inev.code = MAKE_CHAR (charset_id, c1, c2);
@@ -4379,9 +4432,6 @@ w32_read_socket (sd, expected, hold_quit)
inev.kind = NO_EVENT;
break;
}
- inev.modifiers = msg.dwModifiers;
- XSETFRAME (inev.frame_or_window, f);
- inev.timestamp = msg.msg.time;
}
break;