Re: The status of Freedesktop.org MIME support?



Jonathan Blandford wrote:
Argh!  I forgot to update this when I first moved to the freedesktop
system.  This should be pretty easy to fix.  We need to change
gnome-vfs-mime-monitor.c to monitor the correct files -- If anyone is
feeling motivated, they can look into doing this.  Otherwise, I'll try
to get to it.

Here's a patch. There are some issues though:

- It works in the test program I wrote (attached vfs.c) but not in Nautilus. It seems GnomeVFSMimeMonitor's "data_changed" signal is never sent. Nautilus (2.6.0 and 2.6.1) seems to be completely broken in this area. It doesn't detect changes in ~/.gnome/mime-info either. And manually associating a mime type with unknown files using the GUI doesn't work at all.

By the way, I get a lot of debug messages from Nautilus:
** (nautilus:6840): WARNING **: No description found for mime type "application/x-executable" (file is "vfs"), please tell the gnome-vfs mailing list. ** (nautilus:6840): WARNING **: No description found for mime type "text/x-csrc" (file is "vfs.c"), please tell the gnome-vfs mailing list.
[snip]

gnome-vfs (or maybe just Nautilus?) doesn't seem to use the Freedesktop.org MIME database's descriptions.

- Non-existant XDG MIME folders are not watched (such as /usr/local/share/mime, which doesn't exist on my system). This is because GnomeVFSMonitor keeps generating DELETED-type events. The problem now is that if you create /usr/local/share/mime later, gnome-vfs will not notice it.
--- ../original/gnome-vfs-2.6.1/libgnomevfs/gnome-vfs-mime-info.c	2003-07-18 00:33:27.000000000 +0200
+++ gnome-vfs-mime-info.c	2004-05-28 14:14:26.000000000 +0200
@@ -33,6 +33,7 @@
 #include "gnome-vfs-mime-private.h"
 #include "gnome-vfs-mime.h"
 #include "gnome-vfs-private-utils.h"
+#include "xdgmime.h"
 #include <dirent.h>
 #include <stdio.h>
 #include <string.h>
@@ -122,7 +123,7 @@
 #define DELETED_VALUE "moilegrandvizir"
 
 /* These ones are used to automatically reload mime info on demand */
-static mime_dir_source_t gnome_mime_dir, user_mime_dir;
+static mime_dir_source_t gnome_mime_dir, user_mime_dir, xdg_mime_dir;
 static time_t last_checked;
 
 /* To initialize the module automatically */
@@ -136,6 +137,15 @@
    language level */
 static int previous_key_lang_level = -1;
 
+
+#ifdef G_THREADS_ENABLED
+
+/* We lock this mutex whenever we modify global state in this module.  */
+G_LOCK_DEFINE_STATIC (mime_mutex);
+
+#endif /* G_LOCK_DEFINE_STATIC */
+
+
 /*
  * A hash table containing all of the Mime records for specific
  * mime types (full description, like image/png)
@@ -176,6 +186,12 @@
 	user_mime_dir.force_reload = TRUE;
 }
 
+void
+_gnome_vfs_mime_info_mark_xdg_mime_dir_dirty (void)
+{
+	xdg_mime_dir.force_reload = TRUE;
+}
+
 static gboolean
 does_string_contain_caps (const char *string)
 {
@@ -681,7 +697,7 @@
 	if (gnome_vfs_is_frozen > 0)
 		return;
 
-	if (gnome_mime_dir.force_reload || user_mime_dir.force_reload)
+	if (gnome_mime_dir.force_reload || user_mime_dir.force_reload || xdg_mime_dir.force_reload)
 		need_reload = TRUE;
 	else if (now > last_checked + 5) {
 		if (stat (gnome_mime_dir.dirname, &s) != -1 &&
@@ -714,6 +730,10 @@
 	if (registered_types_user != NULL) {
 		g_hash_table_foreach_remove (registered_types_user, remove_keys, NULL);
 	}
+
+	G_LOCK (mime_mutex);
+	xdg_mime_shutdown ();
+	G_UNLOCK (mime_mutex);
 }
 
 /**
@@ -766,6 +786,7 @@
 	/* 3. clear our force flags */
 	gnome_mime_dir.force_reload = FALSE;
 	user_mime_dir.force_reload = FALSE;
+	xdg_mime_dir.force_reload = FALSE;
 
 	/* 3. Tell anyone who cares */
 	_gnome_vfs_mime_monitor_emit_data_changed (gnome_vfs_mime_monitor_get ());
--- ../original/gnome-vfs-2.6.1/libgnomevfs/gnome-vfs-mime-private.h	2004-01-14 17:00:23.000000000 +0100
+++ gnome-vfs-mime-private.h	2004-05-28 14:07:17.000000000 +0200
@@ -23,6 +23,7 @@
 #ifndef GNOME_VFS_MIME_PRIVATE_H
 #define GNOME_VFS_MIME_PRIVATE_H
 
+#include <libgnomevfs/gnome-vfs-monitor.h>
 #include <libgnomevfs/gnome-vfs-mime-monitor.h>
 
 G_BEGIN_DECLS
@@ -39,9 +40,12 @@
 gboolean         _gnome_vfs_file_date_tracker_date_has_changed    (FileDateTracker *tracker);
 void             _gnome_vfs_mime_info_mark_gnome_mime_dir_dirty  (void);
 void             _gnome_vfs_mime_info_mark_user_mime_dir_dirty   (void);
+void             _gnome_vfs_mime_info_mark_xdg_mime_dir_dirty   (void);
 
 char * _gnome_vfs_get_slow_mime_type (const char *text_uri);
 
+GnomeVFSMonitorHandle **_gnome_vfs_monitor_add_xdg_dir (const gchar *dir);
+
 
 G_END_DECLS
 
--- ../original/gnome-vfs-2.6.1/libgnomevfs/gnome-vfs-mime-monitor.c	2004-01-22 13:29:10.000000000 +0100
+++ gnome-vfs-mime-monitor.c	2004-05-28 14:13:28.000000000 +0200
@@ -34,7 +34,8 @@
 
 enum {
 	LOCAL_MIME_DIR,
-	GNOME_MIME_DIR
+	GNOME_MIME_DIR,
+	XDG_MIME_DIR
 };
 
 static guint signals[LAST_SIGNAL];
@@ -51,10 +52,12 @@
 {
 	GnomeVFSMonitorHandle *global_handle;
 	GnomeVFSMonitorHandle *local_handle;
+	GnomeVFSMonitorHandle *xdg_handle;
 
 	/* The hoops I jump through */
 	MonitorCallbackData *gnome_callback_data;
 	MonitorCallbackData *local_callback_data;
+	MonitorCallbackData *xdg_callback_data;
 
 	guint mime_update_tag;
 };
@@ -97,6 +100,7 @@
 
 	monitor->priv->gnome_callback_data = g_new (MonitorCallbackData, 1);
 	monitor->priv->local_callback_data = g_new (MonitorCallbackData, 1);
+	monitor->priv->xdg_callback_data   = g_new (MonitorCallbackData, 1);
 
 	/* FIXME: Bug #80268.  These wouldn't be private members if we had a
 	 * _full variant.  However, if I want to clean them up, I need to keep
@@ -105,6 +109,8 @@
 	monitor->priv->gnome_callback_data->monitor = monitor;
 	monitor->priv->local_callback_data->type = LOCAL_MIME_DIR;
 	monitor->priv->local_callback_data->monitor = monitor;
+	monitor->priv->xdg_callback_data->type = XDG_MIME_DIR;
+	monitor->priv->xdg_callback_data->monitor = monitor;
 
 	mime_dir = g_strdup (DATADIR "/mime-info");
 	gnome_vfs_monitor_add (&monitor->priv->global_handle,
@@ -150,6 +156,8 @@
 		_gnome_vfs_mime_info_mark_gnome_mime_dir_dirty ();
 	else if (monitor_callback_data->type == LOCAL_MIME_DIR)
 		_gnome_vfs_mime_info_mark_user_mime_dir_dirty ();
+	else if (monitor_callback_data->type == XDG_MIME_DIR)
+		_gnome_vfs_mime_info_mark_xdg_mime_dir_dirty ();
 
 	/* We delay the callback for a short while in order to combine several
 	 * changes, something which often happens due to several fam events.
@@ -225,3 +233,20 @@
 
 	return type;
 }
+
+GnomeVFSMonitorHandle **
+_gnome_vfs_monitor_add_xdg_dir (const gchar *dir)
+{
+	GnomeVFSMIMEMonitor *monitor;
+
+	monitor = gnome_vfs_mime_monitor_get ();
+	if (!g_file_test (dir, G_FILE_TEST_EXISTS)) {
+		return &monitor->priv->xdg_handle;
+	}
+	gnome_vfs_monitor_add (&monitor->priv->xdg_handle,
+			       dir,
+			       GNOME_VFS_MONITOR_DIRECTORY,
+			       mime_dir_changed_callback,
+			       monitor->priv->xdg_callback_data);
+	return &monitor->priv->xdg_handle;
+}
--- ../original/gnome-vfs-2.6.1/libgnomevfs/xdgmime.c	2004-01-20 21:02:32.000000000 +0100
+++ xdgmime.c	2004-05-28 14:38:15.000000000 +0200
@@ -29,6 +29,9 @@
 #include "xdgmimeint.h"
 #include "xdgmimeglob.h"
 #include "xdgmimemagic.h"
+#include <libgnomevfs/gnome-vfs-monitor.h>
+#include <libgnomevfs/gnome-vfs-mime-private.h>
+#include <libgnomevfs/gnome-vfs-ops.h>
 #include <stdio.h>
 #include <string.h>
 #include <sys/stat.h>
@@ -39,6 +42,7 @@
 static XdgGlobHash *global_hash = NULL;
 static XdgMimeMagic *global_magic = NULL;
 const char *xdg_mime_type_unknown = "application/octet-stream";
+static GnomeVFSMonitorHandle **xdg_monitor_handle = NULL;
 
 static void
 _xdg_mime_init_from_directory (const char *directory)
@@ -56,6 +60,10 @@
   strcat (file_name, "/mime/magic");
   _xdg_mime_magic_read_from_file (global_magic, file_name);
   free (file_name);
+
+  file_name = g_strdup_printf ("%s/mime", directory);
+  xdg_monitor_handle = _gnome_vfs_monitor_add_xdg_dir (file_name);
+  g_free (file_name);
 }
 
 static void
@@ -247,6 +255,13 @@
       _xdg_mime_magic_free (global_magic);
       global_magic = NULL;
 
+      if (xdg_monitor_handle && *xdg_monitor_handle)
+        {
+          gnome_vfs_monitor_cancel (*xdg_monitor_handle);
+          *xdg_monitor_handle = NULL;
+          xdg_monitor_handle = NULL;
+        }
+
       initted = 0;
     }
 }
#include <glib.h>
#include <stdio.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#include <libgnomevfs/gnome-vfs-mime-monitor.h>
#include <libgnomevfs/gnome-vfs-mime-handlers.h>

gchar *filename;

void
changed_cb ()
{
	GnomeVFSFileInfo info;
	gnome_vfs_get_file_info (filename, &info, GNOME_VFS_FILE_INFO_GET_MIME_TYPE | GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE);
	gnome_vfs_mime_get_description ("application/x-autopackage"); /* trigger reload of MIME database */
	g_print ("%s\n", gnome_vfs_file_info_get_mime_type (&info));
}

/* Detect the mime type of the file specified by argv[1].
   Re-detect mime type every time the mime database has changed. */
int
main (int argc, char *argv[])
{
	if (!argv[1])
	{
		g_print ("Usage: vfs <FILENAME>\n");
		return 1;
	}

	filename = argv[1];
	gnome_vfs_init ();
	changed_cb ();
	g_signal_connect (gnome_vfs_mime_monitor_get (), "data_changed",
		changed_cb, NULL);
	g_main_loop_run (g_main_loop_new (NULL, FALSE));

	return 0;
}


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