[Nautilus-list] fam/imon support, here it is
- From: Seth Nickell <seth eazel com>
- To: nautilus-list lists eazel com
- Subject: [Nautilus-list] fam/imon support, here it is
- Date: Sat, 16 Sep 2000 14:10:37 -0700
So I don't remember who has sent messages inquiring about fam support
for Nautilus, but if you're still on the list I have patches you can
try. I wrote them last night...so beware...but I'm tired and grumpy and
want them tested on more machines than just mine :-) The source is
pretty clean if you just want to read over the files.
put the nautilus-monitor.* files in libnautilus-extensions
The other file is a standard patch file.
Better yet, ask my on irc, I'll probably have something more fresh, I
started writing 9 hours ago so things are still pretty up in the air!
Basically I want people to beat on these really hard to see how deadly
they are to Nautilus. Its built in by extending a pre-existing feature,
so I hope for the best :) If you can't tell I've become largely
incoherent, so I'm going to go sleep.
It is know that text-preview doesn't update instantly when you change
files, I'm working on that right now. Also is that monitor
addition/cleanup is not symmetrical yet (this is a NautilusDirectory
problem, I believe, but it needs to be fixed). Any other reports of
problems would be greatly appreciated.
http://oss.sgi.com/projects/fam/ for fam & imon. (click download on the
left hand edge). If people want to try fam w/o imon I'd be interested in
that too...though you want get the blistering performance ;-)
-seth
? nautilus_patch
? cmon.out
? components/services/startup/Makefile
? components/services/startup/Makefile.in
? components/services/startup/nautilus-view/Makefile
? components/services/startup/nautilus-view/Makefile.in
? components/services/startup/nautilus-view/.deps
? components/services/startup/nautilus-view/.libs
? components/services/startup/nautilus-view/nautilus-service-startup-view
? libnautilus-extensions/nautilus-monitor.h
? libnautilus-extensions/nautilus-monitor.c
Index: configure.in
===================================================================
RCS file: /cvs/gnome/nautilus/configure.in,v
retrieving revision 1.155
diff -u -p -r1.155 configure.in
--- configure.in 2000/09/15 08:33:03 1.155
+++ configure.in 2000/09/16 18:02:43
@@ -32,6 +32,10 @@ dnl Check for different mount systems
AC_CHECK_FUNCS(setmntent endmntent setenv unsetenv putenv)
AC_CHECK_HEADERS(sys/mnttab.h sys/vfstab.h)
+dnl Check for fam (/imon) support
+AC_CHECK_HEADERS(fam.h)
+AC_CHECK_LIB(fam, FAMOpen, [FAM_LIBS="-lfam"])
+AC_SUBST(FAM_LIBS)
dnl Tree view build as executable
@@ -467,8 +471,7 @@ if test "$GCC" = "yes" -a "$set_more_war
CFLAGS="$CFLAGS \
-Wall \
-Wchar-subscripts -Wmissing-declarations -Wmissing-prototypes \
- -Wnested-externs -Wpointer-arith \
- -Werror"
+ -Wnested-externs -Wpointer-arith"
for option in -Wsign-promo -Wno-sign-compare; do
SAVE_CFLAGS="$CFLAGS"
Index: libnautilus-extensions/Makefile.am
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-extensions/Makefile.am,v
retrieving revision 1.125
diff -u -p -r1.125 Makefile.am
--- libnautilus-extensions/Makefile.am 2000/09/14 18:34:49 1.125
+++ libnautilus-extensions/Makefile.am 2000/09/16 18:02:45
@@ -37,6 +37,7 @@ libnautilus_extensions_la_LDFLAGS= \
$(BONOBO_PRINT_LIBS) \
$(GHTTP_LIBS) \
$(VFS_LIBS) \
+ $(FAM_LIBS) \
$(XML_LIBS) \
$(MEDUSA_LIBS) \
$(LIBPNG) \
@@ -96,6 +97,7 @@ libnautilus_extensions_la_SOURCES = \
nautilus-list.c \
nautilus-merged-directory.c \
nautilus-mime-actions.c \
+ nautilus-monitor.c \
nautilus-password-dialog.c \
nautilus-preference.c \
nautilus-preferences-box.c \
@@ -192,6 +194,7 @@ noinst_HEADERS = \
nautilus-merged-directory.h \
nautilus-metadata.h \
nautilus-mime-actions.h \
+ nautilus-monitor.h \
nautilus-password-dialog.h \
nautilus-preference.h \
nautilus-preferences-box.h \
Index: libnautilus-extensions/nautilus-directory-async.c
===================================================================
RCS file: /cvs/gnome/nautilus/libnautilus-extensions/nautilus-directory-async.c,v
retrieving revision 1.74
diff -u -p -r1.74 nautilus-directory-async.c
--- libnautilus-extensions/nautilus-directory-async.c 2000/09/14 19:31:03 1.74
+++ libnautilus-extensions/nautilus-directory-async.c 2000/09/16 18:02:46
@@ -32,6 +32,7 @@
#include "nautilus-glib-extensions.h"
#include "nautilus-global-preferences.h"
#include "nautilus-link.h"
+#include "nautilus-monitor.h"
#include "nautilus-search-uri.h"
#include "nautilus-string.h"
#include <gtk/gtkmain.h>
@@ -793,6 +794,8 @@ nautilus_directory_monitor_add_internal
directory->details->monitor_list =
g_list_prepend (directory->details->monitor_list, monitor);
+ nautilus_monitor_add_directory (directory->details->uri);
+
/* Re-send the "files_added" signal for this set of files.
* Old monitorers already know about them, but it's harmless
* to hear about the same files again.
@@ -1040,6 +1043,8 @@ nautilus_directory_monitor_remove_intern
remove_monitor (directory, file, client);
+ nautilus_monitor_remove (directory->details->uri);
+
nautilus_directory_async_state_changed (directory);
}
@@ -1643,6 +1648,7 @@ start_monitoring_file_list (NautilusDire
DIRECTORY_LOAD_ITEMS_PER_CALLBACK, /* items_per_notification */
directory_load_callback, /* callback */
directory);
+
}
/* Stop monitoring the file list if it is being monitored. */
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-monitor.c: file and directory change monitoring for nautilus
Copyright (C) 2000 Eazel, Inc.
This program 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 2 of the
License, or (at your option) any later version.
This program 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 this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Author: Seth Nickell <seth eazel com>
*/
#include <glib.h>
#if !HAVE_FAM_H
#include <fam.h>
#endif
#include <libgnomevfs/gnome-vfs-types.h>
#include <libgnomevfs/gnome-vfs-uri.h>
#include <stdio.h>
#include <string.h>
#include "nautilus-directory-notify.h"
#include "nautilus-file.h"
#include "nautilus-monitor.h"
#if !HAVE_FAM_H
static FAMConnection *fam_connection;
static gboolean tried_connection = FALSE;
static gboolean connection_valid = TRUE;
static GList *monitoring_list = NULL;
typedef struct {
char *uri;
FAMRequest request;
} URIRequest;
/* FORWARD DECLARATIONS */
static void nautilus_monitor_process_fam_notifications (gpointer data, gint fd, GdkInputCondition condition);
/* establish the initial connection with fam, called the first time the fam_connection */
/* object is "used" by one of the subfunctions */
static gboolean
nautilus_monitor_establish_connection ()
{
gboolean connection_valid;
fam_connection = g_malloc0(sizeof(FAMConnection));
/* Connect to fam */
if (FAMOpen2(fam_connection, "Nautilus") != 0) {
printf ("FAM_DEBUG: Nautilus failed to establish a link to the file alteration monitor\n");
g_free(fam_connection);
fam_connection = NULL;
connection_valid = FALSE;
} else {
/* register our callback into the gtk loop */
gdk_input_add(FAMCONNECTION_GETFD(fam_connection), GDK_INPUT_READ,
nautilus_monitor_process_fam_notifications, NULL);
connection_valid = TRUE;
}
return connection_valid;
}
/* singleton object, instantiate and connect if it doesn't already exist */
/* otherwise just pass back a reference to the existing fam_connection */
static FAMConnection *
nautilus_monitor_get_fam ()
{
if (tried_connection) {
return fam_connection;
} else {
connection_valid = nautilus_monitor_establish_connection();
tried_connection = TRUE;
return fam_connection;
}
}
/* give a request, find what path was used to create it */
static const char *
nautilus_monitor_find_path_from_request (GList *list, FAMRequest request) {
URIRequest *uri_request;
GList *p;
gboolean found = FALSE;
for (p = list; (p != NULL) && (!found); p = p->next) {
uri_request = (URIRequest *)p->data;
if (uri_request->request.reqnum == request.reqnum) {
found = TRUE;
}
}
if (found) {
return uri_request->uri;
} else {
return NULL;
}
}
/* given a path, find the registered "request" that deals with it */
static const FAMRequest
nautilus_monitor_find_request_from_path (GList *list, const char *path) {
URIRequest *uri_request;
GList *p;
gboolean found = FALSE;
FAMRequest fr;
for (p = list; (p != NULL) && (!found); p = p->next) {
uri_request = (URIRequest *)p->data;
if (strcmp (uri_request->uri, path) == 0) {
found = TRUE;
}
}
if (found) {
return uri_request->request;
} else {
fr.reqnum = -1;
return fr;
}
}
/* delete first entry found in list that matches path */
static void
nautilus_monitor_delete_first_request_found (GList *list, const char *path) {
URIRequest *uri_request;
GList *p, *last;
gboolean found = FALSE;
for (p = list; (p != NULL) && (!found); p = p->next) {
uri_request = (URIRequest *)p->data;
if (strcmp (uri_request->uri, path) == 0) {
found = TRUE;
}
last = p;
}
if (found) {
g_free (uri_request->uri);
g_free (uri_request);
g_list_remove_link (list, last);
}
}
static char *
nautilus_monitor_get_uri (char * file_name, FAMRequest fr)
{
const char *base_uri;
char *uri_string;
/* FAM doesn't tell us when something is a full path, and when its just partial */
/* so we have to look and see if it starts with a / */
if (file_name[0] == '/') {
uri_string = g_strdup_printf ("file://%s", file_name);
} else {
/* lookup the directory registry that was used for this file notification */
/* and tack that on as a base uri fragment */
base_uri = nautilus_monitor_find_path_from_request (monitoring_list, fr);
uri_string = g_strdup_printf ("%s/%s", base_uri, file_name);
}
return uri_string;
}
static void
nautilus_monitor_process_fam_notifications (gpointer data, gint fd, GdkInputCondition condition)
{
FAMConnection *fam;
FAMEvent fam_event;
NautilusFile *file;
char *uri_string;
GList *uri_list;
/* get singleton object */
fam = nautilus_monitor_get_fam ();
/* We want to read as many events as are available. */
while (FAMPending(fam)) {
if (FAMNextEvent(fam, &fam_event) != 1) {
printf ("FAM-DEBUG: Nautilus' link to fam died\n");
gdk_input_remove(fd);
FAMClose(fam);
g_free(fam);
connection_valid = FALSE;
return;
}
switch (fam_event.code) {
case FAMChanged:
uri_string = nautilus_monitor_get_uri (fam_event.filename, fam_event.fr);
printf ("FAMChanged : %s\n", uri_string);
file = nautilus_file_get (uri_string);
nautilus_file_changed (file);
nautilus_file_unref (file);
break;
case FAMDeleted:
uri_string = nautilus_monitor_get_uri (fam_event.filename, fam_event.fr);
printf ("FAMDeleted : %s\n", uri_string);
uri_list = NULL;
uri_list = g_list_append (uri_list, uri_string);
nautilus_directory_notify_files_removed (uri_list);
g_free (uri_string);
g_list_free (uri_list);
break;
case FAMCreated:
uri_string = nautilus_monitor_get_uri (fam_event.filename, fam_event.fr);
printf ("FAMCreated : %s\n", uri_string);
uri_list = NULL;
uri_list = g_list_append (uri_list, uri_string);
nautilus_directory_notify_files_added (uri_list);
g_free (uri_string);
g_list_free (uri_list);
break;
case FAMStartExecuting:
case FAMStopExecuting:
case FAMAcknowledge:
case FAMExists:
case FAMEndExist:
case FAMMoved:
}
}
}
#endif /* !HAVE_FAM_H */
void
nautilus_monitor_add_file (const char *uri_string)
{
#if !HAVE_FAM_H
const char *uri_scheme;
char *path_name;
GnomeVFSURI *uri;
FAMConnection *fam;
URIRequest *uri_request;
/* get singleton object for connection */
fam = nautilus_monitor_get_fam ();
/* only try connecting once */
if (!connection_valid) return;
uri = gnome_vfs_uri_new (uri_string);
uri_scheme = gnome_vfs_uri_get_scheme (uri);
/* remove crufty entries registered for this URI */
/* FIXME: this breaks multiple windows? */
/* nautilus_monitor_remove (uri_string); */
/* we only know how to deal with things on the local filesystem for now */
if (strcmp (uri_scheme, "file") == 0) {
uri_request = g_new (URIRequest,1);
path_name = strdup (gnome_vfs_uri_get_path (uri));
FAMMonitorFile(fam, path_name, &uri_request->request, 0);
printf ("ADDED : %d) file monitor for %s\n", uri_request->request.reqnum, uri_string);
uri_request->uri = strdup (uri_string);
/* add this URI to the "Things we watch" list */
monitoring_list = g_list_append (monitoring_list, uri_request);
}
g_free (path_name);
gnome_vfs_uri_unref (uri);
#endif /* !HAVE_FAM_H */
}
void
nautilus_monitor_add_directory (const char *uri_string)
{
#if !HAVE_FAM_H
const char *uri_scheme;
char *path_name;
GnomeVFSURI *uri;
FAMConnection *fam;
URIRequest *uri_request;
fam = nautilus_monitor_get_fam ();
/* only try connection once */
if (!connection_valid) return;
uri = gnome_vfs_uri_new (uri_string);
uri_scheme = gnome_vfs_uri_get_scheme (uri);
/* remove crufty entries registered for this URI */
/* FIXME: this breaks multiple windows? */
/* nautilus_monitor_remove (uri_string); */
/* we only know how to deal with things on the local filesystem for now */
if (strcmp (uri_scheme, "file") == 0) {
uri_request = g_new (URIRequest, 1);
path_name = strdup (gnome_vfs_uri_get_path (uri));
FAMMonitorDirectory(fam, path_name, &uri_request->request, 0);
printf ("ADDED : %d) directory monitor for %s\n", uri_request->request.reqnum, uri_string);
uri_request->uri = strdup (uri_string);
/* add this uri to our list of "things we watch" */
monitoring_list = g_list_append (monitoring_list, uri_request);
}
g_free (path_name);
gnome_vfs_uri_unref (uri);
#endif /* !HAVE_FAM_H */
}
void
nautilus_monitor_remove (const char *uri)
{
#if !HAVE_FAM_H
FAMConnection *fam;
FAMRequest request, request2;
GnomeVFSURI *real_uri;
const char *uri_scheme;
int code;
fam = nautilus_monitor_get_fam ();
/* only try connecting once */
if (!connection_valid) return;
real_uri = gnome_vfs_uri_new (uri);
uri_scheme = gnome_vfs_uri_get_scheme (real_uri);
gnome_vfs_uri_unref (real_uri);
if (strcmp (uri_scheme, "file") == 0) {
/* keep looking for entries and deleting them */
request = nautilus_monitor_find_request_from_path (monitoring_list, uri);
while (request.reqnum != -1) {
request2 = request;
code = FAMCancelMonitor (fam, &request);
printf ("REMOVED : %d) directory monitor for %s (return %d)\n", request2.reqnum, uri, code);
nautilus_monitor_delete_first_request_found (monitoring_list, uri);
request = nautilus_monitor_find_request_from_path (monitoring_list, uri);
}
}
#endif /* !HAVE_FAM_H */
}
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-
nautilus-monitor.h: file and directory change monitoring for nautilus
Copyright (C) 2000 Eazel, Inc.
This program 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 2 of the
License, or (at your option) any later version.
This program 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 this program; if not, write to the
Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
Author: Seth Nickell <seth eazel com>
*/
#include <glib.h>
#include <gtk/gtk.h>
void nautilus_monitor_add_file (const char *uri_string);
void nautilus_monitor_add_directory (const char *uri_string);
void nautilus_monitor_remove (const char *uri_string);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]