+ Emchar quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
+ BYTE keymap_orig[256];
+ POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) };
+ MSG msg, tranmsg;
+ int potential_accelerator = 0;
+ int got_accelerator = 0;
+
+ msg.hwnd = hwnd;
+ msg.message = message;
+ msg.wParam = wParam;
+ msg.lParam = lParam;
+ msg.time = GetMessageTime();
+ msg.pt = pnt;
+
+ /* GetKeyboardState() does not work as documented on Win95. We have
+ * to loosely track Left and Right modifiers on behalf of the OS,
+ * without screwing up Windows NT which tracks them properly. */
+ if (wParam == VK_CONTROL)
+ keymap [extendedp ? VK_RCONTROL : VK_LCONTROL] |= 0x80;
+ else if (wParam == VK_MENU)
+ keymap [extendedp ? VK_RMENU : VK_LMENU] |= 0x80;
+
+ memcpy (keymap_orig, keymap, 256);
+
+ if (!NILP (Vmenu_accelerator_enabled) &&
+ !(mods & XEMACS_MOD_SHIFT) && message == WM_SYSKEYDOWN)
+ potential_accelerator = 1;
+
+ /* Remove shift modifier from an ascii character */
+ mods &= ~XEMACS_MOD_SHIFT;
+
+ /* Clear control and alt modifiers unless AltGr is pressed */
+ keymap [VK_RCONTROL] = 0;
+ keymap [VK_LMENU] = 0;
+ if (!has_AltGr || !(keymap [VK_LCONTROL] & 0x80)
+ || !(keymap [VK_RMENU] & 0x80))
+ {
+ keymap [VK_LCONTROL] = 0;
+ keymap [VK_CONTROL] = 0;
+ keymap [VK_RMENU] = 0;
+ keymap [VK_MENU] = 0;
+ }
+ SetKeyboardState (keymap);
+
+ /* Maybe generate some WM_[SYS]CHARs in the queue */
+ TranslateMessage (&msg);
+
+ while (PeekMessage (&tranmsg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)
+ || PeekMessage (&tranmsg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
+ {
+ int mods1 = mods;
+ WPARAM ch = tranmsg.wParam;
+
+ /* If a quit char with no modifiers other than control and
+ shift, then mark it with a fake modifier, which is removed
+ upon dequeueing the event */
+ /* #### This might also not withstand localization, if
+ quit character is not a latin-1 symbol */
+ if (((quit_ch < ' ' && (mods & XEMACS_MOD_CONTROL) && quit_ch + 'a' - 1 == ch)
+ || (quit_ch >= ' ' && !(mods & XEMACS_MOD_CONTROL) && quit_ch == ch))
+ && ((mods & ~(XEMACS_MOD_CONTROL | XEMACS_MOD_SHIFT)) == 0))
+ {
+ mods1 |= FAKE_MOD_QUIT;
+ ++mswindows_quit_chars_count;
+ }
+ else if (potential_accelerator && !got_accelerator &&
+ msw_char_is_accelerator (frame, ch))
+ {
+ got_accelerator = 1;
+ break;
+ }
+ mswindows_enqueue_keypress_event (hwnd, make_char (ch), mods1);
+ } /* while */
+ SetKeyboardState (keymap_orig);
+ /* This generates WM_SYSCHAR messages, which are interpreted
+ by DefWindowProc as the menu selections. */
+ if (got_accelerator)
+ {
+ TranslateMessage (&msg);
+ goto defproc;
+ }
+ } /* else */