emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r112830: * configure.ac (file-notific


From: Michael Albinus
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r112830: * configure.ac (file-notification): New option, replaces inotify option.
Date: Mon, 03 Jun 2013 15:03:05 +0200
User-agent: Bazaar (2.6b2)

------------------------------------------------------------
revno: 112830
committer: Michael Albinus <address@hidden>
branch nick: trunk
timestamp: Mon 2013-06-03 15:03:05 +0200
message:
  * 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.
added:
  src/gfilenotify.c
modified:
  ChangeLog
  autogen/config.in
  configure.ac
  lisp/ChangeLog
  lisp/autorevert.el
  lisp/subr.el
  src/ChangeLog
  src/Makefile.in
  src/emacs.c
  src/keyboard.c
  src/lisp.h
  src/termhooks.h
=== modified file 'ChangeLog'
--- a/ChangeLog 2013-06-02 03:56:40 +0000
+++ b/ChangeLog 2013-06-03 13:03:05 +0000
@@ -1,3 +1,14 @@
+2013-06-03  Michael Albinus  <address@hidden>
+
+       * 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  <address@hidden>
 
        * .bzrignore: Ignore dirs libexec/, share/ and var/.

=== modified file 'autogen/config.in'
--- a/autogen/config.in 2013-05-16 16:37:05 +0000
+++ b/autogen/config.in 2013-06-03 13:03:05 +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
@@ -547,6 +547,9 @@
 /* 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 @@
 /* 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 @@
 /* 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 @@
 mode: c
 End:
 */
-

=== modified file 'configure.ac'
--- a/configure.ac      2013-05-27 02:03:18 +0000
+++ b/configure.ac      2013-06-03 13:03:05 +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])
+
+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 @@
     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 @@
 AC_SUBST(LIBGNUTLS_LIBS)
 AC_SUBST(LIBGNUTLS_CFLAGS)
 
+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
+
+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_inotify}" = "yes"; then
-   AC_CHECK_HEADERS(sys/inotify.h)
+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)
+       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 "$ac_cv_func_inotify_init1" = yes; then
-  AC_DEFINE(HAVE_INOTIFY, 1, [Define to 1 to use inotify.])
+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 -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/ChangeLog'
--- a/lisp/ChangeLog    2013-06-03 08:51:50 +0000
+++ b/lisp/ChangeLog    2013-06-03 13:03:05 +0000
@@ -1,3 +1,14 @@
+2013-06-03  Michael Albinus  <address@hidden>
+
+       * 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  <address@hidden>
 
        * bindings.el (search-map): Bind `highlight-symbol-at-point' to

=== modified file 'lisp/autorevert.el'
--- a/lisp/autorevert.el        2013-05-22 14:47:19 +0000
+++ b/lisp/autorevert.el        2013-06-03 13:03:05 +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'
--- a/lisp/subr.el      2013-06-03 08:51:50 +0000
+++ b/lisp/subr.el      2013-06-03 13:03:05 +0000
@@ -4440,32 +4440,16 @@
 
 ;;;; 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))))
 
 
 ;;;; Comparing version strings.

=== modified file 'src/ChangeLog'
--- a/src/ChangeLog     2013-06-03 09:01:53 +0000
+++ b/src/ChangeLog     2013-06-03 13:03:05 +0000
@@ -1,3 +1,22 @@
+2013-06-03  Michael Albinus  <address@hidden>
+
+       * 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  <address@hidden>
 
        Merge the specpdl and backtrace stacks.  Make the structure of the

=== modified file 'src/Makefile.in'
--- a/src/Makefile.in   2013-05-29 16:48:42 +0000
+++ b/src/Makefile.in   2013-06-03 13:03:05 +0000
@@ -156,6 +156,11 @@
 ## gtkutil.o if USE_GTK, else empty.
 address@hidden@
 
+## 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 "".
 address@hidden@
 ## 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'
--- a/src/emacs.c       2013-03-19 14:09:05 +0000
+++ b/src/emacs.c       2013-06-03 13:03:05 +0000
@@ -1252,7 +1252,9 @@
 
 #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 @@
       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 @@
 
 #ifdef WINDOWSNT
       syms_of_ntterm ();
+#ifdef HAVE_W32NOTIFY
       syms_of_w32notify ();
+#endif /* HAVE_W32NOTIFY */
 #endif /* WINDOWSNT */
 
       syms_of_profiler ();

=== added file 'src/gfilenotify.c'
--- a/src/gfilenotify.c 1970-01-01 00:00:00 +0000
+++ b/src/gfilenotify.c 2013-06-03 13:03:05 +0000
@@ -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  */

=== modified file 'src/keyboard.c'
--- a/src/keyboard.c    2013-05-23 18:49:57 +0000
+++ b/src/keyboard.c    2013-06-03 13:03:05 +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 */
+#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_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));
@@ -4082,13 +4083,6 @@
          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)
        {
          obj = make_lispy_event (event);
@@ -5991,12 +5985,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 +11000,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 */
+#ifdef USE_FILE_NOTIFY
+  DEFSYM (Qfile_notify, "file-notify");
+#endif /* USE_FILE_NOTIFY */
 
   DEFSYM (QCenable, ":enable");
   DEFSYM (QCvisible, ":visible");
@@ -11762,20 +11752,18 @@
                            "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
 }
 

=== modified file 'src/lisp.h'
--- a/src/lisp.h        2013-06-03 09:01:53 +0000
+++ b/src/lisp.h        2013-06-03 13:03:05 +0000
@@ -3784,9 +3784,9 @@
 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_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;

=== modified file 'src/termhooks.h'
--- a/src/termhooks.h   2013-03-11 01:17:40 +0000
+++ b/src/termhooks.h   2013-06-03 13:03:05 +0000
@@ -212,7 +212,7 @@
   , NS_NONKEY_EVENT
 #endif
 
-#if defined (HAVE_INOTIFY) || defined (HAVE_NTGUI)
+#ifdef USE_FILE_NOTIFY
   /* File or directory was changed.  */
   , FILE_NOTIFY_EVENT
 #endif


reply via email to

[Prev in Thread] Current Thread [Next in Thread]