Merge from emacs-24; up to 2012-12-27T17:59:21Z!rgm@gnu.org
[bpt/emacs.git] / src / w32inevt.c
1 /* Input event support for Emacs on the Microsoft Windows API.
2 Copyright (C) 1992-1993, 1995, 2001-2013 Free Software Foundation,
3 Inc.
4
5 This file is part of GNU Emacs.
6
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.
11
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.
16
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/>. */
19
20 /*
21 Drew Bliss 01-Oct-93
22 Adapted from ntkbd.c by Tim Fleehart
23 */
24
25
26 #include <config.h>
27 #include <stdio.h>
28 #include <windows.h>
29
30 #ifndef MOUSE_MOVED
31 #define MOUSE_MOVED 1
32 #endif
33
34 #include "lisp.h"
35 #include "keyboard.h"
36 #include "frame.h"
37 #include "dispextern.h"
38 #include "window.h"
39 #include "blockinput.h"
40 #include "termhooks.h"
41 #include "termchar.h"
42 #include "w32heap.h"
43 #include "w32term.h"
44 #include "w32inevt.h"
45
46 /* stdin, from w32console.c */
47 extern HANDLE keyboard_handle;
48
49 /* Info for last mouse motion */
50 static COORD movement_pos;
51 static Time movement_time;
52
53 /* from w32fns.c */
54 extern unsigned int map_keypad_keys (unsigned int, unsigned int);
55 extern unsigned int w32_key_to_modifier (int key);
56
57 /* Event queue */
58 #define EVENT_QUEUE_SIZE 50
59 static INPUT_RECORD event_queue[EVENT_QUEUE_SIZE];
60 static INPUT_RECORD *queue_ptr = event_queue, *queue_end = event_queue;
61
62 /* Temporarily store lead byte of DBCS input sequences. */
63 static char dbcs_lead = 0;
64
65 static inline BOOL
66 w32_read_console_input (HANDLE h, INPUT_RECORD *rec, DWORD recsize,
67 DWORD *waiting)
68 {
69 return (w32_console_unicode_input
70 ? ReadConsoleInputW (h, rec, recsize, waiting)
71 : ReadConsoleInputA (h, rec, recsize, waiting));
72 }
73
74 /* Set by w32_console_toggle_lock_key. */
75 int faked_key;
76
77 static int
78 fill_queue (BOOL block)
79 {
80 BOOL rc;
81 DWORD events_waiting;
82
83 if (queue_ptr < queue_end)
84 return queue_end-queue_ptr;
85
86 if (!block)
87 {
88 /* Check to see if there are some events to read before we try
89 because we can't block. */
90 if (!GetNumberOfConsoleInputEvents (keyboard_handle, &events_waiting))
91 return -1;
92 if (events_waiting == 0)
93 return 0;
94 }
95
96 rc = w32_read_console_input (keyboard_handle, event_queue, EVENT_QUEUE_SIZE,
97 &events_waiting);
98 if (!rc)
99 return -1;
100 queue_ptr = event_queue;
101 queue_end = event_queue + events_waiting;
102 return (int) events_waiting;
103 }
104
105 /* In a generic, multi-frame world this should take a console handle
106 and return the frame for it
107
108 Right now, there's only one frame so return it. */
109 static FRAME_PTR
110 get_frame (void)
111 {
112 return SELECTED_FRAME ();
113 }
114
115 /* Translate console modifiers to emacs modifiers.
116 German keyboard support (Kai Morgan Zeise 2/18/95). */
117
118
119 #if 0
120 /* Return nonzero if the virtual key is a dead key. */
121 static int
122 is_dead_key (int wparam)
123 {
124 unsigned int code = MapVirtualKey (wparam, 2);
125
126 /* Windows 95 returns 0x8000, NT returns 0x80000000. */
127 return (code & 0x80008000) ? 1 : 0;
128 }
129 #endif
130
131 /* The return code indicates key code size. cpID is the codepage to
132 use for translation to Unicode; -1 means use the current console
133 input codepage. */
134
135
136 /* return code -1 means that event_queue_ptr won't be incremented.
137 In other word, this event makes two key codes. (by himi) */
138 static int
139 key_event (KEY_EVENT_RECORD *event, struct input_event *emacs_ev, int *isdead)
140 {
141 static int mod_key_state = 0;
142 int wParam;
143
144 *isdead = 0;
145
146 /* Skip key-up events. */
147 if (!event->bKeyDown)
148 {
149 switch (event->wVirtualKeyCode)
150 {
151 case VK_LWIN:
152 mod_key_state &= ~LEFT_WIN_PRESSED;
153 break;
154 case VK_RWIN:
155 mod_key_state &= ~RIGHT_WIN_PRESSED;
156 break;
157 case VK_APPS:
158 mod_key_state &= ~APPS_PRESSED;
159 break;
160 }
161 return 0;
162 }
163
164 /* Ignore keystrokes we fake ourself; see below. */
165 if (faked_key == event->wVirtualKeyCode)
166 {
167 faked_key = 0;
168 return 0;
169 }
170
171 /* To make it easier to debug this code, ignore modifier keys! */
172 switch (event->wVirtualKeyCode)
173 {
174 case VK_LWIN:
175 if (NILP (Vw32_pass_lwindow_to_system))
176 {
177 /* Prevent system from acting on keyup (which opens the Start
178 menu if no other key was pressed) by simulating a press of
179 Space which we will ignore. */
180 if ((mod_key_state & LEFT_WIN_PRESSED) == 0)
181 {
182 if (NUMBERP (Vw32_phantom_key_code))
183 faked_key = XUINT (Vw32_phantom_key_code) & 255;
184 else
185 faked_key = VK_SPACE;
186 keybd_event (faked_key, (BYTE) MapVirtualKey (faked_key, 0), 0, 0);
187 }
188 }
189 mod_key_state |= LEFT_WIN_PRESSED;
190 if (!NILP (Vw32_lwindow_modifier))
191 return 0;
192 break;
193 case VK_RWIN:
194 if (NILP (Vw32_pass_rwindow_to_system))
195 {
196 if ((mod_key_state & RIGHT_WIN_PRESSED) == 0)
197 {
198 if (NUMBERP (Vw32_phantom_key_code))
199 faked_key = XUINT (Vw32_phantom_key_code) & 255;
200 else
201 faked_key = VK_SPACE;
202 keybd_event (faked_key, (BYTE) MapVirtualKey (faked_key, 0), 0, 0);
203 }
204 }
205 mod_key_state |= RIGHT_WIN_PRESSED;
206 if (!NILP (Vw32_rwindow_modifier))
207 return 0;
208 break;
209 case VK_APPS:
210 mod_key_state |= APPS_PRESSED;
211 if (!NILP (Vw32_apps_modifier))
212 return 0;
213 break;
214 case VK_CAPITAL:
215 /* Decide whether to treat as modifier or function key. */
216 if (NILP (Vw32_enable_caps_lock))
217 goto disable_lock_key;
218 return 0;
219 case VK_NUMLOCK:
220 /* Decide whether to treat as modifier or function key. */
221 if (NILP (Vw32_enable_num_lock))
222 goto disable_lock_key;
223 return 0;
224 case VK_SCROLL:
225 /* Decide whether to treat as modifier or function key. */
226 if (NILP (Vw32_scroll_lock_modifier))
227 goto disable_lock_key;
228 return 0;
229 disable_lock_key:
230 /* Ensure the appropriate lock key state is off (and the
231 indicator light as well). */
232 wParam = event->wVirtualKeyCode;
233 if (GetAsyncKeyState (wParam) & 0x8000)
234 {
235 /* Fake another press of the relevant key. Apparently, this
236 really is the only way to turn off the indicator. */
237 faked_key = wParam;
238 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
239 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
240 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
241 KEYEVENTF_EXTENDEDKEY | 0, 0);
242 keybd_event ((BYTE) wParam, (BYTE) MapVirtualKey (wParam, 0),
243 KEYEVENTF_EXTENDEDKEY | KEYEVENTF_KEYUP, 0);
244 }
245 break;
246 case VK_MENU:
247 case VK_CONTROL:
248 case VK_SHIFT:
249 return 0;
250 case VK_CANCEL:
251 /* Windows maps Ctrl-Pause (aka Ctrl-Break) into VK_CANCEL,
252 which is confusing for purposes of key binding; convert
253 VK_CANCEL events into VK_PAUSE events. */
254 event->wVirtualKeyCode = VK_PAUSE;
255 break;
256 case VK_PAUSE:
257 /* Windows maps Ctrl-NumLock into VK_PAUSE, which is confusing
258 for purposes of key binding; convert these back into
259 VK_NUMLOCK events, at least when we want to see NumLock key
260 presses. (Note that there is never any possibility that
261 VK_PAUSE with Ctrl really is C-Pause as per above.) */
262 if (NILP (Vw32_enable_num_lock)
263 && (event->dwControlKeyState
264 & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0)
265 event->wVirtualKeyCode = VK_NUMLOCK;
266 break;
267 }
268
269 /* Recognize state of Windows and Apps keys. */
270 event->dwControlKeyState |= mod_key_state;
271
272 /* Distinguish numeric keypad keys from extended keys. */
273 event->wVirtualKeyCode =
274 map_keypad_keys (event->wVirtualKeyCode,
275 (event->dwControlKeyState & ENHANCED_KEY));
276
277 if (lispy_function_keys[event->wVirtualKeyCode] == 0)
278 {
279 if (!NILP (Vw32_recognize_altgr)
280 && (event->dwControlKeyState & LEFT_CTRL_PRESSED)
281 && (event->dwControlKeyState & RIGHT_ALT_PRESSED))
282 {
283 /* Don't try to interpret AltGr key chords; ToAscii seems not
284 to process them correctly. */
285 }
286 /* Handle key chords including any modifiers other than shift
287 directly, in order to preserve as much modifier information as
288 possible. */
289 else if (event->dwControlKeyState
290 & ( RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED
291 | RIGHT_ALT_PRESSED | LEFT_ALT_PRESSED
292 | (!NILP (Vw32_lwindow_modifier) ? LEFT_WIN_PRESSED : 0)
293 | (!NILP (Vw32_rwindow_modifier) ? RIGHT_WIN_PRESSED : 0)
294 | (!NILP (Vw32_apps_modifier) ? APPS_PRESSED : 0)
295 | (!NILP (Vw32_scroll_lock_modifier) ? SCROLLLOCK_ON : 0)))
296 {
297 /* Don't translate modified alphabetic keystrokes, so the user
298 doesn't need to constantly switch layout to type control or
299 meta keystrokes when the normal layout translates
300 alphabetic characters to non-ascii characters. */
301 if ('A' <= event->wVirtualKeyCode && event->wVirtualKeyCode <= 'Z')
302 {
303 event->uChar.AsciiChar = event->wVirtualKeyCode;
304 if ((event->dwControlKeyState & SHIFT_PRESSED) == 0)
305 event->uChar.AsciiChar += ('a' - 'A');
306 }
307 /* Try to handle unrecognized keystrokes by determining the
308 base character (ie. translating the base key plus shift
309 modifier). */
310 else if (event->uChar.AsciiChar == 0)
311 w32_kbd_patch_key (event, -1);
312 }
313
314 if (event->uChar.AsciiChar == 0)
315 {
316 emacs_ev->kind = NO_EVENT;
317 return 0;
318 }
319 else if (event->uChar.AsciiChar > 0)
320 {
321 /* Pure ASCII characters < 128. */
322 emacs_ev->kind = ASCII_KEYSTROKE_EVENT;
323 emacs_ev->code = event->uChar.AsciiChar;
324 }
325 else if (event->uChar.UnicodeChar > 0
326 && w32_console_unicode_input)
327 {
328 /* Unicode codepoint; only valid if we are using Unicode
329 console input mode. */
330 emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
331 emacs_ev->code = event->uChar.UnicodeChar;
332 }
333 else
334 {
335 /* Fallback handling of non-ASCII characters for non-Unicode
336 versions of Windows, and for non-Unicode input on NT
337 family of Windows. Only characters in the current
338 console codepage are supported by this fallback. */
339 wchar_t code;
340 char dbcs[2];
341 int cpId;
342
343 /* Get the current console input codepage to interpret this
344 key with. Note that the system defaults for the OEM
345 codepage could have been changed by calling SetConsoleCP
346 or w32-set-console-codepage, so using GetLocaleInfo to
347 get LOCALE_IDEFAULTCODEPAGE is not TRT here. */
348 cpId = GetConsoleCP ();
349
350 dbcs[0] = dbcs_lead;
351 dbcs[1] = event->uChar.AsciiChar;
352 if (dbcs_lead)
353 {
354 dbcs_lead = 0;
355 if (!MultiByteToWideChar (cpId, 0, dbcs, 2, &code, 1))
356 {
357 /* Garbage */
358 DebPrint (("Invalid DBCS sequence: %d %d\n",
359 dbcs[0], dbcs[1]));
360 emacs_ev->kind = NO_EVENT;
361 }
362 }
363 else if (IsDBCSLeadByteEx (cpId, dbcs[1]))
364 {
365 dbcs_lead = dbcs[1];
366 emacs_ev->kind = NO_EVENT;
367 }
368 else
369 {
370 if (!MultiByteToWideChar (cpId, 0, &dbcs[1], 1, &code, 1))
371 {
372 /* Garbage */
373 DebPrint (("Invalid character: %d\n", dbcs[1]));
374 emacs_ev->kind = NO_EVENT;
375 }
376 }
377 emacs_ev->kind = MULTIBYTE_CHAR_KEYSTROKE_EVENT;
378 emacs_ev->code = code;
379 }
380 }
381 else
382 {
383 /* Function keys and other non-character keys. */
384 emacs_ev->kind = NON_ASCII_KEYSTROKE_EVENT;
385 emacs_ev->code = event->wVirtualKeyCode;
386 }
387
388 XSETFRAME (emacs_ev->frame_or_window, get_frame ());
389 emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState,
390 event->wVirtualKeyCode);
391 emacs_ev->timestamp = GetTickCount ();
392 return 1;
393 }
394
395 /* Mouse position hook. */
396 void
397 w32_console_mouse_position (FRAME_PTR *f,
398 int insist,
399 Lisp_Object *bar_window,
400 enum scroll_bar_part *part,
401 Lisp_Object *x,
402 Lisp_Object *y,
403 Time *time)
404 {
405 block_input ();
406
407 insist = insist;
408
409 *f = get_frame ();
410 *bar_window = Qnil;
411 *part = 0;
412 SELECTED_FRAME ()->mouse_moved = 0;
413
414 XSETINT (*x, movement_pos.X);
415 XSETINT (*y, movement_pos.Y);
416 *time = movement_time;
417
418 unblock_input ();
419 }
420
421 /* Remember mouse motion and notify emacs. */
422 static void
423 mouse_moved_to (int x, int y)
424 {
425 /* If we're in the same place, ignore it. */
426 if (x != movement_pos.X || y != movement_pos.Y)
427 {
428 SELECTED_FRAME ()->mouse_moved = 1;
429 movement_pos.X = x;
430 movement_pos.Y = y;
431 movement_time = GetTickCount ();
432 }
433 }
434
435 /* Consoles return button bits in a strange order:
436 least significant - Leftmost button
437 next - Rightmost button
438 next - Leftmost+1
439 next - Leftmost+2...
440
441 Assume emacs likes three button mice, so
442 Left == 0
443 Middle == 1
444 Right == 2
445 Others increase from there. */
446
447 #define NUM_TRANSLATED_MOUSE_BUTTONS 3
448 static int emacs_button_translation[NUM_TRANSLATED_MOUSE_BUTTONS] =
449 {
450 0, 2, 1
451 };
452
453 static int
454 do_mouse_event (MOUSE_EVENT_RECORD *event,
455 struct input_event *emacs_ev)
456 {
457 static DWORD button_state = 0;
458 static Lisp_Object last_mouse_window;
459 DWORD but_change, mask;
460 int i;
461
462 if (event->dwEventFlags == MOUSE_MOVED)
463 {
464 FRAME_PTR f = SELECTED_FRAME ();
465 Mouse_HLInfo *hlinfo = MOUSE_HL_INFO (f);
466 int mx = event->dwMousePosition.X, my = event->dwMousePosition.Y;
467
468 mouse_moved_to (mx, my);
469
470 if (f->mouse_moved)
471 {
472 if (hlinfo->mouse_face_hidden)
473 {
474 hlinfo->mouse_face_hidden = 0;
475 clear_mouse_face (hlinfo);
476 }
477
478 /* Generate SELECT_WINDOW_EVENTs when needed. */
479 if (!NILP (Vmouse_autoselect_window))
480 {
481 Lisp_Object mouse_window = window_from_coordinates (f, mx, my,
482 0, 0);
483 /* A window will be selected only when it is not
484 selected now, and the last mouse movement event was
485 not in it. A minibuffer window will be selected iff
486 it is active. */
487 if (WINDOWP (mouse_window)
488 && !EQ (mouse_window, last_mouse_window)
489 && !EQ (mouse_window, selected_window))
490 {
491 struct input_event event;
492
493 EVENT_INIT (event);
494 event.kind = SELECT_WINDOW_EVENT;
495 event.frame_or_window = mouse_window;
496 event.arg = Qnil;
497 event.timestamp = movement_time;
498 kbd_buffer_store_event (&event);
499 }
500 last_mouse_window = mouse_window;
501 }
502 else
503 last_mouse_window = Qnil;
504
505 previous_help_echo_string = help_echo_string;
506 help_echo_string = help_echo_object = help_echo_window = Qnil;
507 help_echo_pos = -1;
508 note_mouse_highlight (f, mx, my);
509 /* If the contents of the global variable help_echo has
510 changed (inside note_mouse_highlight), generate a HELP_EVENT. */
511 if (!NILP (help_echo_string) || !NILP (previous_help_echo_string))
512 gen_help_event (help_echo_string, selected_frame, help_echo_window,
513 help_echo_object, help_echo_pos);
514 }
515 return 0;
516 }
517
518 /* It looks like the console code sends us a mouse event with
519 dwButtonState == 0 when a window is activated. Ignore this case. */
520 if (event->dwButtonState == button_state)
521 return 0;
522
523 emacs_ev->kind = MOUSE_CLICK_EVENT;
524
525 /* Find out what button has changed state since the last button event. */
526 but_change = button_state ^ event->dwButtonState;
527 mask = 1;
528 for (i = 0; mask; i++, mask <<= 1)
529 if (but_change & mask)
530 {
531 if (i < NUM_TRANSLATED_MOUSE_BUTTONS)
532 emacs_ev->code = emacs_button_translation[i];
533 else
534 emacs_ev->code = i;
535 break;
536 }
537
538 button_state = event->dwButtonState;
539 emacs_ev->timestamp = GetTickCount ();
540 emacs_ev->modifiers = w32_kbd_mods_to_emacs (event->dwControlKeyState, 0) |
541 ((event->dwButtonState & mask) ? down_modifier : up_modifier);
542
543 XSETFASTINT (emacs_ev->x, event->dwMousePosition.X);
544 XSETFASTINT (emacs_ev->y, event->dwMousePosition.Y);
545 /* for Mule 2.2 (Based on Emacs 19.28 */
546 #ifdef MULE
547 XSET (emacs_ev->frame_or_window, Lisp_Frame, get_frame ());
548 #else
549 XSETFRAME (emacs_ev->frame_or_window, get_frame ());
550 #endif
551
552 return 1;
553 }
554
555 static void
556 resize_event (WINDOW_BUFFER_SIZE_RECORD *event)
557 {
558 FRAME_PTR f = get_frame ();
559
560 change_frame_size (f, event->dwSize.Y, event->dwSize.X, 0, 1, 0);
561 SET_FRAME_GARBAGED (f);
562 }
563
564 static void
565 maybe_generate_resize_event (void)
566 {
567 CONSOLE_SCREEN_BUFFER_INFO info;
568 FRAME_PTR f = get_frame ();
569
570 GetConsoleScreenBufferInfo (GetStdHandle (STD_OUTPUT_HANDLE), &info);
571
572 /* It is okay to call this unconditionally, since it will do nothing
573 if the size hasn't actually changed. */
574 change_frame_size (f,
575 1 + info.srWindow.Bottom - info.srWindow.Top,
576 1 + info.srWindow.Right - info.srWindow.Left,
577 0, 0, 0);
578 }
579
580 static int
581 handle_file_notifications (struct input_event *hold_quit)
582 {
583 BYTE *p = file_notifications;
584 FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
585 const DWORD min_size
586 = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
587 struct input_event inev;
588 int nevents = 0;
589
590 /* We cannot process notification before Emacs is fully initialized,
591 since we need the UTF-16LE coding-system to be set up. */
592 if (!initialized)
593 {
594 notification_buffer_in_use = 0;
595 return nevents;
596 }
597
598 enter_crit ();
599 if (notification_buffer_in_use)
600 {
601 DWORD info_size = notifications_size;
602 Lisp_Object cs = intern ("utf-16le");
603 Lisp_Object obj = w32_get_watch_object (notifications_desc);
604
605 /* notifications_size could be zero when the buffer of
606 notifications overflowed on the OS level, or when the
607 directory being watched was itself deleted. Do nothing in
608 that case. */
609 if (info_size
610 && !NILP (obj) && CONSP (obj))
611 {
612 Lisp_Object callback = XCDR (obj);
613
614 EVENT_INIT (inev);
615
616 while (info_size >= min_size)
617 {
618 Lisp_Object utf_16_fn
619 = make_unibyte_string ((char *)fni->FileName,
620 fni->FileNameLength);
621 /* Note: mule-conf is preloaded, so utf-16le must
622 already be defined at this point. */
623 Lisp_Object fname
624 = code_convert_string_norecord (utf_16_fn, cs, 0);
625 Lisp_Object action = lispy_file_action (fni->Action);
626
627 inev.kind = FILE_NOTIFY_EVENT;
628 inev.code = (ptrdiff_t)XINT (XIL ((EMACS_INT)notifications_desc));
629 inev.timestamp = GetTickCount ();
630 inev.modifiers = 0;
631 inev.frame_or_window = callback;
632 inev.arg = Fcons (action, fname);
633 kbd_buffer_store_event_hold (&inev, hold_quit);
634
635 if (!fni->NextEntryOffset)
636 break;
637 p += fni->NextEntryOffset;
638 fni = (PFILE_NOTIFY_INFORMATION)p;
639 info_size -= fni->NextEntryOffset;
640 }
641 }
642 notification_buffer_in_use = 0;
643 }
644 leave_crit ();
645 return nevents;
646 }
647
648 /* Here's an overview of how Emacs input works in non-GUI sessions on
649 MS-Windows. (For description of the GUI input, see the commentary
650 before w32_msg_pump in w32fns.c.)
651
652 When Emacs is idle, it loops inside wait_reading_process_output,
653 calling pselect periodically to check whether any input is
654 available. On Windows, pselect is redirected to sys_select, which
655 uses MsgWaitForMultipleObjects to wait for input, either from the
656 keyboard or from any of the Emacs subprocesses. In addition,
657 MsgWaitForMultipleObjects wakes up when some Windows message is
658 posted to the input queue of the Emacs's main thread (which is the
659 thread in which sys_select runs).
660
661 When the Emacs's console window has focus, Windows sends input
662 events that originate from the keyboard or the mouse; these events
663 wake up MsgWaitForMultipleObjects, which reports that input is
664 available. Emacs then calls w32_console_read_socket, below, to
665 read the input. w32_console_read_socket uses
666 GetNumberOfConsoleInputEvents and ReadConsoleInput to peek at and
667 read the console input events.
668
669 One type of non-keyboard input event that gets reported as input
670 available is due to the Emacs's console window receiving focus.
671 When that happens, Emacs gets the FOCUS_EVENT event and sys_select
672 reports some input; however, w32_console_read_socket ignores such
673 events when called to read them.
674
675 Note that any other Windows message sent to the main thread will
676 also wake up MsgWaitForMultipleObjects. These messages get
677 immediately dispatched to their destinations by calling
678 drain_message_queue. */
679
680 int
681 w32_console_read_socket (struct terminal *terminal,
682 struct input_event *hold_quit)
683 {
684 int nev, add;
685 int isdead;
686
687 block_input ();
688
689 for (;;)
690 {
691 int nfnotify = handle_file_notifications (hold_quit);
692
693 nev = fill_queue (0);
694 if (nev <= 0)
695 {
696 /* If nev == -1, there was some kind of error
697 If nev == 0 then no events were available
698 so return. */
699 if (nfnotify)
700 nev = 0;
701 break;
702 }
703
704 while (nev > 0)
705 {
706 struct input_event inev;
707
708 EVENT_INIT (inev);
709 inev.kind = NO_EVENT;
710 inev.arg = Qnil;
711
712 switch (queue_ptr->EventType)
713 {
714 case KEY_EVENT:
715 add = key_event (&queue_ptr->Event.KeyEvent, &inev, &isdead);
716 if (add == -1) /* 95.7.25 by himi */
717 {
718 queue_ptr--;
719 add = 1;
720 }
721 if (add)
722 kbd_buffer_store_event_hold (&inev, hold_quit);
723 break;
724
725 case MOUSE_EVENT:
726 add = do_mouse_event (&queue_ptr->Event.MouseEvent, &inev);
727 if (add)
728 kbd_buffer_store_event_hold (&inev, hold_quit);
729 break;
730
731 case WINDOW_BUFFER_SIZE_EVENT:
732 if (w32_use_full_screen_buffer)
733 resize_event (&queue_ptr->Event.WindowBufferSizeEvent);
734 break;
735
736 case MENU_EVENT:
737 case FOCUS_EVENT:
738 /* Internal event types, ignored. */
739 break;
740 }
741
742 queue_ptr++;
743 nev--;
744 }
745 }
746
747 /* We don't get told about changes in the window size (only the buffer
748 size, which we no longer care about), so we have to check it
749 periodically. */
750 if (!w32_use_full_screen_buffer)
751 maybe_generate_resize_event ();
752
753 unblock_input ();
754 return nev;
755 }