From 8a33bf71c062bc53e2abb55e02a07f11846dc4f2 Mon Sep 17 00:00:00 2001
From: Benedikt Meurer <benny@xfce.org>
Date: Sat, 27 Aug 2005 21:36:58 +0000
Subject: [PATCH] 2005-08-27	Benedikt Meurer <benny@xfce.org>

	* thunar-vfs/thunar-vfs-info.{c,h}: Add support to pass hints from the
	  ThunarVfsInfo to the upper layers. Use these hints to pass icon and
	  name information from .desktop files.
	* thunar-vfs/thunar-vfs.symbols: Add new symbols.
	* thunar/thunar-local-file.c: Use the new hints to display appropriate
	  names and icons for .desktop files.




(Old svn revision: 17137)
---
 ChangeLog                     |  9 ++++
 thunar-vfs/thunar-vfs-info.c  | 77 +++++++++++++++++++++++++++++++++++
 thunar-vfs/thunar-vfs-info.h  | 33 +++++++++++++--
 thunar-vfs/thunar-vfs.symbols |  2 +
 thunar/thunar-local-file.c    | 28 ++++++-------
 5 files changed, 132 insertions(+), 17 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index b8513213d..a5f2c6c06 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2005-08-27	Benedikt Meurer <benny@xfce.org>
+
+	* thunar-vfs/thunar-vfs-info.{c,h}: Add support to pass hints from the
+	  ThunarVfsInfo to the upper layers. Use these hints to pass icon and
+	  name information from .desktop files.
+	* thunar-vfs/thunar-vfs.symbols: Add new symbols.
+	* thunar/thunar-local-file.c: Use the new hints to display appropriate
+	  names and icons for .desktop files.
+
 2005-08-27	Benedikt Meurer <benny@xfce.org>
 
 	* thunar-vfs/thunar-vfs-trash.c: Use ThunarVfsMonitor instead of
diff --git a/thunar-vfs/thunar-vfs-info.c b/thunar-vfs/thunar-vfs-info.c
index ad5e0640e..ecd3c25e8 100644
--- a/thunar-vfs/thunar-vfs-info.c
+++ b/thunar-vfs/thunar-vfs-info.c
@@ -61,8 +61,10 @@ thunar_vfs_info_new_for_uri (ThunarVfsURI *uri,
   ThunarVfsMimeDatabase *database;
   ThunarVfsInfo         *info;
   const gchar           *path;
+  const gchar           *str;
   struct stat            lsb;
   struct stat            sb;
+  XfceRc                *rc;
 
   g_return_val_if_fail (THUNAR_VFS_IS_URI (uri), NULL);
   g_return_val_if_fail (error == NULL || *error == NULL, NULL);
@@ -80,6 +82,7 @@ thunar_vfs_info_new_for_uri (ThunarVfsURI *uri,
   info->uri = thunar_vfs_uri_ref (uri);
   info->ref_count = 1;
   info->display_name = thunar_vfs_uri_get_display_name (uri);
+  info->hints = NULL;
 
   if (G_LIKELY (!S_ISLNK (lsb.st_mode)))
     {
@@ -164,6 +167,34 @@ thunar_vfs_info_new_for_uri (ThunarVfsURI *uri,
     }
   exo_object_unref (EXO_OBJECT (database));
 
+  /* check whether we have a .desktop file here */
+  if (strcmp (info->mime_info->name, "application/x-desktop") == 0)
+    {
+      /* try to query the hints from the .desktop file */
+      rc = xfce_rc_simple_open (path, TRUE);
+      if (G_LIKELY (rc != NULL))
+        {
+          /* we're only interested in the desktop data */
+          xfce_rc_set_group (rc, "Desktop Entry");
+
+          /* allocate the hints for the VFS info */
+          info->hints = g_new0 (gchar *, THUNAR_VFS_FILE_N_HINTS);
+
+          /* check if we have a valid icon info */
+          str = xfce_rc_read_entry (rc, "Icon", NULL);
+          if (G_LIKELY (str != NULL))
+            info->hints[THUNAR_VFS_FILE_HINT_ICON] = g_strdup (str);
+
+          /* check if we have a valid name info */
+          str = xfce_rc_read_entry (rc, "Name", NULL);
+          if (G_LIKELY (str != NULL))
+            info->hints[THUNAR_VFS_FILE_HINT_NAME] = g_strdup (str);
+
+          /* close the file */
+          xfce_rc_close (rc);
+        }
+    }
+
   return info;
 }
 
@@ -183,7 +214,13 @@ thunar_vfs_info_ref (ThunarVfsInfo *info)
 {
   g_return_val_if_fail (info->ref_count > 0, NULL);
 
+#if defined(__GNUC__) && defined(__i386__) && defined(__OPTIMIZE__)
+  __asm__ __volatile__ ("lock; incl %0"
+                        : "=m" (info->ref_count)
+                        : "m" (info->ref_count));
+#else
   g_atomic_int_inc (&info->ref_count);
+#endif
 
   return info;
 }
@@ -201,15 +238,26 @@ thunar_vfs_info_ref (ThunarVfsInfo *info)
 void
 thunar_vfs_info_unref (ThunarVfsInfo *info)
 {
+  guint n;
+
   g_return_if_fail (info != NULL);
   g_return_if_fail (info->ref_count > 0);
 
   if (g_atomic_int_dec_and_test (&info->ref_count))
     {
+      /* drop the public info part */
       thunar_vfs_mime_info_unref (info->mime_info);
       thunar_vfs_uri_unref (info->uri);
       g_free (info->display_name);
 
+      /* free the hints (if any) */
+      if (G_UNLIKELY (info->hints != NULL))
+        {
+          for (n = 0; n < THUNAR_VFS_FILE_N_HINTS; ++n)
+            g_free (info->hints[n]);
+          g_free (info->hints);
+        }
+
 #ifndef G_DISABLE_CHECKS
       memset (info, 0xaa, sizeof (*info));
 #endif
@@ -220,6 +268,35 @@ thunar_vfs_info_unref (ThunarVfsInfo *info)
 
 
 
+/**
+ * thunar_vfs_info_get_hint:
+ * @info : a #ThunarVfsInfo.
+ * @hint : a #ThunarVfsFileHint.
+ *
+ * If @info provides the @hint, then the value available for
+ * @hint will be returned. Else %NULL will be returned.
+ *
+ * The returned string - if any - is owned by @info and must
+ * not be freed by the caller. You should thereby note that the
+ * returned string is no longer valid after @info is finalized.
+ *
+ * Return value: the string stored for @hint on @info or %NULL.
+ **/
+const gchar*
+thunar_vfs_info_get_hint (const ThunarVfsInfo *info,
+                          ThunarVfsFileHint    hint)
+{
+  g_return_val_if_fail (info != NULL, NULL);
+  g_return_val_if_fail (info->ref_count > 0, NULL);
+
+  if (G_UNLIKELY (hint < THUNAR_VFS_FILE_N_HINTS && info->hints != NULL))
+    return info->hints[hint];
+
+  return NULL;
+}
+
+
+
 /**
  * thunar_vfs_info_matches:
  * @a : a #ThunarVfsInfo.
diff --git a/thunar-vfs/thunar-vfs-info.h b/thunar-vfs/thunar-vfs-info.h
index 3c4564ab2..1ae3f75de 100644
--- a/thunar-vfs/thunar-vfs-info.h
+++ b/thunar-vfs/thunar-vfs-info.h
@@ -77,7 +77,7 @@ typedef enum {
  *
  * Special flags and permissions of a filesystem entity.
  **/
-typedef enum {
+typedef enum { /*< flags >*/
   THUNAR_VFS_FILE_MODE_SUID       = 04000,
   THUNAR_VFS_FILE_MODE_SGID       = 02000,
   THUNAR_VFS_FILE_MODE_STICKY     = 01000,
@@ -106,11 +106,34 @@ typedef enum {
  * Flags providing additional information about the
  * file system entity.
  **/
-typedef enum {
+typedef enum { /*< flags >*/
   THUNAR_VFS_FILE_FLAGS_NONE    = 0,
   THUNAR_VFS_FILE_FLAGS_SYMLINK = 1 << 0,
 } ThunarVfsFileFlags;
 
+/**
+ * ThunarVfsFileHint:
+ * @THUNAR_VFS_FILE_HINT_ICON : The name of an icon or the path to
+ *                              an image file, which should be used
+ *                              to represent the file (e.g. the Icon
+ *                              entry specified in a .desktop file).
+ * @THUNAR_VFS_FILE_HINT_NAME : A more precise name to represent the
+ *                              file, which is different from the
+ *                              real file name (e.g. the Name entry
+ *                              specified in a .desktop file).
+ *
+ * Additional hints that may be provided by the file system
+ * backend.
+ *
+ * You can use #thunar_vfs_info_get_hint() to query hints from a
+ * #ThunarVfsInfo.
+ **/
+typedef enum {
+  THUNAR_VFS_FILE_HINT_ICON,
+  THUNAR_VFS_FILE_HINT_NAME,
+  THUNAR_VFS_FILE_N_HINTS,
+} ThunarVfsFileHint;
+
 /**
  * ThunarVfsFileDevice:
  * Datatype to represent the device number of a file.
@@ -198,7 +221,8 @@ typedef struct
   gchar *display_name;
 
   /*< private >*/
-  gint ref_count;
+  gchar **hints;
+  gint    ref_count;
 } ThunarVfsInfo;
 
 ThunarVfsInfo *thunar_vfs_info_new_for_uri (ThunarVfsURI        *uri,
@@ -207,6 +231,9 @@ ThunarVfsInfo *thunar_vfs_info_new_for_uri (ThunarVfsURI        *uri,
 ThunarVfsInfo *thunar_vfs_info_ref         (ThunarVfsInfo       *info);
 void           thunar_vfs_info_unref       (ThunarVfsInfo       *info);
 
+const gchar   *thunar_vfs_info_get_hint    (const ThunarVfsInfo *info,
+                                            ThunarVfsFileHint    hint);
+
 gboolean       thunar_vfs_info_matches     (const ThunarVfsInfo *a,
                                             const ThunarVfsInfo *b);
 
diff --git a/thunar-vfs/thunar-vfs.symbols b/thunar-vfs/thunar-vfs.symbols
index 212968251..c992999fc 100644
--- a/thunar-vfs/thunar-vfs.symbols
+++ b/thunar-vfs/thunar-vfs.symbols
@@ -52,6 +52,7 @@ thunar_vfs_unlink
 thunar_vfs_info_new_for_uri
 thunar_vfs_info_ref
 thunar_vfs_info_unref
+thunar_vfs_info_get_hint
 thunar_vfs_info_matches
 thunar_vfs_info_list_free
 #endif
@@ -61,6 +62,7 @@ thunar_vfs_info_list_free
 #if IN_HEADER(__THUNAR_VFS_ENUM_TYPES_H__)
 #if IN_SOURCE(__THUNAR_VFS_ENUM_TYPES_C__)
 thunar_vfs_file_flags_get_type G_GNUC_CONST
+thunar_vfs_file_hint_get_type G_GNUC_CONST
 thunar_vfs_file_mode_get_type G_GNUC_CONST
 thunar_vfs_file_type_get_type G_GNUC_CONST
 thunar_vfs_interactive_job_response_get_type G_GNUC_CONST
diff --git a/thunar/thunar-local-file.c b/thunar/thunar-local-file.c
index 41e91115a..17458727c 100644
--- a/thunar/thunar-local-file.c
+++ b/thunar/thunar-local-file.c
@@ -27,7 +27,6 @@
 
 
 static void               thunar_local_file_class_init        (ThunarLocalFileClass   *klass);
-static void               thunar_local_file_init              (ThunarLocalFile        *local_file);
 static void               thunar_local_file_finalize          (GObject                *object);
 static ThunarFile        *thunar_local_file_get_parent        (ThunarFile             *file,
                                                                GError                **error);
@@ -103,7 +102,7 @@ thunar_local_file_get_type (void)
         NULL,
         sizeof (ThunarLocalFile),
         512u,
-        (GInstanceInitFunc) thunar_local_file_init,
+        NULL,
         NULL,
       };
 
@@ -155,14 +154,6 @@ thunar_local_file_class_init (ThunarLocalFileClass *klass)
 
 
 
-static void
-thunar_local_file_init (ThunarLocalFile *local_file)
-{
-  local_file->info = NULL;
-}
-
-
-
 static void
 thunar_local_file_finalize (GObject *object)
 {
@@ -244,11 +235,17 @@ static const gchar*
 thunar_local_file_get_display_name (ThunarFile *file)
 {
   ThunarLocalFile *local_file = THUNAR_LOCAL_FILE (file);
+  const gchar     *name;
 
   /* root directory is always displayed as 'Filesystem' */
   if (thunar_vfs_uri_is_root (local_file->info->uri))
     return _("Filesystem");
 
+  /* check if the VFS info provides a name hint */
+  name = thunar_vfs_info_get_hint (local_file->info, THUNAR_VFS_FILE_HINT_NAME);
+  if (G_UNLIKELY (name != NULL))
+    return name;
+
   return local_file->info->display_name;
 }
 
@@ -259,10 +256,8 @@ thunar_local_file_get_special_name (ThunarFile *file)
 {
   ThunarLocalFile *local_file = THUNAR_LOCAL_FILE (file);
 
-  /* root and home dir have special names */
-  if (thunar_vfs_uri_is_root (local_file->info->uri))
-    return _("Filesystem");
-  else if (thunar_vfs_uri_is_home (local_file->info->uri))
+  /* root dir has special name, root is handled in get_display_name() */
+  if (thunar_vfs_uri_is_home (local_file->info->uri))
     return _("Home");
 
   return thunar_file_get_display_name (file);
@@ -405,6 +400,11 @@ thunar_local_file_get_icon_name (ThunarFile   *file,
       return "gnome-fs-home";
     }
 
+  /* check if the VFS info specifies an icon hint */
+  icon_name = thunar_vfs_info_get_hint (local_file->info, THUNAR_VFS_FILE_HINT_ICON);
+  if (G_UNLIKELY (icon_name != NULL && gtk_icon_theme_has_icon (icon_theme, icon_name)))
+    return icon_name;
+
   /* default is the mime type icon */
   icon_name = thunar_vfs_mime_info_lookup_icon_name (local_file->info->mime_info, icon_theme);
 
-- 
GitLab