Commit 477f1e50 authored by Eli Zaretskii's avatar Eli Zaretskii

Initial version of the w32notify code.

Adding and removing a watch seems to work: a new thread is launched
when a watch is added and exits when the watch is removed.
But there are no notifications, so it seems.  At least, the Lisp
callback function passed to w32notify-add-watch is not called.
parent d5acb99a
......@@ -126,7 +126,7 @@ obj = dosfns.o msdos.o \
fontset.o menu.o \
w32.o w32console.o w32fns.o w32heap.o w32inevt.o \
w32menu.o w32proc.o w32reg.o w32select.o w32term.o w32xfns.o \
font.o w32font.o w32uniscribe.o \
font.o w32font.o w32uniscribe.o w32notify.o \
dispnew.o frame.o scroll.o xdisp.o window.o bidi.o \
charset.o coding.o category.o ccl.o character.o chartab.o \
cm.o term.o terminal.o xfaces.o \
......
......@@ -1167,6 +1167,17 @@ The return value has the form (WIDTH . HEIGHT). POSITION should
be a list of the form returned by `event-start' and `event-end'."
(nth 9 position))
(defun w32notify-handle-event (event)
"Handle file system monitoring event.
If EVENT is a file-notification event, then its callback is called.
Otherwise, a `filewatch-error' is signaled."
(interactive "e")
(if (and (eq (car event) 'file-notify)
(= (length event) 3))
(funcall (nth 2 event) (nth 1 event))
(signal 'filewatch-error (cons "Not a valid file-notify event" event))))
;;;; Obsolescent names for functions.
......
......@@ -376,7 +376,7 @@ struct gcpro *gcprolist;
/* Addresses of staticpro'd variables. Initialize it to a nonzero
value; otherwise some compilers put it into BSS. */
#define NSTATICS 0x650
#define NSTATICS 0x660
static Lisp_Object *staticvec[NSTATICS] = {&Vpurify_flag};
/* Index of next unused slot in staticvec. */
......
......@@ -1417,6 +1417,7 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
#ifdef WINDOWSNT
syms_of_ntterm ();
syms_of_w32notify ();
#endif /* WINDOWSNT */
syms_of_profiler ();
......
......@@ -314,7 +314,7 @@ static Lisp_Object Qmouse_fixup_help_message;
static Lisp_Object Qfunction_key;
Lisp_Object Qmouse_click;
#if defined (WINDOWSNT)
Lisp_Object Qlanguage_change;
Lisp_Object Qlanguage_change, Qfile_notify;
#endif
static Lisp_Object Qdrag_n_drop;
static Lisp_Object Qsave_session;
......@@ -3957,6 +3957,16 @@ kbd_buffer_get_event (KBOARD **kbp,
make_number (event->modifiers)));
kbd_fetch_ptr = event + 1;
}
else if (event->kind == FILE_NOTIFY_EVENT)
{
/* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
obj = Fcons (Qfile_notify,
list2 (list3 (event->code,
XCAR (event->arg),
CAR_SAFE (XCDR (event->arg))),
event->frame_or_window));
kbd_fetch_ptr = event + 1;
}
#endif
else if (event->kind == SAVE_SESSION_EVENT)
{
......@@ -11396,6 +11406,7 @@ syms_of_keyboard (void)
#if defined (WINDOWSNT)
DEFSYM (Qlanguage_change, "language-change");
DEFSYM (Qfile_notify, "file-notify");
#endif
#ifdef HAVE_DBUS
......@@ -12167,6 +12178,8 @@ keys_of_keyboard (void)
#if defined (WINDOWSNT)
initial_define_lispy_key (Vspecial_event_map, "language-change",
"ignore");
initial_define_lispy_key (Vspecial_event_map, "file-notify",
"w32notify-handlde-event");
#endif
}
......
......@@ -3497,6 +3497,11 @@ extern void syms_of_fontset (void);
extern Lisp_Object Qfont_param;
#endif
#ifdef WINDOWSNT
/* Defined on w32notify.c. */
extern void syms_of_w32notify (void);
#endif
/* Defined in xfaces.c. */
extern Lisp_Object Qdefault, Qtool_bar, Qfringe;
extern Lisp_Object Qheader_line, Qscroll_bar, Qcursor;
......
......@@ -134,6 +134,7 @@ OBJ2 = $(BLD)/sysdep.$(O) \
$(BLD)/w32menu.$(O) \
$(BLD)/w32reg.$(O) \
$(BLD)/w32font.$(O) \
$(BLD)/w32notify.$(O) \
$(BLD)/w32uniscribe.$(O)
LIBS = $(TLIB0) \
......@@ -209,7 +210,7 @@ GLOBAL_SOURCES = dosfns.c msdos.c \
fontset.c menu.c dbusbind.c \
w32.c w32console.c w32fns.c w32heap.c w32inevt.c \
w32menu.c w32proc.c w32reg.c w32select.c w32term.c w32xfns.c \
font.c w32font.c w32uniscribe.c \
font.c w32font.c w32uniscribe.c w32notify.c \
dispnew.c frame.c scroll.c xdisp.c window.c bidi.c \
charset.c coding.c category.c ccl.c character.c chartab.c \
cm.c term.c terminal.c xfaces.c \
......@@ -1673,6 +1674,17 @@ $(BLD)/w32uniscribe.$(O) : \
$(W32FONT_H) \
$(W32TERM_H)
$(BLD)/w32notify.$(O) : \
$(SRC)/w32notify.c \
$(SRC)/w32heap.h \
$(CODING_H) \
$(CONFIG_H) \
$(FRAME_H) \
$(KEYBOARD_H) \
$(LISP_H) \
$(TERMHOOKS_H) \
$(W32TERM_H)
# Each object file depends on stamp_BLD, because in parallel builds we must
# make sure $(BLD) exists before starting compilations.
#
......
......@@ -201,6 +201,7 @@ enum event_kind
On X, the window manager seems to grab the keys it wants
first, so this is not a problem there. */
, MULTIMEDIA_KEY_EVENT
, FILE_NOTIFY_EVENT
#endif
#ifdef HAVE_NS
......
......@@ -235,6 +235,8 @@ static void x_check_font (struct frame *, struct font *);
#endif
static Lisp_Object Qvendor_specific_keysyms;
static Lisp_Object Qadded, Qremoved, Qmodified;
static Lisp_Object Qrenamed_from, Qrenamed_to;
/***********************************************************************
......@@ -3202,6 +3204,119 @@ construct_drag_n_drop (struct input_event *result, W32Msg *msg, struct frame *f)
return Qnil;
}
static Lisp_Object
lispy_file_action (DWORD action)
{
static char unknown_fmt[] = "unknown-action(%d)";
Lisp_Object retval;
switch (action)
{
case FILE_ACTION_ADDED:
retval = Qadded;
break;
case FILE_ACTION_REMOVED:
retval = Qremoved;
break;
case FILE_ACTION_MODIFIED:
retval = Qmodified;
break;
case FILE_ACTION_RENAMED_OLD_NAME:
retval = Qrenamed_from;
break;
case FILE_ACTION_RENAMED_NEW_NAME:
retval = Qrenamed_to;
break;
default:
{
char buf[sizeof(unknown_fmt) - 1 + INT_STRLEN_BOUND (DWORD)];
sprintf (buf, unknown_fmt, action);
retval = intern (buf);
}
break;
}
return retval;
}
/* Put file notifications into the Emacs input event queue. This
function runs when the WM_EMACS_FILENOTIFY message arrives from a
watcher thread. */
static void
queue_notifications (struct input_event *event, W32Msg *msg, struct frame *f,
int *evcount)
{
BYTE *p = file_notifications;
FILE_NOTIFY_INFORMATION *fni = (PFILE_NOTIFY_INFORMATION)p;
const DWORD min_size
= offsetof (FILE_NOTIFY_INFORMATION, FileName) + sizeof(wchar_t);
Lisp_Object frame;
/* 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;
}
XSETFRAME (frame, f);
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)
{
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))
{
event->kind = FILE_NOTIFY_EVENT;
event->code = (ptrdiff_t)notifications_desc;
event->timestamp = msg->msg.time;
event->modifiers = 0;
event->frame_or_window = XCDR (obj);
event->arg = Fcons (action, fname);
kbd_buffer_store_event (event);
(*evcount)++;
}
if (!fni->NextEntryOffset)
break;
p += fni->NextEntryOffset;
fni = (PFILE_NOTIFY_INFORMATION)p;
info_size -= fni->NextEntryOffset;
}
}
notification_buffer_in_use = 0;
}
else
DebPrint (("We were promised notifications, but in-use flag is zero!\n"));
leave_crit ();
/* We've stuffed all the events ourselves, so w32_read_socket shouldn't. */
event->kind = NO_EVENT;
}
/* Function to report a mouse movement to the mainstream Emacs code.
The input handler calls this.
......@@ -4829,6 +4944,12 @@ w32_read_socket (struct terminal *terminal,
check_visibility = 1;
break;
case WM_EMACS_FILENOTIFY:
f = x_window_to_frame (dpyinfo, msg.msg.hwnd);
if (f)
queue_notifications (&inev, &msg, f, &count);
break;
default:
/* Check for messages registered at runtime. */
if (msg.msg.message == msh_mousewheel)
......@@ -6494,6 +6615,12 @@ syms_of_w32term (void)
DEFSYM (Qvendor_specific_keysyms, "vendor-specific-keysyms");
DEFSYM (Qadded, "added");
DEFSYM (Qremoved, "removed");
DEFSYM (Qmodified, "modified");
DEFSYM (Qrenamed_from, "renamed-from");
DEFSYM (Qrenamed_to, "renamed-to");
DEFVAR_INT ("w32-num-mouse-buttons",
w32_num_mouse_buttons,
doc: /* Number of physical mouse buttons. */);
......
......@@ -584,7 +584,8 @@ do { \
#define WM_EMACS_SETCURSOR (WM_EMACS_START + 19)
#define WM_EMACS_PAINT (WM_EMACS_START + 20)
#define WM_EMACS_BRINGTOTOP (WM_EMACS_START + 21)
#define WM_EMACS_END (WM_EMACS_START + 22)
#define WM_EMACS_FILENOTIFY (WM_EMACS_START + 22)
#define WM_EMACS_END (WM_EMACS_START + 23)
#define WND_FONTWIDTH_INDEX (0)
#define WND_LINEHEIGHT_INDEX (4)
......@@ -642,6 +643,11 @@ extern BOOL parse_button (int, int, int *, int *);
extern void w32_sys_ring_bell (struct frame *f);
extern void x_delete_display (struct w32_display_info *dpyinfo);
extern int notification_buffer_in_use;
extern BYTE file_notifications[16384];
extern DWORD notifications_size;
extern HANDLE notifications_desc;
extern Lisp_Object get_watch_object (Lisp_Object);
/* Keypad command key support. W32 doesn't have virtual keys defined
for the function keys on the keypad (they are mapped to the standard
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment