From: Michael Albinus <michael.albinus@gmx.de>
To: Stefan Monnier <monnier@iro.umontreal.ca>
Cc: emacs-devel@gnu.org
Subject: Re: Using glib's g_file_monitor_file and g_file_monitor_directory
Date: Tue, 28 May 2013 12:39:15 +0200 [thread overview]
Message-ID: <8738t7pewc.fsf@gmx.de> (raw)
In-Reply-To: <jwvtxnnfptz.fsf-monnier+emacs@gnu.org> (Stefan Monnier's message of "Wed, 03 Apr 2013 14:12:44 -0400")
[-- Attachment #1: Type: text/plain, Size: 1389 bytes --]
Stefan Monnier <monnier@iro.umontreal.ca> writes:
>>> What about adding this interface to Emacs, on C level? It could be in
>>> parallel to, or replacing the inotify interface.
>
> That sounds good. AFAIK Emacs almost always links to glib indirectly
> nowadays, so it would probably be OK to replace the inotify version with
> the glib version.
I've appended a patch which I have tested successfully under GNU/Linux.
There is a new gfilenotify.c, which uses glib's functionality. There is
also a new config option --with-file-notification=LIB, LIB can be "yes",
"no", "gfile" or "inotify". Default on non-w32 machines is "gfile" if
applicable. For w32 machines, this option is not taken into account yet,
emacs undonditionally links w32notify (maybe we want also support "no"
there?).
Furthermore, all file notification libraries use now the same lisp event
`file-notify' instead of `file-inotify' and `file-w32notify'.
Changelog entries and proper documentation are not part of this patch yet.
Comments on the patch are welcome. And we should also start to design an
upper layer over gfilenotify.c, inotify.c and w32notify.c, which
abstracts from the respective file notification events. They are very
different for every library, which complicates a convenient use in other
elisp packages. See the changes in autorevert.el in that patch.
> Stefan
Best regards, Michael.
[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: bzr.diff --]
[-- Type: text/x-diff, Size: 24254 bytes --]
=== modified file 'autogen/config.in'
--- autogen/config.in 2013-05-16 16:37:05 +0000
+++ autogen/config.in 2013-05-21 08:25:51 +0000
@@ -132,7 +132,7 @@
#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
@@ -623,6 +623,9 @@
/* Define to 1 if you have inet sockets. */
#undef HAVE_INET_SOCKETS
+/* Define to 1 to use glib's notify. */
+#undef HAVE_GFILENOTIFY
+
/* Define to 1 to use inotify. */
#undef HAVE_INOTIFY
@@ -1836,4 +1839,3 @@
mode: c
End:
*/
-
=== modified file 'configure.ac'
--- configure.ac 2013-05-27 02:03:18 +0000
+++ configure.ac 2013-05-28 09:28:06 +0000
@@ -200,7 +200,23 @@
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])
+
+## In case of mingw32, it doesn't matter.
+AC_ARG_WITH([file-notification],[AS_HELP_STRING([--with-file-notification=LIB],
+ [use a file notification library (LIB one of: yes or gfile, inotify, no)])],
+ [ case "${withval}" in
+ y | ye | yes ) val=gfile ;;
+ n | no ) val=no ;;
+ g | gf | gfi | gfil | gfile ) val=gfile ;;
+ i | in | ino | inot | inoti | inotif | inotify ) val=inotify ;;
+ * )
+AC_MSG_ERROR([`--with-file-notification=$withval' is invalid;
+this option's value should be `yes', `no', `gfile' or `inotify'.
+`yes' and `gfile' are synonyms.])
+ ;;
+ esac
+ with_file_notification=$val
+])
## 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 @@
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,38 @@
AC_SUBST(LIBGNUTLS_LIBS)
AC_SUBST(LIBGNUTLS_CFLAGS)
+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?
+NOTIFY_OBJ=
+NOTIFY_SUMMARY=no
+if test "${with_file_notification}" = "gfile" || test -z "${with_file_notification}"; 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_inotify}" = "yes"; then
+if test "${with_file_notification}" = "inotify" || (test -z "${with_file_notification}" && test -z "$NOTIFY_OBJ"); then
AC_CHECK_HEADERS(sys/inotify.h)
if test "$ac_cv_header_sys_inotify_h" = yes ; then
- AC_CHECK_FUNC(inotify_init1)
- fi
-fi
-if test "$ac_cv_func_inotify_init1" = yes; then
- AC_DEFINE(HAVE_INOTIFY, 1, [Define to 1 to use inotify.])
-fi
+ 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
+if "${opsys}" = "mingw32"; then
+ NOTIFY_OBJ=w32notify.o
+ NOTIFY_SUMMARY="yes"
+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 +4719,7 @@
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}"
=== modified file 'lisp/autorevert.el'
--- lisp/autorevert.el 2013-05-22 14:47:19 +0000
+++ lisp/autorevert.el 2013-05-22 15:03:33 +0000
@@ -271,7 +271,7 @@
: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 @@
(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 @@
(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 @@
(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 @@
(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 @@
;; 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)
=== modified file 'lisp/subr.el'
--- lisp/subr.el 2013-05-25 16:05:19 +0000
+++ lisp/subr.el 2013-05-27 06:24:20 +0000
@@ -4432,32 +4432,16 @@
\f
;;;; 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.
-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))
+(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")
+ (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))))
\f
;;;; Comparing version strings.
=== modified file 'src/Makefile.in'
--- src/Makefile.in 2013-05-16 09:58:56 +0000
+++ src/Makefile.in 2013-05-28 09:35:00 +0000
@@ -156,6 +156,11 @@
## gtkutil.o if USE_GTK, else empty.
GTK_OBJ=@GTK_OBJ@
+## gfilenotify.o if HAVE_GFILENOTIFY.
+## inotify.o if HAVE_INOTIFY.
+## w32notify.o for mingw32.
+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 @@
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)
=== modified file 'src/emacs.c'
--- src/emacs.c 2013-03-19 14:09:05 +0000
+++ src/emacs.c 2013-04-10 09:27:58 +0000
@@ -1409,6 +1409,10 @@
syms_of_gnutls ();
#endif
+#ifdef HAVE_GFILENOTIFY
+ syms_of_gfilenotify ();
+#endif /* HAVE_GFILENOTIFY */
+
#ifdef HAVE_INOTIFY
syms_of_inotify ();
#endif /* HAVE_INOTIFY */
=== added file 'src/gfilenotify.c'
--- src/gfilenotify.c 1970-01-01 00:00:00 +0000
+++ src/gfilenotify.c 2013-05-22 15:04:04 +0000
@@ -0,0 +1,266 @@
+/* Elisp bindings for D-Bus.
+ 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"
+
+\f
+/* 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;
+}
+
+\f
+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 */
=== modified file 'src/keyboard.c'
--- src/keyboard.c 2013-05-23 18:49:57 +0000
+++ src/keyboard.c 2013-05-24 09:51:35 +0000
@@ -308,18 +308,15 @@
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 */
+#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY || defined WINDOWSNT
+static Lisp_Object Qfile_notify;
+#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY || defined WINDOWSNT */
static Lisp_Object Qconfig_changed_event;
/* Lisp_Object Qmouse_movement; - also an event header */
@@ -4017,7 +4014,7 @@
else if (event->kind == FILE_NOTIFY_EVENT)
{
/* 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)),
@@ -4082,7 +4079,7 @@
kbd_fetch_ptr = event + 1;
}
#endif
-#ifdef HAVE_INOTIFY
+#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY
else if (event->kind == FILE_NOTIFY_EVENT)
{
obj = make_lispy_event (event);
@@ -5991,12 +5988,12 @@
}
#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 +11003,13 @@
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 */
+#if defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY || defined WINDOWSNT
+ DEFSYM (Qfile_notify, "file-notify");
+#endif /* defined HAVE_GFILENOTIFY || defined HAVE_INOTIFY || defined WINDOWSNT */
DEFSYM (QCenable, ":enable");
DEFSYM (QCvisible, ":visible");
@@ -11762,20 +11755,18 @@
"dbus-handle-event");
#endif
-#ifdef HAVE_INOTIFY
- /* Define a special event which is raised for inotify callback
+#if defined HAVE_GFILENOTIFY || HAVE_INOTIFY || defined WINDOWSNT
+ /* 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 /* defined HAVE_GFILENOTIFY || HAVE_INOTIFY || defined WINDOWSNT */
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
}
=== modified file 'src/lisp.h'
--- src/lisp.h 2013-05-15 18:54:49 +0000
+++ src/lisp.h 2013-05-21 08:25:51 +0000
@@ -3728,6 +3728,11 @@
extern void syms_of_w32notify (void);
#endif
+/* Defined in gfilenotify.c */
+#ifdef HAVE_GFILENOTIFY
+extern void syms_of_gfilenotify (void);
+#endif
+
/* Defined in inotify.c */
#ifdef HAVE_INOTIFY
extern void syms_of_inotify (void);
=== modified file 'src/termhooks.h'
--- src/termhooks.h 2013-03-11 01:17:40 +0000
+++ src/termhooks.h 2013-04-10 09:24:04 +0000
@@ -212,7 +212,7 @@
, NS_NONKEY_EVENT
#endif
-#if defined (HAVE_INOTIFY) || defined (HAVE_NTGUI)
+#if defined (HAVE_GFILENOTIFY) || defined (HAVE_INOTIFY) || defined (HAVE_NTGUI)
/* File or directory was changed. */
, FILE_NOTIFY_EVENT
#endif
next prev parent reply other threads:[~2013-05-28 10:39 UTC|newest]
Thread overview: 68+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-20 20:40 Using glib's g_file_monitor_file and g_file_monitor_directory Michael Albinus
2013-03-21 14:06 ` Ted Zlatanov
2013-03-21 14:54 ` Michael Albinus
2013-03-21 16:05 ` Ted Zlatanov
2013-03-22 7:52 ` Michael Albinus
2013-04-01 11:36 ` Michael Albinus
2013-04-01 17:50 ` Jan Djärv
2013-04-03 18:12 ` Stefan Monnier
2013-04-03 19:21 ` James Cloos
2013-04-03 19:36 ` Eli Zaretskii
2013-04-03 20:46 ` James Cloos
2013-04-03 19:55 ` Michael Albinus
2013-04-03 19:58 ` James Cloos
2013-04-04 0:49 ` Stefan Monnier
2013-05-28 10:39 ` Michael Albinus [this message]
2013-05-28 14:44 ` Paul Eggert
2013-05-28 15:33 ` Eli Zaretskii
2013-05-28 16:02 ` Paul Eggert
2013-05-28 16:21 ` Stefan Monnier
2013-05-28 16:45 ` Eli Zaretskii
2013-05-28 18:19 ` Stefan Monnier
2013-05-29 13:46 ` Michael Albinus
2013-05-29 14:03 ` Stefan Monnier
2013-05-29 14:09 ` Michael Albinus
2013-05-29 17:40 ` Stefan Monnier
2013-05-30 14:09 ` Michael Albinus
2013-05-30 21:08 ` Stefan Monnier
2013-05-28 16:43 ` Eli Zaretskii
2013-05-28 16:52 ` Paul Eggert
2013-05-28 16:59 ` Eli Zaretskii
2013-05-28 19:32 ` Paul Eggert
2013-05-28 15:58 ` Michael Albinus
2013-05-28 19:04 ` Paul Eggert
2013-05-28 20:31 ` Michael Albinus
2013-05-28 20:38 ` Paul Eggert
2013-05-29 6:12 ` Michael Albinus
2013-05-28 15:29 ` Eli Zaretskii
2013-05-29 13:30 ` Michael Albinus
2013-05-29 15:25 ` Eli Zaretskii
2013-05-29 15:57 ` Michael Albinus
2013-05-30 20:15 ` Daniel Colascione
2013-05-31 6:38 ` Michael Albinus
2013-06-02 16:57 ` Eli Zaretskii
2013-06-03 13:21 ` Michael Albinus
2013-06-03 15:12 ` Eli Zaretskii
2013-06-03 15:30 ` Glenn Morris
2013-06-03 16:29 ` Eli Zaretskii
2013-06-03 17:04 ` Eli Zaretskii
2013-06-03 17:27 ` Glenn Morris
2013-06-03 19:41 ` Michael Albinus
2013-06-04 6:09 ` Paul Eggert
2013-06-05 13:25 ` Michael Albinus
2013-06-05 18:37 ` Jan Djärv
2013-06-06 11:06 ` Michael Albinus
2013-06-07 10:53 ` Jan Djärv
2013-06-07 12:18 ` Michael Albinus
2013-06-07 14:22 ` Jan Djärv
2013-06-07 14:50 ` Michael Albinus
2013-06-08 8:50 ` Jan Djärv
2013-06-04 6:45 ` Paul Eggert
2013-06-04 15:16 ` Eli Zaretskii
2013-06-04 15:50 ` Paul Eggert
2013-06-05 1:23 ` Stefan Monnier
2013-06-06 7:10 ` Paul Eggert
2013-06-03 19:10 ` Michael Albinus
2013-05-30 11:11 ` Ken Brown
2013-05-28 15:30 ` Eli Zaretskii
2013-05-29 13:31 ` Michael Albinus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=8738t7pewc.fsf@gmx.de \
--to=michael.albinus@gmx.de \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).