0, 0, 0);
}
+static int
+handle_file_notifications (struct input_event *hold_quit)
+{
+ BYTE *p = file_notifications;
+ FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
+ const DWORD min_size
+ = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
+ struct input_event inev;
+ int nevents = 0;
+
+ /* We cannot process notification before Emacs is fully initialized,
+ since we need the UTF-16LE coding-system to be set up. */
+ if (!initialized)
+ {
+ notification_buffer_in_use = 0;
+ return nevents;
+ }
+
+ enter_crit ();
+ if (notification_buffer_in_use)
+ {
+ DWORD info_size = notifications_size;
+ Lisp_Object cs = intern ("utf-16le");
+ Lisp_Object obj = get_watch_object (make_number (notifications_desc));
+
+ /* notifications_size could be zero when the buffer of
+ notifications overflowed on the OS level, or when the
+ directory being watched was itself deleted. Do nothing in
+ that case. */
+ if (info_size
+ && !NILP (obj) && CONSP (obj))
+ {
+ Lisp_Object callback = XCDR (obj);
+
+ EVENT_INIT (inev);
+
+ while (info_size >= min_size)
+ {
+ Lisp_Object utf_16_fn
+ = make_unibyte_string ((char *)fni->FileName,
+ fni->FileNameLength);
+ /* Note: mule-conf is preloaded, so utf-16le must
+ already be defined at this point. */
+ Lisp_Object fname
+ = code_convert_string_norecord (utf_16_fn, cs, 0);
+ Lisp_Object action = lispy_file_action (fni->Action);
+
+ inev.kind = FILE_NOTIFY_EVENT;
+ inev.code = (ptrdiff_t)notifications_desc;
+ inev.timestamp = GetTickCount ();
+ inev.modifiers = 0;
+ inev.frame_or_window = callback;
+ inev.arg = Fcons (action, fname);
+ kbd_buffer_store_event_hold (&inev, hold_quit);
+
+ if (!fni->NextEntryOffset)
+ break;
+ p += fni->NextEntryOffset;
+ fni = (PFILE_NOTIFY_INFORMATION)p;
+ info_size -= fni->NextEntryOffset;
+ }
+ }
+ notification_buffer_in_use = 0;
+ }
+ leave_crit ();
+ return nevents;
+}
+
+ /* Here's an overview of how Emacs input works in non-GUI sessions on
+ MS-Windows. (For description of the GUI input, see the commentary
+ before w32_msg_pump in w32fns.c.)
+
+ When Emacs is idle, it loops inside wait_reading_process_output,
+ calling pselect periodically to check whether any input is
+ available. On Windows, pselect is redirected to sys_select, which
+ uses MsgWaitForMultipleObjects to wait for input, either from the
+ keyboard or from any of the Emacs subprocesses. In addition,
+ MsgWaitForMultipleObjects wakes up when some Windows message is
+ posted to the input queue of the Emacs's main thread (which is the
+ thread in which sys_select runs).
+
+ When the Emacs's console window has focus, Windows sends input
+ events that originate from the keyboard or the mouse; these events
+ wake up MsgWaitForMultipleObjects, which reports that input is
+ available. Emacs then calls w32_console_read_socket, below, to
+ read the input. w32_console_read_socket uses
+ GetNumberOfConsoleInputEvents and ReadConsoleInput to peek at and
+ read the console input events.
+
+ One type of non-keyboard input event that gets reported as input
+ available is due to the Emacs's console window receiving focus.
+ When that happens, Emacs gets the FOCUS_EVENT event and sys_select
+ reports some input; however, w32_console_read_socket ignores such
+ events when called to read them.
+
+ Note that any other Windows message sent to the main thread will
+ also wake up MsgWaitForMultipleObjects. These messages get
+ immediately dispatched to their destinations by calling
+ drain_message_queue. */
+
int
w32_console_read_socket (struct terminal *terminal,
struct input_event *hold_quit)