From: Eli Zaretskii Date: Sun, 14 Oct 2012 08:03:16 +0000 (+0200) Subject: Merge from trunk. X-Git-Tag: emacs-24.3.90~173^2~7^2~665 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=dd8c2f5adeba029790a007ec829e18442a4ade36;p=emacs.git Merge from trunk. --- dd8c2f5adeba029790a007ec829e18442a4ade36 diff --cc src/w32inevt.c index 7d60c06d78d,899a6fb89bf..a5868be612c --- a/src/w32inevt.c +++ b/src/w32inevt.c @@@ -576,74 -576,38 +576,106 @@@ maybe_generate_resize_event (void 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)