- case WM_KEYDOWN:
- case WM_SYSKEYDOWN:
- /* In some locales the right-hand Alt key is labelled AltGr. This key
- * should produce alternative charcaters when combined with another key.
- * eg on a German keyboard pressing AltGr+q should produce '@'.
- * AltGr generates exactly the same keystrokes as LCtrl+RAlt. But if
- * TranslateMessage() is called with *any* combination of Ctrl+Alt down,
- * it translates as if AltGr were down.
- * We get round this by removing all modifiers from the keymap before
- * calling TranslateMessage() unless AltGr is *really* down. */
- {
- BYTE keymap[256];
- int has_AltGr = mswindows_current_layout_has_AltGr ();
- int mods;
- int extendedp = lParam & 0x1000000;
- Lisp_Object keysym;
-
- GetKeyboardState (keymap);
- mods = mswindows_modifier_state (keymap, has_AltGr);
-
- /* Handle non-printables */
- if (!NILP (keysym = mswindows_key_to_emacs_keysym (wParam, mods,
- extendedp)))
- mswindows_enqueue_keypress_event (hwnd, keysym, mods);
- else /* Normal keys & modifiers */
- {
- int quit_ch = CONSOLE_QUIT_CHAR (XCONSOLE (mswindows_find_console (hwnd)));
- BYTE keymap_orig[256];
- POINT pnt = { LOWORD (GetMessagePos()), HIWORD (GetMessagePos()) };
- MSG msg;
-
- 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);
-
- /* Remove shift modifier from an ascii character */
- mods &= ~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 (&msg, hwnd, WM_CHAR, WM_CHAR, PM_REMOVE)
- || PeekMessage (&msg, hwnd, WM_SYSCHAR, WM_SYSCHAR, PM_REMOVE))
- {
- int mods1 = mods;
- WPARAM ch = msg.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 & MOD_CONTROL) && quit_ch + 'a' - 1 == ch)
- || (quit_ch >= ' ' && !(mods & MOD_CONTROL) && quit_ch == ch))
- && ((mods & ~(MOD_CONTROL | MOD_SHIFT)) == 0))
- {
- mods1 |= FAKE_MOD_QUIT;
- ++mswindows_quit_chars_count;
- }