Re: PATCH: use gnome-vfs for monitoring files
- From: Alex Graveley <alex ximian com>
- To: Alex Larsson <alexl redhat com>
- Cc: nautilus-list lists eazel com
- Subject: Re: PATCH: use gnome-vfs for monitoring files
- Date: 21 May 2002 17:09:58 -0400
Hi,
Second try. Brings back the nautilus-monitor apis, so we can check for
a read-only volume. Also caches result of nautilus_monitor_active().
-Alex
--
"I don't find excessive sanity a virtue."
? autom4te.cache
? desktop-links-use-uris.diff
? stamp-h1
? use-vfs-monitors.diff
? components/tree/nautilus-tree-model.c.flc
? libnautilus/nautilus-view.c.flc
? libnautilus-private/nautilus-directory-async.c.flc
? libnautilus-private/nautilus-metafile.c.flc
? src/nautilus-sidebar.c.flc
? src/nautilus-window.c.flc
? src/file-manager/fm-desktop-icon-view.c.flc
? src/file-manager/fm-directory-view.c.flc
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/nautilus/ChangeLog,v
retrieving revision 1.5314
diff -u -r1.5314 ChangeLog
--- ChangeLog 21 May 2002 18:24:16 -0000 1.5314
+++ ChangeLog 21 May 2002 21:12:50 -0000
@@ -1,3 +1,12 @@
+2002-05-21 Alex Graveley <alex ximian com>
+
+ * libnautilus-private/nautilus-monitor.[ch]: Convert to using
+ gnome-vfs monitors. nautilus_monitor_active() now checks if FAM
+ can be used by creating a monitor for the user's desktop
+ directory, and caches this if successful. Adds an idle handler to
+ call nautilus_file_changes_consume_changes(), so multiple file
+ changes have a chance of being chunked together.
+
2002-05-21 Frank Worsley <fworsley shaw ca>
* libnautilus-private/nautilus-link-desktop-file.c:
Index: libnautilus-private/nautilus-monitor.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-private/nautilus-monitor.c,v
retrieving revision 1.20
diff -u -r1.20 nautilus-monitor.c
--- libnautilus-private/nautilus-monitor.c 7 Mar 2002 04:17:50 -0000 1.20
+++ libnautilus-private/nautilus-monitor.c 21 May 2002 21:12:50 -0000
@@ -25,206 +25,44 @@
#include <config.h>
#include "nautilus-monitor.h"
-
-#include <eel/eel-glib-extensions.h>
-
-#ifdef HAVE_LIBFAM
-
#include "nautilus-file-changes-queue.h"
+#include "nautilus-file-utilities.h"
#include "nautilus-volume-monitor.h"
-#include <fam.h>
-#include <gdk/gdk.h>
-#include <gmodule.h>
+
#include <libgnome/gnome-util.h>
#include <libgnomevfs/gnome-vfs-utils.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
struct NautilusMonitor {
- FAMRequest request;
+ GnomeVFSMonitorHandle *handle;
};
-static gboolean got_connection;
-
-static gboolean process_fam_notifications (GIOChannel *channel,
- GIOCondition cond,
- gpointer callback_data);
-
-/* singleton object, instantiate and connect if it doesn't already exist */
-static FAMConnection *
-get_fam_connection (void)
+gboolean
+nautilus_monitor_active (void)
{
- static gboolean tried_connection;
- static FAMConnection connection;
- GIOChannel *ioc;
-
- /* Only try once. */
- if (tried_connection) {
- if (!got_connection) {
- return NULL;
- }
- } else {
- tried_connection = TRUE;
- if (FAMOpen2 (&connection, "Nautilus") != 0) {
- return NULL;
- }
-
- /* Make the main loop's select function watch the FAM
- * connection's file descriptor for us.
- */
- ioc = g_io_channel_unix_new (FAMCONNECTION_GETFD (&connection));
- g_io_add_watch (ioc, G_IO_IN | G_IO_HUP, process_fam_notifications, NULL);
- g_io_channel_unref (ioc);
+ static gboolean tried_monitor = FALSE;
+ static gboolean monitor_success;
- got_connection = TRUE;
- }
- return &connection;
-}
+ if (tried_monitor == FALSE) {
+ char *desktop_directory, *uri;
+ NautilusMonitor *monitor;
+
+ desktop_directory = nautilus_get_desktop_directory ();
+ uri = gnome_vfs_get_uri_from_local_path (desktop_directory);
-static GHashTable *
-get_request_hash_table (void)
-{
- static GHashTable *table;
+ monitor = nautilus_monitor_directory (uri);
+ monitor_success = (monitor != NULL);
- if (table == NULL) {
- table = eel_g_hash_table_new_free_at_exit
- (NULL, NULL, "nautilus-monitor.c: FAM requests");
- }
- return table;
-}
+ if (monitor != NULL)
+ nautilus_monitor_cancel (monitor);
-static char *
-get_event_uri (const FAMEvent *event)
-{
- const char *base_path;
- char *path, *uri;
+ g_free (desktop_directory);
+ g_free (uri);
- /* FAM doesn't tell us when something is a full path and when
- * it's just partial so we have to look and see if it starts
- * with a /.
- */
- if (event->filename[0] == '/') {
- return gnome_vfs_get_uri_from_local_path (event->filename);
- }
-
- /* Look up the directory registry that was used for this file
- * notification and tack that on.
- */
- base_path = g_hash_table_lookup (get_request_hash_table (),
- GINT_TO_POINTER (FAMREQUEST_GETREQNUM (&event->fr)));
-
- /* base_path can be NULL if we've cancelled the monitor but still have
- * some change notifications in our queue. Just return NULL In that case.
- */
- if (base_path == NULL) {
- return NULL;
+ tried_monitor = TRUE;
}
- path = g_build_filename (base_path, event->filename, NULL);
- uri = gnome_vfs_get_uri_from_local_path (path);
- g_free (path);
- return uri;
-}
-
-static gboolean
-process_fam_notifications (GIOChannel *channel,
- GIOCondition cond,
- gpointer callback_data)
-{
- FAMConnection *connection;
- FAMEvent event;
- char *uri;
-
- connection = get_fam_connection ();
- g_return_val_if_fail (connection != NULL, FALSE);
-
- /* Process all the pending events right now. */
-
- while (FAMPending (connection)) {
- if (FAMNextEvent (connection, &event) != 1) {
- g_warning ("connection to FAM died");
- FAMClose (connection);
- got_connection = FALSE;
- return FALSE;
- }
-
- switch (event.code) {
- case FAMChanged:
- uri = get_event_uri (&event);
- if (uri == NULL) {
- break;
- }
- nautilus_file_changes_queue_file_changed (uri);
- g_free (uri);
- break;
-
- case FAMDeleted:
- uri = get_event_uri (&event);
- if (uri == NULL) {
- break;
- }
- nautilus_file_changes_queue_file_removed (uri);
- g_free (uri);
- break;
-
- case FAMCreated:
- uri = get_event_uri (&event);
- if (uri == NULL) {
- break;
- }
- nautilus_file_changes_queue_file_added (uri);
- g_free (uri);
- break;
-
- case FAMStartExecuting:
- /* Emitted when a file you are monitoring is
- * executed. This should work for both
- * binaries and shell scripts. Nautilus is not
- * doing anything with this yet.
- */
- break;
-
- case FAMStopExecuting:
- /* Emitted when a file you are monitoring
- * ceases execution. Nautilus is not doing
- * anything with this yet.
- */
- break;
-
- case FAMAcknowledge:
- /* Called in response to a successful
- * CancelMonitor. We don't need to do anything
- * with this information.
- */
- break;
-
- case FAMExists:
- /* Emitted when you start monitoring a
- * directory. It tells you what's in the
- * directory. Unhandled because Nautilus
- * already handles this by calling
- * gnome_vfs_directory_load, which gives us
- * more information than merely the file name.
- */
- break;
-
- case FAMEndExist:
- /* Emitted at the end of a FAMExists stream. */
- break;
-
- case FAMMoved:
- /* FAMMoved doesn't need to be handled because
- * FAM never seems to generate this event on
- * Linux systems (with or without kernel
- * support). Instead it generates a FAMDeleted
- * followed by a FAMCreated.
- */
- g_warning ("unexpected FAMMoved notification");
- break;
- }
- }
-
- nautilus_file_changes_consume_changes (TRUE);
-
- return TRUE;
+ return monitor_success;
}
static gboolean
@@ -234,130 +72,103 @@
NautilusVolume *volume;
volume_monitor = nautilus_volume_monitor_get ();
- volume = nautilus_volume_monitor_get_volume_for_path (volume_monitor, path);
- return (volume != NULL) && nautilus_volume_is_read_only (volume);
+ volume = nautilus_volume_monitor_get_volume_for_path (volume_monitor,
+ path);
+ if (volume != NULL)
+ return nautilus_volume_is_read_only (volume);
+ else
+ return FALSE;
}
-#endif /* HAVE_LIBFAM */
+static gboolean call_consume_changes_idle_id = 0;
-gboolean
-nautilus_monitor_active (void)
+static gboolean
+call_consume_changes_idle_cb (gpointer not_used)
{
-#ifndef HAVE_LIBFAM
+ nautilus_file_changes_consume_changes (TRUE);
+ call_consume_changes_idle_id = 0;
return FALSE;
-#else
- return get_fam_connection () != NULL;
-#endif
}
-NautilusMonitor *
-nautilus_monitor_file (const char *uri)
-{
-#ifndef HAVE_LIBFAM
- return NULL;
-#else
- FAMConnection *connection;
- char *path;
- NautilusMonitor *monitor;
-
- connection = get_fam_connection ();
- if (connection == NULL) {
- return NULL;
+static void
+monitor_notify_cb (GnomeVFSMonitorHandle *handle,
+ const gchar *monitor_uri,
+ const gchar *info_uri,
+ GnomeVFSMonitorEventType event_type,
+ gpointer user_data)
+{
+ switch (event_type) {
+ case GNOME_VFS_MONITOR_EVENT_CHANGED:
+ nautilus_file_changes_queue_file_changed (info_uri);
+ break;
+ case GNOME_VFS_MONITOR_EVENT_DELETED:
+ nautilus_file_changes_queue_file_removed (info_uri);
+ break;
+ case GNOME_VFS_MONITOR_EVENT_CREATED:
+ nautilus_file_changes_queue_file_added (info_uri);
+ break;
+
+ /* None of the following are supported yet */
+ case GNOME_VFS_MONITOR_EVENT_STARTEXECUTING:
+ case GNOME_VFS_MONITOR_EVENT_STOPEXECUTING:
+ case GNOME_VFS_MONITOR_EVENT_METADATA_CHANGED:
+ break;
+ }
+
+ if (call_consume_changes_idle_id == 0) {
+ call_consume_changes_idle_id =
+ g_idle_add (call_consume_changes_idle_cb, NULL);
}
+}
- path = gnome_vfs_get_local_path_from_uri (uri);
- if (path == NULL) {
- return NULL;
- }
+static NautilusMonitor *
+monitor_add_internal (const char *uri, gboolean is_directory)
+{
+ gchar *path;
+ NautilusMonitor *ret;
+ GnomeVFSResult result;
- /* Check to see if the file system is readonly. If so, don't monitor --
- * there is no point, and we'll just keep the file system busy for
- * no reason, preventing unmounting
- */
- if (path_is_on_readonly_volume (path)) {
+ path = gnome_vfs_get_local_path_from_uri (uri);
+ if (path && path_is_on_readonly_volume (path)) {
g_free (path);
return NULL;
}
-
- monitor = g_new0 (NautilusMonitor, 1);
- FAMMonitorFile (connection, path, &monitor->request, NULL);
-
g_free (path);
- return monitor;
-#endif
-}
+ ret = g_new0 (NautilusMonitor, 1);
+ result = gnome_vfs_monitor_add (&ret->handle,
+ uri,
+ is_directory == TRUE ?
+ GNOME_VFS_MONITOR_DIRECTORY :
+ GNOME_VFS_MONITOR_FILE,
+ monitor_notify_cb,
+ NULL);
+ if (result != GNOME_VFS_OK) {
+ g_free (ret);
+ return NULL;
+ }
+ return ret;
+}
NautilusMonitor *
nautilus_monitor_directory (const char *uri)
{
-#ifndef HAVE_LIBFAM
- return NULL;
-#else
- FAMConnection *connection;
- char *path;
- NautilusMonitor *monitor;
-
- connection = get_fam_connection ();
- if (connection == NULL) {
- return NULL;
- }
-
- path = gnome_vfs_get_local_path_from_uri (uri);
- if (path == NULL) {
- return NULL;
- }
-
- /* Check to see if the file system is readonly. If so, don't monitor --
- * there is no point, and we'll just keep the file system busy for
- * no reason, preventing unmounting
- */
- if (path_is_on_readonly_volume (path)) {
- g_free (path);
- return NULL;
- }
-
- monitor = g_new0 (NautilusMonitor, 1);
- FAMMonitorDirectory (connection, path, &monitor->request, NULL);
-
- g_assert (g_hash_table_lookup (get_request_hash_table (),
- GINT_TO_POINTER (FAMREQUEST_GETREQNUM (&monitor->request))) == NULL);
-
- g_hash_table_insert (get_request_hash_table (),
- GINT_TO_POINTER (FAMREQUEST_GETREQNUM (&monitor->request)),
- path);
+ return monitor_add_internal (uri, TRUE);
+}
- return monitor;
-#endif
+NautilusMonitor *
+nautilus_monitor_file (const char *uri)
+{
+ return monitor_add_internal (uri, FALSE);
}
-void
+void
nautilus_monitor_cancel (NautilusMonitor *monitor)
-{
-#ifndef HAVE_LIBFAM
- g_return_if_fail (monitor == NULL);
-#else
- FAMConnection *connection;
- int reqnum;
- char *path;
-
- if (monitor == NULL) {
- return;
- }
-
- reqnum = FAMREQUEST_GETREQNUM (&monitor->request);
- path = g_hash_table_lookup (get_request_hash_table (),
- GINT_TO_POINTER (reqnum));
- g_hash_table_remove (get_request_hash_table (),
- GINT_TO_POINTER (reqnum));
- g_free (path);
-
- connection = get_fam_connection ();
- g_return_if_fail (connection != NULL);
+{
+ if (monitor->handle != NULL)
+ gnome_vfs_monitor_cancel (monitor->handle);
- FAMCancelMonitor (connection, &monitor->request);
g_free (monitor);
-#endif
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]