Commit 7c16c979 authored by Sean Davis's avatar Sean Davis

Drop unused xfce-desktop-thumbnail.{c,h}

parent b011935a
......@@ -253,8 +253,6 @@ xfce4_screensaver_SOURCES = \
xfce-rr.h \
xfce-bg.c \
xfce-bg.h \
xfce-desktop-thumbnail.c \
xfce-desktop-thumbnail.h \
xfce-desktop-utils.c \
xfce-desktop-utils.h \
xfcekbd-indicator.c \
......
......@@ -30,7 +30,6 @@
#include <glib.h>
#include <gdk/gdk.h>
#include <gio/gio.h>
#include "xfce-desktop-thumbnail.h"
G_BEGIN_DECLS
......
/*
* mate-thumbnail.c: Utilities for handling thumbnails
*
* Copyright (C) 2002 Red Hat, Inc.
* Copyright (C) 2010 Carlos Garcia Campos <carlosgc@gnome.org>
*
* This file is part of the Mate Library.
*
* The Mate Library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* The Mate Library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with the Mate Library; see the file COPYING.LIB. If not,
* write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* Author: Alexander Larsson <alexl@redhat.com>
*/
#include <config.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <time.h>
#include <math.h>
#include <string.h>
#include <glib.h>
#include <stdio.h>
#define GDK_PIXBUF_ENABLE_BACKEND
#include <gdk-pixbuf/gdk-pixbuf.h>
#include "xfce-desktop-thumbnail.h"
#include <glib/gstdio.h>
#include <glib-unix.h>
#define SECONDS_BETWEEN_STATS 10
struct _XfceDesktopThumbnailFactoryPrivate {
XfceDesktopThumbnailSize size;
GMutex lock;
GList *thumbnailers;
GHashTable *mime_types_map;
GList *monitors;
GSettings *settings;
gboolean loaded : 1;
gboolean disabled : 1;
gchar **disabled_types;
};
static const char *appname = "mate-thumbnail-factory";
static void xfce_desktop_thumbnail_factory_init (XfceDesktopThumbnailFactory *factory);
static void xfce_desktop_thumbnail_factory_class_init (XfceDesktopThumbnailFactoryClass *class);
static gboolean
xfce_desktop_thumbnail_is_valid(GdkPixbuf *pixbuf,
const char *uri,
time_t mtime);
G_DEFINE_TYPE(XfceDesktopThumbnailFactory,
xfce_desktop_thumbnail_factory,
G_TYPE_OBJECT)
#define parent_class xfce_desktop_thumbnail_factory_parent_class
#define XFCE_DESKTOP_THUMBNAIL_FACTORY_GET_PRIVATE(object) \
(G_TYPE_INSTANCE_GET_PRIVATE ((object), XFCE_DESKTOP_TYPE_THUMBNAIL_FACTORY, XfceDesktopThumbnailFactoryPrivate))
typedef struct {
gint width;
gint height;
gint input_width;
gint input_height;
gboolean preserve_aspect_ratio;
} SizePrepareContext;
#define LOAD_BUFFER_SIZE 4096
#define THUMBNAILER_ENTRY_GROUP "Thumbnailer Entry"
#define THUMBNAILER_EXTENSION ".thumbnailer"
typedef struct {
volatile gint ref_count;
gchar *path;
gchar *try_exec;
gchar *command;
gchar **mime_types;
} Thumbnailer;
static Thumbnailer *
thumbnailer_ref (Thumbnailer *thumb)
{
g_return_val_if_fail (thumb != NULL, NULL);
g_return_val_if_fail (thumb->ref_count > 0, NULL);
g_atomic_int_inc (&thumb->ref_count);
return thumb;
}
static void
thumbnailer_unref (Thumbnailer *thumb)
{
g_return_if_fail (thumb != NULL);
g_return_if_fail (thumb->ref_count > 0);
if (g_atomic_int_dec_and_test (&thumb->ref_count))
{
g_free (thumb->path);
g_free (thumb->try_exec);
g_free (thumb->command);
g_strfreev (thumb->mime_types);
g_slice_free (Thumbnailer, thumb);
}
}
static Thumbnailer *
thumbnailer_load (Thumbnailer *thumb)
{
GKeyFile *key_file;
GError *error = NULL;
key_file = g_key_file_new ();
if (!g_key_file_load_from_file (key_file, thumb->path, 0, &error))
{
g_warning ("Failed to load thumbnailer from \"%s\": %s\n", thumb->path, error->message);
g_error_free (error);
thumbnailer_unref (thumb);
g_key_file_free (key_file);
return NULL;
}
if (!g_key_file_has_group (key_file, THUMBNAILER_ENTRY_GROUP))
{
g_warning ("Invalid thumbnailer: missing group \"%s\"\n", THUMBNAILER_ENTRY_GROUP);
thumbnailer_unref (thumb);
g_key_file_free (key_file);
return NULL;
}
thumb->command = g_key_file_get_string (key_file, THUMBNAILER_ENTRY_GROUP, "Exec", NULL);
if (!thumb->command)
{
g_warning ("Invalid thumbnailer: missing Exec key\n");
thumbnailer_unref (thumb);
g_key_file_free (key_file);
return NULL;
}
thumb->mime_types = g_key_file_get_string_list (key_file, THUMBNAILER_ENTRY_GROUP, "MimeType", NULL, NULL);
if (!thumb->mime_types)
{
g_warning ("Invalid thumbnailer: missing MimeType key\n");
thumbnailer_unref (thumb);
g_key_file_free (key_file);
return NULL;
}
thumb->try_exec = g_key_file_get_string (key_file, THUMBNAILER_ENTRY_GROUP, "TryExec", NULL);
g_key_file_free (key_file);
return thumb;
}
static Thumbnailer *
thumbnailer_reload (Thumbnailer *thumb)
{
g_return_val_if_fail (thumb != NULL, NULL);
g_free (thumb->command);
thumb->command = NULL;
g_strfreev (thumb->mime_types);
thumb->mime_types = NULL;
g_free (thumb->try_exec);
thumb->try_exec = NULL;
return thumbnailer_load (thumb);
}
static Thumbnailer *
thumbnailer_new (const gchar *path)
{
Thumbnailer *thumb;
thumb = g_slice_new0 (Thumbnailer);
thumb->ref_count = 1;
thumb->path = g_strdup (path);
return thumbnailer_load (thumb);
}
static gpointer
init_thumbnailers_dirs (gpointer data)
{
const gchar * const *data_dirs;
gchar **thumbs_dirs;
guint i, length;
data_dirs = g_get_system_data_dirs ();
length = g_strv_length ((char **) data_dirs);
thumbs_dirs = g_new (gchar *, length + 2);
thumbs_dirs[0] = g_build_filename (g_get_user_data_dir (), "thumbnailers", NULL);
for (i = 0; i < length; i++)
thumbs_dirs[i + 1] = g_build_filename (data_dirs[i], "thumbnailers", NULL);
thumbs_dirs[length + 1] = NULL;
return thumbs_dirs;
}
static const gchar * const *
get_thumbnailers_dirs (void)
{
static GOnce once_init = G_ONCE_INIT;
return g_once (&once_init, init_thumbnailers_dirs, NULL);
}
static void
xfce_desktop_thumbnail_factory_finalize (GObject *object)
{
XfceDesktopThumbnailFactory *factory;
XfceDesktopThumbnailFactoryPrivate *priv;
factory = XFCE_DESKTOP_THUMBNAIL_FACTORY (object);
priv = factory->priv;
if (priv->thumbnailers)
{
g_list_free_full (priv->thumbnailers, (GDestroyNotify)thumbnailer_unref);
priv->thumbnailers = NULL;
}
if (priv->mime_types_map)
{
g_hash_table_destroy (priv->mime_types_map);
priv->mime_types_map = NULL;
}
if (priv->monitors)
{
g_list_free_full (priv->monitors, (GDestroyNotify)g_object_unref);
priv->monitors = NULL;
}
g_mutex_clear (&priv->lock);
if (priv->disabled_types)
{
g_strfreev (priv->disabled_types);
priv->disabled_types = NULL;
}
if (priv->settings)
{
g_object_unref (priv->settings);
priv->settings = NULL;
}
if (G_OBJECT_CLASS (parent_class)->finalize)
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
/* These should be called with the lock held */
static void
xfce_desktop_thumbnail_factory_register_mime_types (XfceDesktopThumbnailFactory *factory,
Thumbnailer *thumb)
{
XfceDesktopThumbnailFactoryPrivate *priv = factory->priv;
gint i;
for (i = 0; thumb->mime_types[i]; i++)
{
if (!g_hash_table_lookup (priv->mime_types_map, thumb->mime_types[i]))
g_hash_table_insert (priv->mime_types_map,
g_strdup (thumb->mime_types[i]),
thumbnailer_ref (thumb));
}
}
static void
xfce_desktop_thumbnail_factory_add_thumbnailer (XfceDesktopThumbnailFactory *factory,
Thumbnailer *thumb)
{
XfceDesktopThumbnailFactoryPrivate *priv = factory->priv;
xfce_desktop_thumbnail_factory_register_mime_types (factory, thumb);
priv->thumbnailers = g_list_prepend (priv->thumbnailers, thumb);
}
static gboolean
remove_thumbnailer_from_mime_type_map (gchar *key,
Thumbnailer *value,
gchar *path)
{
return (strcmp (value->path, path) == 0);
}
static void
update_or_create_thumbnailer (XfceDesktopThumbnailFactory *factory,
const gchar *path)
{
XfceDesktopThumbnailFactoryPrivate *priv = factory->priv;
GList *l;
Thumbnailer *thumb;
gboolean found = FALSE;
g_mutex_lock (&priv->lock);
for (l = priv->thumbnailers; l && !found; l = g_list_next (l))
{
thumb = (Thumbnailer *)l->data;
if (strcmp (thumb->path, path) == 0)
{
found = TRUE;
/* First remove the mime_types associated to this thumbnailer */
g_hash_table_foreach_remove (priv->mime_types_map,
(GHRFunc)remove_thumbnailer_from_mime_type_map,
(gpointer)path);
if (!thumbnailer_reload (thumb))
priv->thumbnailers = g_list_delete_link (priv->thumbnailers, l);
else
xfce_desktop_thumbnail_factory_register_mime_types (factory, thumb);
}
}
if (!found)
{
thumb = thumbnailer_new (path);
if (thumb)
xfce_desktop_thumbnail_factory_add_thumbnailer (factory, thumb);
}
g_mutex_unlock (&priv->lock);
}
static void
remove_thumbnailer (XfceDesktopThumbnailFactory *factory,
const gchar *path)
{
XfceDesktopThumbnailFactoryPrivate *priv = factory->priv;
GList *l;
Thumbnailer *thumb;
g_mutex_lock (&priv->lock);
for (l = priv->thumbnailers; l; l = g_list_next (l))
{
thumb = (Thumbnailer *)l->data;
if (strcmp (thumb->path, path) == 0)
{
priv->thumbnailers = g_list_delete_link (priv->thumbnailers, l);
g_hash_table_foreach_remove (priv->mime_types_map,
(GHRFunc)remove_thumbnailer_from_mime_type_map,
(gpointer)path);
thumbnailer_unref (thumb);
break;
}
}
g_mutex_unlock (&priv->lock);
}
static void
thumbnailers_directory_changed (GFileMonitor *monitor,
GFile *file,
GFile *other_file,
GFileMonitorEvent event_type,
XfceDesktopThumbnailFactory *factory)
{
gchar *path;
switch (event_type)
{
case G_FILE_MONITOR_EVENT_CREATED:
case G_FILE_MONITOR_EVENT_CHANGED:
case G_FILE_MONITOR_EVENT_DELETED:
path = g_file_get_path (file);
if (!g_str_has_suffix (path, THUMBNAILER_EXTENSION))
{
g_free (path);
return;
}
if (event_type == G_FILE_MONITOR_EVENT_DELETED)
remove_thumbnailer (factory, path);
else
update_or_create_thumbnailer (factory, path);
g_free (path);
break;
default:
break;
}
}
static void
xfce_desktop_thumbnail_factory_load_thumbnailers (XfceDesktopThumbnailFactory *factory)
{
XfceDesktopThumbnailFactoryPrivate *priv = factory->priv;
const gchar * const *dirs;
guint i;
if (priv->loaded)
return;
dirs = get_thumbnailers_dirs ();
for (i = 0; dirs[i]; i++)
{
const gchar *path = dirs[i];
GDir *dir;
GFile *dir_file;
GFileMonitor *monitor;
const gchar *dirent;
dir = g_dir_open (path, 0, NULL);
if (!dir)
continue;
/* Monitor dir */
dir_file = g_file_new_for_path (path);
monitor = g_file_monitor_directory (dir_file,
G_FILE_MONITOR_NONE,
NULL, NULL);
if (monitor)
{
g_signal_connect (monitor, "changed",
G_CALLBACK (thumbnailers_directory_changed),
factory);
priv->monitors = g_list_prepend (priv->monitors, monitor);
}
g_object_unref (dir_file);
while ((dirent = g_dir_read_name (dir)))
{
Thumbnailer *thumb;
gchar *filename;
if (!g_str_has_suffix (dirent, THUMBNAILER_EXTENSION))
continue;
filename = g_build_filename (path, dirent, NULL);
thumb = thumbnailer_new (filename);
g_free (filename);
if (thumb)
xfce_desktop_thumbnail_factory_add_thumbnailer (factory, thumb);
}
g_dir_close (dir);
}
priv->loaded = TRUE;
}
static void
external_thumbnailers_disabled_all_changed_cb (GSettings *settings,
const gchar *key,
XfceDesktopThumbnailFactory *factory)
{
XfceDesktopThumbnailFactoryPrivate *priv = factory->priv;
g_mutex_lock (&priv->lock);
priv->disabled = g_settings_get_boolean (priv->settings, "disable-all");
if (priv->disabled)
{
g_strfreev (priv->disabled_types);
priv->disabled_types = NULL;
}
else
{
priv->disabled_types = g_settings_get_strv (priv->settings, "disable");
xfce_desktop_thumbnail_factory_load_thumbnailers (factory);
}
g_mutex_unlock (&priv->lock);
}
static void
external_thumbnailers_disabled_changed_cb (GSettings *settings,
const gchar *key,
XfceDesktopThumbnailFactory *factory)
{
XfceDesktopThumbnailFactoryPrivate *priv = factory->priv;
g_mutex_lock (&priv->lock);
if (!priv->disabled)
{
g_strfreev (priv->disabled_types);
priv->disabled_types = g_settings_get_strv (priv->settings, "disable");
}
g_mutex_unlock (&priv->lock);
}
static void
xfce_desktop_thumbnail_factory_init (XfceDesktopThumbnailFactory *factory)
{
XfceDesktopThumbnailFactoryPrivate *priv;
factory->priv = XFCE_DESKTOP_THUMBNAIL_FACTORY_GET_PRIVATE (factory);
priv = factory->priv;
priv->size = XFCE_DESKTOP_THUMBNAIL_SIZE_NORMAL;
priv->mime_types_map = g_hash_table_new_full (g_str_hash,
g_str_equal,
(GDestroyNotify)g_free,
(GDestroyNotify)thumbnailer_unref);
g_mutex_init (&priv->lock);
priv->settings = g_settings_new ("org.mate.thumbnailers");
g_signal_connect (priv->settings, "changed::disable-all",
G_CALLBACK (external_thumbnailers_disabled_all_changed_cb),
factory);
g_signal_connect (priv->settings, "changed::disable",
G_CALLBACK (external_thumbnailers_disabled_changed_cb),
factory);
priv->disabled = g_settings_get_boolean (priv->settings, "disable-all");
if (!priv->disabled)
priv->disabled_types = g_settings_get_strv (priv->settings, "disable");
if (!priv->disabled)
xfce_desktop_thumbnail_factory_load_thumbnailers (factory);
}
static void
xfce_desktop_thumbnail_factory_class_init (XfceDesktopThumbnailFactoryClass *class)
{
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = xfce_desktop_thumbnail_factory_finalize;
g_type_class_add_private (class, sizeof (XfceDesktopThumbnailFactoryPrivate));
}
/**
* xfce_desktop_thumbnail_factory_lookup:
* @factory: a #XfceDesktopThumbnailFactory
* @uri: the uri of a file
* @mtime: the mtime of the file
*
* Tries to locate an existing thumbnail for the file specified.
*
* Usage of this function is threadsafe.
*
* Return value: (transfer full): The absolute path of the thumbnail, or %NULL if none exist.
*
* Since: 2.2
**/
char *
xfce_desktop_thumbnail_factory_lookup (XfceDesktopThumbnailFactory *factory,
const char *uri,
time_t mtime)
{
XfceDesktopThumbnailFactoryPrivate *priv = factory->priv;
char *path, *file;
GChecksum *checksum;
guint8 digest[16];
gsize digest_len = sizeof (digest);
GdkPixbuf *pixbuf;
gboolean res;
g_return_val_if_fail (uri != NULL, NULL);
res = FALSE;
checksum = g_checksum_new (G_CHECKSUM_MD5);
g_checksum_update (checksum, (const guchar *) uri, strlen (uri));
g_checksum_get_digest (checksum, digest, &digest_len);
g_assert (digest_len == 16);
file = g_strconcat (g_checksum_get_string (checksum), ".png", NULL);