From: Eli Zaretskii Date: Wed, 10 Oct 2012 17:11:25 +0000 (+0200) Subject: Support file notifications in a TTY session. X-Git-Tag: emacs-24.3.90~173^2~7^2~669 X-Git-Url: http://git.eshelyaron.com/gitweb/?a=commitdiff_plain;h=182b170f7ec712b7f89ada65095aae5bb8fe553e;p=emacs.git Support file notifications in a TTY session. FIXME: file notifications detected only when the Emacs window has focus. --- diff --git a/src/w32inevt.c b/src/w32inevt.c index c322d3a0b44..9b63d0c24b6 100644 --- a/src/w32inevt.c +++ b/src/w32inevt.c @@ -576,6 +576,73 @@ maybe_generate_resize_event (void) 0, 0, 0); } +static void +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; + + /* 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; + } + + enter_crit (); + if (notification_buffer_in_use) + { + DWORD info_size = notifications_size; + + /* 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) + { + 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, + intern ("utf-16le"), 0); + Lisp_Object action = lispy_file_action (fni->Action); + Lisp_Object obj; + + obj = get_watch_object (make_number (notifications_desc)); + if (!NILP (obj) && CONSP (obj)) + { + inev.kind = FILE_NOTIFY_EVENT; + inev.code = (ptrdiff_t)notifications_desc; + inev.timestamp = GetTickCount (); + inev.modifiers = 0; + inev.frame_or_window = XCDR (obj); + 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 (); +} + int w32_console_read_socket (struct terminal *terminal, struct input_event *hold_quit) @@ -587,6 +654,7 @@ w32_console_read_socket (struct terminal *terminal, for (;;) { + handle_file_notifications (hold_quit); nev = fill_queue (0); if (nev <= 0) { diff --git a/src/w32notify.c b/src/w32notify.c index 05c918d8ac8..59547635636 100644 --- a/src/w32notify.c +++ b/src/w32notify.c @@ -115,10 +115,6 @@ send_notifications (BYTE *info, DWORD info_size, HANDLE hdir, int *terminate) int done = 0; FRAME_PTR f = SELECTED_FRAME (); - /* Too bad, but PostMessage will not work in non-GUI sessions. - FIXME. */ - if (!FRAME_W32_P (f)) - return; /* A single buffer is used to communicate all notifications to the main thread. Since both the main thread and several watcher @@ -138,11 +134,14 @@ send_notifications (BYTE *info, DWORD info_size, HANDLE hdir, int *terminate) memcpy (file_notifications, info, info_size); notifications_size = info_size; notifications_desc = hdir; - /* If PostMessage fails, the message queue is full. If that - happens, the last thing they will worry about is file - notifications. So we effectively discard the - notification in that case. */ - if (PostMessage (FRAME_W32_WINDOW (f), WM_EMACS_FILENOTIFY, 0, 0)) + if (FRAME_TERMCAP_P (f) + || (FRAME_W32_P (f) + /* If PostMessage fails, the message queue is full. + If that happens, the last thing they will worry + about is file notifications. So we effectively + discard the notification in that case. */ + && PostMessage (FRAME_W32_WINDOW (f), + WM_EMACS_FILENOTIFY, 0, 0))) notification_buffer_in_use = 1; done = 1; } diff --git a/src/w32term.c b/src/w32term.c index 806b82297f1..e1a2fbbf824 100644 --- a/src/w32term.c +++ b/src/w32term.c @@ -3218,7 +3218,7 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f) /* File event notifications (see w32notify.c). */ -static Lisp_Object +Lisp_Object lispy_file_action (DWORD action) { static char unknown_fmt[] = "unknown-action(%d)"; diff --git a/src/w32term.h b/src/w32term.h index 6e4f8594d67..6540d0f4d3d 100644 --- a/src/w32term.h +++ b/src/w32term.h @@ -687,6 +687,7 @@ extern BYTE file_notifications[16384]; extern DWORD notifications_size; extern HANDLE notifications_desc; extern Lisp_Object get_watch_object (Lisp_Object); +extern Lisp_Object lispy_file_action (DWORD); /* Keypad command key support. W32 doesn't have virtual keys defined for the function keys on the keypad (they are mapped to the standard