aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEli Zaretskii2012-10-10 19:11:25 +0200
committerEli Zaretskii2012-10-10 19:11:25 +0200
commit182b170f7ec712b7f89ada65095aae5bb8fe553e (patch)
tree7f3d70b6c8cfc035b0e753c016a12b69067a4866 /src
parentb97f22cdad55a0964758cef3a19ce3fa1098657d (diff)
downloademacs-182b170f7ec712b7f89ada65095aae5bb8fe553e.tar.gz
emacs-182b170f7ec712b7f89ada65095aae5bb8fe553e.zip
Support file notifications in a TTY session.
FIXME: file notifications detected only when the Emacs window has focus.
Diffstat (limited to 'src')
-rw-r--r--src/w32inevt.c68
-rw-r--r--src/w32notify.c17
-rw-r--r--src/w32term.c2
-rw-r--r--src/w32term.h1
4 files changed, 78 insertions, 10 deletions
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)
576 0, 0, 0); 576 0, 0, 0);
577} 577}
578 578
579static void
580handle_file_notifications (struct input_event *hold_quit)
581{
582 BYTE *p = file_notifications;
583 FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
584 const DWORD min_size
585 = offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
586 struct input_event inev;
587
588 /* We cannot process notification before Emacs is fully initialized,
589 since we need the UTF-16LE coding-system to be set up. */
590 if (!initialized)
591 {
592 notification_buffer_in_use = 0;
593 return;
594 }
595
596 enter_crit ();
597 if (notification_buffer_in_use)
598 {
599 DWORD info_size = notifications_size;
600
601 /* notifications_size could be zero when the buffer of
602 notifications overflowed on the OS level, or when the
603 directory being watched was itself deleted. Do nothing in
604 that case. */
605 if (info_size)
606 {
607 EVENT_INIT (inev);
608
609 while (info_size >= min_size)
610 {
611 Lisp_Object utf_16_fn
612 = make_unibyte_string ((char *)fni->FileName,
613 fni->FileNameLength);
614 /* Note: mule-conf is preloaded, so utf-16le must
615 already be defined at this point. */
616 Lisp_Object fname
617 = code_convert_string_norecord (utf_16_fn,
618 intern ("utf-16le"), 0);
619 Lisp_Object action = lispy_file_action (fni->Action);
620 Lisp_Object obj;
621
622 obj = get_watch_object (make_number (notifications_desc));
623 if (!NILP (obj) && CONSP (obj))
624 {
625 inev.kind = FILE_NOTIFY_EVENT;
626 inev.code = (ptrdiff_t)notifications_desc;
627 inev.timestamp = GetTickCount ();
628 inev.modifiers = 0;
629 inev.frame_or_window = XCDR (obj);
630 inev.arg = Fcons (action, fname);
631 kbd_buffer_store_event_hold (&inev, hold_quit);
632 }
633
634 if (!fni->NextEntryOffset)
635 break;
636 p += fni->NextEntryOffset;
637 fni = (PFILE_NOTIFY_INFORMATION)p;
638 info_size -= fni->NextEntryOffset;
639 }
640 }
641 notification_buffer_in_use = 0;
642 }
643 leave_crit ();
644}
645
579int 646int
580w32_console_read_socket (struct terminal *terminal, 647w32_console_read_socket (struct terminal *terminal,
581 struct input_event *hold_quit) 648 struct input_event *hold_quit)
@@ -587,6 +654,7 @@ w32_console_read_socket (struct terminal *terminal,
587 654
588 for (;;) 655 for (;;)
589 { 656 {
657 handle_file_notifications (hold_quit);
590 nev = fill_queue (0); 658 nev = fill_queue (0);
591 if (nev <= 0) 659 if (nev <= 0)
592 { 660 {
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)
115 int done = 0; 115 int done = 0;
116 FRAME_PTR f = SELECTED_FRAME (); 116 FRAME_PTR f = SELECTED_FRAME ();
117 117
118 /* Too bad, but PostMessage will not work in non-GUI sessions.
119 FIXME. */
120 if (!FRAME_W32_P (f))
121 return;
122 118
123 /* A single buffer is used to communicate all notifications to the 119 /* A single buffer is used to communicate all notifications to the
124 main thread. Since both the main thread and several watcher 120 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)
138 memcpy (file_notifications, info, info_size); 134 memcpy (file_notifications, info, info_size);
139 notifications_size = info_size; 135 notifications_size = info_size;
140 notifications_desc = hdir; 136 notifications_desc = hdir;
141 /* If PostMessage fails, the message queue is full. If that 137 if (FRAME_TERMCAP_P (f)
142 happens, the last thing they will worry about is file 138 || (FRAME_W32_P (f)
143 notifications. So we effectively discard the 139 /* If PostMessage fails, the message queue is full.
144 notification in that case. */ 140 If that happens, the last thing they will worry
145 if (PostMessage (FRAME_W32_WINDOW (f), WM_EMACS_FILENOTIFY, 0, 0)) 141 about is file notifications. So we effectively
142 discard the notification in that case. */
143 && PostMessage (FRAME_W32_WINDOW (f),
144 WM_EMACS_FILENOTIFY, 0, 0)))
146 notification_buffer_in_use = 1; 145 notification_buffer_in_use = 1;
147 done = 1; 146 done = 1;
148 } 147 }
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)
3218 3218
3219/* File event notifications (see w32notify.c). */ 3219/* File event notifications (see w32notify.c). */
3220 3220
3221static Lisp_Object 3221Lisp_Object
3222lispy_file_action (DWORD action) 3222lispy_file_action (DWORD action)
3223{ 3223{
3224 static char unknown_fmt[] = "unknown-action(%d)"; 3224 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];
687extern DWORD notifications_size; 687extern DWORD notifications_size;
688extern HANDLE notifications_desc; 688extern HANDLE notifications_desc;
689extern Lisp_Object get_watch_object (Lisp_Object); 689extern Lisp_Object get_watch_object (Lisp_Object);
690extern Lisp_Object lispy_file_action (DWORD);
690 691
691/* Keypad command key support. W32 doesn't have virtual keys defined 692/* Keypad command key support. W32 doesn't have virtual keys defined
692 for the function keys on the keypad (they are mapped to the standard 693 for the function keys on the keypad (they are mapped to the standard