* makefile.w32-in (INFO_TARGETS, DVI_TARGETS, clean): Add ns-emacs.
[emacs.git] / src / w32inevt.c
blob7932990061de1fede69686e7476d45dd35bdf6fc
1 /* Input event support for Emacs on the Microsoft W32 API.
2 Copyright (C) 1992, 1993, 1995, 2001, 2002, 2003, 2004, 2005, 2006,
3 2007, 2008 Free Software Foundation, Inc.
5 This file is part of GNU Emacs.
7 GNU Emacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU Emacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
21 Drew Bliss 01-Oct-93
22 Adapted from ntkbd.c by Tim Fleehart
26 #ifdef HAVE_CONFIG_H
27 #include <config.h>
28 #endif
30 #include <stdlib.h>
31 #include <stdio.h>
32 #include <windows.h>
34 #ifndef MOUSE_MOVED
35 #define MOUSE_MOVED 1
36 #endif
38 #include "lisp.h"
39 #include "keyboard.h"
40 #include "frame.h"
41 #include "blockinput.h"
42 #include "termhooks.h"
43 #include "w32heap.h"
44 #include "w32term.h"
46 /* stdin, from ntterm */
47 extern HANDLE keyboard_handle;
49 /* Info for last mouse motion */
50 static COORD movement_pos;
51 static DWORD movement_time;
53 /* from keyboard.c */
54 extern void reinvoke_input_signal (void);
56 /* from w32console.c */
57 extern int w32_use_full_screen_buffer;
59 /* from w32fns.c */
60 extern Lisp_Object Vw32_alt_is_meta;
61 extern unsigned int map_keypad_keys (unsigned int, unsigned int);
63 /* from w32term */
64 extern Lisp_Object Vw32_capslock_is_shiftlock;
65 extern Lisp_Object Vw32_enable_caps_lock;
66 extern Lisp_Object Vw32_enable_num_lock;
67 extern Lisp_Object Vw32_recognize_altgr;
68 extern Lisp_Object Vw32_pass_lwindow_to_system;
69 extern Lisp_Object Vw32_pass_rwindow_to_system;
70 extern Lisp_Object Vw32_phantom_key_code;
71 extern Lisp_Object Vw32_lwindow_modifier;
72 extern Lisp_Object Vw32_rwindow_modifier;
73 extern Lisp_Object Vw32_apps_modifier;
74 extern Lisp_Object Vw32_scroll_lock_modifier;
75 extern unsigned int w32_key_to_modifier (int key);
77 /* Event queue */
78 #define EVENT_QUEUE_SIZE 50
79 static INPUT_RECORD event_queue[EVENT_QUEUE_SIZE];
80 static INPUT_RECORD *queue_ptr = event_queue, *queue_end = event_queue;
82 static int
83 fill_queue (BOOL block)
85 BOOL rc;
86 DWORD events_waiting;
88 if (queue_ptr < queue_end)
89 return queue_end-queue_ptr;
91 if (!block)
93 /* Check to see if there are some events to read before we try
94 because we can't block. */
95 if (!GetNumberOfConsoleInputEvents (keyboard_handle, &events_waiting))
96 return -1;
97 if (events_waiting == 0)
98 return 0;
101 rc = ReadConsoleInput (keyboard_handle, event_queue, EVENT_QUEUE_SIZE,
102 &events_waiting);
103 if (!rc)
104 return -1;
105 queue_ptr = event_queue;
106 queue_end = event_queue + events_waiting;
107 return (int) events_waiting;
110 /* In a generic, multi-frame world this should take a console handle
111 and return the frame for it
113 Right now, there's only one frame so return it. */
114 static FRAME_PTR
115 get_frame (void)
117 return SELECTED_FRAME ();
120 /* Translate console modifiers to emacs modifiers.
121 German keyboard support (Kai Morgan Zeise 2/18/95). */
123 w32_kbd_mods_to_emacs (DWORD mods, WORD key)
125 int retval = 0;
127 /* If we recognize right-alt and left-ctrl as AltGr, and it has been
128 pressed, first remove those modifiers. */
129 if (!NILP (Vw32_recognize_altgr)
130 && (mods & (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
131 == (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED))
132 mods &= ~ (RIGHT_ALT_PRESSED | LEFT_CTRL_PRESSED);
134 if (mods & (RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED))
135 retval = ((NILP (Vw32_alt_is_meta)) ? alt_modifier : meta_modifier);
137 if (mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
139 retval |= ctrl_modifier;
140 if ((mods & (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
141 == (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED))
142 retval |= meta_modifier;
145 if (mods & LEFT_WIN_PRESSED)
146 retval |= w32_key_to_modifier (VK_LWIN);
147 if (mods & RIGHT_WIN_PRESSED)
148 retval |= w32_key_to_modifier (VK_RWIN);
149 if (mods & APPS_PRESSED)
150 retval |= w32_key_to_modifier (VK_APPS);
151 if (mods & SCROLLLOCK_ON)
152 retval |= w32_key_to_modifier (VK_SCROLL);
154 /* Just in case someone wanted the original behavior, make it
155 optional by setting w32-capslock-is-shiftlock to t. */
156 if (NILP (Vw32_capslock_is_shiftlock)
157 /* Keys that should _not_ be affected by CapsLock. */
158 && ( (key == VK_BACK)
159 || (key == VK_TAB)
160 || (key == VK_CLEAR)
161 || (key == VK_RETURN)
162 || (key == VK_ESCAPE)
163 || ((key >= VK_SPACE) && (key <= VK_HELP))
164 || ((key >= VK_NUMPAD0) && (key <= VK_F24))
165 || ((key >= VK_NUMPAD_CLEAR) && (key <= VK_NUMPAD_DELETE))
168 /* Only consider shift state. */
169 if ((mods & SHIFT_PRESSED) != 0)
170 retval |= shift_modifier;
172 else
174 /* Ignore CapsLock state if not enabled. */
175 if (NILP (Vw32_enable_caps_lock))
176 mods &= ~CAPSLOCK_ON;
177 if ((mods & (SHIFT_PRESSED | CAPSLOCK_ON)) != 0)
178 retval |= shift_modifier;
181 return retval;
184 #if 0
185 /* Return nonzero if the virtual key is a dead key. */
186 static int
187 is_dead_key (int wparam)
189 unsigned int code = MapVirtualKey (wparam, 2);
191 /* Windows 95 returns 0x8000, NT returns 0x80000000. */
192 return (code & 0x80008000) ? 1 : 0;
194 #endif
196 /* The return code indicates key code size. */
198 w32_kbd_patch_key (KEY_EVENT_RECORD *event)
200 unsigned int key_code = event->wVirtualKeyCode;
201 unsigned int mods = event->dwControlKeyState;
202 BYTE keystate[256];
203 static BYTE ansi_code[4];
204 static int isdead = 0;
206 if (isdead == 2)
208 event->uChar.AsciiChar = ansi_code[2];
209 isdead = 0;
210 return 1;
212 if (event->uChar.AsciiChar != 0)
213 return 1;
215 memset (keystate, 0, sizeof (keystate));
216 keystate[key_code] = 0x80;
217 if (mods & SHIFT_PRESSED)
218 keystate[VK_SHIFT] = 0x80;
219 if (mods & CAPSLOCK_ON)
220 keystate[VK_CAPITAL] = 1;
221 /* If we recognize right-alt and left-ctrl as AltGr, set the key
222 states accordingly before invoking ToAscii. */
223 if (!NILP (Vw32_recognize_altgr)
224 && (mods & LEFT_CTRL_PRESSED) && (mods & RIGHT_ALT_PRESSED))
226 keystate[VK_CONTROL] = 0x80;
227 keystate[VK_LCONTROL] = 0x80;
228 keystate[VK_MENU] = 0x80;
229 keystate[VK_RMENU] = 0x80;
232 #if 0
233 /* Because of an OS bug, ToAscii corrupts the stack when called to
234 convert a dead key in console mode on NT4. Unfortunately, trying
235 to check for dead keys using MapVirtualKey doesn't work either -
236 these functions apparently use internal information about keyboard
237 layout which doesn't get properly updated in console programs when
238 changing layout (though apparently it gets partly updated,
239 otherwise ToAscii wouldn't crash). */
240 if (is_dead_key (event->wVirtualKeyCode))
241 return 0;
242 #endif
244 /* On NT, call ToUnicode instead and then convert to the current
245 locale's default codepage. */
246 if (os_subtype == OS_NT)
248 WCHAR buf[128];
250 isdead = ToUnicode (event->wVirtualKeyCode, event->wVirtualScanCode,
251 keystate, buf, 128, 0);
252 if (isdead > 0)
254 char cp[20];
255 int cpId;
257 GetLocaleInfo (GetThreadLocale (),
258 LOCALE_IDEFAULTANSICODEPAGE, cp, 20);
259 cpId = atoi (cp);
260 isdead = WideCharToMultiByte (cpId, 0, buf, isdead,
261 ansi_code, 4, NULL, NULL);
263 else
264 isdead = 0;
266 else
268 isdead = ToAscii (event->wVirtualKeyCode, event->wVirtualScanCode,
269 keystate, (LPWORD) ansi_code, 0);
272 if (isdead == 0)
273 return 0;
274 event->uChar.AsciiChar = ansi_code[0];
275 return isdead;
279 extern char *lispy_function_keys[];
281 static int faked_key = 0;
283 /* return code -1 means that event_queue_ptr won't be incremented.
284 In other word, this event makes two key codes. (by himi) */
286 key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
288 static int mod_key_state = 0;
289 int wParam;
291 *isdead = 0;
293 /* Skip key-up events. */
294 if (!event->bKeyDown)
296 switch (event->wVirtualKeyCode)
298 case VK_LWIN:
299 mod_key_state &= ~LEFT_WIN_PRESSED;
300 break;
301 case VK_RWIN:
302 mod_key_state &= ~RIGHT_WIN_PRESSED;
303 break;
304 case VK_APPS:
305 mod_key_state &= ~APPS_PRESSED;
306 break;
308 return 0;
311 /* Ignore keystrokes we fake ourself; see below. */
312 if (faked_key == event->wVirtualKeyCode)
314 faked_key = 0;
315 return 0;
318 /* To make it easier to debug this code, ignore modifier keys! */
319 switch (event->wVirtualKeyCode)
321 case VK_LWIN:
322 if (NILP (Vw32_pass_lwindow_to_system))
324 /* Prevent system from acting on keyup (which opens the Start
325 menu if no other key was pressed) by simulating a press of
326 Space which we will ignore. */
327 if ((mod_key_state & LEFT_WIN_PRESSED) == 0)
329 if (NUMBERP (Vw32_phantom_key_code))
330 faked_key = XUINT (Vw32_phantom_key_code) & 255;
331 else
332 faked_key = VK_SPACE;
333 keybd_event (faked_key, (BYTE) MapVirtualKey (faked_key, 0), 0, 0);
336 mod_key_state |= LEFT_WIN_PRESSED;
337 if (!NILP (Vw32_lwindow_modifier))
338 return 0;
339 break;
340 case VK_RWIN:
341 if (NILP (Vw32_pass_rwindow_to_system))
343 if ((mod_key_state & RIGHT_WIN_PRESSED) == 0)
345 if (NUMBERP (Vw32_phantom_key_code))
346 faked_key = XUINT (Vw32_phantom_key_code) & 255;
347 else
348 faked_key = VK_SPACE;
349 keybd_event (faked_key, (BYTE) MapVirtualKey (faked_key, 0), 0, 0);
352 mod_key_state |= RIGHT_WIN_PRESSED;
353 if (!NILP (Vw32_rwindow_modifier))
354 return 0;
355 break;
356 case VK_APPS:
357 mod_key_state |= APPS_PRESSED;
358 if (!NILP (Vw32_apps_modifier))
359 return 0;
360 break;
361 case VK_CAPITAL:
362 /* Decide whether to treat as modifier or function key. */
363 if (NILP (Vw32_enable_caps_lock))
364 goto disable_lock_key;
365 return 0;
366 case VK_NUMLOCK:
367 /* Decide whether to treat as modifier or function key. */
368 if (NILP (Vw32_enable_num_lock))
369 goto disable_lock_key;
370 return 0;
371 case VK_SCROLL:
372 /* Decide whether to treat as modifier or function key. */
373 if (NILP (Vw32_scroll_lock_modifier))
374 goto disable_lock_key;
375 return 0;
376 disable_lock_key:
377 /* Ensure the appropriate lock key state is off (and the
378 indicator light as well). */
379 wParam = event->wVirtualKeyCode;
380 if (GetAsyncKeyState (wParam) & 0x8000)
382 /* Fake another press of the relevant key. Apparently, this
383 really is the only way to turn off the indicator. */
384 faked_key = wParam;
385 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
386 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
387 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
388 KEYEVENTF_EXTENDEDKEY | 0, 0);
389 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
390 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
392 break;
393 case VK_MENU:
394 case VK_CONTROL:
395 case VK_SHIFT:
396 return 0;
397 case VK_CANCEL:
398 /* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL,
399 which is confusing for purposes of key binding; convert
400 VK_CANCEL events into VK_PAUSE events. */
401 event->wVirtualKeyCode = VK_PAUSE;
402 break;
403 case VK_PAUSE:
404 /* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing
405 for purposes of key binding; convert these back into
406 VK_NUMLOCK events, at least when we want to see NumLock key
407 presses. (Note that there is never any possibility that
408 VK_PAUSE with Ctrl really is C-Pause as per above.) */
409 if (NILP (Vw32_enable_num_lock)
410 && (event->dwControlKeyState
411 & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0)
412 event->wVirtualKeyCode = VK_NUMLOCK;
413 break;
416 /* Recognize state of Windows and Apps keys. */
417 event->dwControlKeyState |= mod_key_state;
419 /* Distinguish numeric keypad keys from extended keys. */
420 event->wVirtualKeyCode =
421 map_keypad_keys (event->wVirtualKeyCode,
422 (event->dwControlKeyState & ENHANCED_KEY));
424 if (lispy_function_keys[event->wVirtualKeyCode] == 0)
426 emacs_ev->kind = ASCII_KEYSTROKE_EVENT;
428 if (!NILP (Vw32_recognize_altgr)
429 && (event->dwControlKeyState & LEFT_CTRL_PRESSED)
430 && (event->dwControlKeyState & RIGHT_ALT_PRESSED))
432 /* Don't try to interpret AltGr key chords; ToAscii seems not
433 to process them correctly. */
435 /* Handle key chords including any modifiers other than shift
436 directly, in order to preserve as much modifier information as
437 possible. */
438 else if (event->dwControlKeyState
439 & ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED
440 | RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED
441 | (!NILP (Vw32_lwindow_modifier) ? LEFT_WIN_PRESSED : 0)
442 | (!NILP (Vw32_rwindow_modifier) ? RIGHT_WIN_PRESSED : 0)
443 | (!NILP (Vw32_apps_modifier) ? APPS_PRESSED : 0)
444 | (!NILP (Vw32_scroll_lock_modifier) ? SCROLLLOCK_ON : 0)))
446 /* Don't translate modified alphabetic keystrokes, so the user
447 doesn't need to constantly switch layout to type control or
448 meta keystrokes when the normal layout translates
449 alphabetic characters to non-ascii characters. */
450 if ('A' <= event->wVirtualKeyCode && event->wVirtualKeyCode <= 'Z')
452 event->uChar.AsciiChar = event->wVirtualKeyCode;
453 if ((event->dwControlKeyState & SHIFT_PRESSED) == 0)
454 event->uChar.AsciiChar += ('a' - 'A');
456 /* Try to handle unrecognized keystrokes by determining the
457 base character (ie. translating the base key plus shift
458 modifier). */
459 else if (event->uChar.AsciiChar == 0)
460 w32_kbd_patch_key (event);
462 if (event->uChar.AsciiChar == 0)
463 return 0;
464 emacs_ev->code = event->uChar.AsciiChar;
466 else
468 emacs_ev->kind = NON_ASCII_KEYSTROKE_EVENT;
469 emacs_ev->code = event->wVirtualKeyCode;
472 XSETFRAME (emacs_ev->frame_or_window, get_frame ());
473 emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState,
474 event->wVirtualKeyCode);
475 emacs_ev->timestamp = GetTickCount ();
476 return 1;
480 w32_console_toggle_lock_key (int vk_code, Lisp_Object new_state)
482 int cur_state = (GetKeyState (vk_code) & 1);
484 if (NILP (new_state)
485 || (NUMBERP (new_state)
486 && ((XUINT (new_state)) & 1) != cur_state))
488 faked_key = vk_code;
490 keybd_event ((BYTE) vk_code,
491 (BYTE) MapVirtualKey (vk_code, 0),
492 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
493 keybd_event ((BYTE) vk_code,
494 (BYTE) MapVirtualKey (vk_code, 0),
495 KEYEVENTF_EXTENDEDKEY | 0, 0);
496 keybd_event ((BYTE) vk_code,
497 (BYTE) MapVirtualKey (vk_code, 0),
498 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
499 cur_state = !cur_state;
502 return cur_state;
505 /* Mouse position hook. */
506 void
507 w32_console_mouse_position (FRAME_PTR *f,
508 int insist,
509 Lisp_Object *bar_window,
510 enum scroll_bar_part *part,
511 Lisp_Object *x,
512 Lisp_Object *y,
513 unsigned long *time)
515 BLOCK_INPUT;
517 insist = insist;
519 *f = get_frame ();
520 *bar_window = Qnil;
521 *part = 0;
522 SELECTED_FRAME ()->mouse_moved = 0;
524 XSETINT(*x, movement_pos.X);
525 XSETINT(*y, movement_pos.Y);
526 *time = movement_time;
528 UNBLOCK_INPUT;
531 /* Remember mouse motion and notify emacs. */
532 static void
533 mouse_moved_to (int x, int y)
535 /* If we're in the same place, ignore it */
536 if (x != movement_pos.X || y != movement_pos.Y)
538 SELECTED_FRAME ()->mouse_moved = 1;
539 movement_pos.X = x;
540 movement_pos.Y = y;
541 movement_time = GetTickCount ();
545 /* Consoles return button bits in a strange order:
546 least significant - Leftmost button
547 next - Rightmost button
548 next - Leftmost+1
549 next - Leftmost+2...
551 Assume emacs likes three button mice, so
552 Left == 0
553 Middle == 1
554 Right == 2
555 Others increase from there. */
557 #define NUM_TRANSLATED_MOUSE_BUTTONS 3
558 static int emacs_button_translation[NUM_TRANSLATED_MOUSE_BUTTONS] =
560 0, 2, 1
563 static int
564 do_mouse_event (MOUSE_EVENT_RECORD *event,
565 struct input_event *emacs_ev)
567 static DWORD button_state = 0;
568 DWORD but_change, mask;
569 int i;
571 if (event->dwEventFlags == MOUSE_MOVED)
573 /* For movement events we just note that the mouse has moved
574 so that emacs will generate drag events. */
575 mouse_moved_to (event->dwMousePosition.X, event->dwMousePosition.Y);
576 return 0;
579 /* It looks like the console code sends us a mouse event with
580 dwButtonState == 0 when a window is activated. Ignore this case. */
581 if (event->dwButtonState == button_state)
582 return 0;
584 emacs_ev->kind = MOUSE_CLICK_EVENT;
586 /* Find out what button has changed state since the last button event. */
587 but_change = button_state ^ event->dwButtonState;
588 mask = 1;
589 for (i = 0; mask; i++, mask <<= 1)
590 if (but_change & mask)
592 if (i < NUM_TRANSLATED_MOUSE_BUTTONS)
593 emacs_ev->code = emacs_button_translation[i];
594 else
595 emacs_ev->code = i;
596 break;
599 button_state = event->dwButtonState;
600 emacs_ev->timestamp = GetTickCount ();
601 emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState, 0) |
602 ((event->dwButtonState & mask) ? down_modifier : up_modifier);
604 XSETFASTINT (emacs_ev->x, event->dwMousePosition.X);
605 XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y);
606 /* for Mule 2.2 (Based on Emacs 19.28 */
607 #ifdef MULE
608 XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ());
609 #else
610 XSETFRAME (emacs_ev->frame_or_window, get_frame ());
611 #endif
613 return 1;
616 static void
617 resize_event (WINDOW_BUFFER_SIZE_RECORD *event)
619 FRAME_PTR f = get_frame ();
621 change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1, 0);
622 SET_FRAME_GARBAGED (f);
625 static void
626 maybe_generate_resize_event ()
628 CONSOLE_SCREEN_BUFFER_INFO info;
629 FRAME_PTR f = get_frame ();
631 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
633 /* It is okay to call this unconditionally, since it will do nothing
634 if the size hasn't actually changed. */
635 change_frame_size (f,
636 1 + info.srWindow.Bottom - info.srWindow.Top,
637 1 + info.srWindow.Right - info.srWindow.Left,
638 0, 0, 0);
642 w32_console_read_socket (struct terminal *terminal,
643 int expected,
644 struct input_event *hold_quit)
646 BOOL no_events = TRUE;
647 int nev, ret = 0, add;
648 int isdead;
650 if (interrupt_input_blocked)
652 interrupt_input_pending = 1;
653 return -1;
656 interrupt_input_pending = 0;
657 BLOCK_INPUT;
659 for (;;)
661 nev = fill_queue (0);
662 if (nev <= 0)
664 /* If nev == -1, there was some kind of error
665 If nev == 0 then waitp must be zero and no events were available
666 so return. */
667 UNBLOCK_INPUT;
668 return nev;
671 while (nev > 0)
673 struct input_event inev;
675 EVENT_INIT (inev);
676 inev.kind = NO_EVENT;
677 inev.arg = Qnil;
679 switch (queue_ptr->EventType)
681 case KEY_EVENT:
682 add = key_event (&queue_ptr->Event.KeyEvent, &inev, &isdead);
683 if (add == -1) /* 95.7.25 by himi */
685 queue_ptr--;
686 add = 1;
688 if (add)
689 kbd_buffer_store_event_hold (&inev, hold_quit);
690 break;
692 case MOUSE_EVENT:
693 add = do_mouse_event (&queue_ptr->Event.MouseEvent, &inev);
694 if (add)
695 kbd_buffer_store_event_hold (&inev, hold_quit);
696 break;
698 case WINDOW_BUFFER_SIZE_EVENT:
699 if (w32_use_full_screen_buffer)
700 resize_event (&queue_ptr->Event.WindowBufferSizeEvent);
701 break;
703 case MENU_EVENT:
704 case FOCUS_EVENT:
705 /* Internal event types, ignored. */
706 break;
709 queue_ptr++;
710 nev--;
713 if (ret > 0 || expected == 0)
714 break;
717 /* We don't get told about changes in the window size (only the buffer
718 size, which we no longer care about), so we have to check it
719 periodically. */
720 if (!w32_use_full_screen_buffer)
721 maybe_generate_resize_event ();
723 UNBLOCK_INPUT;
724 return ret;
727 /* arch-tag: 0bcb39b7-d085-4b85-9070-6750e8c03047
728 (do not change this comment) */