Commit 93fd3d10 authored by Alex Graveley's avatar Alex Graveley Committed by Alex Graveley

Remove FAM check.

2002-05-22  Alex Graveley  <alex@ximian.com>

	* configure.in: Remove FAM check.

	* acconfig.h: Remove HAVE_LIBFAM.

	* 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.
parent f25b7013
2002-05-22 Alex Graveley <alex@ximian.com>
* configure.in: Remove FAM check.
* acconfig.h: Remove HAVE_LIBFAM.
* 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-22 Bastien Nocera <hadess@hadess.net>
reviewed by: Alex Larsson <alexl@redhat.com>
......
......@@ -6,7 +6,6 @@
#undef HAVE_GETTEXT
#undef HAVE_LC_MESSAGES
#undef HAVE_LIBBZ2
#undef HAVE_LIBFAM
#undef HAVE_LIBJPEG
#undef HAVE_MEDUSA
#undef HAVE_STPCPY
......
......@@ -106,25 +106,6 @@ AC_CHECK_FUNCS(setenv unsetenv putenv)
dnl ==========================================================================
dnl FAM
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
FAM_MISSING_WARNING="Nautilus depends on FAM to provide notification when files are altered (either through filesystem polling, or a kernel notification mechanism). If Nautilus is built without FAM support, directories viewed with Nautilus will not remain in synch with the actual filesystem when they are altered by external processes. Particularly if you are a distributor please compile Nautilus with FAM support. FAM is available from http://oss.sgi.com/projects/fam/. A patch to add Linux Kernel 2.4 directory notify support to FAM (highly desirable) is available from http://people.redhat.com/alexl/files/"
FAM_LIBS=
AC_CHECK_LIB(fam, FAMOpen,
[AC_CHECK_HEADERS(fam.h,
[AC_DEFINE(HAVE_LIBFAM)
FAM_LIBS="-lfam"],
AC_MSG_WARN(*** FAM support will not be built (header files not found) $FAM_MISSING_WARNING ***))],
AC_MSG_WARN(*** FAM support will not be built (FAM library not found) $FAM_MISSING_WARNING ***))
AC_SUBST(FAM_LIBS)
AC_LANG_RESTORE
dnl ==========================================================================
dnl x86 checks (used by audio routines in music component)
_system_is_x86="no"
......@@ -287,7 +268,7 @@ dnl core nautilus (must list bonobo-activation and libbonobo because idldir does
CORE_MODULES="eel-2.0 librsvg-2.0 bonobo-activation-2.0 libbonobo-2.0 libbonoboui-2.0 esound gnome-desktop-2.0 $EXTRA_CORE_MODULES"
CORE_CFLAGS="`$PKG_CONFIG --cflags $CORE_MODULES` $x_cflags"
AC_SUBST(CORE_CFLAGS)
CORE_LIBS="`$PKG_CONFIG --libs $CORE_MODULES` $CDDA_LIBS $FAM_LIBS $LIBJPEG $x_libs"
CORE_LIBS="`$PKG_CONFIG --libs $CORE_MODULES` $CDDA_LIBS $LIBJPEG $x_libs"
AC_SUBST(CORE_LIBS)
CORE_IDL_INCLUDES="`$PKG_CONFIG --variable=idldir $CORE_MODULES | $srcdir/add-include-prefix`"
AC_SUBST(CORE_IDL_INCLUDES)
......
......@@ -21,210 +21,49 @@
Authors: Seth Nickell <seth@eazel.com>
Darin Adler <darin@bentspoon.com>
Alex Graveley <alex@ximian.com>
*/
#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)
{
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);
got_connection = TRUE;
}
return &connection;
}
static GHashTable *
get_request_hash_table (void)
gboolean
nautilus_monitor_active (void)
{
static GHashTable *table;
static gboolean tried_monitor = FALSE;
static gboolean monitor_success;
char *desktop_directory, *uri;
NautilusMonitor *monitor;
if (table == NULL) {
table = eel_g_hash_table_new_free_at_exit
(NULL, NULL, "nautilus-monitor.c: FAM requests");
}
return table;
}
if (tried_monitor == FALSE) {
desktop_directory = nautilus_get_desktop_directory ();
uri = gnome_vfs_get_uri_from_local_path (desktop_directory);
static char *
get_event_uri (const FAMEvent *event)
{
const char *base_path;
char *path, *uri;
monitor = nautilus_monitor_directory (uri);
monitor_success = (monitor != NULL);
/* 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);
}
if (monitor != NULL) {
nautilus_monitor_cancel (monitor);
}
/* 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)));
g_free (desktop_directory);
g_free (uri);
/* 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 +73,106 @@ path_is_on_readonly_volume (const char *path)
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)
static void
monitor_notify_cb (GnomeVFSMonitorHandle *handle,
const gchar *monitor_uri,
const gchar *info_uri,
GnomeVFSMonitorEventType event_type,
gpointer user_data)
{
#ifndef HAVE_LIBFAM
return NULL;
#else
FAMConnection *connection;
char *path;
NautilusMonitor *monitor;
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;
}
connection = get_fam_connection ();
if (connection == NULL) {
return NULL;
if (call_consume_changes_idle_id == 0) {
call_consume_changes_idle_id =
g_idle_add (call_consume_changes_idle_cb, NULL);
}
}
static NautilusMonitor *
monitor_add_internal (const char *uri, gboolean is_directory)
{
gchar *path;
NautilusMonitor *ret;
GnomeVFSResult result;
path = gnome_vfs_get_local_path_from_uri (uri);
if (path == NULL) {
if (path != NULL &&
path_is_on_readonly_volume (path) == FALSE) {
g_free (path);
return NULL;
}
g_free (path);
/* 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);
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;
}
monitor = g_new0 (NautilusMonitor, 1);
FAMMonitorFile (connection, path, &monitor->request, NULL);
g_free (path);
return monitor;
#endif
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;
{
if (monitor->handle != NULL) {
gnome_vfs_monitor_cancel (monitor->handle);
}
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);
FAMCancelMonitor (connection, &monitor->request);
g_free (monitor);
#endif
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment