* configure.ac (file-notification): New option, replaces inotify option.
(HAVE_W32): Remove w32notify.o. (with_file_notification): Add checks for glib and w32. Adapt check for inotify. (Summary): Add entry for file notification. * autogen/config.in: Add entries for HAVE_GFILENOTIFY, HAVE_W32NOTIFY and USE_FILE_NOTIFY. * lisp/autorevert.el (auto-revert-notify-enabled) (auto-revert-notify-rm-watch, auto-revert-notify-add-watch) (auto-revert-notify-event-p, auto-revert-notify-event-file-name) (auto-revert-notify-handler): Handle also gfilenotify. * lisp/subr.el: (file-notify-handle-event): New defun. Replacing ... (inotify-event-p, inotify-handle-event, w32notify-handle-event): Removed. * src/Makefile.in (NOTIFY_OBJ): New variable. (base_obj): Replace inotify.o by $(NOTIFY_OBJ). * src/emacs.c (main): Use HAVE_W32NOTIFY to wrap respective code. Call syms_of_gfilenotify. * src/gfilenotify.c: New file. * src/keyboard.c (Qfile_notify): New variable. Replaces Qfile_inotify and Qfile_w32notify. (top): Wrap respective code by HAVE_GFILENOTIFY, HAVE_INOTIFY, HAVE_W32NOTIFY and USE_FILE_NOTIFY. * src/lisp.h: Declare syms_of_gfilenotify. * src/termhooks.h (e): Wrap enum by USE_FILE_NOTIFY.
This commit is contained in:
parent
2041ae1fa7
commit
c9628c79bb
13 changed files with 468 additions and 88 deletions
11
ChangeLog
11
ChangeLog
|
@ -1,3 +1,14 @@
|
|||
2013-06-03 Michael Albinus <michael.albinus@gmx.de>
|
||||
|
||||
* configure.ac (file-notification): New option, replaces inotify option.
|
||||
(HAVE_W32): Remove w32notify.o.
|
||||
(with_file_notification): Add checks for glib and w32. Adapt check
|
||||
for inotify.
|
||||
(Summary): Add entry for file notification.
|
||||
|
||||
* autogen/config.in: Add entries for HAVE_GFILENOTIFY,
|
||||
HAVE_W32NOTIFY and USE_FILE_NOTIFY.
|
||||
|
||||
2013-06-02 Juanma Barranquero <lekktu@gmail.com>
|
||||
|
||||
* .bzrignore: Ignore dirs libexec/, share/ and var/.
|
||||
|
|
|
@ -132,7 +132,7 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
#if !defined _FORTIFY_SOURCE && defined __OPTIMIZE__ && __OPTIMIZE__
|
||||
# define _FORTIFY_SOURCE 2
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/* Define to 1 if futimesat mishandles a NULL file name. */
|
||||
#undef FUTIMESAT_NULL_BUG
|
||||
|
@ -547,6 +547,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
/* Define to 1 if you have the `get_current_dir_name' function. */
|
||||
#undef HAVE_GET_CURRENT_DIR_NAME
|
||||
|
||||
/* Define to 1 to use glib's notify. */
|
||||
#undef HAVE_GFILENOTIFY
|
||||
|
||||
/* Define to 1 if you have a gif (or ungif) library. */
|
||||
#undef HAVE_GIF
|
||||
|
||||
|
@ -1140,6 +1143,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
/* Define to 1 if you have the <vfork.h> header file. */
|
||||
#undef HAVE_VFORK_H
|
||||
|
||||
/* Define to 1 to use w32notify. */
|
||||
#undef HAVE_W32NOTIFY
|
||||
|
||||
/* Define to 1 if you have the <wchar.h> header file. */
|
||||
#undef HAVE_WCHAR_H
|
||||
|
||||
|
@ -1496,6 +1502,9 @@ along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
|||
/* Define to nonzero if you want access control list support. */
|
||||
#undef USE_ACL
|
||||
|
||||
/* Define to 1 if if using file notifications. */
|
||||
#undef USE_FILE_NOTIFY
|
||||
|
||||
/* Define to 1 if using GTK. */
|
||||
#undef USE_GTK
|
||||
|
||||
|
@ -1836,4 +1845,3 @@ Local Variables:
|
|||
mode: c
|
||||
End:
|
||||
*/
|
||||
|
||||
|
|
74
configure.ac
74
configure.ac
|
@ -200,7 +200,23 @@ OPTION_DEFAULT_ON([gconf],[don't compile with GConf support])
|
|||
OPTION_DEFAULT_ON([gsettings],[don't compile with GSettings support])
|
||||
OPTION_DEFAULT_ON([selinux],[don't compile with SELinux support])
|
||||
OPTION_DEFAULT_ON([gnutls],[don't use -lgnutls for SSL/TLS support])
|
||||
OPTION_DEFAULT_ON([inotify],[don't compile with inotify (file-watch) support])
|
||||
|
||||
AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
|
||||
[use a file notification library (LIB one of: yes, gfile, inotify, w32, no)])],
|
||||
[ case "${withval}" in
|
||||
y | ye | yes ) val=yes ;;
|
||||
n | no ) val=no ;;
|
||||
g | gf | gfi | gfil | gfile ) val=gfile ;;
|
||||
i | in | ino | inot | inoti | inotif | inotify ) val=inotify ;;
|
||||
w | w3 | w32 ) val=w32 ;;
|
||||
* ) AC_MSG_ERROR([`--with-file-notification=$withval' is invalid;
|
||||
this option's value should be `yes', `no', `gfile', `inotify' or `w32'.
|
||||
`yes' is a synonym for `w32' on MS-Windows, and for `gfile' otherwise.])
|
||||
;;
|
||||
esac
|
||||
with_file_notification=$val
|
||||
],
|
||||
[with_file_notification=yes])
|
||||
|
||||
## For the times when you want to build Emacs but don't have
|
||||
## a suitable makeinfo, and can live without the manuals.
|
||||
|
@ -1668,7 +1684,6 @@ if test "${HAVE_W32}" = "yes"; then
|
|||
W32_RES_LINK="-Wl,emacs.res"
|
||||
else
|
||||
W32_OBJ="$W32_OBJ w32.o w32console.o w32heap.o w32inevt.o w32proc.o"
|
||||
W32_OBJ="$W32_OBJ w32notify.o"
|
||||
W32_LIBS="$W32_LIBS -lwinmm -lgdi32 -lcomdlg32"
|
||||
W32_LIBS="$W32_LIBS -lmpr -lwinspool -lole32 -lcomctl32 -lusp10"
|
||||
W32_RES_LINK="\$(EMACSRES)"
|
||||
|
@ -2294,16 +2309,56 @@ fi
|
|||
AC_SUBST(LIBGNUTLS_LIBS)
|
||||
AC_SUBST(LIBGNUTLS_CFLAGS)
|
||||
|
||||
dnl inotify is only available on GNU/Linux.
|
||||
if test "${with_inotify}" = "yes"; then
|
||||
AC_CHECK_HEADERS(sys/inotify.h)
|
||||
if test "$ac_cv_header_sys_inotify_h" = yes ; then
|
||||
AC_CHECK_FUNC(inotify_init1)
|
||||
NOTIFY_OBJ=
|
||||
NOTIFY_SUMMARY=no
|
||||
|
||||
dnl Set defaults of $with_file_notification.
|
||||
if test "${with_file_notification}" = "yes"; then
|
||||
if test "${opsys}" = "mingw32"; then
|
||||
with_file_notification=w32
|
||||
else
|
||||
with_file_notification=gfile
|
||||
fi
|
||||
fi
|
||||
if test "$ac_cv_func_inotify_init1" = yes; then
|
||||
AC_DEFINE(HAVE_INOTIFY, 1, [Define to 1 to use inotify.])
|
||||
|
||||
dnl g_file_monitor exists since glib 2.18. It has been tested under
|
||||
dnl GNU/Linux only. We take precedence over inotify, but this makes
|
||||
dnl only sense when glib has been compiled with inotify support. How
|
||||
dnl to check?
|
||||
if test "${with_file_notification}" = "gfile"; then
|
||||
PKG_CHECK_MODULES(GFILENOTIFY, gio-2.0 >= 2.18, HAVE_GFILENOTIFY=yes, HAVE_GFILENOTIFY=no)
|
||||
if test "$HAVE_GFILENOTIFY" = "yes"; then
|
||||
AC_DEFINE(HAVE_GFILENOTIFY, 1, [Define to 1 if using GFile.])
|
||||
LIBS="$LIBS $GFILENOTIFY_LIBS"
|
||||
NOTIFY_OBJ=gfilenotify.o
|
||||
NOTIFY_SUMMARY="yes -lgio (gfile)"
|
||||
fi
|
||||
fi
|
||||
dnl inotify is only available on GNU/Linux.
|
||||
if test "${with_file_notification}" = "inotify"; then
|
||||
AC_CHECK_HEADER(sys/inotify.h)
|
||||
if test "$ac_cv_header_sys_inotify_h" = yes ; then
|
||||
AC_CHECK_FUNC(inotify_init1)
|
||||
if test "$ac_cv_func_inotify_init1" = yes; then
|
||||
AC_DEFINE(HAVE_INOTIFY, 1, [Define to 1 to use inotify.])
|
||||
NOTIFY_OBJ=inotify.o
|
||||
NOTIFY_SUMMARY="yes -lglibc (inotify)"
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
dnl MS Windows native file monitor is available for mingw32 only.
|
||||
if test "${with_file_notification}" = "w32"; then
|
||||
AC_CHECK_HEADER(windows.h)
|
||||
if test "$ac_cv_header_windows_h" = yes ; then
|
||||
AC_DEFINE(HAVE_W32NOTIFY, 1, [Define to 1 to use w32notify.])
|
||||
NOTIFY_OBJ=w32notify.o
|
||||
NOTIFY_SUMMARY="yes (w32)"
|
||||
fi
|
||||
fi
|
||||
if test -n "$NOTIFY_OBJ"; then
|
||||
AC_DEFINE(USE_FILE_NOTIFY, 1, [Define to 1 if using file notifications.])
|
||||
fi
|
||||
AC_SUBST(NOTIFY_OBJ)
|
||||
|
||||
dnl Do not put whitespace before the #include statements below.
|
||||
dnl Older compilers (eg sunos4 cc) choke on it.
|
||||
|
@ -4682,6 +4737,7 @@ echo " Does Emacs use -lgpm? ${HAVE_GPM}"
|
|||
echo " Does Emacs use -ldbus? ${HAVE_DBUS}"
|
||||
echo " Does Emacs use -lgconf? ${HAVE_GCONF}"
|
||||
echo " Does Emacs use GSettings? ${HAVE_GSETTINGS}"
|
||||
echo " Does Emacs use a file notification library? ${NOTIFY_SUMMARY}"
|
||||
echo " Does Emacs use -lselinux? ${HAVE_LIBSELINUX}"
|
||||
echo " Does Emacs use -lgnutls? ${HAVE_GNUTLS}"
|
||||
echo " Does Emacs use -lxml2? ${HAVE_LIBXML2}"
|
||||
|
|
|
@ -1,3 +1,14 @@
|
|||
2013-06-03 Michael Albinus <michael.albinus@gmx.de>
|
||||
|
||||
* autorevert.el (auto-revert-notify-enabled)
|
||||
(auto-revert-notify-rm-watch, auto-revert-notify-add-watch)
|
||||
(auto-revert-notify-event-p, auto-revert-notify-event-file-name)
|
||||
(auto-revert-notify-handler): Handle also gfilenotify.
|
||||
|
||||
* subr.el: (file-notify-handle-event): New defun. Replacing ...
|
||||
(inotify-event-p, inotify-handle-event, w32notify-handle-event):
|
||||
Removed.
|
||||
|
||||
2013-06-03 Juri Linkov <juri@jurta.org>
|
||||
|
||||
* bindings.el (search-map): Bind `highlight-symbol-at-point' to
|
||||
|
|
|
@ -271,7 +271,7 @@ This variable becomes buffer local when set in any fashion.")
|
|||
:version "24.4")
|
||||
|
||||
(defconst auto-revert-notify-enabled
|
||||
(or (featurep 'inotify) (featurep 'w32notify))
|
||||
(or (featurep 'gfilenotify) (featurep 'inotify) (featurep 'w32notify))
|
||||
"Non-nil when Emacs has been compiled with file notification support.")
|
||||
|
||||
(defcustom auto-revert-use-notify auto-revert-notify-enabled
|
||||
|
@ -502,9 +502,12 @@ will use an up-to-date value of `auto-revert-interval'"
|
|||
(puthash key value auto-revert-notify-watch-descriptor-hash-list)
|
||||
(remhash key auto-revert-notify-watch-descriptor-hash-list)
|
||||
(ignore-errors
|
||||
(funcall (if (fboundp 'inotify-rm-watch)
|
||||
'inotify-rm-watch 'w32notify-rm-watch)
|
||||
auto-revert-notify-watch-descriptor)))))
|
||||
(funcall
|
||||
(cond
|
||||
((fboundp 'gfile-rm-watch) 'gfile-rm-watch)
|
||||
((fboundp 'inotify-rm-watch) 'inotify-rm-watch)
|
||||
((fboundp 'w32notify-rm-watch) 'w32notify-rm-watch))
|
||||
auto-revert-notify-watch-descriptor)))))
|
||||
auto-revert-notify-watch-descriptor-hash-list)
|
||||
(remove-hook 'kill-buffer-hook 'auto-revert-notify-rm-watch))
|
||||
(setq auto-revert-notify-watch-descriptor nil
|
||||
|
@ -519,12 +522,18 @@ will use an up-to-date value of `auto-revert-interval'"
|
|||
|
||||
(when (and buffer-file-name auto-revert-use-notify
|
||||
(not auto-revert-notify-watch-descriptor))
|
||||
(let ((func (if (fboundp 'inotify-add-watch)
|
||||
'inotify-add-watch 'w32notify-add-watch))
|
||||
;; `attrib' is needed for file modification time.
|
||||
(aspect (if (fboundp 'inotify-add-watch)
|
||||
'(attrib create modify moved-to) '(size last-write-time)))
|
||||
(file (if (fboundp 'inotify-add-watch)
|
||||
(let ((func
|
||||
(cond
|
||||
((fboundp 'gfile-add-watch) 'gfile-add-watch)
|
||||
((fboundp 'inotify-add-watch) 'inotify-add-watch)
|
||||
((fboundp 'w32notify-add-watch) 'w32notify-add-watch)))
|
||||
(aspect
|
||||
(cond
|
||||
((fboundp 'gfile-add-watch) '(watch-mounts))
|
||||
;; `attrib' is needed for file modification time.
|
||||
((fboundp 'inotify-add-watch) '(attrib create modify moved-to))
|
||||
((fboundp 'w32notify-add-watch) '(size last-write-time))))
|
||||
(file (if (or (fboundp 'gfile-add-watch) (fboundp 'inotify-add-watch))
|
||||
(directory-file-name (expand-file-name default-directory))
|
||||
(buffer-file-name))))
|
||||
(setq auto-revert-notify-watch-descriptor
|
||||
|
@ -545,10 +554,13 @@ will use an up-to-date value of `auto-revert-interval'"
|
|||
|
||||
(defun auto-revert-notify-event-p (event)
|
||||
"Check that event is a file notification event."
|
||||
(cond ((featurep 'inotify)
|
||||
(and (listp event) (= (length event) 4)))
|
||||
((featurep 'w32notify)
|
||||
(and (listp event) (= (length event) 3) (stringp (nth 2 event))))))
|
||||
(and (listp event)
|
||||
(cond ((featurep 'gfilenotify)
|
||||
(and (>= (length event) 3) (stringp (nth 2 event))))
|
||||
((featurep 'inotify)
|
||||
(= (length event) 4))
|
||||
((featurep 'w32notify)
|
||||
(and (= (length event) 3) (stringp (nth 2 event)))))))
|
||||
|
||||
(defun auto-revert-notify-event-descriptor (event)
|
||||
"Return watch descriptor of file notification event, or nil."
|
||||
|
@ -561,7 +573,8 @@ will use an up-to-date value of `auto-revert-interval'"
|
|||
(defun auto-revert-notify-event-file-name (event)
|
||||
"Return file name of file notification event, or nil."
|
||||
(and (auto-revert-notify-event-p event)
|
||||
(cond ((featurep 'inotify) (nth 3 event))
|
||||
(cond ((featurep 'gfilenotify) (nth 2 event))
|
||||
((featurep 'inotify) (nth 3 event))
|
||||
((featurep 'w32notify) (nth 2 event)))))
|
||||
|
||||
(defun auto-revert-notify-handler (event)
|
||||
|
@ -576,12 +589,18 @@ will use an up-to-date value of `auto-revert-interval'"
|
|||
;; Check, that event is meant for us.
|
||||
;; TODO: Filter events which stop watching, like `move' or `removed'.
|
||||
(cl-assert descriptor)
|
||||
(when (featurep 'inotify)
|
||||
(cond
|
||||
((featurep 'gfilenotify)
|
||||
(cl-assert (or (eq 'attribute-changed action)
|
||||
(eq 'changed action)
|
||||
(eq 'created action)
|
||||
(eq 'deleted action))))
|
||||
((featurep 'inotify)
|
||||
(cl-assert (or (memq 'attrib action)
|
||||
(memq 'create action)
|
||||
(memq 'modify action)
|
||||
(memq 'moved-to action))))
|
||||
(when (featurep 'w32notify) (cl-assert (eq 'modified action)))
|
||||
((featurep 'w32notify) (cl-assert (eq 'modified action))))
|
||||
;; Since we watch a directory, a file name must be returned.
|
||||
(cl-assert (stringp file))
|
||||
(dolist (buffer buffers)
|
||||
|
|
28
lisp/subr.el
28
lisp/subr.el
|
@ -4440,32 +4440,16 @@ convenience wrapper around `make-progress-reporter' and friends.
|
|||
|
||||
;;;; Support for watching filesystem events.
|
||||
|
||||
(defun inotify-event-p (event)
|
||||
"Check if EVENT is an inotify event."
|
||||
(and (listp event)
|
||||
(>= (length event) 3)
|
||||
(eq (car event) 'file-inotify)))
|
||||
|
||||
;;;###autoload
|
||||
(defun inotify-handle-event (event)
|
||||
"Handle inotify file system monitoring event.
|
||||
If EVENT is an inotify filewatch event, call its callback.
|
||||
(defun file-notify-handle-event (event)
|
||||
"Handle file system monitoring event.
|
||||
If EVENT is a filewatch event, call its callback.
|
||||
Otherwise, signal a `filewatch-error'."
|
||||
(interactive "e")
|
||||
(unless (inotify-event-p event)
|
||||
(signal 'filewatch-error (cons "Not a valid inotify event" event)))
|
||||
(funcall (nth 2 event) (nth 1 event)))
|
||||
|
||||
(defun w32notify-handle-event (event)
|
||||
"Handle MS-Windows file system monitoring event.
|
||||
If EVENT is an MS-Windows filewatch event, call its callback.
|
||||
Otherwise, signal a `filewatch-error'."
|
||||
(interactive "e")
|
||||
(if (and (eq (car event) 'file-w32notify)
|
||||
(= (length event) 3))
|
||||
(if (and (eq (car event) 'file-notify)
|
||||
(>= (length event) 3))
|
||||
(funcall (nth 2 event) (nth 1 event))
|
||||
(signal 'filewatch-error
|
||||
(cons "Not a valid MS-Windows file-notify event" event))))
|
||||
(cons "Not a valid file-notify event" event))))
|
||||
|
||||
|
||||
;;;; Comparing version strings.
|
||||
|
|
|
@ -1,3 +1,22 @@
|
|||
2013-06-03 Michael Albinus <michael.albinus@gmx.de>
|
||||
|
||||
* Makefile.in (NOTIFY_OBJ): New variable.
|
||||
(base_obj): Replace inotify.o by $(NOTIFY_OBJ).
|
||||
|
||||
* emacs.c (main): Use HAVE_W32NOTIFY to wrap respective code.
|
||||
Call syms_of_gfilenotify.
|
||||
|
||||
* gfilenotify.c: New file.
|
||||
|
||||
* keyboard.c (Qfile_notify): New variable. Replaces Qfile_inotify
|
||||
and Qfile_w32notify.
|
||||
(top): Wrap respective code by HAVE_GFILENOTIFY, HAVE_INOTIFY,
|
||||
HAVE_W32NOTIFY and USE_FILE_NOTIFY.
|
||||
|
||||
* lisp.h: Declare syms_of_gfilenotify.
|
||||
|
||||
* termhooks.h (e): Wrap enum by USE_FILE_NOTIFY.
|
||||
|
||||
2013-06-03 Stefan Monnier <monnier@iro.umontreal.ca>
|
||||
|
||||
Merge the specpdl and backtrace stacks. Make the structure of the
|
||||
|
|
|
@ -156,6 +156,11 @@ SETTINGS_LIBS = @SETTINGS_LIBS@
|
|||
## gtkutil.o if USE_GTK, else empty.
|
||||
GTK_OBJ=@GTK_OBJ@
|
||||
|
||||
## gfilenotify.o if HAVE_GFILENOTIFY.
|
||||
## inotify.o if HAVE_INOTIFY.
|
||||
## w32notify.o if HAVE_W32NOTIFY.
|
||||
NOTIFY_OBJ = @NOTIFY_OBJ@
|
||||
|
||||
## -ltermcap, or -lncurses, or -lcurses, or "".
|
||||
LIBS_TERMCAP=@LIBS_TERMCAP@
|
||||
## terminfo.o if TERMINFO, else tparam.o.
|
||||
|
@ -363,7 +368,7 @@ base_obj = dispnew.o frame.o scroll.o xdisp.o menu.o $(XMENU_OBJ) window.o \
|
|||
syntax.o $(UNEXEC_OBJ) bytecode.o \
|
||||
process.o gnutls.o callproc.o \
|
||||
region-cache.o sound.o atimer.o \
|
||||
doprnt.o intervals.o textprop.o composite.o xml.o inotify.o \
|
||||
doprnt.o intervals.o textprop.o composite.o xml.o $(NOTIFY_OBJ) \
|
||||
profiler.o \
|
||||
$(MSDOS_OBJ) $(MSDOS_X_OBJ) $(NS_OBJ) $(CYGWIN_OBJ) $(FONT_OBJ) \
|
||||
$(W32_OBJ) $(WINDOW_SYSTEM_OBJ)
|
||||
|
|
|
@ -1252,7 +1252,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
|
||||
#ifdef WINDOWSNT
|
||||
globals_of_w32 ();
|
||||
#ifdef HAVE_W32NOTIFY
|
||||
globals_of_w32notify ();
|
||||
#endif
|
||||
/* Initialize environment from registry settings. */
|
||||
init_environment (argv);
|
||||
init_ntproc (dumping); /* must precede init_editfns. */
|
||||
|
@ -1409,6 +1411,10 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
syms_of_gnutls ();
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GFILENOTIFY
|
||||
syms_of_gfilenotify ();
|
||||
#endif /* HAVE_GFILENOTIFY */
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
syms_of_inotify ();
|
||||
#endif /* HAVE_INOTIFY */
|
||||
|
@ -1419,7 +1425,9 @@ Using an Emacs configured with --with-x-toolkit=lucid does not have this problem
|
|||
|
||||
#ifdef WINDOWSNT
|
||||
syms_of_ntterm ();
|
||||
#ifdef HAVE_W32NOTIFY
|
||||
syms_of_w32notify ();
|
||||
#endif /* HAVE_W32NOTIFY */
|
||||
#endif /* WINDOWSNT */
|
||||
|
||||
syms_of_profiler ();
|
||||
|
|
266
src/gfilenotify.c
Normal file
266
src/gfilenotify.c
Normal file
|
@ -0,0 +1,266 @@
|
|||
/* Filesystem notifications support with glib API.
|
||||
Copyright (C) 2013 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU Emacs.
|
||||
|
||||
GNU Emacs is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GNU Emacs is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#ifdef HAVE_GFILENOTIFY
|
||||
#include <stdio.h>
|
||||
#include <gio/gio.h>
|
||||
#include "lisp.h"
|
||||
#include "coding.h"
|
||||
#include "frame.h"
|
||||
#include "termhooks.h"
|
||||
#include "keyboard.h"
|
||||
#include "process.h"
|
||||
|
||||
|
||||
/* Subroutines. */
|
||||
static Lisp_Object Qgfile_add_watch;
|
||||
static Lisp_Object Qgfile_rm_watch;
|
||||
|
||||
/* Filter objects. */
|
||||
static Lisp_Object Qwatch_mounts; /* G_FILE_MONITOR_WATCH_MOUNTS */
|
||||
static Lisp_Object Qsend_moved; /* G_FILE_MONITOR_SEND_MOVED */
|
||||
|
||||
/* Event types. */
|
||||
static Lisp_Object Qchanged; /* G_FILE_MONITOR_EVENT_CHANGED */
|
||||
static Lisp_Object Qchanges_done_hint; /* G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT */
|
||||
static Lisp_Object Qdeleted; /* G_FILE_MONITOR_EVENT_DELETED */
|
||||
static Lisp_Object Qcreated; /* G_FILE_MONITOR_EVENT_CREATED */
|
||||
static Lisp_Object Qattribute_changed; /* G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED */
|
||||
static Lisp_Object Qpre_unmount; /* G_FILE_MONITOR_EVENT_PRE_UNMOUNT */
|
||||
static Lisp_Object Qunmounted; /* G_FILE_MONITOR_EVENT_UNMOUNTED */
|
||||
static Lisp_Object Qmoved; /* G_FILE_MONITOR_EVENT_MOVED */
|
||||
|
||||
static Lisp_Object watch_list;
|
||||
|
||||
/* This is the callback function for arriving signals from
|
||||
g_file_monitor. It shall create a Lisp event, and put it into
|
||||
Emacs input queue. */
|
||||
static gboolean
|
||||
dir_monitor_callback (GFileMonitor* monitor,
|
||||
GFile* file,
|
||||
GFile* other_file,
|
||||
GFileMonitorEvent event_type,
|
||||
gpointer user_data)
|
||||
{
|
||||
Lisp_Object symbol, watch_object;
|
||||
char *name = g_file_get_parse_name (file);
|
||||
char *oname = other_file ? g_file_get_parse_name (other_file) : NULL;
|
||||
|
||||
/* Determine event symbol. */
|
||||
switch (event_type)
|
||||
{
|
||||
case G_FILE_MONITOR_EVENT_CHANGED:
|
||||
symbol = Qchanged;
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_CHANGES_DONE_HINT:
|
||||
symbol = Qchanges_done_hint;
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_DELETED:
|
||||
symbol = Qdeleted;
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_CREATED:
|
||||
symbol = Qcreated;
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_ATTRIBUTE_CHANGED:
|
||||
symbol = Qattribute_changed;
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_PRE_UNMOUNT:
|
||||
symbol = Qpre_unmount;
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_UNMOUNTED:
|
||||
symbol = Qunmounted;
|
||||
break;
|
||||
case G_FILE_MONITOR_EVENT_MOVED:
|
||||
symbol = Qmoved;
|
||||
break;
|
||||
default:
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* Determine callback function. */
|
||||
watch_object = Fassoc (XIL ((EMACS_INT) monitor), watch_list);
|
||||
|
||||
if (FUNCTIONP (CDR_SAFE (watch_object)))
|
||||
{
|
||||
/* Construct an event. */
|
||||
struct input_event event;
|
||||
EVENT_INIT (event);
|
||||
event.kind = FILE_NOTIFY_EVENT;
|
||||
event.frame_or_window = Qnil;
|
||||
event.arg = oname
|
||||
? list2 (list4 (XIL ((EMACS_INT) monitor), symbol,
|
||||
build_string (name), build_string (oname)),
|
||||
CDR_SAFE (watch_object))
|
||||
: list2 (list3 (XIL ((EMACS_INT) monitor), symbol, build_string (name)),
|
||||
CDR_SAFE (watch_object));
|
||||
|
||||
/* Store it into the input event queue. */
|
||||
kbd_buffer_store_event (&event);
|
||||
}
|
||||
|
||||
/* Cleanup. */
|
||||
cleanup:
|
||||
g_free (name);
|
||||
g_free (oname);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
DEFUN ("gfile-add-watch", Fgfile_add_watch, Sgfile_add_watch, 3, 3, 0,
|
||||
doc: /* Add a watch for filesystem events pertaining to FILE.
|
||||
|
||||
This arranges for filesystem events pertaining to FILE to be reported
|
||||
to Emacs. Use `gfile-rm-watch' to cancel the watch.
|
||||
|
||||
Value is a descriptor for the added watch. If the file cannot be
|
||||
watched for some reason, this function signals a `file-error' error.
|
||||
|
||||
FLAGS is a list of conditions to set what will be watched for. It can
|
||||
include the following symbols:
|
||||
|
||||
'watch-mounts' -- watch for mount events
|
||||
'send-moved' -- pair 'deleted' and 'created' events caused by file
|
||||
renames (moves) and send a single 'event-moved'
|
||||
event instead
|
||||
|
||||
When any event happens, Emacs will call the CALLBACK function passing
|
||||
it a single argument EVENT, which is of the form
|
||||
|
||||
(DESCRIPTOR ACTION FILE [FILE1])
|
||||
|
||||
DESCRIPTOR is the same object as the one returned by this function.
|
||||
ACTION is the description of the event. It could be any one of the
|
||||
following:
|
||||
|
||||
'changed' -- FILE has changed
|
||||
'changes-done-hint' -- a hint that this was probably the last change
|
||||
in a set of changes
|
||||
'deleted' -- FILE was deleted
|
||||
'created' -- FILE was created
|
||||
'attribute-changed' -- a FILE attribute was changed
|
||||
'pre-unmount' -- the FILE location will soon be unmounted
|
||||
'unmounted' -- the FILE location was unmounted
|
||||
'moved' -- FILE was moved to FILE1
|
||||
|
||||
FILE is the name of the file whose event is being reported. FILE1
|
||||
will be reported only in case of the 'moved' event. */)
|
||||
(Lisp_Object file, Lisp_Object flags, Lisp_Object callback)
|
||||
{
|
||||
Lisp_Object watch_descriptor, watch_object;
|
||||
GFile *gfile;
|
||||
GFileMonitor* monitor;
|
||||
GFileMonitorFlags gflags = G_FILE_MONITOR_NONE;
|
||||
|
||||
/* Check parameters. */
|
||||
CHECK_STRING (file);
|
||||
file = Fdirectory_file_name (Fexpand_file_name (file, Qnil));
|
||||
if (NILP (Ffile_exists_p (file)))
|
||||
report_file_error ("File does not exists", Fcons (file, Qnil));
|
||||
|
||||
CHECK_LIST (flags);
|
||||
|
||||
if (!FUNCTIONP (callback))
|
||||
wrong_type_argument (Qinvalid_function, callback);
|
||||
|
||||
/* Create GFile name. */
|
||||
gfile = g_file_new_for_path (SSDATA (ENCODE_FILE (file)));
|
||||
|
||||
/* Assemble flags. */
|
||||
if (!NILP (Fmember (Qwatch_mounts, flags)))
|
||||
gflags |= G_FILE_MONITOR_WATCH_MOUNTS;
|
||||
if (!NILP (Fmember (Qsend_moved, flags)))
|
||||
gflags |= G_FILE_MONITOR_SEND_MOVED;
|
||||
|
||||
/* Enable watch. */
|
||||
monitor = g_file_monitor (gfile, gflags, NULL, NULL);
|
||||
if (monitor != NULL)
|
||||
g_signal_connect (monitor, "changed",
|
||||
(GCallback) dir_monitor_callback, NULL);
|
||||
else
|
||||
report_file_error ("Cannot watch file", Fcons (file, Qnil));
|
||||
|
||||
/* Store watch object in watch list. */
|
||||
watch_descriptor = XIL ((EMACS_INT) monitor);
|
||||
watch_object = Fcons (watch_descriptor, callback);
|
||||
watch_list = Fcons (watch_object, watch_list);
|
||||
|
||||
return watch_descriptor;
|
||||
}
|
||||
|
||||
DEFUN ("gfile-rm-watch", Fgfile_rm_watch, Sgfile_rm_watch, 1, 1, 0,
|
||||
doc: /* Remove an existing WATCH-DESCRIPTOR.
|
||||
|
||||
WATCH-DESCRIPTOR should be an object returned by `gfile-add-watch'. */)
|
||||
(Lisp_Object watch_descriptor)
|
||||
{
|
||||
Lisp_Object watch_object;
|
||||
GFileMonitor *monitor = (GFileMonitor *) XLI (watch_descriptor);
|
||||
|
||||
watch_object = Fassoc (watch_descriptor, watch_list);
|
||||
if (NILP (watch_object))
|
||||
report_file_error ("Not a watch descriptor",
|
||||
Fcons (watch_descriptor, Qnil));
|
||||
|
||||
if (!g_file_monitor_cancel (monitor))
|
||||
report_file_error ("Could not rm watch",
|
||||
Fcons (watch_descriptor, Qnil));
|
||||
|
||||
/* Remove watch descriptor from watch list. */
|
||||
watch_list = Fdelete (watch_object, watch_list);
|
||||
|
||||
/* Cleanup. */
|
||||
g_object_unref (monitor);
|
||||
|
||||
return Qt;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
syms_of_gfilenotify (void)
|
||||
{
|
||||
|
||||
g_type_init ();
|
||||
|
||||
DEFSYM (Qgfile_add_watch, "gfile-add-watch");
|
||||
defsubr (&Sgfile_add_watch);
|
||||
|
||||
DEFSYM (Qgfile_rm_watch, "gfile-rm-watch");
|
||||
defsubr (&Sgfile_rm_watch);
|
||||
|
||||
DEFSYM (Qwatch_mounts, "watch-mounts");
|
||||
DEFSYM (Qsend_moved, "send-moved");
|
||||
DEFSYM (Qchanged, "changed");
|
||||
DEFSYM (Qchanges_done_hint, "changes-done-hint");
|
||||
DEFSYM (Qdeleted, "deleted");
|
||||
DEFSYM (Qcreated, "created");
|
||||
DEFSYM (Qattribute_changed, "attribute-changed");
|
||||
DEFSYM (Qpre_unmount, "pre-unmount");
|
||||
DEFSYM (Qunmounted, "unmounted");
|
||||
DEFSYM (Qmoved, "moved");
|
||||
|
||||
/* Initialize internal objects. */
|
||||
watch_list = Qnil;
|
||||
staticpro (&watch_list);
|
||||
|
||||
Fprovide (intern_c_string ("gfilenotify"), Qnil);
|
||||
|
||||
}
|
||||
|
||||
#endif /* HAVE_GFILENOTIFY */
|
|
@ -308,18 +308,15 @@ static Lisp_Object Qfunction_key;
|
|||
Lisp_Object Qmouse_click;
|
||||
#ifdef HAVE_NTGUI
|
||||
Lisp_Object Qlanguage_change;
|
||||
#ifdef WINDOWSNT
|
||||
Lisp_Object Qfile_w32notify;
|
||||
#endif
|
||||
#endif
|
||||
static Lisp_Object Qdrag_n_drop;
|
||||
static Lisp_Object Qsave_session;
|
||||
#ifdef HAVE_DBUS
|
||||
static Lisp_Object Qdbus_event;
|
||||
#endif
|
||||
#ifdef HAVE_INOTIFY
|
||||
static Lisp_Object Qfile_inotify;
|
||||
#endif /* HAVE_INOTIFY */
|
||||
#ifdef USE_FILE_NOTIFY
|
||||
static Lisp_Object Qfile_notify;
|
||||
#endif /* USE_FILE_NOTIFY */
|
||||
static Lisp_Object Qconfig_changed_event;
|
||||
|
||||
/* Lisp_Object Qmouse_movement; - also an event header */
|
||||
|
@ -4013,18 +4010,22 @@ kbd_buffer_get_event (KBOARD **kbp,
|
|||
kbd_fetch_ptr = event + 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef WINDOWSNT
|
||||
#ifdef USE_FILE_NOTIFY
|
||||
else if (event->kind == FILE_NOTIFY_EVENT)
|
||||
{
|
||||
#ifdef HAVE_W32NOTIFY
|
||||
/* Make an event (file-notify (DESCRIPTOR ACTION FILE) CALLBACK). */
|
||||
obj = Fcons (Qfile_w32notify,
|
||||
obj = Fcons (Qfile_notify,
|
||||
list2 (list3 (make_number (event->code),
|
||||
XCAR (event->arg),
|
||||
XCDR (event->arg)),
|
||||
event->frame_or_window));
|
||||
#else
|
||||
obj = make_lispy_event (event);
|
||||
#endif
|
||||
kbd_fetch_ptr = event + 1;
|
||||
}
|
||||
#endif
|
||||
#endif /* USE_FILE_NOTIFY */
|
||||
else if (event->kind == SAVE_SESSION_EVENT)
|
||||
{
|
||||
obj = Fcons (Qsave_session, Fcons (event->arg, Qnil));
|
||||
|
@ -4081,13 +4082,6 @@ kbd_buffer_get_event (KBOARD **kbp,
|
|||
obj = make_lispy_event (event);
|
||||
kbd_fetch_ptr = event + 1;
|
||||
}
|
||||
#endif
|
||||
#ifdef HAVE_INOTIFY
|
||||
else if (event->kind == FILE_NOTIFY_EVENT)
|
||||
{
|
||||
obj = make_lispy_event (event);
|
||||
kbd_fetch_ptr = event + 1;
|
||||
}
|
||||
#endif
|
||||
else if (event->kind == CONFIG_CHANGED_EVENT)
|
||||
{
|
||||
|
@ -5991,12 +5985,12 @@ make_lispy_event (struct input_event *event)
|
|||
}
|
||||
#endif /* HAVE_DBUS */
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY
|
||||
case FILE_NOTIFY_EVENT:
|
||||
{
|
||||
return Fcons (Qfile_inotify, event->arg);
|
||||
return Fcons (Qfile_notify, event->arg);
|
||||
}
|
||||
#endif /* HAVE_INOTIFY */
|
||||
#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY */
|
||||
|
||||
case CONFIG_CHANGED_EVENT:
|
||||
return Fcons (Qconfig_changed_event,
|
||||
|
@ -11006,17 +11000,13 @@ syms_of_keyboard (void)
|
|||
DEFSYM (Qlanguage_change, "language-change");
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
DEFSYM (Qfile_w32notify, "file-w32notify");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_DBUS
|
||||
DEFSYM (Qdbus_event, "dbus-event");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
DEFSYM (Qfile_inotify, "file-inotify");
|
||||
#endif /* HAVE_INOTIFY */
|
||||
#ifdef USE_FILE_NOTIFY
|
||||
DEFSYM (Qfile_notify, "file-notify");
|
||||
#endif /* USE_FILE_NOTIFY */
|
||||
|
||||
DEFSYM (QCenable, ":enable");
|
||||
DEFSYM (QCvisible, ":visible");
|
||||
|
@ -11762,20 +11752,18 @@ keys_of_keyboard (void)
|
|||
"dbus-handle-event");
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
/* Define a special event which is raised for inotify callback
|
||||
#ifdef USE_FILE_NOTIFY
|
||||
/* Define a special event which is raised for notification callback
|
||||
functions. */
|
||||
initial_define_lispy_key (Vspecial_event_map, "file-inotify",
|
||||
"inotify-handle-event");
|
||||
#endif /* HAVE_INOTIFY */
|
||||
initial_define_lispy_key (Vspecial_event_map, "file-notify",
|
||||
"file-notify-handle-event");
|
||||
#endif /* USE_FILE_NOTIFY */
|
||||
|
||||
initial_define_lispy_key (Vspecial_event_map, "config-changed-event",
|
||||
"ignore");
|
||||
#if defined (WINDOWSNT)
|
||||
initial_define_lispy_key (Vspecial_event_map, "language-change",
|
||||
"ignore");
|
||||
initial_define_lispy_key (Vspecial_event_map, "file-w32notify",
|
||||
"w32notify-handle-event");
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
11
src/lisp.h
11
src/lisp.h
|
@ -3784,9 +3784,9 @@ extern void syms_of_fontset (void);
|
|||
extern Lisp_Object Qfont_param;
|
||||
#endif
|
||||
|
||||
#ifdef WINDOWSNT
|
||||
/* Defined on w32notify.c. */
|
||||
extern void syms_of_w32notify (void);
|
||||
/* Defined in gfilenotify.c */
|
||||
#ifdef HAVE_GFILENOTIFY
|
||||
extern void syms_of_gfilenotify (void);
|
||||
#endif
|
||||
|
||||
/* Defined in inotify.c */
|
||||
|
@ -3794,6 +3794,11 @@ extern void syms_of_w32notify (void);
|
|||
extern void syms_of_inotify (void);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_W32NOTIFY
|
||||
/* 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;
|
||||
|
|
|
@ -212,7 +212,7 @@ enum event_kind
|
|||
, NS_NONKEY_EVENT
|
||||
#endif
|
||||
|
||||
#if defined (HAVE_INOTIFY) || defined (HAVE_NTGUI)
|
||||
#ifdef USE_FILE_NOTIFY
|
||||
/* File or directory was changed. */
|
||||
, FILE_NOTIFY_EVENT
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue