aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIlya Zakharevich2015-07-31 11:50:23 +0300
committerEli Zaretskii2015-07-31 11:50:23 +0300
commit123c82e8307ca386ba7f161dc725e3953dffc5c0 (patch)
treeb52752e19fe6f93384c6b6d0b1d74380b05f701f /src
parentb07ca177d449e58e6e5c14e21e140e63354e335c (diff)
downloademacs-123c82e8307ca386ba7f161dc725e3953dffc5c0.tar.gz
emacs-123c82e8307ca386ba7f161dc725e3953dffc5c0.zip
Improve handling of Unicode keyboard input on MS-Windows
* src/w32fns.c (get_wm_chars, deliver_wm_chars): New functions. (FPRINTF_WM_CHARS) [DEBUG_WM_CHARS]: New macro for debugging. (w32_wnd_proc): Call deliver_wm_chars to process non-special keys upon receiving WM_KEYDOWN or WM_SYSKEYDOWN messages. If that is successful, don't call TranslateMessage. (Bug#19994)
Diffstat (limited to 'src')
-rw-r--r--src/w32fns.c979
1 files changed, 718 insertions, 261 deletions
diff --git a/src/w32fns.c b/src/w32fns.c
index c742ca8534f..fecdf7cb72d 100644
--- a/src/w32fns.c
+++ b/src/w32fns.c
@@ -270,7 +270,7 @@ check_x_display_info (Lisp_Object object)
270 struct terminal *t = decode_live_terminal (object); 270 struct terminal *t = decode_live_terminal (object);
271 271
272 if (t->type != output_w32) 272 if (t->type != output_w32)
273 error ("Terminal %d is not a W32 display", t->id); 273 error ("Terminal %d is not a W32 display", t->id);
274 274
275 return t->display_info.w32; 275 return t->display_info.w32;
276 } 276 }
@@ -304,7 +304,7 @@ x_window_to_frame (struct w32_display_info *dpyinfo, HWND wdesc)
304 continue; 304 continue;
305 305
306 if (FRAME_W32_WINDOW (f) == wdesc) 306 if (FRAME_W32_WINDOW (f) == wdesc)
307 return f; 307 return f;
308 } 308 }
309 return 0; 309 return 0;
310} 310}
@@ -366,7 +366,7 @@ w32_fullscreen_rect (HWND hwnd, int fsmode, RECT normal, RECT *rect)
366 if (monitor_from_window_fn && get_monitor_info_fn) 366 if (monitor_from_window_fn && get_monitor_info_fn)
367 { 367 {
368 HMONITOR monitor = 368 HMONITOR monitor =
369 monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST); 369 monitor_from_window_fn (hwnd, MONITOR_DEFAULT_TO_NEAREST);
370 get_monitor_info_fn (monitor, &mi); 370 get_monitor_info_fn (monitor, &mi);
371 } 371 }
372 else 372 else
@@ -949,8 +949,8 @@ x_to_w32_color (const char * colorname)
949 break; 949 break;
950 val = (UINT)(0x100 * value); 950 val = (UINT)(0x100 * value);
951 /* We used 0x100 instead of 0xFF to give a continuous 951 /* We used 0x100 instead of 0xFF to give a continuous
952 range between 0.0 and 1.0 inclusive. The next statement 952 range between 0.0 and 1.0 inclusive. The next statement
953 fixes the 1.0 case. */ 953 fixes the 1.0 case. */
954 if (val == 0x100) 954 if (val == 0x100)
955 val = 0xFF; 955 val = 0xFF;
956 colorval |= (val << pos); 956 colorval |= (val << pos);
@@ -1060,7 +1060,7 @@ w32_map_color (struct frame *f, COLORREF color)
1060 while (list) 1060 while (list)
1061 { 1061 {
1062 if (W32_COLOR (list->entry) == color) 1062 if (W32_COLOR (list->entry) == color)
1063 { 1063 {
1064 ++list->refcount; 1064 ++list->refcount;
1065 return; 1065 return;
1066 } 1066 }
@@ -1092,7 +1092,7 @@ w32_unmap_color (struct frame *f, COLORREF color)
1092 while (list) 1092 while (list)
1093 { 1093 {
1094 if (W32_COLOR (list->entry) == color) 1094 if (W32_COLOR (list->entry) == color)
1095 { 1095 {
1096 if (--list->refcount == 0) 1096 if (--list->refcount == 0)
1097 { 1097 {
1098 *prev = list->next; 1098 *prev = list->next;
@@ -1121,9 +1121,9 @@ gamma_correct (struct frame *f, COLORREF *color)
1121 if (f->gamma) 1121 if (f->gamma)
1122 { 1122 {
1123 *color = PALETTERGB ( 1123 *color = PALETTERGB (
1124 pow (GetRValue (*color) / 255.0, f->gamma) * 255.0 + 0.5, 1124 pow (GetRValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
1125 pow (GetGValue (*color) / 255.0, f->gamma) * 255.0 + 0.5, 1125 pow (GetGValue (*color) / 255.0, f->gamma) * 255.0 + 0.5,
1126 pow (GetBValue (*color) / 255.0, f->gamma) * 255.0 + 0.5); 1126 pow (GetBValue (*color) / 255.0, f->gamma) * 255.0 + 0.5);
1127 } 1127 }
1128} 1128}
1129 1129
@@ -1144,12 +1144,12 @@ w32_defined_color (struct frame *f, const char *color, XColor *color_def,
1144 if (!NILP (tem)) 1144 if (!NILP (tem))
1145 { 1145 {
1146 if (f) 1146 if (f)
1147 { 1147 {
1148 /* Apply gamma correction. */ 1148 /* Apply gamma correction. */
1149 w32_color_ref = XUINT (tem); 1149 w32_color_ref = XUINT (tem);
1150 gamma_correct (f, &w32_color_ref); 1150 gamma_correct (f, &w32_color_ref);
1151 XSETINT (tem, w32_color_ref); 1151 XSETINT (tem, w32_color_ref);
1152 } 1152 }
1153 1153
1154 /* Map this color to the palette if it is enabled. */ 1154 /* Map this color to the palette if it is enabled. */
1155 if (!NILP (Vw32_enable_palette)) 1155 if (!NILP (Vw32_enable_palette))
@@ -1258,7 +1258,7 @@ x_set_foreground_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1258 1258
1259 update_face_from_frame_parameter (f, Qforeground_color, arg); 1259 update_face_from_frame_parameter (f, Qforeground_color, arg);
1260 if (FRAME_VISIBLE_P (f)) 1260 if (FRAME_VISIBLE_P (f))
1261 redraw_frame (f); 1261 redraw_frame (f);
1262 } 1262 }
1263} 1263}
1264 1264
@@ -1271,12 +1271,12 @@ x_set_background_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1271 if (FRAME_W32_WINDOW (f) != 0) 1271 if (FRAME_W32_WINDOW (f) != 0)
1272 { 1272 {
1273 SetWindowLong (FRAME_W32_WINDOW (f), WND_BACKGROUND_INDEX, 1273 SetWindowLong (FRAME_W32_WINDOW (f), WND_BACKGROUND_INDEX,
1274 FRAME_BACKGROUND_PIXEL (f)); 1274 FRAME_BACKGROUND_PIXEL (f));
1275 1275
1276 update_face_from_frame_parameter (f, Qbackground_color, arg); 1276 update_face_from_frame_parameter (f, Qbackground_color, arg);
1277 1277
1278 if (FRAME_VISIBLE_P (f)) 1278 if (FRAME_VISIBLE_P (f))
1279 redraw_frame (f); 1279 redraw_frame (f);
1280 } 1280 }
1281} 1281}
1282 1282
@@ -1399,9 +1399,9 @@ x_set_mouse_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1399 XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor, 1399 XRecolorCursor (FRAME_W32_DISPLAY (f), mode_cursor,
1400 &fore_color, &back_color); 1400 &fore_color, &back_color);
1401 XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor, 1401 XRecolorCursor (FRAME_W32_DISPLAY (f), hand_cursor,
1402 &fore_color, &back_color); 1402 &fore_color, &back_color);
1403 XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor, 1403 XRecolorCursor (FRAME_W32_DISPLAY (f), hourglass_cursor,
1404 &fore_color, &back_color); 1404 &fore_color, &back_color);
1405 } 1405 }
1406 1406
1407 if (FRAME_W32_WINDOW (f) != 0) 1407 if (FRAME_W32_WINDOW (f) != 0)
@@ -1445,7 +1445,7 @@ x_set_cursor_color (struct frame *f, Lisp_Object arg, Lisp_Object oldval)
1445 1445
1446 if (!NILP (Vx_cursor_fore_pixel)) 1446 if (!NILP (Vx_cursor_fore_pixel))
1447 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel, 1447 fore_pixel = x_decode_color (f, Vx_cursor_fore_pixel,
1448 WHITE_PIX_DEFAULT (f)); 1448 WHITE_PIX_DEFAULT (f));
1449 else 1449 else
1450 fore_pixel = FRAME_BACKGROUND_PIXEL (f); 1450 fore_pixel = FRAME_BACKGROUND_PIXEL (f);
1451 1451
@@ -1494,7 +1494,7 @@ x_set_border_pixel (struct frame *f, int pix)
1494 if (FRAME_W32_WINDOW (f) != 0 && f->border_width > 0) 1494 if (FRAME_W32_WINDOW (f) != 0 && f->border_width > 0)
1495 { 1495 {
1496 if (FRAME_VISIBLE_P (f)) 1496 if (FRAME_VISIBLE_P (f))
1497 redraw_frame (f); 1497 redraw_frame (f);
1498 } 1498 }
1499} 1499}
1500 1500
@@ -1771,7 +1771,7 @@ w32_set_title_bar_text (struct frame *f, Lisp_Object name)
1771 block_input (); 1771 block_input ();
1772#ifdef __CYGWIN__ 1772#ifdef __CYGWIN__
1773 GUI_FN (SetWindowText) (FRAME_W32_WINDOW (f), 1773 GUI_FN (SetWindowText) (FRAME_W32_WINDOW (f),
1774 GUI_SDATA (GUI_ENCODE_SYSTEM (name))); 1774 GUI_SDATA (GUI_ENCODE_SYSTEM (name)));
1775#else 1775#else
1776 /* The frame's title many times shows the name of the file 1776 /* The frame's title many times shows the name of the file
1777 visited in the selected window's buffer, so it makes sense to 1777 visited in the selected window's buffer, so it makes sense to
@@ -2319,7 +2319,7 @@ w32_get_modifiers (void)
2319 (modifier_set (VK_RWIN) ? w32_key_to_modifier (VK_RWIN) : 0) | 2319 (modifier_set (VK_RWIN) ? w32_key_to_modifier (VK_RWIN) : 0) |
2320 (modifier_set (VK_APPS) ? w32_key_to_modifier (VK_APPS) : 0) | 2320 (modifier_set (VK_APPS) ? w32_key_to_modifier (VK_APPS) : 0) |
2321 (modifier_set (VK_SCROLL) ? w32_key_to_modifier (VK_SCROLL) : 0) | 2321 (modifier_set (VK_SCROLL) ? w32_key_to_modifier (VK_SCROLL) : 0) |
2322 (modifier_set (VK_MENU) ? 2322 (modifier_set (VK_MENU) ?
2323 ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier) : 0)); 2323 ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier) : 0));
2324} 2324}
2325 2325
@@ -2541,13 +2541,13 @@ w32_msg_pump (deferred_msg * msg_buf)
2541 /* Produced by complete_deferred_msg; just ignore. */ 2541 /* Produced by complete_deferred_msg; just ignore. */
2542 break; 2542 break;
2543 case WM_EMACS_CREATEWINDOW: 2543 case WM_EMACS_CREATEWINDOW:
2544 /* Initialize COM for this window. Even though we don't use it, 2544 /* Initialize COM for this window. Even though we don't use it,
2545 some third party shell extensions can cause it to be used in 2545 some third party shell extensions can cause it to be used in
2546 system dialogs, which causes a crash if it is not initialized. 2546 system dialogs, which causes a crash if it is not initialized.
2547 This is a known bug in Windows, which was fixed long ago, but 2547 This is a known bug in Windows, which was fixed long ago, but
2548 the patch for XP is not publicly available until XP SP3, 2548 the patch for XP is not publicly available until XP SP3,
2549 and older versions will never be patched. */ 2549 and older versions will never be patched. */
2550 CoInitialize (NULL); 2550 CoInitialize (NULL);
2551 w32_createwindow ((struct frame *) msg.wParam, 2551 w32_createwindow ((struct frame *) msg.wParam,
2552 (int *) msg.lParam); 2552 (int *) msg.lParam);
2553 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) 2553 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
@@ -2577,9 +2577,9 @@ w32_msg_pump (deferred_msg * msg_buf)
2577 if (focus_window != NULL) 2577 if (focus_window != NULL)
2578 UnregisterHotKey (focus_window, RAW_HOTKEY_ID (msg.wParam)); 2578 UnregisterHotKey (focus_window, RAW_HOTKEY_ID (msg.wParam));
2579 /* Mark item as erased. NB: this code must be 2579 /* Mark item as erased. NB: this code must be
2580 thread-safe. The next line is okay because the cons 2580 thread-safe. The next line is okay because the cons
2581 cell is never made into garbage and is not relocated by 2581 cell is never made into garbage and is not relocated by
2582 GC. */ 2582 GC. */
2583 XSETCAR (make_lisp_ptr ((void *)msg.lParam, Lisp_Cons), Qnil); 2583 XSETCAR (make_lisp_ptr ((void *)msg.lParam, Lisp_Cons), Qnil);
2584 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0)) 2584 if (!PostThreadMessage (dwMainThreadId, WM_EMACS_DONE, 0, 0))
2585 emacs_abort (); 2585 emacs_abort ();
@@ -2612,10 +2612,10 @@ w32_msg_pump (deferred_msg * msg_buf)
2612 } 2612 }
2613 break; 2613 break;
2614#ifdef MSG_DEBUG 2614#ifdef MSG_DEBUG
2615 /* Broadcast messages make it here, so you need to be looking 2615 /* Broadcast messages make it here, so you need to be looking
2616 for something in particular for this to be useful. */ 2616 for something in particular for this to be useful. */
2617 default: 2617 default:
2618 DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message)); 2618 DebPrint (("msg %x not expected by w32_msg_pump\n", msg.message));
2619#endif 2619#endif
2620 } 2620 }
2621 } 2621 }
@@ -2809,19 +2809,19 @@ post_character_message (HWND hwnd, UINT msg,
2809 signal_quit (); 2809 signal_quit ();
2810 2810
2811 /* As a safety precaution, forcibly complete any deferred 2811 /* As a safety precaution, forcibly complete any deferred
2812 messages. This is a kludge, but I don't see any particularly 2812 messages. This is a kludge, but I don't see any particularly
2813 clean way to handle the situation where a deferred message is 2813 clean way to handle the situation where a deferred message is
2814 "dropped" in the lisp thread, and will thus never be 2814 "dropped" in the lisp thread, and will thus never be
2815 completed, eg. by the user trying to activate the menubar 2815 completed, eg. by the user trying to activate the menubar
2816 when the lisp thread is busy, and then typing C-g when the 2816 when the lisp thread is busy, and then typing C-g when the
2817 menubar doesn't open promptly (with the result that the 2817 menubar doesn't open promptly (with the result that the
2818 menubar never responds at all because the deferred 2818 menubar never responds at all because the deferred
2819 WM_INITMENU message is never completed). Another problem 2819 WM_INITMENU message is never completed). Another problem
2820 situation is when the lisp thread calls SendMessage (to send 2820 situation is when the lisp thread calls SendMessage (to send
2821 a window manager command) when a message has been deferred; 2821 a window manager command) when a message has been deferred;
2822 the lisp thread gets blocked indefinitely waiting for the 2822 the lisp thread gets blocked indefinitely waiting for the
2823 deferred message to be completed, which itself is waiting for 2823 deferred message to be completed, which itself is waiting for
2824 the lisp thread to respond. 2824 the lisp thread to respond.
2825 2825
2826 Note that we don't want to block the input thread waiting for 2826 Note that we don't want to block the input thread waiting for
2827 a response from the lisp thread (although that would at least 2827 a response from the lisp thread (although that would at least
@@ -2836,6 +2836,407 @@ post_character_message (HWND hwnd, UINT msg,
2836 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 2836 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2837} 2837}
2838 2838
2839static int
2840get_wm_chars (HWND aWnd, int *buf, int buflen, int ignore_ctrl, int ctrl,
2841 int *ctrl_cnt, int *is_dead, int vk, int exp)
2842{
2843 MSG msg;
2844 /* If doubled is at the end, ignore it. */
2845 int i = buflen, doubled = 0, code_unit;
2846
2847 if (ctrl_cnt)
2848 *ctrl_cnt = 0;
2849 if (is_dead)
2850 *is_dead = -1;
2851 eassert(w32_unicode_gui);
2852 while (buflen
2853 /* Should be called only when w32_unicode_gui: */
2854 && PeekMessageW(&msg, aWnd, WM_KEYFIRST, WM_KEYLAST,
2855 PM_NOREMOVE | PM_NOYIELD)
2856 && (msg.message == WM_CHAR || msg.message == WM_SYSCHAR
2857 || msg.message == WM_DEADCHAR || msg.message == WM_SYSDEADCHAR
2858 || msg.message == WM_UNICHAR))
2859 {
2860 /* We extract character payload, but in this call we handle only the
2861 characters which comes BEFORE the next keyup/keydown message. */
2862 int dead;
2863
2864 GetMessageW(&msg, aWnd, msg.message, msg.message);
2865 dead = (msg.message == WM_DEADCHAR || msg.message == WM_SYSDEADCHAR);
2866 if (is_dead)
2867 *is_dead = (dead ? msg.wParam : -1);
2868 if (dead)
2869 continue;
2870 code_unit = msg.wParam;
2871 if (doubled)
2872 {
2873 /* Had surrogate. */
2874 if (msg.message == WM_UNICHAR
2875 || code_unit < 0xDC00 || code_unit > 0xDFFF)
2876 { /* Mismatched first surrogate.
2877 Pass both code units as if they were two characters. */
2878 *buf++ = doubled;
2879 if (!--buflen)
2880 return i; /* Drop the 2nd char if at the end of the buffer. */
2881 }
2882 else /* see https://en.wikipedia.org/wiki/UTF-16 */
2883 code_unit = (doubled << 10) + code_unit - 0x35FDC00;
2884 doubled = 0;
2885 }
2886 else if (code_unit >= 0xD800 && code_unit <= 0xDBFF)
2887 {
2888 /* Handle mismatched 2nd surrogate the same as a normal character. */
2889 doubled = code_unit;
2890 continue;
2891 }
2892
2893 /* The only "fake" characters delivered by ToUnicode() or
2894 TranslateMessage() are:
2895 0x01 .. 0x1a for Ctrl-letter, Enter, Tab, Ctrl-Break, Esc, Backspace
2896 0x00 and 0x1b .. 0x1f for Control- []\@^_
2897 0x7f for Control-BackSpace
2898 0x20 for Control-Space */
2899 if (ignore_ctrl
2900 && (code_unit < 0x20 || code_unit == 0x7f
2901 || (code_unit == 0x20 && ctrl)))
2902 {
2903 /* Non-character payload in a WM_CHAR
2904 (Ctrl-something pressed, see above). Ignore, and report. */
2905 if (ctrl_cnt)
2906 *ctrl_cnt++;
2907 continue;
2908 }
2909 /* Traditionally, Emacs would ignore the character payload of VK_NUMPAD*
2910 keys, and would treat them later via `function-key-map'. In addition
2911 to usual 102-key NUMPAD keys, this map also treats `kp-'-variants of
2912 space, tab, enter, separator, equal. TAB and EQUAL, apparently,
2913 cannot be generated on Win-GUI branch. ENTER is already handled
2914 by the code above. According to `lispy_function_keys', kp_space is
2915 generated by not-extended VK_CLEAR. (kp-tab != VK_OEM_NEC_EQUAL!).
2916
2917 We do similarly for backward-compatibility, but ignore only the
2918 characters restorable later by `function-key-map'. */
2919 if (code_unit < 0x7f
2920 && ((vk >= VK_NUMPAD0 && vk <= VK_DIVIDE)
2921 || (exp && ((vk >= VK_PRIOR && vk <= VK_DOWN) ||
2922 vk == VK_INSERT || vk == VK_DELETE || vk == VK_CLEAR)))
2923 && strchr("0123456789/*-+.,", code_unit))
2924 continue;
2925 *buf++ = code_unit;
2926 buflen--;
2927 }
2928 return i - buflen;
2929}
2930
2931#ifdef DBG_WM_CHARS
2932# define FPRINTF_WM_CHARS(ARG) fprintf ARG
2933#else
2934# define FPRINTF_WM_CHARS(ARG) 0
2935#endif
2936
2937/* This is a heuristic only. This is supposed to track the state of the
2938 finite automaton in the language environment of Windows.
2939
2940 However, separate windows (if with the same different language
2941 environments!) should have different values. Moreover, switching to a
2942 non-Emacs window with the same language environment, and using (dead)keys
2943 there would change the value stored in the kernel, but not this value. */
2944static int after_deadkey = 0;
2945
2946int
2947deliver_wm_chars (int do_translate, HWND hwnd, UINT msg, UINT wParam,
2948 UINT lParam, int legacy_alt_meta)
2949{
2950 /* An "old style" keyboard description may assign up to 125 UTF-16 code
2951 points to a keypress.
2952 (However, the "old style" TranslateMessage() would deliver at most 16 of
2953 them.) Be on a safe side, and prepare to treat many more. */
2954 int ctrl_cnt, buf[1024], count, is_dead, after_dead = (after_deadkey != -1);
2955
2956 /* Since the keypress processing logic of Windows has a lot of state, it
2957 is important to call TranslateMessage() for every keyup/keydown, AND
2958 do it exactly once. (The actual change of state is done by
2959 ToUnicode[Ex](), which is called by TranslateMessage(). So one can
2960 call ToUnicode[Ex]() instead.)
2961
2962 The "usual" message pump calls TranslateMessage() for EVERY event.
2963 Emacs calls TranslateMessage() very selectively (is it needed for doing
2964 some tricky stuff with Win95??? With newer Windows, selectiveness is,
2965 most probably, not needed - and harms a lot).
2966
2967 So, with the usual message pump, the following call to TranslateMessage()
2968 is not needed (and is going to be VERY harmful). With Emacs' message
2969 pump, the call is needed. */
2970 if (do_translate)
2971 {
2972 MSG windows_msg = { hwnd, msg, wParam, lParam, 0, {0,0} };
2973
2974 windows_msg.time = GetMessageTime ();
2975 TranslateMessage (&windows_msg);
2976 }
2977 count = get_wm_chars (hwnd, buf, sizeof(buf)/sizeof(*buf), 1,
2978 /* The message may have been synthesized by
2979 who knows what; be conservative. */
2980 modifier_set (VK_LCONTROL)
2981 || modifier_set (VK_RCONTROL)
2982 || modifier_set (VK_CONTROL),
2983 &ctrl_cnt, &is_dead, wParam,
2984 (lParam & 0x1000000L) != 0);
2985 if (count)
2986 {
2987 W32Msg wmsg;
2988 DWORD console_modifiers = construct_console_modifiers ();
2989 int *b = buf, strip_Alt = 1, strip_ExtraMods = 1, hairy = 0;
2990 char *type_CtrlAlt = NULL;
2991
2992 /* XXXX In fact, there may be another case when we need to do the same:
2993 What happens if the string defined in the LIGATURES has length
2994 0? Probably, we will get count==0, but the state of the finite
2995 automaton would reset to 0??? */
2996 after_deadkey = -1;
2997
2998 /* wParam is checked when converting CapsLock to Shift; this is a clone
2999 of w32_get_key_modifiers (). */
3000 wmsg.dwModifiers = w32_kbd_mods_to_emacs (console_modifiers, wParam);
3001
3002 /* What follows is just heuristics; the correct treatement requires
3003 non-destructive ToUnicode():
3004 http://search.cpan.org/~ilyaz/UI-KeyboardLayout/lib/UI/KeyboardLayout.pm#Can_an_application_on_Windows_accept_keyboard_events?_Part_IV:_application-specific_modifiers
3005
3006 What one needs to find is:
3007 * which of the present modifiers AFFECT the resulting char(s)
3008 (so should be stripped, since their EFFECT is "already
3009 taken into account" in the string in buf), and
3010 * which modifiers are not affecting buf, so should be reported to
3011 the application for further treatment.
3012
3013 Example: assume that we know:
3014 (A) lCtrl+rCtrl+rAlt modifiers with VK_A key produce a Latin "f"
3015 ("may be logical" in JCUKEN-flavored Russian keyboard flavors);
3016 (B) removing any of lCtrl, rCtrl, rAlt changes the produced char;
3017 (C) Win-modifier is not affecting the produced character
3018 (this is the common case: happens with all "standard" layouts).
3019
3020 Suppose the user presses Win+lCtrl+rCtrl+rAlt modifiers with VK_A.
3021 What is the intent of the user? We need to guess the intent to decide
3022 which event to deliver to the application.
3023
3024 This looks like a reasonable logic: since Win- modifier doesn't affect
3025 the output string, the user was pressing Win for SOME OTHER purpose.
3026 So the user wanted to generate Win-SOMETHING event. Now, what is
3027 something? If one takes the mantra that "character payload is more
3028 important than the combination of keypresses which resulted in this
3029 payload", then one should ignore lCtrl+rCtrl+rAlt, ignore VK_A, and
3030 assume that the user wanted to generate Win-f.
3031
3032 Unfortunately, without non-destructive ToUnicode(), checking (B),(C)
3033 is out of question. So we use heuristics (hopefully, covering
3034 99.9999% of cases). */
3035
3036 /* Another thing to watch for is a possibility to use AltGr-* and
3037 Ctrl-Alt-* with different semantic.
3038
3039 Background: the layout defining the KLLF_ALTGR bit are treated
3040 specially by the kernel: when VK_RMENU (=rightAlt, =AltGr) is pressed
3041 (released), a press (release) of VK_LCONTROL is emulated (unless Ctrl
3042 is already down). As a result, any press/release of AltGr is seen
3043 by applications as a press/release of lCtrl AND rAlt. This is
3044 applicable, in particular, to ToUnicode[Ex](). (Keyrepeat is covered
3045 the same way!)
3046
3047 NOTE: it IS possible to see bare rAlt even with KLLF_ALTGR; but this
3048 requires a good finger coordination: doing (physically)
3049 Down-lCtrl Down-rAlt Up-lCtrl Down-a
3050 (doing quick enough, so that key repeat of rAlt [which would
3051 generate new "fake" Down-lCtrl events] does not happens before 'a'
3052 is down) results in no "fake" events, so the application will see
3053 only rAlt down when 'a' is pressed. (However, fake Up-lCtrl WILL
3054 be generated when rAlt goes UP.)
3055
3056 In fact, note also that KLLF_ALTGR does not prohibit construction of
3057 rCtrl-rAlt (just press them in this order!).
3058
3059 Moreover: "traditional" layouts do not define distinct modifier-masks
3060 for VK_LMENU and VK_RMENU (same for VK_L/RCONTROL). Instead, they
3061 rely on the KLLF_ALTGR bit to make the behaviour of VK_LMENU and
3062 VK_RMENU distinct. As a corollary, for such layouts, the produced
3063 character is the same for AltGr-* (=rAlt-*) and Ctrl-Alt-* (in any
3064 combination of handedness). For description of masks, see
3065
3066 http://search.cpan.org/~ilyaz/UI-KeyboardLayout/lib/UI/KeyboardLayout.pm#Keyboard_input_on_Windows,_Part_I:_what_is_the_kernel_doing?
3067
3068 By default, Emacs was using these coincidences via the following
3069 heuristics: it was treating:
3070 (*) keypresses with lCtrl-rAlt modifiers as if they are carrying
3071 ONLY the character payload (no matter what the actual keyboard
3072 was defining: if lCtrl-lAlt-b was delivering U+05df=beta, then
3073 Emacs saw [beta]; if lCtrl-lAlt-b was undefined in the layout,
3074 the keypress was completely ignored), and
3075 (*) keypresses with the other combinations of handedness of Ctrl-Alt
3076 modifiers (e.g., lCtrl-lAlt) as if they NEVER carry a character
3077 payload (so they were reported "raw": if lCtrl-lAlt-b was
3078 delivering beta, then Emacs saw event [C-A-b], and not [beta]).
3079 This worked good for "traditional" layouts: users could type both
3080 AltGr-x and Ctrl-Alt-x, and one was a character, another a bindable
3081 event.
3082
3083 However, for layouts which deliver different characters for AltGr-x
3084 and lCtrl-lAlt-x, this scheme makes the latter character unaccessible
3085 in Emacs. While it is easy to access functionality of [C-M-x] in
3086 Emacs by other means (for example, by the `controlify' prefix, or
3087 using lCtrl-rCtrl-x, or rCtrl-rAlt-x [in this order]), missing
3088 characters cannot be reconstructed without a tedious manual work. */
3089
3090 /* These two cases are often going to be distinguishable, since at most
3091 one of these character is defined with KBDCTRL | KBDMENU modifier
3092 bitmap. (This heuristic breaks if both lCtrl-lAlt- AND lCtrl-rAlt-
3093 are translated to modifier bitmaps distinct from KBDCTRL | KBDMENU,
3094 or in the cases when lCtrl-lAlt-* and lCtrl-rAlt-* are generally
3095 different, but lCtrl-lAlt-x and lCtrl-rAlt-x happen to deliver the
3096 same character.)
3097
3098 So we have 2 chunks of info:
3099 (A) is it lCtrl-rAlt-, or lCtrl-lAlt, or some other combination?
3100 (B) is the delivered character defined with KBDCTRL | KBDMENU bits?
3101 Basing on (A) and (B), we should decide whether to ignore the
3102 delivered character. (Before, Emacs was completely ignoring (B), and
3103 was treating the 3-state of (A) as a bit.) This means that we have 6
3104 bits of customization.
3105
3106 Additionally, a presence of two Ctrl down may be AltGr-rCtrl-. */
3107
3108 /* Strip all non-Shift modifiers if:
3109 - more than one UTF-16 code point delivered (can't call VkKeyScanW ())
3110 - or the character is a result of combining with a prefix key. */
3111 if (!after_dead && count == 1 && *b < 0x10000)
3112 {
3113 if (console_modifiers & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED)
3114 && console_modifiers & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
3115 {
3116 type_CtrlAlt = "bB"; /* generic bindable Ctrl-Alt- modifiers */
3117 if (console_modifiers & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)
3118 == (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED))
3119 /* double-Ctrl:
3120 e.g. AltGr-rCtrl on some layouts (in this order!) */
3121 type_CtrlAlt = "dD";
3122 else if (console_modifiers
3123 & (LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED)
3124 == (LEFT_CTRL_PRESSED | LEFT_ALT_PRESSED))
3125 type_CtrlAlt = "lL"; /* Ctrl-Alt- modifiers on the left */
3126 else if (!NILP (Vw32_recognize_altgr)
3127 && (console_modifiers
3128 & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
3129 == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
3130 type_CtrlAlt = "gG"; /* modifiers as in AltGr */
3131 }
3132 else if (wmsg.dwModifiers & (alt_modifier | meta_modifier)
3133 || (console_modifiers
3134 & (RIGHT_WIN_PRESSED | RIGHT_WIN_PRESSED
3135 | APPS_PRESSED | SCROLLLOCK_ON)))
3136 {
3137 /* Pure Alt (or combination of Alt, Win, APPS, scrolllock. */
3138 type_CtrlAlt = "aA";
3139 }
3140 if (type_CtrlAlt)
3141 {
3142 /* Out of bound bitmap: */
3143 SHORT r = VkKeyScanW( *b ), bitmap = 0x1FF;
3144
3145 FPRINTF_WM_CHARS((stderr, "VkKeyScanW %#06x %#04x\n", (int)r,
3146 wParam));
3147 if ((r & 0xFF) == wParam)
3148 bitmap = r>>8; /* *b is reachable via simple interface */
3149 if (*type_CtrlAlt == 'a') /* Simple Alt seen */
3150 {
3151 if ((bitmap & ~1) == 0) /* 1: KBDSHIFT */
3152 {
3153 /* In "traditional" layouts, Alt without Ctrl does not
3154 change the delivered character. This detects this
3155 situation; it is safe to report this as Alt-something
3156 - as opposed to delivering the reported character
3157 without modifiers. */
3158 if (legacy_alt_meta
3159 && *b > 0x7f && ('A' <= wParam && wParam <= 'Z'))
3160 /* For backward-compatibility with older Emacsen, let
3161 this be processed by another branch below (which
3162 would convert it to Alt-Latin char via wParam). */
3163 return 0;
3164 }
3165 else
3166 hairy = 1;
3167 }
3168 /* Check whether the delivered character(s) is accessible via
3169 KBDCTRL | KBDALT ( | KBDSHIFT ) modifier mask (which is 7). */
3170 else if ((bitmap & ~1) != 6)
3171 {
3172 /* The character is not accessible via plain Ctrl-Alt(-Shift)
3173 (which is, probably, same as AltGr) modifiers.
3174 Either it was after a prefix key, or is combined with
3175 modifier keys which we don't see, or there is an asymmetry
3176 between left-hand and right-hand modifiers, or other hairy
3177 stuff. */
3178 hairy = 1;
3179 }
3180 /* The best solution is to delegate these tough (but rarely
3181 needed) choices to the user. Temporarily (???), it is
3182 implemented as C macros.
3183
3184 Essentially, there are 3 things to do: return 0 (handle to the
3185 legacy processing code [ignoring the character payload]; keep
3186 some modifiers (so that they will be processed by the binding
3187 system [on top of the character payload]; strip modifiers [so
3188 that `self-insert' is going to be triggered with the character
3189 payload]).
3190
3191 The default below should cover 99.9999% of cases:
3192 (a) strip Alt- in the hairy case only;
3193 (stripping = not ignoring)
3194 (l) for lAlt-lCtrl, ignore the char in simple cases only;
3195 (g) for what looks like AltGr, ignore the modifiers;
3196 (d) for what looks like lCtrl-rCtrl-Alt (probably
3197 AltGr-rCtrl), ignore the character in simple cases only;
3198 (b) for other cases of Ctrl-Alt, ignore the character in
3199 simple cases only.
3200
3201 Essentially, in all hairy cases, and in looks-like-AltGr case,
3202 we keep the character, ignoring the modifiers. In all the
3203 other cases, we ignore the delivered character. */
3204#define S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD "aldb"
3205#define S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS ""
3206 if (strchr(S_TYPES_TO_IGNORE_CHARACTER_PAYLOAD,
3207 type_CtrlAlt[hairy]))
3208 return 0;
3209 /* If in neither list, report all the modifiers we see COMBINED
3210 WITH the reported character. */
3211 if (strchr(S_TYPES_TO_REPORT_CHARACTER_PAYLOAD_WITH_MODIFIERS,
3212 type_CtrlAlt[hairy]))
3213 strip_ExtraMods = 0;
3214 }
3215 }
3216 if (strip_ExtraMods)
3217 wmsg.dwModifiers = wmsg.dwModifiers & shift_modifier;
3218
3219 signal_user_input ();
3220 while (count--)
3221 {
3222 FPRINTF_WM_CHARS((stderr, "unichar %#06x\n", *b));
3223 my_post_msg (&wmsg, hwnd, WM_UNICHAR, *b++, lParam);
3224 }
3225 if (!ctrl_cnt) /* Process ALSO as ctrl */
3226 return 1;
3227 else
3228 FPRINTF_WM_CHARS((stderr, "extra ctrl char\n"));
3229 return -1;
3230 }
3231 else if (is_dead >= 0)
3232 {
3233 FPRINTF_WM_CHARS((stderr, "dead %#06x\n", is_dead));
3234 after_deadkey = is_dead;
3235 return 1;
3236 }
3237 return 0;
3238}
3239
2839/* Main window procedure */ 3240/* Main window procedure */
2840 3241
2841static LRESULT CALLBACK 3242static LRESULT CALLBACK
@@ -2869,15 +3270,15 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2869 f = x_window_to_frame (dpyinfo, hwnd); 3270 f = x_window_to_frame (dpyinfo, hwnd);
2870 if (f) 3271 if (f)
2871 { 3272 {
2872 HDC hdc = get_frame_dc (f); 3273 HDC hdc = get_frame_dc (f);
2873 GetUpdateRect (hwnd, &wmsg.rect, FALSE); 3274 GetUpdateRect (hwnd, &wmsg.rect, FALSE);
2874 w32_clear_rect (f, hdc, &wmsg.rect); 3275 w32_clear_rect (f, hdc, &wmsg.rect);
2875 release_frame_dc (f, hdc); 3276 release_frame_dc (f, hdc);
2876 3277
2877#if defined (W32_DEBUG_DISPLAY) 3278#if defined (W32_DEBUG_DISPLAY)
2878 DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n", 3279 DebPrint (("WM_ERASEBKGND (frame %p): erasing %d,%d-%d,%d\n",
2879 f, 3280 f,
2880 wmsg.rect.left, wmsg.rect.top, 3281 wmsg.rect.left, wmsg.rect.top,
2881 wmsg.rect.right, wmsg.rect.bottom)); 3282 wmsg.rect.right, wmsg.rect.bottom));
2882#endif /* W32_DEBUG_DISPLAY */ 3283#endif /* W32_DEBUG_DISPLAY */
2883 } 3284 }
@@ -2885,7 +3286,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2885 case WM_PALETTECHANGED: 3286 case WM_PALETTECHANGED:
2886 /* ignore our own changes */ 3287 /* ignore our own changes */
2887 if ((HWND)wParam != hwnd) 3288 if ((HWND)wParam != hwnd)
2888 { 3289 {
2889 f = x_window_to_frame (dpyinfo, hwnd); 3290 f = x_window_to_frame (dpyinfo, hwnd);
2890 if (f) 3291 if (f)
2891 /* get_frame_dc will realize our palette and force all 3292 /* get_frame_dc will realize our palette and force all
@@ -2895,24 +3296,24 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2895 return 0; 3296 return 0;
2896 case WM_PAINT: 3297 case WM_PAINT:
2897 { 3298 {
2898 PAINTSTRUCT paintStruct; 3299 PAINTSTRUCT paintStruct;
2899 RECT update_rect; 3300 RECT update_rect;
2900 memset (&update_rect, 0, sizeof (update_rect)); 3301 memset (&update_rect, 0, sizeof (update_rect));
2901 3302
2902 f = x_window_to_frame (dpyinfo, hwnd); 3303 f = x_window_to_frame (dpyinfo, hwnd);
2903 if (f == 0) 3304 if (f == 0)
2904 { 3305 {
2905 DebPrint (("WM_PAINT received for unknown window %p\n", hwnd)); 3306 DebPrint (("WM_PAINT received for unknown window %p\n", hwnd));
2906 return 0; 3307 return 0;
2907 } 3308 }
2908 3309
2909 /* MSDN Docs say not to call BeginPaint if GetUpdateRect 3310 /* MSDN Docs say not to call BeginPaint if GetUpdateRect
2910 fails. Apparently this can happen under some 3311 fails. Apparently this can happen under some
2911 circumstances. */ 3312 circumstances. */
2912 if (GetUpdateRect (hwnd, &update_rect, FALSE) || !w32_strict_painting) 3313 if (GetUpdateRect (hwnd, &update_rect, FALSE) || !w32_strict_painting)
2913 { 3314 {
2914 enter_crit (); 3315 enter_crit ();
2915 BeginPaint (hwnd, &paintStruct); 3316 BeginPaint (hwnd, &paintStruct);
2916 3317
2917 /* The rectangles returned by GetUpdateRect and BeginPaint 3318 /* The rectangles returned by GetUpdateRect and BeginPaint
2918 do not always match. Play it safe by assuming both areas 3319 do not always match. Play it safe by assuming both areas
@@ -2920,40 +3321,49 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
2920 UnionRect (&(wmsg.rect), &update_rect, &(paintStruct.rcPaint)); 3321 UnionRect (&(wmsg.rect), &update_rect, &(paintStruct.rcPaint));
2921 3322
2922#if defined (W32_DEBUG_DISPLAY) 3323#if defined (W32_DEBUG_DISPLAY)
2923 DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n", 3324 DebPrint (("WM_PAINT (frame %p): painting %d,%d-%d,%d\n",
2924 f, 3325 f,
2925 wmsg.rect.left, wmsg.rect.top, 3326 wmsg.rect.left, wmsg.rect.top,
2926 wmsg.rect.right, wmsg.rect.bottom)); 3327 wmsg.rect.right, wmsg.rect.bottom));
2927 DebPrint ((" [update region is %d,%d-%d,%d]\n", 3328 DebPrint ((" [update region is %d,%d-%d,%d]\n",
2928 update_rect.left, update_rect.top, 3329 update_rect.left, update_rect.top,
2929 update_rect.right, update_rect.bottom)); 3330 update_rect.right, update_rect.bottom));
2930#endif 3331#endif
2931 EndPaint (hwnd, &paintStruct); 3332 EndPaint (hwnd, &paintStruct);
2932 leave_crit (); 3333 leave_crit ();
2933 3334
2934 /* Change the message type to prevent Windows from 3335 /* Change the message type to prevent Windows from
2935 combining WM_PAINT messages in the Lisp thread's queue, 3336 combining WM_PAINT messages in the Lisp thread's queue,
2936 since Windows assumes that each message queue is 3337 since Windows assumes that each message queue is
2937 dedicated to one frame and does not bother checking 3338 dedicated to one frame and does not bother checking
2938 that hwnd matches before combining them. */ 3339 that hwnd matches before combining them. */
2939 my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam); 3340 my_post_msg (&wmsg, hwnd, WM_EMACS_PAINT, wParam, lParam);
2940 3341
2941 return 0; 3342 return 0;
2942 } 3343 }
2943 3344
2944 /* If GetUpdateRect returns 0 (meaning there is no update 3345 /* If GetUpdateRect returns 0 (meaning there is no update
2945 region), assume the whole window needs to be repainted. */ 3346 region), assume the whole window needs to be repainted. */
2946 GetClientRect (hwnd, &wmsg.rect); 3347 GetClientRect (hwnd, &wmsg.rect);
2947 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 3348 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2948 return 0; 3349 return 0;
2949 } 3350 }
2950 3351
2951 case WM_INPUTLANGCHANGE: 3352 case WM_INPUTLANGCHANGE:
2952 /* Inform lisp thread of keyboard layout changes. */ 3353 /* Inform lisp thread of keyboard layout changes. */
2953 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 3354 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
2954 3355
3356 /* The state of the finite automaton is separate per every input
3357 language environment (so it does not change when one switches
3358 to a different window with the same environment). Moreover,
3359 the experiments show that the state is not remembered when
3360 one switches back to the pre-previous environment. */
3361 after_deadkey = -1;
3362
3363 /* XXXX??? What follows is a COMPLETE misunderstanding of Windows! */
3364
2955 /* Clear dead keys in the keyboard state; for simplicity only 3365 /* Clear dead keys in the keyboard state; for simplicity only
2956 preserve modifier key states. */ 3366 preserve modifier key states. */
2957 { 3367 {
2958 int i; 3368 int i;
2959 BYTE keystate[256]; 3369 BYTE keystate[256];
@@ -3011,7 +3421,6 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3011 /* Synchronize modifiers with current keystroke. */ 3421 /* Synchronize modifiers with current keystroke. */
3012 sync_modifiers (); 3422 sync_modifiers ();
3013 record_keydown (wParam, lParam); 3423 record_keydown (wParam, lParam);
3014 wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0);
3015 3424
3016 windows_translate = 0; 3425 windows_translate = 0;
3017 3426
@@ -3052,14 +3461,14 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3052 if (!NILP (Vw32_rwindow_modifier)) 3461 if (!NILP (Vw32_rwindow_modifier))
3053 return 0; 3462 return 0;
3054 break; 3463 break;
3055 case VK_APPS: 3464 case VK_APPS:
3056 if (!NILP (Vw32_apps_modifier)) 3465 if (!NILP (Vw32_apps_modifier))
3057 return 0; 3466 return 0;
3058 break; 3467 break;
3059 case VK_MENU: 3468 case VK_MENU:
3060 if (NILP (Vw32_pass_alt_to_system)) 3469 if (NILP (Vw32_pass_alt_to_system))
3061 /* Prevent DefWindowProc from activating the menu bar if an 3470 /* Prevent DefWindowProc from activating the menu bar if an
3062 Alt key is pressed and released by itself. */ 3471 Alt key is pressed and released by itself. */
3063 return 0; 3472 return 0;
3064 windows_translate = 1; 3473 windows_translate = 1;
3065 break; 3474 break;
@@ -3083,9 +3492,9 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3083 break; 3492 break;
3084 disable_lock_key: 3493 disable_lock_key:
3085 /* Ensure the appropriate lock key state (and indicator light) 3494 /* Ensure the appropriate lock key state (and indicator light)
3086 remains in the same state. We do this by faking another 3495 remains in the same state. We do this by faking another
3087 press of the relevant key. Apparently, this really is the 3496 press of the relevant key. Apparently, this really is the
3088 only way to toggle the state of the indicator lights. */ 3497 only way to toggle the state of the indicator lights. */
3089 dpyinfo->faked_key = wParam; 3498 dpyinfo->faked_key = wParam;
3090 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0), 3499 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
3091 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); 3500 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
@@ -3094,8 +3503,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3094 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0), 3503 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
3095 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0); 3504 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
3096 /* Ensure indicator lights are updated promptly on Windows 9x 3505 /* Ensure indicator lights are updated promptly on Windows 9x
3097 (TranslateMessage apparently does this), after forwarding 3506 (TranslateMessage apparently does this), after forwarding
3098 input event. */ 3507 input event. */
3099 post_character_message (hwnd, msg, wParam, lParam, 3508 post_character_message (hwnd, msg, wParam, lParam,
3100 w32_get_key_modifiers (wParam, lParam)); 3509 w32_get_key_modifiers (wParam, lParam));
3101 windows_translate = 1; 3510 windows_translate = 1;
@@ -3107,21 +3516,67 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3107 break; 3516 break;
3108 case VK_CANCEL: 3517 case VK_CANCEL:
3109 /* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL, 3518 /* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL,
3110 which is confusing for purposes of key binding; convert 3519 which is confusing for purposes of key binding; convert
3111 VK_CANCEL events into VK_PAUSE events. */ 3520 VK_CANCEL events into VK_PAUSE events. */
3112 wParam = VK_PAUSE; 3521 wParam = VK_PAUSE;
3113 break; 3522 break;
3114 case VK_PAUSE: 3523 case VK_PAUSE:
3115 /* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing 3524 /* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing
3116 for purposes of key binding; convert these back into 3525 for purposes of key binding; convert these back into
3117 VK_NUMLOCK events, at least when we want to see NumLock key 3526 VK_NUMLOCK events, at least when we want to see NumLock key
3118 presses. (Note that there is never any possibility that 3527 presses. (Note that there is never any possibility that
3119 VK_PAUSE with Ctrl really is C-Pause as per above.) */ 3528 VK_PAUSE with Ctrl really is C-Pause as per above.) */
3120 if (NILP (Vw32_enable_num_lock) && modifier_set (VK_CONTROL)) 3529 if (NILP (Vw32_enable_num_lock) && modifier_set (VK_CONTROL))
3121 wParam = VK_NUMLOCK; 3530 wParam = VK_NUMLOCK;
3122 break; 3531 break;
3123 default: 3532 default:
3124 /* If not defined as a function key, change it to a WM_CHAR message. */ 3533 if (w32_unicode_gui)
3534 {
3535 /* If this event generates characters or deadkeys, do
3536 not interpret it as a "raw combination of modifiers
3537 and keysym". Hide deadkeys, and use the generated
3538 character(s) instead of the keysym. (Backward
3539 compatibility: exceptions for numpad keys generating
3540 0-9 . , / * - +, and for extra-Alt combined with a
3541 non-Latin char.)
3542
3543 Try to not report modifiers which have effect on
3544 which character or deadkey is generated.
3545
3546 Example (contrived): if rightAlt-? generates f (on a
3547 Cyrillic keyboard layout), and Ctrl, leftAlt do not
3548 affect the generated character, one wants to report
3549 Ctrl-leftAlt-f if the user presses
3550 Ctrl-leftAlt-rightAlt-?. */
3551 int res;
3552#if 0
3553 /* Some of WM_CHAR may be fed to us directly, some are
3554 results of TranslateMessage(). Using 0 as the first
3555 argument (in a separate call) might help us
3556 distinguish these two cases.
3557
3558 However, the keypress feeders would most probably
3559 expect the "standard" message pump, when
3560 TranslateMessage() is called on EVERY KeyDown/Keyup
3561 event. So they may feed us Down-Ctrl Down-FAKE
3562 Char-o and expect us to recognize it as Ctrl-o.
3563 Using 0 as the first argument would interfere with
3564 this. */
3565 deliver_wm_chars (0, hwnd, msg, wParam, lParam, 1);
3566#endif
3567 /* Processing the generated WM_CHAR messages *WHILE* we
3568 handle KEYDOWN/UP event is the best choice, since
3569 withoug any fuss, we know all 3 of: scancode, virtual
3570 keycode, and expansion. (Additionally, one knows
3571 boundaries of expansion of different keypresses.) */
3572 res = deliver_wm_chars (1, hwnd, msg, wParam, lParam, 1);
3573 windows_translate = -( res != 0 );
3574 if (res > 0) /* Bound to character(s) or a deadkey */
3575 break;
3576 /* deliver_wm_chars may make some branches after this vestigal. */
3577 }
3578 wParam = map_keypad_keys (wParam, (lParam & 0x1000000L) != 0);
3579 /* If not defined as a function key, change it to a WM_CHAR message. */
3125 if (wParam > 255 || !lispy_function_keys[wParam]) 3580 if (wParam > 255 || !lispy_function_keys[wParam])
3126 { 3581 {
3127 DWORD modifiers = construct_console_modifiers (); 3582 DWORD modifiers = construct_console_modifiers ();
@@ -3173,7 +3628,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3173 /* Forward asciified character sequence. */ 3628 /* Forward asciified character sequence. */
3174 post_character_message 3629 post_character_message
3175 (hwnd, WM_CHAR, 3630 (hwnd, WM_CHAR,
3176 (unsigned char) key.uChar.AsciiChar, lParam, 3631 (unsigned char) key.uChar.AsciiChar, lParam,
3177 w32_get_key_modifiers (wParam, lParam)); 3632 w32_get_key_modifiers (wParam, lParam));
3178 w32_kbd_patch_key (&key, w32_keyboard_codepage); 3633 w32_kbd_patch_key (&key, w32_keyboard_codepage);
3179 } 3634 }
@@ -3188,6 +3643,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3188 } 3643 }
3189 } 3644 }
3190 3645
3646 if (windows_translate == -1)
3647 break;
3191 translate: 3648 translate:
3192 if (windows_translate) 3649 if (windows_translate)
3193 { 3650 {
@@ -3202,73 +3659,73 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3202 case WM_SYSCHAR: 3659 case WM_SYSCHAR:
3203 case WM_CHAR: 3660 case WM_CHAR:
3204 if (wParam > 255 ) 3661 if (wParam > 255 )
3205 { 3662 {
3206 W32Msg wmsg; 3663 W32Msg wmsg;
3207 3664
3208 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam); 3665 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
3209 signal_user_input (); 3666 signal_user_input ();
3210 my_post_msg (&wmsg, hwnd, WM_UNICHAR, wParam, lParam); 3667 my_post_msg (&wmsg, hwnd, WM_UNICHAR, wParam, lParam);
3211 3668
3212 } 3669 }
3213 else 3670 else
3214 post_character_message (hwnd, msg, wParam, lParam, 3671 post_character_message (hwnd, msg, wParam, lParam,
3215 w32_get_key_modifiers (wParam, lParam)); 3672 w32_get_key_modifiers (wParam, lParam));
3216 break; 3673 break;
3217 3674
3218 case WM_UNICHAR: 3675 case WM_UNICHAR:
3219 /* WM_UNICHAR looks promising from the docs, but the exact 3676 /* WM_UNICHAR looks promising from the docs, but the exact
3220 circumstances in which TranslateMessage sends it is one of those 3677 circumstances in which TranslateMessage sends it is one of those
3221 Microsoft secret API things that EU and US courts are supposed 3678 Microsoft secret API things that EU and US courts are supposed
3222 to have put a stop to already. Spy++ shows it being sent to Notepad 3679 to have put a stop to already. Spy++ shows it being sent to Notepad
3223 and other MS apps, but never to Emacs. 3680 and other MS apps, but never to Emacs.
3224 3681
3225 Some third party IMEs send it in accordance with the official 3682 Some third party IMEs send it in accordance with the official
3226 documentation though, so handle it here. 3683 documentation though, so handle it here.
3227 3684
3228 UNICODE_NOCHAR is used to test for support for this message. 3685 UNICODE_NOCHAR is used to test for support for this message.
3229 TRUE indicates that the message is supported. */ 3686 TRUE indicates that the message is supported. */
3230 if (wParam == UNICODE_NOCHAR) 3687 if (wParam == UNICODE_NOCHAR)
3231 return TRUE; 3688 return TRUE;
3232 3689
3233 { 3690 {
3234 W32Msg wmsg; 3691 W32Msg wmsg;
3235 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam); 3692 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
3236 signal_user_input (); 3693 signal_user_input ();
3237 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 3694 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3238 } 3695 }
3239 break; 3696 break;
3240 3697
3241 case WM_IME_CHAR: 3698 case WM_IME_CHAR:
3242 /* If we can't get the IME result as Unicode, use default processing, 3699 /* If we can't get the IME result as Unicode, use default processing,
3243 which will at least allow characters decodable in the system locale 3700 which will at least allow characters decodable in the system locale
3244 get through. */ 3701 get through. */
3245 if (!get_composition_string_fn) 3702 if (!get_composition_string_fn)
3246 goto dflt; 3703 goto dflt;
3247 3704
3248 else if (!ignore_ime_char) 3705 else if (!ignore_ime_char)
3249 { 3706 {
3250 wchar_t * buffer; 3707 wchar_t * buffer;
3251 int size, i; 3708 int size, i;
3252 W32Msg wmsg; 3709 W32Msg wmsg;
3253 HIMC context = get_ime_context_fn (hwnd); 3710 HIMC context = get_ime_context_fn (hwnd);
3254 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam); 3711 wmsg.dwModifiers = w32_get_key_modifiers (wParam, lParam);
3255 /* Get buffer size. */ 3712 /* Get buffer size. */
3256 size = get_composition_string_fn (context, GCS_RESULTSTR, NULL, 0); 3713 size = get_composition_string_fn (context, GCS_RESULTSTR, NULL, 0);
3257 buffer = alloca (size); 3714 buffer = alloca (size);
3258 size = get_composition_string_fn (context, GCS_RESULTSTR, 3715 size = get_composition_string_fn (context, GCS_RESULTSTR,
3259 buffer, size); 3716 buffer, size);
3260 release_ime_context_fn (hwnd, context); 3717 release_ime_context_fn (hwnd, context);
3261 3718
3262 signal_user_input (); 3719 signal_user_input ();
3263 for (i = 0; i < size / sizeof (wchar_t); i++) 3720 for (i = 0; i < size / sizeof (wchar_t); i++)
3264 { 3721 {
3265 my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i], 3722 my_post_msg (&wmsg, hwnd, WM_UNICHAR, (WPARAM) buffer[i],
3266 lParam); 3723 lParam);
3267 } 3724 }
3268 /* Ignore the messages for the rest of the 3725 /* Ignore the messages for the rest of the
3269 characters in the string that was output above. */ 3726 characters in the string that was output above. */
3270 ignore_ime_char = (size / sizeof (wchar_t)) - 1; 3727 ignore_ime_char = (size / sizeof (wchar_t)) - 1;
3271 } 3728 }
3272 else 3729 else
3273 ignore_ime_char--; 3730 ignore_ime_char--;
3274 3731
@@ -3490,7 +3947,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3490 signal_user_input (); 3947 signal_user_input ();
3491 3948
3492 /* Need to return true for XBUTTON messages, false for others, 3949 /* Need to return true for XBUTTON messages, false for others,
3493 to indicate that we processed the message. */ 3950 to indicate that we processed the message. */
3494 return (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONUP); 3951 return (msg == WM_XBUTTONDOWN || msg == WM_XBUTTONUP);
3495 3952
3496 case WM_MOUSEMOVE: 3953 case WM_MOUSEMOVE:
@@ -3553,11 +4010,11 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3553 case WM_VSCROLL: 4010 case WM_VSCROLL:
3554 if (w32_mouse_move_interval <= 0 4011 if (w32_mouse_move_interval <= 0
3555 || (msg == WM_MOUSEMOVE && button_state == 0)) 4012 || (msg == WM_MOUSEMOVE && button_state == 0))
3556 { 4013 {
3557 wmsg.dwModifiers = w32_get_modifiers (); 4014 wmsg.dwModifiers = w32_get_modifiers ();
3558 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 4015 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3559 return 0; 4016 return 0;
3560 } 4017 }
3561 4018
3562 /* Hang onto mouse move and scroll messages for a bit, to avoid 4019 /* Hang onto mouse move and scroll messages for a bit, to avoid
3563 sending such events to Emacs faster than it can process them. 4020 sending such events to Emacs faster than it can process them.
@@ -3588,15 +4045,15 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3588 4045
3589 case WM_APPCOMMAND: 4046 case WM_APPCOMMAND:
3590 if (w32_pass_multimedia_buttons_to_system) 4047 if (w32_pass_multimedia_buttons_to_system)
3591 goto dflt; 4048 goto dflt;
3592 /* Otherwise, pass to lisp, the same way we do with mousehwheel. */ 4049 /* Otherwise, pass to lisp, the same way we do with mousehwheel. */
3593 case WM_MOUSEHWHEEL: 4050 case WM_MOUSEHWHEEL:
3594 wmsg.dwModifiers = w32_get_modifiers (); 4051 wmsg.dwModifiers = w32_get_modifiers ();
3595 my_post_msg (&wmsg, hwnd, msg, wParam, lParam); 4052 my_post_msg (&wmsg, hwnd, msg, wParam, lParam);
3596 signal_user_input (); 4053 signal_user_input ();
3597 /* Non-zero must be returned when WM_MOUSEHWHEEL messages are 4054 /* Non-zero must be returned when WM_MOUSEHWHEEL messages are
3598 handled, to prevent the system trying to handle it by faking 4055 handled, to prevent the system trying to handle it by faking
3599 scroll bar events. */ 4056 scroll bar events. */
3600 return 1; 4057 return 1;
3601 4058
3602 case WM_TIMER: 4059 case WM_TIMER:
@@ -3627,15 +4084,15 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3627 KillTimer (hwnd, menu_free_timer); 4084 KillTimer (hwnd, menu_free_timer);
3628 menu_free_timer = 0; 4085 menu_free_timer = 0;
3629 f = x_window_to_frame (dpyinfo, hwnd); 4086 f = x_window_to_frame (dpyinfo, hwnd);
3630 /* If a popup menu is active, don't wipe its strings. */ 4087 /* If a popup menu is active, don't wipe its strings. */
3631 if (menubar_in_use 4088 if (menubar_in_use
3632 && current_popup_menu == NULL) 4089 && current_popup_menu == NULL)
3633 { 4090 {
3634 /* Free memory used by owner-drawn and help-echo strings. */ 4091 /* Free memory used by owner-drawn and help-echo strings. */
3635 w32_free_menu_strings (hwnd); 4092 w32_free_menu_strings (hwnd);
3636 if (f) 4093 if (f)
3637 f->output_data.w32->menubar_active = 0; 4094 f->output_data.w32->menubar_active = 0;
3638 menubar_in_use = 0; 4095 menubar_in_use = 0;
3639 } 4096 }
3640 } 4097 }
3641 return 0; 4098 return 0;
@@ -3687,7 +4144,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3687 if (find_deferred_msg (hwnd, msg) != NULL) 4144 if (find_deferred_msg (hwnd, msg) != NULL)
3688 emacs_abort (); 4145 emacs_abort ();
3689 4146
3690 menubar_in_use = 1; 4147 menubar_in_use = 1;
3691 4148
3692 return send_deferred_msg (&msg_buf, hwnd, msg, wParam, lParam); 4149 return send_deferred_msg (&msg_buf, hwnd, msg, wParam, lParam);
3693 } 4150 }
@@ -3698,8 +4155,8 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3698 /* If a menu is still active, check again after a short delay, 4155 /* If a menu is still active, check again after a short delay,
3699 since Windows often (always?) sends the WM_EXITMENULOOP 4156 since Windows often (always?) sends the WM_EXITMENULOOP
3700 before the corresponding WM_COMMAND message. 4157 before the corresponding WM_COMMAND message.
3701 Don't do this if a popup menu is active, since it is only 4158 Don't do this if a popup menu is active, since it is only
3702 menubar menus that require cleaning up in this way. 4159 menubar menus that require cleaning up in this way.
3703 */ 4160 */
3704 if (f && menubar_in_use && current_popup_menu == NULL) 4161 if (f && menubar_in_use && current_popup_menu == NULL)
3705 menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL); 4162 menu_free_timer = SetTimer (hwnd, MENU_FREE_ID, MENU_FREE_DELAY, NULL);
@@ -3744,9 +4201,9 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3744 menu_font = CreateFontIndirect (&menu_logfont); 4201 menu_font = CreateFontIndirect (&menu_logfont);
3745 old_font = SelectObject (hdc, menu_font); 4202 old_font = SelectObject (hdc, menu_font);
3746 4203
3747 pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE); 4204 pMis->itemHeight = GetSystemMetrics (SM_CYMENUSIZE);
3748 if (title) 4205 if (title)
3749 { 4206 {
3750 if (unicode_append_menu) 4207 if (unicode_append_menu)
3751 GetTextExtentPoint32W (hdc, (WCHAR *) title, 4208 GetTextExtentPoint32W (hdc, (WCHAR *) title,
3752 wcslen ((WCHAR *) title), 4209 wcslen ((WCHAR *) title),
@@ -3754,12 +4211,12 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3754 else 4211 else
3755 GetTextExtentPoint32 (hdc, title, strlen (title), &size); 4212 GetTextExtentPoint32 (hdc, title, strlen (title), &size);
3756 4213
3757 pMis->itemWidth = size.cx; 4214 pMis->itemWidth = size.cx;
3758 if (pMis->itemHeight < size.cy) 4215 if (pMis->itemHeight < size.cy)
3759 pMis->itemHeight = size.cy; 4216 pMis->itemHeight = size.cy;
3760 } 4217 }
3761 else 4218 else
3762 pMis->itemWidth = 0; 4219 pMis->itemWidth = 0;
3763 4220
3764 SelectObject (hdc, old_font); 4221 SelectObject (hdc, old_font);
3765 DeleteObject (menu_font); 4222 DeleteObject (menu_font);
@@ -3779,17 +4236,17 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3779 { 4236 {
3780 /* Draw popup menu title. */ 4237 /* Draw popup menu title. */
3781 char * title = (char *) pDis->itemData; 4238 char * title = (char *) pDis->itemData;
3782 if (title) 4239 if (title)
3783 { 4240 {
3784 HDC hdc = pDis->hDC; 4241 HDC hdc = pDis->hDC;
3785 HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT); 4242 HFONT menu_font = GetCurrentObject (hdc, OBJ_FONT);
3786 LOGFONT menu_logfont; 4243 LOGFONT menu_logfont;
3787 HFONT old_font; 4244 HFONT old_font;
3788 4245
3789 GetObject (menu_font, sizeof (menu_logfont), &menu_logfont); 4246 GetObject (menu_font, sizeof (menu_logfont), &menu_logfont);
3790 menu_logfont.lfWeight = FW_BOLD; 4247 menu_logfont.lfWeight = FW_BOLD;
3791 menu_font = CreateFontIndirect (&menu_logfont); 4248 menu_font = CreateFontIndirect (&menu_logfont);
3792 old_font = SelectObject (hdc, menu_font); 4249 old_font = SelectObject (hdc, menu_font);
3793 4250
3794 /* Always draw title as if not selected. */ 4251 /* Always draw title as if not selected. */
3795 if (unicode_append_menu) 4252 if (unicode_append_menu)
@@ -3808,9 +4265,9 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3808 ETO_OPAQUE, &pDis->rcItem, 4265 ETO_OPAQUE, &pDis->rcItem,
3809 title, strlen (title), NULL); 4266 title, strlen (title), NULL);
3810 4267
3811 SelectObject (hdc, old_font); 4268 SelectObject (hdc, old_font);
3812 DeleteObject (menu_font); 4269 DeleteObject (menu_font);
3813 } 4270 }
3814 return TRUE; 4271 return TRUE;
3815 } 4272 }
3816 } 4273 }
@@ -3891,16 +4348,16 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
3891 /* Don't restrict the sizing of any kind of frames. If the window 4348 /* Don't restrict the sizing of any kind of frames. If the window
3892 manager doesn't, there's no reason to do it ourselves. */ 4349 manager doesn't, there's no reason to do it ourselves. */
3893#if 0 4350#if 0
3894 if (frame_resize_pixelwise || hwnd == tip_window) 4351 if (frame_resize_pixelwise || hwnd == tip_window)
3895#endif 4352#endif
3896 return 0; 4353 return 0;
3897 4354
3898#if 0 4355#if 0
3899 /* Don't restrict the sizing of fullscreened frames, allowing them to be 4356 /* Don't restrict the sizing of fullscreened frames, allowing them to be
3900 flush with the sides of the screen. */ 4357 flush with the sides of the screen. */
3901 f = x_window_to_frame (dpyinfo, hwnd); 4358 f = x_window_to_frame (dpyinfo, hwnd);
3902 if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE) 4359 if (f && FRAME_PREV_FSMODE (f) != FULLSCREEN_NONE)
3903 return 0; 4360 return 0;
3904 4361
3905 { 4362 {
3906 WINDOWPLACEMENT wp; 4363 WINDOWPLACEMENT wp;
@@ -4049,30 +4506,30 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
4049 case WM_EMACS_BRINGTOTOP: 4506 case WM_EMACS_BRINGTOTOP:
4050 case WM_EMACS_SETFOREGROUND: 4507 case WM_EMACS_SETFOREGROUND:
4051 { 4508 {
4052 HWND foreground_window; 4509 HWND foreground_window;
4053 DWORD foreground_thread, retval; 4510 DWORD foreground_thread, retval;
4054 4511
4055 /* On NT 5.0, and apparently Windows 98, it is necessary to 4512 /* On NT 5.0, and apparently Windows 98, it is necessary to
4056 attach to the thread that currently has focus in order to 4513 attach to the thread that currently has focus in order to
4057 pull the focus away from it. */ 4514 pull the focus away from it. */
4058 foreground_window = GetForegroundWindow (); 4515 foreground_window = GetForegroundWindow ();
4059 foreground_thread = GetWindowThreadProcessId (foreground_window, NULL); 4516 foreground_thread = GetWindowThreadProcessId (foreground_window, NULL);
4060 if (!foreground_window 4517 if (!foreground_window
4061 || foreground_thread == GetCurrentThreadId () 4518 || foreground_thread == GetCurrentThreadId ()
4062 || !AttachThreadInput (GetCurrentThreadId (), 4519 || !AttachThreadInput (GetCurrentThreadId (),
4063 foreground_thread, TRUE)) 4520 foreground_thread, TRUE))
4064 foreground_thread = 0; 4521 foreground_thread = 0;
4065 4522
4066 retval = SetForegroundWindow ((HWND) wParam); 4523 retval = SetForegroundWindow ((HWND) wParam);
4067 if (msg == WM_EMACS_BRINGTOTOP) 4524 if (msg == WM_EMACS_BRINGTOTOP)
4068 retval = BringWindowToTop ((HWND) wParam); 4525 retval = BringWindowToTop ((HWND) wParam);
4069 4526
4070 /* Detach from the previous foreground thread. */ 4527 /* Detach from the previous foreground thread. */
4071 if (foreground_thread) 4528 if (foreground_thread)
4072 AttachThreadInput (GetCurrentThreadId (), 4529 AttachThreadInput (GetCurrentThreadId (),
4073 foreground_thread, FALSE); 4530 foreground_thread, FALSE);
4074 4531
4075 return retval; 4532 return retval;
4076 } 4533 }
4077 4534
4078 case WM_EMACS_SETWINDOWPOS: 4535 case WM_EMACS_SETWINDOWPOS:
@@ -4145,7 +4602,7 @@ w32_wnd_proc (HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
4145 button_state = 0; 4602 button_state = 0;
4146 4603
4147 /* Use menubar_active to indicate that WM_INITMENU is from 4604 /* Use menubar_active to indicate that WM_INITMENU is from
4148 TrackPopupMenu below, and should be ignored. */ 4605 TrackPopupMenu below, and should be ignored. */
4149 f = x_window_to_frame (dpyinfo, hwnd); 4606 f = x_window_to_frame (dpyinfo, hwnd);
4150 if (f) 4607 if (f)
4151 f->output_data.w32->menubar_active = 1; 4608 f->output_data.w32->menubar_active = 1;
@@ -4452,20 +4909,20 @@ x_default_font_parameter (struct frame *f, Lisp_Object parms)
4452 { 4909 {
4453 int i; 4910 int i;
4454 static char *names[] 4911 static char *names[]
4455 = { "Courier New-10", 4912 = { "Courier New-10",
4456 "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1", 4913 "-*-Courier-normal-r-*-*-13-*-*-*-c-*-iso8859-1",
4457 "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1", 4914 "-*-Fixedsys-normal-r-*-*-12-*-*-*-c-*-iso8859-1",
4458 "Fixedsys", 4915 "Fixedsys",
4459 NULL }; 4916 NULL };
4460 4917
4461 for (i = 0; names[i]; i++) 4918 for (i = 0; names[i]; i++)
4462 { 4919 {
4463 font = font_open_by_name (f, build_unibyte_string (names[i])); 4920 font = font_open_by_name (f, build_unibyte_string (names[i]));
4464 if (! NILP (font)) 4921 if (! NILP (font))
4465 break; 4922 break;
4466 } 4923 }
4467 if (NILP (font)) 4924 if (NILP (font))
4468 error ("No suitable font was found"); 4925 error ("No suitable font was found");
4469 } 4926 }
4470 else if (!NILP (font_param)) 4927 else if (!NILP (font_param))
4471 { 4928 {
@@ -4573,7 +5030,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4573 5030
4574 fset_icon_name 5031 fset_icon_name
4575 (f, x_get_arg (dpyinfo, parameters, Qicon_name, "iconName", "Title", 5032 (f, x_get_arg (dpyinfo, parameters, Qicon_name, "iconName", "Title",
4576 RES_TYPE_STRING)); 5033 RES_TYPE_STRING));
4577 if (! STRINGP (f->icon_name)) 5034 if (! STRINGP (f->icon_name))
4578 fset_icon_name (f, Qnil); 5035 fset_icon_name (f, Qnil);
4579 5036
@@ -4797,7 +5254,7 @@ This function is an internal primitive--use `make-frame' instead. */)
4797 frame on this terminal. */ 5254 frame on this terminal. */
4798 if (FRAME_HAS_MINIBUF_P (f) 5255 if (FRAME_HAS_MINIBUF_P (f)
4799 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame)) 5256 && (!FRAMEP (KVAR (kb, Vdefault_minibuffer_frame))
4800 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame))))) 5257 || !FRAME_LIVE_P (XFRAME (KVAR (kb, Vdefault_minibuffer_frame)))))
4801 kset_default_minibuffer_frame (kb, frame); 5258 kset_default_minibuffer_frame (kb, frame);
4802 5259
4803 /* All remaining specified parameters, which have not been "used" 5260 /* All remaining specified parameters, which have not been "used"
@@ -5522,7 +5979,7 @@ If TERMINAL is omitted or nil, that stands for the selected frame's display. */
5522 5979
5523 5980
5524/*********************************************************************** 5981/***********************************************************************
5525 Window properties 5982 Window properties
5526 ***********************************************************************/ 5983 ***********************************************************************/
5527 5984
5528#if 0 /* TODO : port window properties to W32 */ 5985#if 0 /* TODO : port window properties to W32 */
@@ -5658,9 +6115,9 @@ no value of TYPE (always string in the MS Windows case). */)
5658 ***********************************************************************/ 6115 ***********************************************************************/
5659 6116
5660static Lisp_Object x_create_tip_frame (struct w32_display_info *, 6117static Lisp_Object x_create_tip_frame (struct w32_display_info *,
5661 Lisp_Object, Lisp_Object); 6118 Lisp_Object, Lisp_Object);
5662static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object, 6119static void compute_tip_xy (struct frame *, Lisp_Object, Lisp_Object,
5663 Lisp_Object, int, int, int *, int *); 6120 Lisp_Object, int, int, int *, int *);
5664 6121
5665/* The frame of a currently visible tooltip. */ 6122/* The frame of a currently visible tooltip. */
5666 6123
@@ -5868,7 +6325,7 @@ x_create_tip_frame (struct w32_display_info *dpyinfo,
5868 "cursorType", "CursorType", RES_TYPE_SYMBOL); 6325 "cursorType", "CursorType", RES_TYPE_SYMBOL);
5869 /* Process alpha here (Bug#17344). */ 6326 /* Process alpha here (Bug#17344). */
5870 x_default_parameter (f, parms, Qalpha, Qnil, 6327 x_default_parameter (f, parms, Qalpha, Qnil,
5871 "alpha", "Alpha", RES_TYPE_NUMBER); 6328 "alpha", "Alpha", RES_TYPE_NUMBER);
5872 6329
5873 /* Dimensions, especially FRAME_LINES (f), must be done via 6330 /* Dimensions, especially FRAME_LINES (f), must be done via
5874 change_frame_size. Change will not be effected unless different 6331 change_frame_size. Change will not be effected unless different
@@ -6766,25 +7223,25 @@ value of DIR as in previous invocations; this is standard Windows behavior. */)
6766 7223
6767 if (file_opened) 7224 if (file_opened)
6768 { 7225 {
6769 /* Get an Emacs string from the value Windows gave us. */ 7226 /* Get an Emacs string from the value Windows gave us. */
6770#ifdef NTGUI_UNICODE 7227#ifdef NTGUI_UNICODE
6771 filename = from_unicode_buffer (filename_buf_w); 7228 filename = from_unicode_buffer (filename_buf_w);
6772#else /* !NTGUI_UNICODE */ 7229#else /* !NTGUI_UNICODE */
6773 if (use_unicode) 7230 if (use_unicode)
6774 filename_from_utf16 (filename_buf_w, fname_ret); 7231 filename_from_utf16 (filename_buf_w, fname_ret);
6775 else 7232 else
6776 filename_from_ansi (filename_buf_a, fname_ret); 7233 filename_from_ansi (filename_buf_a, fname_ret);
6777 dostounix_filename (fname_ret); 7234 dostounix_filename (fname_ret);
6778 filename = DECODE_FILE (build_unibyte_string (fname_ret)); 7235 filename = DECODE_FILE (build_unibyte_string (fname_ret));
6779#endif /* NTGUI_UNICODE */ 7236#endif /* NTGUI_UNICODE */
6780 7237
6781#ifdef CYGWIN 7238#ifdef CYGWIN
6782 filename = Fcygwin_convert_file_name_from_windows (filename, Qt); 7239 filename = Fcygwin_convert_file_name_from_windows (filename, Qt);
6783#endif /* CYGWIN */ 7240#endif /* CYGWIN */
6784 7241
6785 /* Strip the dummy filename off the end of the string if we 7242 /* Strip the dummy filename off the end of the string if we
6786 added it to select a directory. */ 7243 added it to select a directory. */
6787 if ((use_unicode && file_details_w->nFilterIndex == 2) 7244 if ((use_unicode && file_details_w->nFilterIndex == 2)
6788#ifndef NTGUI_UNICODE 7245#ifndef NTGUI_UNICODE
6789 || (!use_unicode && file_details_a->nFilterIndex == 2) 7246 || (!use_unicode && file_details_a->nFilterIndex == 2)
6790#endif 7247#endif
@@ -6797,14 +7254,14 @@ value of DIR as in previous invocations; this is standard Windows behavior. */)
6797 /* An error occurred, fallback on reading from the mini-buffer. */ 7254 /* An error occurred, fallback on reading from the mini-buffer. */
6798 else 7255 else
6799 filename = Fcompleting_read ( 7256 filename = Fcompleting_read (
6800 orig_prompt, 7257 orig_prompt,
6801 intern ("read-file-name-internal"), 7258 intern ("read-file-name-internal"),
6802 orig_dir, 7259 orig_dir,
6803 mustmatch, 7260 mustmatch,
6804 orig_dir, 7261 orig_dir,
6805 Qfile_name_history, 7262 Qfile_name_history,
6806 default_filename, 7263 default_filename,
6807 Qnil); 7264 Qnil);
6808 7265
6809 UNGCPRO; 7266 UNGCPRO;
6810 } 7267 }
@@ -6917,7 +7374,7 @@ DEFUN ("system-move-file-to-trash", Fsystem_move_file_to_trash,
6917 7374
6918 7375
6919/*********************************************************************** 7376/***********************************************************************
6920 w32 specialized functions 7377 w32 specialized functions
6921 ***********************************************************************/ 7378 ***********************************************************************/
6922 7379
6923DEFUN ("w32-send-sys-command", Fw32_send_sys_command, 7380DEFUN ("w32-send-sys-command", Fw32_send_sys_command,
@@ -6952,37 +7409,37 @@ handler application, but typically it is one of the following common
6952operations: 7409operations:
6953 7410
6954 \"open\" - open DOCUMENT, which could be a file, a directory, or an 7411 \"open\" - open DOCUMENT, which could be a file, a directory, or an
6955 executable program (application). If it is an application, 7412 executable program (application). If it is an application,
6956 that application is launched in the current buffer's default 7413 that application is launched in the current buffer's default
6957 directory. Otherwise, the application associated with 7414 directory. Otherwise, the application associated with
6958 DOCUMENT is launched in the buffer's default directory. 7415 DOCUMENT is launched in the buffer's default directory.
6959 \"opennew\" - like \"open\", but instruct the application to open 7416 \"opennew\" - like \"open\", but instruct the application to open
6960 DOCUMENT in a new window. 7417 DOCUMENT in a new window.
6961 \"openas\" - open the \"Open With\" dialog for DOCUMENT. 7418 \"openas\" - open the \"Open With\" dialog for DOCUMENT.
6962 \"print\" - print DOCUMENT, which must be a file. 7419 \"print\" - print DOCUMENT, which must be a file.
6963 \"printto\" - print DOCUMENT, which must be a file, to a specified printer. 7420 \"printto\" - print DOCUMENT, which must be a file, to a specified printer.
6964 The printer should be provided in PARAMETERS, see below. 7421 The printer should be provided in PARAMETERS, see below.
6965 \"explore\" - start the Windows Explorer on DOCUMENT. 7422 \"explore\" - start the Windows Explorer on DOCUMENT.
6966 \"edit\" - launch an editor and open DOCUMENT for editing; which 7423 \"edit\" - launch an editor and open DOCUMENT for editing; which
6967 editor is launched depends on the association for the 7424 editor is launched depends on the association for the
6968 specified DOCUMENT. 7425 specified DOCUMENT.
6969 \"find\" - initiate search starting from DOCUMENT, which must specify 7426 \"find\" - initiate search starting from DOCUMENT, which must specify
6970 a directory. 7427 a directory.
6971 \"delete\" - move DOCUMENT, a file or a directory, to Recycle Bin. 7428 \"delete\" - move DOCUMENT, a file or a directory, to Recycle Bin.
6972 \"copy\" - copy DOCUMENT, which must be a file or a directory, into 7429 \"copy\" - copy DOCUMENT, which must be a file or a directory, into
6973 the clipboard. 7430 the clipboard.
6974 \"cut\" - move DOCUMENT, a file or a directory, into the clipboard. 7431 \"cut\" - move DOCUMENT, a file or a directory, into the clipboard.
6975 \"paste\" - paste the file whose name is in the clipboard into DOCUMENT, 7432 \"paste\" - paste the file whose name is in the clipboard into DOCUMENT,
6976 which must be a directory. 7433 which must be a directory.
6977 \"pastelink\" 7434 \"pastelink\"
6978 - create a shortcut in DOCUMENT (which must be a directory) 7435 - create a shortcut in DOCUMENT (which must be a directory)
6979 the file or directory whose name is in the clipboard. 7436 the file or directory whose name is in the clipboard.
6980 \"runas\" - run DOCUMENT, which must be an excutable file, with 7437 \"runas\" - run DOCUMENT, which must be an excutable file, with
6981 elevated privileges (a.k.a. \"as Administrator\"). 7438 elevated privileges (a.k.a. \"as Administrator\").
6982 \"properties\" 7439 \"properties\"
6983 - open the property sheet dialog for DOCUMENT. 7440 - open the property sheet dialog for DOCUMENT.
6984 nil - invoke the default OPERATION, or \"open\" if default is 7441 nil - invoke the default OPERATION, or \"open\" if default is
6985 not defined or unavailable. 7442 not defined or unavailable.
6986 7443
6987DOCUMENT is typically the name of a document file or a URL, but can 7444DOCUMENT is typically the name of a document file or a URL, but can
6988also be an executable program to run, or a directory to open in the 7445also be an executable program to run, or a directory to open in the
@@ -7678,7 +8135,7 @@ elements (all size values are in pixels).
7678 ? Fcons (make_number (0), make_number (0)) 8135 ? Fcons (make_number (0), make_number (0))
7679 : Fcons (make_number (border_width), 8136 : Fcons (make_number (border_width),
7680 make_number (border_height)))), 8137 make_number (border_height)))),
7681 Fcons (Qtitle_height, 8138 Fcons (Qtitle_height,
7682 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen)) 8139 ((EQ (fullscreen, Qfullboth) || EQ (fullscreen, Qfullscreen))
7683 ? make_number (0) 8140 ? make_number (0)
7684 : make_number (title_height))), 8141 : make_number (title_height))),
@@ -8063,14 +8520,14 @@ w32_strerror (int error_no)
8063 error_no = GetLastError (); 8520 error_no = GetLastError ();
8064 8521
8065 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | 8522 ret = FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |
8066 FORMAT_MESSAGE_IGNORE_INSERTS, 8523 FORMAT_MESSAGE_IGNORE_INSERTS,
8067 NULL, 8524 NULL,
8068 error_no, 8525 error_no,
8069 0, /* choose most suitable language */ 8526 0, /* choose most suitable language */
8070 buf, sizeof (buf), NULL); 8527 buf, sizeof (buf), NULL);
8071 8528
8072 while (ret > 0 && (buf[ret - 1] == '\n' || 8529 while (ret > 0 && (buf[ret - 1] == '\n' ||
8073 buf[ret - 1] == '\r' )) 8530 buf[ret - 1] == '\r' ))
8074 --ret; 8531 --ret;
8075 buf[ret] = '\0'; 8532 buf[ret] = '\0';
8076 if (!ret) 8533 if (!ret)
@@ -8316,7 +8773,7 @@ w32_kbd_patch_key (KEY_EVENT_RECORD *event, int cpId)
8316 else 8773 else
8317 { 8774 {
8318 isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode, 8775 isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
8319 keystate, (LPWORD) ansi_code, 0); 8776 keystate, (LPWORD) ansi_code, 0);
8320 } 8777 }
8321 8778
8322 if (isdead == 0) 8779 if (isdead == 0)
@@ -8580,8 +9037,8 @@ system to handle them. */);
8580 w32_pass_extra_mouse_buttons_to_system = 0; 9037 w32_pass_extra_mouse_buttons_to_system = 0;
8581 9038
8582 DEFVAR_BOOL ("w32-pass-multimedia-buttons-to-system", 9039 DEFVAR_BOOL ("w32-pass-multimedia-buttons-to-system",
8583 w32_pass_multimedia_buttons_to_system, 9040 w32_pass_multimedia_buttons_to_system,
8584 doc: /* If non-nil, media buttons are passed to Windows. 9041 doc: /* If non-nil, media buttons are passed to Windows.
8585Some modern keyboards contain buttons for controlling media players, web 9042Some modern keyboards contain buttons for controlling media players, web
8586browsers and other applications. Generally these buttons are handled on a 9043browsers and other applications. Generally these buttons are handled on a
8587system wide basis, but by setting this to nil they are made available 9044system wide basis, but by setting this to nil they are made available
@@ -8669,12 +9126,12 @@ Chinese, Japanese, and Korean. */);
8669 Vx_pixel_size_width_font_regexp = Qnil; 9126 Vx_pixel_size_width_font_regexp = Qnil;
8670 9127
8671 DEFVAR_LISP ("w32-bdf-filename-alist", 9128 DEFVAR_LISP ("w32-bdf-filename-alist",
8672 Vw32_bdf_filename_alist, 9129 Vw32_bdf_filename_alist,
8673 doc: /* List of bdf fonts and their corresponding filenames. */); 9130 doc: /* List of bdf fonts and their corresponding filenames. */);
8674 Vw32_bdf_filename_alist = Qnil; 9131 Vw32_bdf_filename_alist = Qnil;
8675 9132
8676 DEFVAR_BOOL ("w32-strict-fontnames", 9133 DEFVAR_BOOL ("w32-strict-fontnames",
8677 w32_strict_fontnames, 9134 w32_strict_fontnames,
8678 doc: /* Non-nil means only use fonts that are exact matches for those requested. 9135 doc: /* Non-nil means only use fonts that are exact matches for those requested.
8679Default is nil, which allows old fontnames that are not XLFD compliant, 9136Default is nil, which allows old fontnames that are not XLFD compliant,
8680and allows third-party CJK display to work by specifying false charset 9137and allows third-party CJK display to work by specifying false charset
@@ -8684,7 +9141,7 @@ fontsets are automatically created. */);
8684 w32_strict_fontnames = 0; 9141 w32_strict_fontnames = 0;
8685 9142
8686 DEFVAR_BOOL ("w32-strict-painting", 9143 DEFVAR_BOOL ("w32-strict-painting",
8687 w32_strict_painting, 9144 w32_strict_painting,
8688 doc: /* Non-nil means use strict rules for repainting frames. 9145 doc: /* Non-nil means use strict rules for repainting frames.
8689Set this to nil to get the old behavior for repainting; this should 9146Set this to nil to get the old behavior for repainting; this should
8690only be necessary if the default setting causes problems. */); 9147only be necessary if the default setting causes problems. */);