diff options
| author | Eli Zaretskii | 2012-10-10 19:11:25 +0200 |
|---|---|---|
| committer | Eli Zaretskii | 2012-10-10 19:11:25 +0200 |
| commit | 182b170f7ec712b7f89ada65095aae5bb8fe553e (patch) | |
| tree | 7f3d70b6c8cfc035b0e753c016a12b69067a4866 /src | |
| parent | b97f22cdad55a0964758cef3a19ce3fa1098657d (diff) | |
| download | emacs-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.c | 68 | ||||
| -rw-r--r-- | src/w32notify.c | 17 | ||||
| -rw-r--r-- | src/w32term.c | 2 | ||||
| -rw-r--r-- | src/w32term.h | 1 |
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 | ||
| 579 | static void | ||
| 580 | handle_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 | |||
| 579 | int | 646 | int |
| 580 | w32_console_read_socket (struct terminal *terminal, | 647 | w32_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 | ||
| 3221 | static Lisp_Object | 3221 | Lisp_Object |
| 3222 | lispy_file_action (DWORD action) | 3222 | lispy_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]; | |||
| 687 | extern DWORD notifications_size; | 687 | extern DWORD notifications_size; |
| 688 | extern HANDLE notifications_desc; | 688 | extern HANDLE notifications_desc; |
| 689 | extern Lisp_Object get_watch_object (Lisp_Object); | 689 | extern Lisp_Object get_watch_object (Lisp_Object); |
| 690 | extern 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 |