gnome-desktop r5252 - in trunk: . libgnome-desktop libgnome-desktop/libgnome libgnome-desktop/libgnomeui
- From: alexl svn gnome org
- To: svn-commits-list gnome org
- Subject: gnome-desktop r5252 - in trunk: . libgnome-desktop libgnome-desktop/libgnome libgnome-desktop/libgnomeui
- Date: Tue, 7 Oct 2008 19:12:19 +0000 (UTC)
Author: alexl
Date: Tue Oct 7 19:12:18 2008
New Revision: 5252
URL: http://svn.gnome.org/viewvc/gnome-desktop?rev=5252&view=rev
Log:
2008-10-07 Alexander Larsson <alexl redhat com>
Removes the dependency on libgnome* by removing some
ancient code that uses it and pulling in some code from
libgnome that we need internally and that other apps that
don't want to require libgnome needs.
* gnome-desktop-thumbnail.c: Added.
* gnome-thumbnail-pixbuf-utils.c: Added.
* libgnomeui/gnome-desktop-thumbnail.h: Added.
Added a copy of gnome-thumbnail from libgnomeui, renamed
to GnomeDesktopThumbnail.
* gnome-desktop-utils.c: Added.
* libgnome/gnome-desktop-utils.h: Added.
Add gnome_desktop_prepend_terminal_to_vector (from libgnome).
Used internally and by nautilus.
* gnome-ditem-edit.c:
* gnome-hint.c:
* test-hint.c:
* test-ditem-edit.c:
* libgnomeui/gnome-ditem-edit.h: Removed.
* libgnomeui/gnome-hint.h: Removed.
Remove gnome-ditem-edit and gnome-hint.
* gnome-bg.c:
* libgnomeui/gnome-bg.h:
Use GnomeDesktopThumbnail instead of GnomeThumbnail
* gnome-desktop-2.0.pc.in:
Remove libgnomeui dependency
* gnome-desktop-item.c:
* libgnome/gnome-desktop-item.h:
Don't use libgnome* stuff.
If needed, instead use the new copies from gnome-desktop.
This drops backwards compat for really old gnome1 and kde2 icons
in desktop files...
* test-ditem.c:
Don't use gnome-program.
* Makefile.am:
* libgnome/Makefile.am:
* libgnomeui/Makefile.am:
Update for removed/added files
2008-10-07 Alexander Larsson <alexl redhat com>
* configure.in:
Bump version to 2.25.1
Remove dependencies on libgnome*
Added:
trunk/libgnome-desktop/gnome-desktop-thumbnail.c
trunk/libgnome-desktop/gnome-desktop-utils.c
trunk/libgnome-desktop/gnome-thumbnail-pixbuf-utils.c
trunk/libgnome-desktop/libgnome/gnome-desktop-utils.h
trunk/libgnome-desktop/libgnomeui/gnome-desktop-thumbnail.h
Removed:
trunk/libgnome-desktop/gnome-ditem-edit.c
trunk/libgnome-desktop/gnome-hint.c
trunk/libgnome-desktop/libgnomeui/gnome-ditem-edit.h
trunk/libgnome-desktop/libgnomeui/gnome-hint.h
trunk/libgnome-desktop/test-ditem-edit.c
trunk/libgnome-desktop/test-hint.c
Modified:
trunk/ChangeLog
trunk/configure.in
trunk/libgnome-desktop/ChangeLog
trunk/libgnome-desktop/Makefile.am
trunk/libgnome-desktop/gnome-bg.c
trunk/libgnome-desktop/gnome-desktop-2.0.pc.in
trunk/libgnome-desktop/gnome-desktop-item.c
trunk/libgnome-desktop/libgnome/Makefile.am
trunk/libgnome-desktop/libgnome/gnome-desktop-item.h
trunk/libgnome-desktop/libgnomeui/Makefile.am
trunk/libgnome-desktop/libgnomeui/gnome-bg.h
trunk/libgnome-desktop/test-ditem.c
Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in (original)
+++ trunk/configure.in Tue Oct 7 19:12:18 2008
@@ -1,4 +1,4 @@
-AC_INIT([gnome-desktop], [2.24.1],
+AC_INIT([gnome-desktop], [2.25.1],
[http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-desktop])
AC_CONFIG_SRCDIR([libgnome-desktop])
@@ -69,21 +69,17 @@
dnl If you add a version number here, you *must* add an AC_SUBST line for
dnl it too, or it will never make it into the spec file!
-LIBXML_REQUIRED=2.4.20
GDK_PIXBUF_REQUIRED=2.4.0
GTK_REQUIRED=2.11.3
GLIB_REQUIRED=2.15.4
GCONF_REQUIRED=2.0.0
-LIBGNOMEUI_REQUIRED=2.6.0
STARTUP_NOTIFICATION_REQUIRED=0.5
XRANDR_REQUIRED=1.2
-AC_SUBST(LIBXML_REQUIRED)
AC_SUBST(GTK_REQUIRED)
AC_SUBST(GLIB_REQUIRED)
AC_SUBST(GDK_PIXBUF_REQUIRED)
AC_SUBST(GCONF_REQUIRED)
-AC_SUBST(LIBGNOMEUI_REQUIRED)
AC_SUBST(STARTUP_NOTIFICATION_REQUIRED)
AC_SUBST(XRANDR_REQUIRED)
@@ -119,7 +115,7 @@
dnl pkg-config dependency checks
-PKG_CHECK_MODULES(GNOME_DESKTOP, libxml-2.0 >= $LIBXML_REQUIRED gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED gtk+-2.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GLIB_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED gconf-2.0 >= $GCONF_REQUIRED $STARTUP_NOTIFICATION_PACKAGE)
+PKG_CHECK_MODULES(GNOME_DESKTOP, gdk-pixbuf-2.0 >= $GDK_PIXBUF_REQUIRED gtk+-2.0 >= $GTK_REQUIRED glib-2.0 >= $GLIB_REQUIRED gio-2.0 >= $GLIB_REQUIRED gconf-2.0 >= $GCONF_REQUIRED $STARTUP_NOTIFICATION_PACKAGE)
dnl for gnome-about
AM_PATH_PYTHON
Modified: trunk/libgnome-desktop/Makefile.am
==============================================================================
--- trunk/libgnome-desktop/Makefile.am (original)
+++ trunk/libgnome-desktop/Makefile.am Tue Oct 7 19:12:18 2008
@@ -14,12 +14,13 @@
lib_LTLIBRARIES = libgnome-desktop-2.la
-noinst_PROGRAMS = test-ditem test-hint test-ditem-edit
+noinst_PROGRAMS = test-ditem
libgnome_desktop_2_la_SOURCES = \
gnome-desktop-item.c \
- gnome-ditem-edit.c \
- gnome-hint.c \
+ gnome-desktop-utils.c \
+ gnome-desktop-thumbnail.c \
+ gnome-thumbnail-pixbuf-utils.c \
gnome-bg.c \
display-name.c \
gnome-rr.c \
@@ -44,21 +45,6 @@
$(XLIB_LIBS) \
$(GNOME_DESKTOP_LIBS)
-test_hint_SOURCES = \
- test-hint.c
-
-test_hint_LDADD = \
- libgnome-desktop-2.la \
- $(XLIB_LIBS) \
- $(GNOME_DESKTOP_LIBS)
-
-test_ditem_edit_SOURCES = test-ditem-edit.c
-
-test_ditem_edit_LDADD = \
- libgnome-desktop-2.la \
- $(XLIB_LIBS) \
- $(GNOME_DESKTOP_LIBS)
-
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = gnome-desktop-2.0.pc
Modified: trunk/libgnome-desktop/gnome-bg.c
==============================================================================
--- trunk/libgnome-desktop/gnome-bg.c (original)
+++ trunk/libgnome-desktop/gnome-bg.c Tue Oct 7 19:12:18 2008
@@ -30,6 +30,7 @@
#include <string.h>
#include <math.h>
#include <stdarg.h>
+#include <stdlib.h>
#include <gio/gio.h>
@@ -38,7 +39,6 @@
#include <X11/Xatom.h>
#include <gconf/gconf-client.h>
-#include <libgnomeui/libgnomeui.h>
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include <libgnomeui/gnome-bg.h>
@@ -151,7 +151,7 @@
double alpha);
/* Thumbnail utilities */
-static GdkPixbuf *create_thumbnail_for_filename (GnomeThumbnailFactory *factory,
+static GdkPixbuf *create_thumbnail_for_filename (GnomeDesktopThumbnailFactory *factory,
const char *filename);
static gboolean get_thumb_annotations (GdkPixbuf *thumb,
int *orig_width,
@@ -164,7 +164,7 @@
const char *filename);
static time_t get_mtime (const char *filename);
static GdkPixbuf *create_img_thumbnail (GnomeBG *bg,
- GnomeThumbnailFactory *factory,
+ GnomeDesktopThumbnailFactory *factory,
GdkScreen *screen,
int dest_width,
int dest_height);
@@ -934,7 +934,7 @@
gboolean
gnome_bg_get_image_size (GnomeBG *bg,
- GnomeThumbnailFactory *factory,
+ GnomeDesktopThumbnailFactory *factory,
int *width,
int *height)
{
@@ -987,7 +987,7 @@
GdkPixbuf *
gnome_bg_create_thumbnail (GnomeBG *bg,
- GnomeThumbnailFactory *factory,
+ GnomeDesktopThumbnailFactory *factory,
GdkScreen *screen,
int dest_width,
int dest_height)
@@ -1315,7 +1315,7 @@
}
static GdkPixbuf *
-get_as_thumbnail (GnomeBG *bg, GnomeThumbnailFactory *factory, const char *filename)
+get_as_thumbnail (GnomeBG *bg, GnomeDesktopThumbnailFactory *factory, const char *filename)
{
const FileCacheEntry *ent;
if ((ent = file_cache_lookup (bg, THUMBNAIL, filename))) {
@@ -1458,7 +1458,7 @@
static GdkPixbuf *
create_img_thumbnail (GnomeBG *bg,
- GnomeThumbnailFactory *factory,
+ GnomeDesktopThumbnailFactory *factory,
GdkScreen *screen,
int dest_width,
int dest_height)
@@ -2251,7 +2251,7 @@
/* Thumbnail utilities */
static GdkPixbuf *
-create_thumbnail_for_filename (GnomeThumbnailFactory *factory,
+create_thumbnail_for_filename (GnomeDesktopThumbnailFactory *factory,
const char *filename)
{
char *thumb;
@@ -2266,7 +2266,7 @@
uri = g_filename_to_uri (filename, NULL, NULL);
- thumb = gnome_thumbnail_factory_lookup (factory, uri, mtime);
+ thumb = gnome_desktop_thumbnail_factory_lookup (factory, uri, mtime);
if (thumb) {
result = gdk_pixbuf_new_from_file (thumb, NULL);
@@ -2287,10 +2287,10 @@
g_object_unref (orig);
- gnome_thumbnail_factory_save_thumbnail (factory, result, uri, mtime);
+ gnome_desktop_thumbnail_factory_save_thumbnail (factory, result, uri, mtime);
}
else {
- gnome_thumbnail_factory_create_failed_thumbnail (factory, uri, mtime);
+ gnome_desktop_thumbnail_factory_create_failed_thumbnail (factory, uri, mtime);
}
}
Modified: trunk/libgnome-desktop/gnome-desktop-2.0.pc.in
==============================================================================
--- trunk/libgnome-desktop/gnome-desktop-2.0.pc.in (original)
+++ trunk/libgnome-desktop/gnome-desktop-2.0.pc.in Tue Oct 7 19:12:18 2008
@@ -5,7 +5,7 @@
Name: gnome-desktop-2.0
Description: Utility library for loading .desktop files
-Requires: gtk+-2.0 libgnomeui-2.0 @STARTUP_NOTIFICATION_PACKAGE@
+Requires: gtk+-2.0 @STARTUP_NOTIFICATION_PACKAGE@
Version: @VERSION@
Libs: -L${libdir} -lgnome-desktop-2
Cflags: -I${includedir}/gnome-desktop-2.0
Modified: trunk/libgnome-desktop/gnome-desktop-item.c
==============================================================================
--- trunk/libgnome-desktop/gnome-desktop-item.c (original)
+++ trunk/libgnome-desktop/gnome-desktop-item.c Tue Oct 7 19:12:18 2008
@@ -39,11 +39,8 @@
#include <time.h>
#include <string.h>
#include <glib/gi18n-lib.h>
-#include <libgnome/gnome-util.h>
-#include <libgnome/gnome-exec.h>
-#include <libgnome/gnome-url.h>
#include <locale.h>
-#include <popt.h>
+#include <stdlib.h>
#include <gio/gio.h>
@@ -57,8 +54,10 @@
#define sure_string(s) ((s)!=NULL?(s):"")
+#define GNOME_DESKTOP_USE_UNSTABLE_API
#undef GNOME_DISABLE_DEPRECATED
#include <libgnome/gnome-desktop-item.h>
+#include <libgnome/gnome-desktop-utils.h>
struct _GnomeDesktopItem {
int refcount;
@@ -1788,7 +1787,7 @@
/* ignore errors */
}
- gnome_prepend_terminal_to_vector (&term_argc, &term_argv);
+ gnome_desktop_prepend_terminal_to_vector (&term_argc, &term_argv);
}
args = make_args (file_list);
@@ -2068,7 +2067,10 @@
return -1;
}
- retval = gnome_url_show (url, error);
+ retval = gtk_show_uri (screen,
+ url,
+ GDK_CURRENT_TIME,
+ error);
return retval ? 0 : -1;
}
@@ -2449,178 +2451,6 @@
return retval;
}
-static char *kde_icondir = NULL;
-static GSList *hicolor_kde_48 = NULL;
-static GSList *hicolor_kde_32 = NULL;
-static GSList *hicolor_kde_22 = NULL;
-static GSList *hicolor_kde_16 = NULL;
-/* XXX: maybe we don't care about locolor
-static GSList *locolor_kde_48 = NULL;
-static GSList *locolor_kde_32 = NULL;
-static GSList *locolor_kde_22 = NULL;
-static GSList *locolor_kde_16 = NULL;
-*/
-
-static GSList *
-add_dirs (GSList *list, const char *dirname)
-{
- DIR *dir;
- struct dirent *dent;
-
- dir = opendir (dirname);
- if (dir == NULL)
- return list;
-
- list = g_slist_prepend (list, g_strdup (dirname));
-
- while ((dent = readdir (dir)) != NULL) {
- char *full;
-
- /* skip hidden and self/parent references */
- if (dent->d_name[0] == '.')
- continue;
-
- full = g_build_filename (dirname, dent->d_name, NULL);
- if (g_file_test (full, G_FILE_TEST_IS_DIR)) {
- list = g_slist_prepend (list, full);
- list = add_dirs (list, full);
- } else {
- g_free (full);
- }
- }
- closedir (dir);
-
- return list;
-}
-
-static void
-init_kde_dirs (void)
-{
- char *dirname;
-
- if (kde_icondir == NULL)
- return;
-
-#define ADD_DIRS(color,size) \
- dirname = g_build_filename (kde_icondir, #color, \
- #size "x" #size , NULL); \
- color ## _kde_ ## size = add_dirs (NULL, dirname); \
- g_free (dirname);
-
- ADD_DIRS (hicolor, 48);
- ADD_DIRS (hicolor, 32);
- ADD_DIRS (hicolor, 22);
- ADD_DIRS (hicolor, 16);
-
-/* XXX: maybe we don't care about locolor
- ADD_DIRS (locolor, 48);
- ADD_DIRS (locolor, 32);
- ADD_DIRS (locolor, 22);
- */
-
-#undef ADD_DIRS
-}
-
-static GSList *
-get_kde_dirs (int size)
-{
- GSList *list = NULL;
-
- if (kde_icondir == NULL)
- return NULL;
-
- if (size > 32) {
- /* 48-inf */
- list = g_slist_concat (g_slist_copy (hicolor_kde_48),
- g_slist_copy (hicolor_kde_32));
- list = g_slist_concat (list,
- g_slist_copy (hicolor_kde_22));
- list = g_slist_concat (list,
- g_slist_copy (hicolor_kde_16));
- } else if (size > 22) {
- /* 23-32 */
- list = g_slist_concat (g_slist_copy (hicolor_kde_32),
- g_slist_copy (hicolor_kde_48));
- list = g_slist_concat (list,
- g_slist_copy (hicolor_kde_22));
- list = g_slist_concat (list,
- g_slist_copy (hicolor_kde_16));
- } else if (size > 16) {
- /* 17-22 */
- list = g_slist_concat (g_slist_copy (hicolor_kde_22),
- g_slist_copy (hicolor_kde_32));
- list = g_slist_concat (list,
- g_slist_copy (hicolor_kde_48));
- list = g_slist_concat (list,
- g_slist_copy (hicolor_kde_16));
- } else {
- /* 1-16 */
- list = g_slist_concat (g_slist_copy (hicolor_kde_16),
- g_slist_copy (hicolor_kde_22));
- list = g_slist_concat (list,
- g_slist_copy (hicolor_kde_32));
- list = g_slist_concat (list,
- g_slist_copy (hicolor_kde_48));
- }
-
- list = g_slist_append (list, kde_icondir);
-
- return list;
-}
-
-/* similar function is in panel/main.c */
-static void
-find_kde_directory (void)
-{
- int i;
- const char *kdedir;
- char *try_prefixes[] = {
- "/usr",
- "/opt/kde",
- "/opt/kde2",
- "/usr/local",
- "/kde",
- "/kde2",
- NULL
- };
-
- if (kde_icondir != NULL)
- return;
-
- kdedir = g_getenv ("KDEDIR");
-
- if (kdedir != NULL) {
- kde_icondir = g_build_filename (kdedir, "share", "icons", NULL);
- init_kde_dirs ();
- return;
- }
-
- /* if what configure gave us works use that */
- if (g_file_test (KDE_ICONDIR, G_FILE_TEST_IS_DIR)) {
- kde_icondir = g_strdup (KDE_ICONDIR);
- init_kde_dirs ();
- return;
- }
-
- for (i = 0; try_prefixes[i] != NULL; i++) {
- char *try;
- try = g_build_filename (try_prefixes[i], "share", "applnk", NULL);
- if (g_file_test (try, G_FILE_TEST_IS_DIR)) {
- g_free (try);
- kde_icondir = g_build_filename (try_prefixes[i], "share", "icons", NULL);
- init_kde_dirs ();
- return;
- }
- g_free (try);
- }
-
- /* absolute fallback, these don't exist, but we're out of options
- here */
- kde_icondir = g_strdup (KDE_ICONDIR);
-
- init_kde_dirs ();
-}
-
/**
* gnome_desktop_item_find_icon:
* @icon_theme: a #GtkIconTheme
@@ -2640,11 +2470,11 @@
int desired_size,
int flags)
{
+ GtkIconInfo *info;
char *full = NULL;
g_return_val_if_fail (icon_theme == NULL ||
- GTK_IS_ICON_THEME (icon_theme) ||
- GNOME_IS_ICON_THEME (icon_theme), NULL);
+ GTK_IS_ICON_THEME (icon_theme), NULL);
if (icon == NULL || strcmp(icon,"") == 0) {
return NULL;
@@ -2669,82 +2499,22 @@
strcmp (p, ".svg") == 0)) {
*p = 0;
}
-
- /* For backwards compat we support GnomeIconTheme too */
- if (GNOME_IS_ICON_THEME (icon_theme)) {
- full = gnome_icon_theme_lookup_icon (icon_theme,
- icon_no_extension,
- desired_size,
- NULL, NULL);
- } else {
- GtkIconInfo *info;
-
- info = gtk_icon_theme_lookup_icon (icon_theme,
- icon_no_extension,
- desired_size,
- 0);
-
- full = NULL;
- if (info) {
- full = g_strdup (gtk_icon_info_get_filename (info));
- gtk_icon_info_free (info);
- }
- }
- g_free (icon_no_extension);
- }
-
- if (full == NULL) { /* Fall back on old Gnome/KDE code */
- GSList *kde_dirs = NULL;
- GSList *li;
- const char *exts[] = { ".png", ".xpm", NULL };
- const char *no_exts[] = { "", NULL };
- const char **check_exts;
-
- full = gnome_program_locate_file (NULL,
- GNOME_FILE_DOMAIN_PIXMAP,
- icon,
- TRUE /* only_if_exists */,
- NULL /* ret_locations */);
- if (full == NULL)
- full = gnome_program_locate_file (NULL,
- GNOME_FILE_DOMAIN_APP_PIXMAP,
- icon,
- TRUE /* only_if_exists */,
- NULL /* ret_locations */);
-
- /* if we found something or no kde, then just return now */
- if (full != NULL ||
- flags & GNOME_DESKTOP_ITEM_ICON_NO_KDE)
- return full;
-
- /* If there is an extention don't add any extensions */
- if (strchr (icon, '.') != NULL) {
- check_exts = no_exts;
- } else {
- check_exts = exts;
- }
-
- find_kde_directory ();
-
- kde_dirs = get_kde_dirs (desired_size);
-
- for (li = kde_dirs; full == NULL && li != NULL; li = li->next) {
- int i;
- for (i = 0; full == NULL && check_exts[i] != NULL; i++) {
- full = g_strconcat (li->data, G_DIR_SEPARATOR_S, icon,
- check_exts[i], NULL);
- if ( ! g_file_test (full, G_FILE_TEST_EXISTS)) {
- g_free (full);
- full = NULL;
- }
- }
+
+ info = gtk_icon_theme_lookup_icon (icon_theme,
+ icon_no_extension,
+ desired_size,
+ 0);
+
+ full = NULL;
+ if (info) {
+ full = g_strdup (gtk_icon_info_get_filename (info));
+ gtk_icon_info_free (info);
}
-
- g_slist_free (kde_dirs);
-
+ g_free (icon_no_extension);
}
- return full;
+
+ return full;
}
Added: trunk/libgnome-desktop/gnome-desktop-thumbnail.c
==============================================================================
--- (empty file)
+++ trunk/libgnome-desktop/gnome-desktop-thumbnail.c Tue Oct 7 19:12:18 2008
@@ -0,0 +1,1258 @@
+/*
+ * gnome-thumbnail.c: Utilities for handling thumbnails
+ *
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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 Gnome 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 Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, 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>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include "libgnomeui/gnome-desktop-thumbnail.h"
+#include <gconf/gconf.h>
+#include <gconf/gconf-client.h>
+#include <glib/gstdio.h>
+
+#define SECONDS_BETWEEN_STATS 10
+
+struct _GnomeDesktopThumbnailFactoryPrivate {
+ char *application;
+ GnomeDesktopThumbnailSize size;
+
+ GMutex *lock;
+
+ GHashTable *scripts_hash;
+ guint thumbnailers_notify;
+ guint reread_scheduled;
+};
+
+static void gnome_desktop_thumbnail_factory_init (GnomeDesktopThumbnailFactory *factory);
+static void gnome_desktop_thumbnail_factory_class_init (GnomeDesktopThumbnailFactoryClass *class);
+
+G_DEFINE_TYPE (GnomeDesktopThumbnailFactory,
+ gnome_desktop_thumbnail_factory,
+ G_TYPE_OBJECT)
+#define parent_class gnome_desktop_thumbnail_factory_parent_class
+
+typedef struct {
+ gint width;
+ gint height;
+ gint input_width;
+ gint input_height;
+ gboolean preserve_aspect_ratio;
+} SizePrepareContext;
+
+#define LOAD_BUFFER_SIZE 4096
+
+static void
+size_prepared_cb (GdkPixbufLoader *loader,
+ int width,
+ int height,
+ gpointer data)
+{
+ SizePrepareContext *info = data;
+
+ g_return_if_fail (width > 0 && height > 0);
+
+ info->input_width = width;
+ info->input_height = height;
+
+ if (width < info->width && height < info->height) return;
+
+ if (info->preserve_aspect_ratio &&
+ (info->width > 0 || info->height > 0)) {
+ if (info->width < 0)
+ {
+ width = width * (double)info->height/(double)height;
+ height = info->height;
+ }
+ else if (info->height < 0)
+ {
+ height = height * (double)info->width/(double)width;
+ width = info->width;
+ }
+ else if ((double)height * (double)info->width >
+ (double)width * (double)info->height) {
+ width = 0.5 + (double)width * (double)info->height / (double)height;
+ height = info->height;
+ } else {
+ height = 0.5 + (double)height * (double)info->width / (double)width;
+ width = info->width;
+ }
+ } else {
+ if (info->width > 0)
+ width = info->width;
+ if (info->height > 0)
+ height = info->height;
+ }
+
+ gdk_pixbuf_loader_set_size (loader, width, height);
+}
+
+static GdkPixbuf *
+_gdk_pixbuf_new_from_uri_at_scale (const char *uri,
+ gint width,
+ gint height,
+ gboolean preserve_aspect_ratio)
+{
+ gboolean result;
+ char buffer[LOAD_BUFFER_SIZE];
+ gsize bytes_read;
+ GdkPixbufLoader *loader;
+ GdkPixbuf *pixbuf;
+ GdkPixbufAnimation *animation;
+ GdkPixbufAnimationIter *iter;
+ gboolean has_frame;
+ SizePrepareContext info;
+ GFile *file;
+ GFileInputStream *file_input_stream;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+
+ file = g_file_new_for_uri (uri);
+ file_input_stream = g_file_read (file, NULL, NULL);
+ if (file_input_stream == NULL) {
+ g_object_unref (file);
+ return NULL;
+ }
+
+ loader = gdk_pixbuf_loader_new ();
+ if (1 <= width || 1 <= height) {
+ info.width = width;
+ info.height = height;
+ info.input_width = info.input_height = 0;
+ info.preserve_aspect_ratio = preserve_aspect_ratio;
+ g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
+ }
+
+ has_frame = FALSE;
+
+ result = FALSE;
+ while (!has_frame) {
+
+ bytes_read = g_input_stream_read (G_INPUT_STREAM (file_input_stream),
+ buffer,
+ sizeof (buffer),
+ NULL,
+ NULL);
+ if (bytes_read == -1) {
+ break;
+ }
+ result = TRUE;
+ if (bytes_read == 0) {
+ break;
+ }
+
+ if (!gdk_pixbuf_loader_write (loader,
+ (unsigned char *)buffer,
+ bytes_read,
+ NULL)) {
+ result = FALSE;
+ break;
+ }
+
+ animation = gdk_pixbuf_loader_get_animation (loader);
+ if (animation) {
+ iter = gdk_pixbuf_animation_get_iter (animation, NULL);
+ if (!gdk_pixbuf_animation_iter_on_currently_loading_frame (iter)) {
+ has_frame = TRUE;
+ }
+ g_object_unref (iter);
+ }
+ }
+
+ gdk_pixbuf_loader_close (loader, NULL);
+
+ if (result) {
+ g_object_unref (G_OBJECT (loader));
+ g_input_stream_close (G_INPUT_STREAM (file_input_stream), NULL, NULL);
+ g_object_unref (file_input_stream);
+ g_object_unref (file);
+ return NULL;
+ }
+
+ g_input_stream_close (G_INPUT_STREAM (file_input_stream), NULL, NULL);
+ g_object_unref (file_input_stream);
+ g_object_unref (file);
+
+ pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+ if (pixbuf != NULL) {
+ g_object_ref (G_OBJECT (pixbuf));
+ g_object_set_data (G_OBJECT (pixbuf), "gnome-original-width",
+ GINT_TO_POINTER (info.input_width));
+ g_object_set_data (G_OBJECT (pixbuf), "gnome-original-height",
+ GINT_TO_POINTER (info.input_height));
+ }
+ g_object_unref (G_OBJECT (loader));
+
+ return pixbuf;
+}
+
+static void
+gnome_desktop_thumbnail_factory_finalize (GObject *object)
+{
+ GnomeDesktopThumbnailFactory *factory;
+ GnomeDesktopThumbnailFactoryPrivate *priv;
+ GConfClient *client;
+
+ factory = GNOME_DESKTOP_THUMBNAIL_FACTORY (object);
+
+ priv = factory->priv;
+
+ g_free (priv->application);
+ priv->application = NULL;
+
+ if (priv->reread_scheduled != 0) {
+ g_source_remove (priv->reread_scheduled);
+ priv->reread_scheduled = 0;
+ }
+
+ if (priv->thumbnailers_notify != 0) {
+ client = gconf_client_get_default ();
+ gconf_client_notify_remove (client, priv->thumbnailers_notify);
+ priv->thumbnailers_notify = 0;
+ g_object_unref (client);
+ }
+
+ if (priv->scripts_hash)
+ {
+ g_hash_table_destroy (priv->scripts_hash);
+ priv->scripts_hash = NULL;
+ }
+
+ if (priv->lock)
+ {
+ g_mutex_free (priv->lock);
+ priv->lock = NULL;
+ }
+
+ g_free (priv);
+ factory->priv = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->finalize)
+ (* G_OBJECT_CLASS (parent_class)->finalize) (object);
+}
+
+/* Must be called on main thread */
+static GHashTable *
+read_scripts (void)
+{
+ GHashTable *scripts_hash;
+ GConfClient *client;
+ GSList *subdirs, *l;
+ char *subdir, *enable, *escape, *commandkey, *command, *mimetype;
+
+ client = gconf_client_get_default ();
+
+ if (gconf_client_get_bool (client,
+ "/desktop/gnome/thumbnailers/disable_all",
+ NULL))
+ {
+ g_object_unref (G_OBJECT (client));
+ return NULL;
+ }
+
+ scripts_hash = g_hash_table_new_full (g_str_hash,
+ g_str_equal,
+ g_free, g_free);
+
+
+ subdirs = gconf_client_all_dirs (client, "/desktop/gnome/thumbnailers", NULL);
+
+ for (l = subdirs; l != NULL; l = l->next)
+ {
+ subdir = l->data;
+
+ enable = g_strdup_printf ("%s/enable", subdir);
+ if (gconf_client_get_bool (client,
+ enable,
+ NULL))
+ {
+ commandkey = g_strdup_printf ("%s/command", subdir);
+ command = gconf_client_get_string (client, commandkey, NULL);
+ g_free (commandkey);
+
+ if (command != NULL) {
+ mimetype = strrchr (subdir, '/');
+ if (mimetype != NULL)
+ {
+ mimetype++; /* skip past slash */
+
+ /* Convert '@' to slash in mimetype */
+ escape = strchr (mimetype, '@');
+ if (escape != NULL)
+ *escape = '/';
+
+ /* Convert any remaining '@' to '+' in mimetype */
+ while ((escape = strchr (mimetype, '@')) != NULL)
+ *escape = '+';
+
+ g_hash_table_insert (scripts_hash,
+ g_strdup (mimetype), command);
+ }
+ else
+ {
+ g_free (command);
+ }
+ }
+ }
+ g_free (enable);
+
+ g_free (subdir);
+ }
+
+ g_slist_free(subdirs);
+
+ g_object_unref (G_OBJECT (client));
+
+ return scripts_hash;
+}
+
+
+/* Must be called on main thread */
+static void
+gnome_desktop_thumbnail_factory_reread_scripts (GnomeDesktopThumbnailFactory *factory)
+{
+ GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+ GHashTable *scripts_hash;
+
+ scripts_hash = read_scripts ();
+
+ g_mutex_lock (priv->lock);
+
+ if (priv->scripts_hash != NULL)
+ g_hash_table_destroy (priv->scripts_hash);
+
+ priv->scripts_hash = scripts_hash;
+
+ g_mutex_unlock (priv->lock);
+}
+
+static gboolean
+reread_idle_callback (gpointer user_data)
+{
+ GnomeDesktopThumbnailFactory *factory = user_data;
+ GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+
+ gnome_desktop_thumbnail_factory_reread_scripts (factory);
+
+ g_mutex_lock (priv->lock);
+ priv->reread_scheduled = 0;
+ g_mutex_unlock (priv->lock);
+
+ return FALSE;
+}
+
+static void
+schedule_reread (GConfClient* client,
+ guint cnxn_id,
+ GConfEntry *entry,
+ gpointer user_data)
+{
+ GnomeDesktopThumbnailFactory *factory = user_data;
+ GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+
+ g_mutex_lock (priv->lock);
+
+ if (priv->reread_scheduled == 0)
+ {
+ priv->reread_scheduled = g_idle_add (reread_idle_callback,
+ factory);
+ }
+
+ g_mutex_unlock (priv->lock);
+}
+
+
+static void
+gnome_desktop_thumbnail_factory_init (GnomeDesktopThumbnailFactory *factory)
+{
+ GConfClient *client;
+ GnomeDesktopThumbnailFactoryPrivate *priv;
+
+ factory->priv = g_new0 (GnomeDesktopThumbnailFactoryPrivate, 1);
+
+ priv = factory->priv;
+
+ priv->size = GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL;
+ priv->application = g_strdup ("gnome-thumbnail-factory");
+
+ priv->scripts_hash = NULL;
+
+ priv->lock = g_mutex_new ();
+
+ gnome_desktop_thumbnail_factory_reread_scripts (factory);
+
+ client = gconf_client_get_default ();
+ gconf_client_add_dir (client,
+ "/desktop/gnome",
+ GCONF_CLIENT_PRELOAD_NONE, NULL);
+
+ priv->thumbnailers_notify = gconf_client_notify_add (client, "/desktop/gnome/thumbnailers",
+ schedule_reread, factory, NULL,
+ NULL);
+
+ g_object_unref (G_OBJECT (client));
+}
+
+static void
+gnome_desktop_thumbnail_factory_class_init (GnomeDesktopThumbnailFactoryClass *class)
+{
+ GObjectClass *gobject_class;
+
+ gobject_class = G_OBJECT_CLASS (class);
+
+ gobject_class->finalize = gnome_desktop_thumbnail_factory_finalize;
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_new:
+ * @size: The thumbnail size to use
+ *
+ * Creates a new #GnomeDesktopThumbnailFactory.
+ *
+ * This function must be called on the main thread.
+ *
+ * Return value: a new #GnomeDesktopThumbnailFactory
+ *
+ * Since: 2.2
+ **/
+GnomeDesktopThumbnailFactory *
+gnome_desktop_thumbnail_factory_new (GnomeDesktopThumbnailSize size)
+{
+ GnomeDesktopThumbnailFactory *factory;
+
+ factory = g_object_new (GNOME_TYPE_THUMBNAIL_FACTORY, NULL);
+
+ factory->priv->size = size;
+
+ return factory;
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_lookup:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @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: The absolute path of the thumbnail, or %NULL if none exist.
+ *
+ * Since: 2.2
+ **/
+char *
+gnome_desktop_thumbnail_factory_lookup (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ time_t mtime)
+{
+ GnomeDesktopThumbnailFactoryPrivate *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);
+
+ path = g_build_filename (g_get_home_dir (),
+ ".thumbnails",
+ (priv->size == GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL)?"normal":"large",
+ file,
+ NULL);
+ g_free (file);
+
+ pixbuf = gdk_pixbuf_new_from_file (path, NULL);
+ if (pixbuf != NULL)
+ {
+ res = gnome_desktop_thumbnail_is_valid (pixbuf, uri, mtime);
+ g_object_unref (pixbuf);
+ }
+
+ g_checksum_free (checksum);
+
+ if (res)
+ return path;
+
+ g_free (path);
+ return FALSE;
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @uri: the uri of a file
+ * @mtime: the mtime of the file
+ *
+ * Tries to locate an failed thumbnail for the file specified. Writing
+ * and looking for failed thumbnails is important to avoid to try to
+ * thumbnail e.g. broken images several times.
+ *
+ * Usage of this function is threadsafe.
+ *
+ * Return value: TRUE if there is a failed thumbnail for the file.
+ *
+ * Since: 2.2
+ **/
+gboolean
+gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ time_t mtime)
+{
+ char *path, *file;
+ GdkPixbuf *pixbuf;
+ gboolean res;
+ GChecksum *checksum;
+ guint8 digest[16];
+ gsize digest_len = sizeof (digest);
+
+ 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);
+
+ res = FALSE;
+
+ file = g_strconcat (g_checksum_get_string (checksum), ".png", NULL);
+
+ path = g_build_filename (g_get_home_dir (),
+ ".thumbnails/fail",
+ factory->priv->application,
+ file,
+ NULL);
+ g_free (file);
+
+ pixbuf = gdk_pixbuf_new_from_file (path, NULL);
+ g_free (path);
+
+ if (pixbuf)
+ {
+ res = gnome_desktop_thumbnail_is_valid (pixbuf, uri, mtime);
+ g_object_unref (pixbuf);
+ }
+
+ g_checksum_free (checksum);
+
+ return res;
+}
+
+static gboolean
+mimetype_supported_by_gdk_pixbuf (const char *mime_type)
+{
+ guint i;
+ static GHashTable *formats_hash = NULL;
+
+ if (!formats_hash) {
+ GSList *formats, *list;
+
+ formats_hash = g_hash_table_new (g_str_hash, g_str_equal);
+
+ formats = gdk_pixbuf_get_formats ();
+ list = formats;
+
+ while (list) {
+ GdkPixbufFormat *format = list->data;
+ gchar **mime_types;
+
+ mime_types = gdk_pixbuf_format_get_mime_types (format);
+
+ for (i = 0; mime_types[i] != NULL; i++)
+ g_hash_table_insert (formats_hash,
+ (gpointer) g_strdup (mime_types[i]),
+ GUINT_TO_POINTER (1));
+
+ g_strfreev (mime_types);
+ list = list->next;
+ }
+ g_slist_free (formats);
+ }
+
+ if (g_hash_table_lookup (formats_hash, mime_type))
+ return TRUE;
+
+ return FALSE;
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_can_thumbnail:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @uri: the uri of a file
+ * @mime_type: the mime type of the file
+ * @mtime: the mtime of the file
+ *
+ * Returns TRUE if this GnomeIconFactory can (at least try) to thumbnail
+ * this file. Thumbnails or files with failed thumbnails won't be thumbnailed.
+ *
+ * Usage of this function is threadsafe.
+ *
+ * Return value: TRUE if the file can be thumbnailed.
+ *
+ * Since: 2.2
+ **/
+gboolean
+gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ const char *mime_type,
+ time_t mtime)
+{
+ /* Don't thumbnail thumbnails */
+ if (uri &&
+ strncmp (uri, "file:/", 6) == 0 &&
+ strstr (uri, "/.thumbnails/") != NULL)
+ return FALSE;
+
+ if (mime_type != NULL &&
+ (mimetype_supported_by_gdk_pixbuf (mime_type) ||
+ (factory->priv->scripts_hash != NULL &&
+ g_hash_table_lookup (factory->priv->scripts_hash, mime_type))))
+ {
+ return !gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (factory,
+ uri,
+ mtime);
+ }
+
+ return FALSE;
+}
+
+static char *
+expand_thumbnailing_script (const char *script,
+ const int size,
+ const char *inuri,
+ const char *outfile)
+{
+ GString *str;
+ const char *p, *last;
+ char *localfile, *quoted;
+ gboolean got_in;
+
+ str = g_string_new (NULL);
+
+ got_in = FALSE;
+ last = script;
+ while ((p = strchr (last, '%')) != NULL)
+ {
+ g_string_append_len (str, last, p - last);
+ p++;
+
+ switch (*p) {
+ case 'u':
+ quoted = g_shell_quote (inuri);
+ g_string_append (str, quoted);
+ g_free (quoted);
+ got_in = TRUE;
+ p++;
+ break;
+ case 'i':
+ localfile = g_filename_from_uri (inuri, NULL, NULL);
+ if (localfile)
+ {
+ quoted = g_shell_quote (localfile);
+ g_string_append (str, quoted);
+ got_in = TRUE;
+ g_free (quoted);
+ g_free (localfile);
+ }
+ p++;
+ break;
+ case 'o':
+ quoted = g_shell_quote (outfile);
+ g_string_append (str, quoted);
+ g_free (quoted);
+ p++;
+ break;
+ case 's':
+ g_string_append_printf (str, "%d", size);
+ p++;
+ break;
+ case '%':
+ g_string_append_c (str, '%');
+ p++;
+ break;
+ case 0:
+ default:
+ break;
+ }
+ last = p;
+ }
+ g_string_append (str, last);
+
+ if (got_in)
+ return g_string_free (str, FALSE);
+
+ g_string_free (str, TRUE);
+ return NULL;
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_generate_thumbnail:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @uri: the uri of a file
+ * @mime_type: the mime type of the file
+ *
+ * Tries to generate a thumbnail for the specified file. If it succeeds
+ * it returns a pixbuf that can be used as a thumbnail.
+ *
+ * Usage of this function is threadsafe.
+ *
+ * Return value: thumbnail pixbuf if thumbnailing succeeded, %NULL otherwise.
+ *
+ * Since: 2.2
+ **/
+GdkPixbuf *
+gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ const char *mime_type)
+{
+ GdkPixbuf *pixbuf, *scaled, *tmp_pixbuf;
+ char *script, *expanded_script;
+ int width, height, size;
+ int original_width = 0;
+ int original_height = 0;
+ char dimension[12];
+ double scale;
+ int exit_status;
+ char *tmpname;
+
+ g_return_val_if_fail (uri != NULL, NULL);
+ g_return_val_if_fail (mime_type != NULL, NULL);
+
+ /* Doesn't access any volatile fields in factory, so it's threadsafe */
+
+ size = 128;
+ if (factory->priv->size == GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE)
+ size = 256;
+
+ pixbuf = NULL;
+
+ script = NULL;
+ if (factory->priv->scripts_hash != NULL)
+ script = g_hash_table_lookup (factory->priv->scripts_hash, mime_type);
+
+ if (script)
+ {
+ int fd;
+ GError *error = NULL;
+
+ fd = g_file_open_tmp (".gnome_desktop_thumbnail.XXXXXX", &tmpname, &error);
+
+ if (fd != -1)
+ {
+ close (fd);
+
+ expanded_script = expand_thumbnailing_script (script, size, uri, tmpname);
+ if (expanded_script != NULL &&
+ g_spawn_command_line_sync (expanded_script,
+ NULL, NULL, &exit_status, NULL) &&
+ exit_status == 0)
+ {
+ pixbuf = gdk_pixbuf_new_from_file (tmpname, NULL);
+ }
+
+ g_free (expanded_script);
+ g_unlink(tmpname);
+ }
+ g_free (tmpname);
+ }
+
+ /* Fall back to gdk-pixbuf */
+ if (pixbuf == NULL)
+ {
+ pixbuf = _gdk_pixbuf_new_from_uri_at_scale (uri, size, size, TRUE);
+
+ if (pixbuf != NULL)
+ {
+ original_width = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pixbuf),
+ "gnome-original-width"));
+ original_height = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (pixbuf),
+ "gnome-original-height"));
+ }
+ }
+
+ if (pixbuf == NULL)
+ return NULL;
+
+ /* The pixbuf loader may attach an "orientation" option to the pixbuf,
+ if the tiff or exif jpeg file had an orientation tag. Rotate/flip
+ the pixbuf as specified by this tag, if present. */
+ tmp_pixbuf = gdk_pixbuf_apply_embedded_orientation (pixbuf);
+ g_object_unref (pixbuf);
+ pixbuf = tmp_pixbuf;
+
+ width = gdk_pixbuf_get_width (pixbuf);
+ height = gdk_pixbuf_get_height (pixbuf);
+
+ if (width > size || height > size)
+ {
+ const gchar *orig_width, *orig_height;
+ scale = (double)size / MAX (width, height);
+
+ scaled = gnome_desktop_thumbnail_scale_down_pixbuf (pixbuf,
+ floor (width * scale + 0.5),
+ floor (height * scale + 0.5));
+
+ orig_width = gdk_pixbuf_get_option (pixbuf, "tEXt::Thumb::Image::Width");
+ orig_height = gdk_pixbuf_get_option (pixbuf, "tEXt::Thumb::Image::Height");
+
+ if (orig_width != NULL) {
+ gdk_pixbuf_set_option (scaled, "tEXt::Thumb::Image::Width", orig_width);
+ }
+ if (orig_height != NULL) {
+ gdk_pixbuf_set_option (scaled, "tEXt::Thumb::Image::Height", orig_height);
+ }
+
+ g_object_unref (pixbuf);
+ pixbuf = scaled;
+ }
+
+ if (original_width > 0) {
+ g_snprintf (dimension, sizeof (dimension), "%i", original_width);
+ gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Width", dimension);
+ }
+ if (original_height > 0) {
+ g_snprintf (dimension, sizeof (dimension), "%i", original_height);
+ gdk_pixbuf_set_option (pixbuf, "tEXt::Thumb::Image::Height", dimension);
+ }
+
+ return pixbuf;
+}
+
+static gboolean
+make_thumbnail_dirs (GnomeDesktopThumbnailFactory *factory)
+{
+ char *thumbnail_dir;
+ char *image_dir;
+ gboolean res;
+
+ res = FALSE;
+
+ thumbnail_dir = g_build_filename (g_get_home_dir (),
+ ".thumbnails",
+ NULL);
+ if (!g_file_test (thumbnail_dir, G_FILE_TEST_IS_DIR))
+ {
+ g_mkdir (thumbnail_dir, 0700);
+ res = TRUE;
+ }
+
+ image_dir = g_build_filename (thumbnail_dir,
+ (factory->priv->size == GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL)?"normal":"large",
+ NULL);
+ if (!g_file_test (image_dir, G_FILE_TEST_IS_DIR))
+ {
+ g_mkdir (image_dir, 0700);
+ res = TRUE;
+ }
+
+ g_free (thumbnail_dir);
+ g_free (image_dir);
+
+ return res;
+}
+
+static gboolean
+make_thumbnail_fail_dirs (GnomeDesktopThumbnailFactory *factory)
+{
+ char *thumbnail_dir;
+ char *fail_dir;
+ char *app_dir;
+ gboolean res;
+
+ res = FALSE;
+
+ thumbnail_dir = g_build_filename (g_get_home_dir (),
+ ".thumbnails",
+ NULL);
+ if (!g_file_test (thumbnail_dir, G_FILE_TEST_IS_DIR))
+ {
+ g_mkdir (thumbnail_dir, 0700);
+ res = TRUE;
+ }
+
+ fail_dir = g_build_filename (thumbnail_dir,
+ "fail",
+ NULL);
+ if (!g_file_test (fail_dir, G_FILE_TEST_IS_DIR))
+ {
+ g_mkdir (fail_dir, 0700);
+ res = TRUE;
+ }
+
+ app_dir = g_build_filename (fail_dir,
+ factory->priv->application,
+ NULL);
+ if (!g_file_test (app_dir, G_FILE_TEST_IS_DIR))
+ {
+ g_mkdir (app_dir, 0700);
+ res = TRUE;
+ }
+
+ g_free (thumbnail_dir);
+ g_free (fail_dir);
+ g_free (app_dir);
+
+ return res;
+}
+
+
+/**
+ * gnome_desktop_thumbnail_factory_save_thumbnail:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @thumbnail: the thumbnail as a pixbuf
+ * @uri: the uri of a file
+ * @original_mtime: the modification time of the original file
+ *
+ * Saves @thumbnail at the right place. If the save fails a
+ * failed thumbnail is written.
+ *
+ * Usage of this function is threadsafe.
+ *
+ * Since: 2.2
+ **/
+void
+gnome_desktop_thumbnail_factory_save_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ GdkPixbuf *thumbnail,
+ const char *uri,
+ time_t original_mtime)
+{
+ GnomeDesktopThumbnailFactoryPrivate *priv = factory->priv;
+ char *path, *file, *dir;
+ char *tmp_path;
+ const char *width, *height;
+ int tmp_fd;
+ char mtime_str[21];
+ gboolean saved_ok;
+ GChecksum *checksum;
+ guint8 digest[16];
+ gsize digest_len = sizeof (digest);
+
+ 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);
+
+ dir = g_build_filename (g_get_home_dir (),
+ ".thumbnails",
+ (priv->size == GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL)?"normal":"large",
+ NULL);
+
+ path = g_build_filename (dir,
+ file,
+ NULL);
+ g_free (file);
+
+ g_checksum_free (checksum);
+
+ tmp_path = g_strconcat (path, ".XXXXXX", NULL);
+
+ tmp_fd = g_mkstemp (tmp_path);
+ if (tmp_fd == -1 &&
+ make_thumbnail_dirs (factory))
+ {
+ g_free (tmp_path);
+ tmp_path = g_strconcat (path, ".XXXXXX", NULL);
+ tmp_fd = g_mkstemp (tmp_path);
+ }
+
+ if (tmp_fd == -1)
+ {
+ gnome_desktop_thumbnail_factory_create_failed_thumbnail (factory, uri, original_mtime);
+ g_free (dir);
+ g_free (tmp_path);
+ g_free (path);
+ return;
+ }
+ close (tmp_fd);
+
+ g_snprintf (mtime_str, 21, "%ld", original_mtime);
+ width = gdk_pixbuf_get_option (thumbnail, "tEXt::Thumb::Image::Width");
+ height = gdk_pixbuf_get_option (thumbnail, "tEXt::Thumb::Image::Height");
+
+ if (width != NULL && height != NULL)
+ saved_ok = gdk_pixbuf_save (thumbnail,
+ tmp_path,
+ "png", NULL,
+ "tEXt::Thumb::Image::Width", width,
+ "tEXt::Thumb::Image::Height", height,
+ "tEXt::Thumb::URI", uri,
+ "tEXt::Thumb::MTime", mtime_str,
+ "tEXt::Software", "GNOME::ThumbnailFactory",
+ NULL);
+ else
+ saved_ok = gdk_pixbuf_save (thumbnail,
+ tmp_path,
+ "png", NULL,
+ "tEXt::Thumb::URI", uri,
+ "tEXt::Thumb::MTime", mtime_str,
+ "tEXt::Software", "GNOME::ThumbnailFactory",
+ NULL);
+
+
+ if (saved_ok)
+ {
+ g_chmod (tmp_path, 0600);
+ g_rename(tmp_path, path);
+ }
+ else
+ {
+ gnome_desktop_thumbnail_factory_create_failed_thumbnail (factory, uri, original_mtime);
+ }
+
+ g_free (dir);
+ g_free (path);
+ g_free (tmp_path);
+}
+
+/**
+ * gnome_desktop_thumbnail_factory_create_failed_thumbnail:
+ * @factory: a #GnomeDesktopThumbnailFactory
+ * @uri: the uri of a file
+ * @mtime: the modification time of the file
+ *
+ * Creates a failed thumbnail for the file so that we don't try
+ * to re-thumbnail the file later.
+ *
+ * Usage of this function is threadsafe.
+ *
+ * Since: 2.2
+ **/
+void
+gnome_desktop_thumbnail_factory_create_failed_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ time_t mtime)
+{
+ char *path, *file, *dir;
+ char *tmp_path;
+ int tmp_fd;
+ char mtime_str[21];
+ gboolean saved_ok;
+ GdkPixbuf *pixbuf;
+ GChecksum *checksum;
+ guint8 digest[16];
+ gsize digest_len = sizeof (digest);
+
+ 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);
+
+ dir = g_build_filename (g_get_home_dir (),
+ ".thumbnails/fail",
+ factory->priv->application,
+ NULL);
+
+ path = g_build_filename (dir,
+ file,
+ NULL);
+ g_free (file);
+
+ g_checksum_free (checksum);
+
+ tmp_path = g_strconcat (path, ".XXXXXX", NULL);
+
+ tmp_fd = g_mkstemp (tmp_path);
+ if (tmp_fd == -1 &&
+ make_thumbnail_fail_dirs (factory))
+ {
+ g_free (tmp_path);
+ tmp_path = g_strconcat (path, ".XXXXXX", NULL);
+ tmp_fd = g_mkstemp (tmp_path);
+ }
+
+ if (tmp_fd == -1)
+ {
+ g_free (dir);
+ g_free (tmp_path);
+ g_free (path);
+ return;
+ }
+ close (tmp_fd);
+
+ g_snprintf (mtime_str, 21, "%ld", mtime);
+ pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
+ saved_ok = gdk_pixbuf_save (pixbuf,
+ tmp_path,
+ "png", NULL,
+ "tEXt::Thumb::URI", uri,
+ "tEXt::Thumb::MTime", mtime_str,
+ "tEXt::Software", "GNOME::ThumbnailFactory",
+ NULL);
+ g_object_unref (pixbuf);
+ if (saved_ok)
+ {
+ g_chmod (tmp_path, 0600);
+ g_rename(tmp_path, path);
+ }
+
+ g_free (dir);
+ g_free (path);
+ g_free (tmp_path);
+}
+
+/**
+ * gnome_desktop_thumbnail_md5:
+ * @uri: an uri
+ *
+ * Calculates the MD5 checksum of the uri. This can be useful
+ * if you want to manually handle thumbnail files.
+ *
+ * Return value: A string with the MD5 digest of the uri string.
+ *
+ * Since: 2.2
+ *
+ * @Deprecated: 2.22: Use #GChecksum instead
+ **/
+char *
+gnome_desktop_thumbnail_md5 (const char *uri)
+{
+ return g_compute_checksum_for_data (G_CHECKSUM_MD5,
+ (const guchar *) uri,
+ strlen (uri));
+}
+
+/**
+ * gnome_desktop_thumbnail_path_for_uri:
+ * @uri: an uri
+ * @size: a thumbnail size
+ *
+ * Returns the filename that a thumbnail of size @size for @uri would have.
+ *
+ * Return value: an absolute filename
+ *
+ * Since: 2.2
+ **/
+char *
+gnome_desktop_thumbnail_path_for_uri (const char *uri,
+ GnomeDesktopThumbnailSize size)
+{
+ char *md5;
+ char *file;
+ char *path;
+
+ md5 = gnome_desktop_thumbnail_md5 (uri);
+ file = g_strconcat (md5, ".png", NULL);
+ g_free (md5);
+
+ path = g_build_filename (g_get_home_dir (),
+ ".thumbnails",
+ (size == GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL)?"normal":"large",
+ file,
+ NULL);
+
+ g_free (file);
+
+ return path;
+}
+
+/**
+ * gnome_desktop_thumbnail_has_uri:
+ * @pixbuf: an loaded thumbnail pixbuf
+ * @uri: a uri
+ *
+ * Returns whether the thumbnail has the correct uri embedded in the
+ * Thumb::URI option in the png.
+ *
+ * Return value: TRUE if the thumbnail is for @uri
+ *
+ * Since: 2.2
+ **/
+gboolean
+gnome_desktop_thumbnail_has_uri (GdkPixbuf *pixbuf,
+ const char *uri)
+{
+ const char *thumb_uri;
+
+ thumb_uri = gdk_pixbuf_get_option (pixbuf, "tEXt::Thumb::URI");
+ if (!thumb_uri)
+ return FALSE;
+
+ return strcmp (uri, thumb_uri) == 0;
+}
+
+/**
+ * gnome_desktop_thumbnail_is_valid:
+ * @pixbuf: an loaded thumbnail #GdkPixbuf
+ * @uri: a uri
+ * @mtime: the mtime
+ *
+ * Returns whether the thumbnail has the correct uri and mtime embedded in the
+ * png options.
+ *
+ * Return value: TRUE if the thumbnail has the right @uri and @mtime
+ *
+ * Since: 2.2
+ **/
+gboolean
+gnome_desktop_thumbnail_is_valid (GdkPixbuf *pixbuf,
+ const char *uri,
+ time_t mtime)
+{
+ const char *thumb_uri, *thumb_mtime_str;
+ time_t thumb_mtime;
+
+ thumb_uri = gdk_pixbuf_get_option (pixbuf, "tEXt::Thumb::URI");
+ if (!thumb_uri)
+ return FALSE;
+ if (strcmp (uri, thumb_uri) != 0)
+ return FALSE;
+
+ thumb_mtime_str = gdk_pixbuf_get_option (pixbuf, "tEXt::Thumb::MTime");
+ if (!thumb_mtime_str)
+ return FALSE;
+ thumb_mtime = atol (thumb_mtime_str);
+ if (mtime != thumb_mtime)
+ return FALSE;
+
+ return TRUE;
+}
Added: trunk/libgnome-desktop/gnome-desktop-utils.c
==============================================================================
--- (empty file)
+++ trunk/libgnome-desktop/gnome-desktop-utils.c Tue Oct 7 19:12:18 2008
@@ -0,0 +1,161 @@
+/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-desktop-utils.c - Utilities for the GNOME Desktop
+
+ Copyright (C) 1998 Tom Tromey
+ All rights reserved.
+
+ This file is part of the Gnome Library.
+
+ The Gnome 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 Gnome 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 Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+/*
+ @NOTATION@
+ */
+
+#include <config.h>
+#include <glib.h>
+#include <gconf/gconf-client.h>
+#include <glib/gi18n-lib.h>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnome/gnome-desktop-utils.h>
+
+
+/**
+ * gnome_desktop_prepend_terminal_to_vector:
+ * @argc: a pointer to the vector size
+ * @argv: a pointer to the vector
+ *
+ * Description: Prepends a terminal (either the one configured as default in
+ * the user's GNOME setup, or one of the common xterm emulators) to the passed
+ * in vector, modifying it in the process. The vector should be allocated with
+ * #g_malloc, as this will #g_free the original vector. Also all elements must
+ * have been allocated separately. That is the standard glib/GNOME way of
+ * doing vectors however. If the integer that @argc points to is negative, the
+ * size will first be computed. Also note that passing in pointers to a vector
+ * that is empty, will just create a new vector for you.
+ **/
+void
+gnome_desktop_prepend_terminal_to_vector (int *argc, char ***argv)
+{
+#ifndef G_OS_WIN32
+ char **real_argv;
+ int real_argc;
+ int i, j;
+ char **term_argv = NULL;
+ int term_argc = 0;
+ GConfClient *client;
+
+ gchar *terminal = NULL;
+
+ char **the_argv;
+
+ g_return_if_fail (argc != NULL);
+ g_return_if_fail (argv != NULL);
+
+ /* sanity */
+ if(*argv == NULL)
+ *argc = 0;
+
+ the_argv = *argv;
+
+ /* compute size if not given */
+ if (*argc < 0) {
+ for (i = 0; the_argv[i] != NULL; i++)
+ ;
+ *argc = i;
+ }
+
+ client = gconf_client_get_default ();
+ terminal = gconf_client_get_string (client, "/desktop/gnome/applications/terminal/exec", NULL);
+ g_object_unref (client);
+
+ if (terminal) {
+ gchar *command_line;
+ gchar *exec_flag;
+ exec_flag = gconf_client_get_string (client, "/desktop/gnome/applications/terminal/exec_arg", NULL);
+
+ if (exec_flag == NULL)
+ command_line = g_strdup (terminal);
+ else
+ command_line = g_strdup_printf ("%s %s", terminal,
+ exec_flag);
+
+ g_shell_parse_argv (command_line,
+ &term_argc,
+ &term_argv,
+ NULL /* error */);
+
+ g_free (command_line);
+ g_free (exec_flag);
+ g_free (terminal);
+ }
+
+ if (term_argv == NULL) {
+ char *check;
+
+ term_argc = 2;
+ term_argv = g_new0 (char *, 3);
+
+ check = g_find_program_in_path ("gnome-terminal");
+ if (check != NULL) {
+ term_argv[0] = check;
+ /* Note that gnome-terminal takes -x and
+ * as -e in gnome-terminal is broken we use that. */
+ term_argv[1] = g_strdup ("-x");
+ } else {
+ if (check == NULL)
+ check = g_find_program_in_path ("nxterm");
+ if (check == NULL)
+ check = g_find_program_in_path ("color-xterm");
+ if (check == NULL)
+ check = g_find_program_in_path ("rxvt");
+ if (check == NULL)
+ check = g_find_program_in_path ("xterm");
+ if (check == NULL)
+ check = g_find_program_in_path ("dtterm");
+ if (check == NULL) {
+ g_warning (_("Cannot find a terminal, using "
+ "xterm, even if it may not work"));
+ check = g_strdup ("xterm");
+ }
+ term_argv[0] = check;
+ term_argv[1] = g_strdup ("-e");
+ }
+ }
+
+ real_argc = term_argc + *argc;
+ real_argv = g_new (char *, real_argc + 1);
+
+ for (i = 0; i < term_argc; i++)
+ real_argv[i] = term_argv[i];
+
+ for (j = 0; j < *argc; j++, i++)
+ real_argv[i] = (char *)the_argv[j];
+
+ real_argv[i] = NULL;
+
+ g_free (*argv);
+ *argv = real_argv;
+ *argc = real_argc;
+
+ /* we use g_free here as we sucked all the inner strings
+ * out from it into real_argv */
+ g_free (term_argv);
+#else
+ /* FIXME: Implement when needed */
+ g_warning ("gnome_prepend_terminal_to_vector: Not implemented");
+#endif
+}
Added: trunk/libgnome-desktop/gnome-thumbnail-pixbuf-utils.c
==============================================================================
--- (empty file)
+++ trunk/libgnome-desktop/gnome-thumbnail-pixbuf-utils.c Tue Oct 7 19:12:18 2008
@@ -0,0 +1,172 @@
+/*
+ * gnome-thumbnail-pixbuf-utils.c: Utilities for handling pixbufs when thumbnailing
+ *
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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 Gnome 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 Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <glib.h>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include "libgnomeui/gnome-desktop-thumbnail.h"
+
+#define LOAD_BUFFER_SIZE 65536
+
+/**
+ * gnome_thumbnail_scale_down_pixbuf:
+ * @pixbuf: a #GdkPixbuf
+ * @dest_width: the desired new width
+ * @dest_height: the desired new height
+ *
+ * Scales the pixbuf to the desired size. This function
+ * is a lot faster than gdk-pixbuf when scaling down by
+ * large amounts.
+ *
+ * Return value: a scaled pixbuf
+ *
+ * Since: 2.2
+ **/
+GdkPixbuf *
+gnome_desktop_thumbnail_scale_down_pixbuf (GdkPixbuf *pixbuf,
+ int dest_width,
+ int dest_height)
+{
+ int source_width, source_height;
+ int s_x1, s_y1, s_x2, s_y2;
+ int s_xfrac, s_yfrac;
+ int dx, dx_frac, dy, dy_frac;
+ div_t ddx, ddy;
+ int x, y;
+ int r, g, b, a;
+ int n_pixels;
+ gboolean has_alpha;
+ guchar *dest, *src, *xsrc, *src_pixels;
+ GdkPixbuf *dest_pixbuf;
+ int pixel_stride;
+ int source_rowstride, dest_rowstride;
+
+ if (dest_width == 0 || dest_height == 0) {
+ return NULL;
+ }
+
+ source_width = gdk_pixbuf_get_width (pixbuf);
+ source_height = gdk_pixbuf_get_height (pixbuf);
+
+ g_assert (source_width >= dest_width);
+ g_assert (source_height >= dest_height);
+
+ ddx = div (source_width, dest_width);
+ dx = ddx.quot;
+ dx_frac = ddx.rem;
+
+ ddy = div (source_height, dest_height);
+ dy = ddy.quot;
+ dy_frac = ddy.rem;
+
+ has_alpha = gdk_pixbuf_get_has_alpha (pixbuf);
+ source_rowstride = gdk_pixbuf_get_rowstride (pixbuf);
+ src_pixels = gdk_pixbuf_get_pixels (pixbuf);
+
+ dest_pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, has_alpha, 8,
+ dest_width, dest_height);
+ dest = gdk_pixbuf_get_pixels (dest_pixbuf);
+ dest_rowstride = gdk_pixbuf_get_rowstride (dest_pixbuf);
+
+ pixel_stride = (has_alpha)?4:3;
+
+ s_y1 = 0;
+ s_yfrac = -dest_height/2;
+ while (s_y1 < source_height) {
+ s_y2 = s_y1 + dy;
+ s_yfrac += dy_frac;
+ if (s_yfrac > 0) {
+ s_y2++;
+ s_yfrac -= dest_height;
+ }
+
+ s_x1 = 0;
+ s_xfrac = -dest_width/2;
+ while (s_x1 < source_width) {
+ s_x2 = s_x1 + dx;
+ s_xfrac += dx_frac;
+ if (s_xfrac > 0) {
+ s_x2++;
+ s_xfrac -= dest_width;
+ }
+
+ /* Average block of [x1,x2[ x [y1,y2[ and store in dest */
+ r = g = b = a = 0;
+ n_pixels = 0;
+
+ src = src_pixels + s_y1 * source_rowstride + s_x1 * pixel_stride;
+ for (y = s_y1; y < s_y2; y++) {
+ xsrc = src;
+ if (has_alpha) {
+ for (x = 0; x < s_x2-s_x1; x++) {
+ n_pixels++;
+
+ r += xsrc[3] * xsrc[0];
+ g += xsrc[3] * xsrc[1];
+ b += xsrc[3] * xsrc[2];
+ a += xsrc[3];
+ xsrc += 4;
+ }
+ } else {
+ for (x = 0; x < s_x2-s_x1; x++) {
+ n_pixels++;
+ r += *xsrc++;
+ g += *xsrc++;
+ b += *xsrc++;
+ }
+ }
+ src += source_rowstride;
+ }
+
+ if (has_alpha) {
+ if (a != 0) {
+ *dest++ = r / a;
+ *dest++ = g / a;
+ *dest++ = b / a;
+ *dest++ = a / n_pixels;
+ } else {
+ *dest++ = 0;
+ *dest++ = 0;
+ *dest++ = 0;
+ *dest++ = 0;
+ }
+ } else {
+ *dest++ = r / n_pixels;
+ *dest++ = g / n_pixels;
+ *dest++ = b / n_pixels;
+ }
+
+ s_x1 = s_x2;
+ }
+ s_y1 = s_y2;
+ dest += dest_rowstride - dest_width * pixel_stride;
+ }
+
+ return dest_pixbuf;
+}
Modified: trunk/libgnome-desktop/libgnome/Makefile.am
==============================================================================
--- trunk/libgnome-desktop/libgnome/Makefile.am (original)
+++ trunk/libgnome-desktop/libgnome/Makefile.am Tue Oct 7 19:12:18 2008
@@ -1,3 +1,4 @@
libgnome_desktopdir = $(includedir)/gnome-desktop-2.0/libgnome
libgnome_desktop_HEADERS = \
+ gnome-desktop-utils.h \
gnome-desktop-item.h
Modified: trunk/libgnome-desktop/libgnome/gnome-desktop-item.h
==============================================================================
--- trunk/libgnome-desktop/libgnome/gnome-desktop-item.h (original)
+++ trunk/libgnome-desktop/libgnome/gnome-desktop-item.h Tue Oct 7 19:12:18 2008
@@ -33,7 +33,6 @@
#include <gdk/gdk.h>
#include <gtk/gtk.h>
-#include <libgnomeui/gnome-icon-theme.h>
G_BEGIN_DECLS
Added: trunk/libgnome-desktop/libgnome/gnome-desktop-utils.h
==============================================================================
--- (empty file)
+++ trunk/libgnome-desktop/libgnome/gnome-desktop-utils.h Tue Oct 7 19:12:18 2008
@@ -0,0 +1,47 @@
+/* -*- Mode: C; c-set-style: linux indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-ditem.h - Utilities for the GNOME Desktop
+
+ Copyright (C) 1998 Tom Tromey
+ All rights reserved.
+
+ This file is part of the Gnome Library.
+
+ The Gnome 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 Gnome 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 Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+/*
+ @NOTATION@
+ */
+
+#ifndef GNOME_DESKTOP_UTILS_H
+#define GNOME_DESKTOP_UTILS_H
+
+#ifndef GNOME_DESKTOP_USE_UNSTABLE_API
+#error gnome-desktop-utils is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-desktop-utils.h
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+
+#include <gdk/gdk.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+/* prepend the terminal command to a vector */
+void gnome_desktop_prepend_terminal_to_vector (int *argc, char ***argv);
+
+G_END_DECLS
+
+#endif /* GNOME_DITEM_H */
Modified: trunk/libgnome-desktop/libgnomeui/Makefile.am
==============================================================================
--- trunk/libgnome-desktop/libgnomeui/Makefile.am (original)
+++ trunk/libgnome-desktop/libgnomeui/Makefile.am Tue Oct 7 19:12:18 2008
@@ -1,8 +1,7 @@
libgnomeui_desktopdir = $(includedir)/gnome-desktop-2.0/libgnomeui
libgnomeui_desktop_HEADERS = \
- gnome-ditem-edit.h \
- gnome-hint.h \
gnome-bg.h \
+ gnome-desktop-thumbnail.h \
gnome-rr.h \
gnome-rr-config.h \
gnome-rr-labeler.h
Modified: trunk/libgnome-desktop/libgnomeui/gnome-bg.h
==============================================================================
--- trunk/libgnome-desktop/libgnomeui/gnome-bg.h (original)
+++ trunk/libgnome-desktop/libgnomeui/gnome-bg.h Tue Oct 7 19:12:18 2008
@@ -29,9 +29,9 @@
#error GnomeBG is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-bg.h
#endif
-#include <libgnomeui/libgnomeui.h>
#include <gdk/gdk.h>
#include <gconf/gconf-client.h>
+#include <libgnomeui/gnome-desktop-thumbnail.h>
G_BEGIN_DECLS
@@ -93,11 +93,11 @@
int height,
gboolean root);
gboolean gnome_bg_get_image_size (GnomeBG *bg,
- GnomeThumbnailFactory *factory,
+ GnomeDesktopThumbnailFactory *factory,
int *width,
int *height);
GdkPixbuf * gnome_bg_create_thumbnail (GnomeBG *bg,
- GnomeThumbnailFactory *factory,
+ GnomeDesktopThumbnailFactory *factory,
GdkScreen *screen,
int dest_width,
int dest_height);
Added: trunk/libgnome-desktop/libgnomeui/gnome-desktop-thumbnail.h
==============================================================================
--- (empty file)
+++ trunk/libgnome-desktop/libgnomeui/gnome-desktop-thumbnail.h Tue Oct 7 19:12:18 2008
@@ -0,0 +1,110 @@
+/*
+ * gnome-thumbnail.h: Utilities for handling thumbnails
+ *
+ * Copyright (C) 2002 Red Hat, Inc.
+ *
+ * This file is part of the Gnome Library.
+ *
+ * The Gnome 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 Gnome 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 Gnome Library; see the file COPYING.LIB. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl redhat com>
+ */
+
+#ifndef GNOME_DESKTOP_THUMBNAIL_H
+#define GNOME_DESKTOP_THUMBNAIL_H
+
+#ifndef GNOME_DESKTOP_USE_UNSTABLE_API
+#error GnomeDesktopThumbnail is unstable API. You must define GNOME_DESKTOP_USE_UNSTABLE_API before including gnome-desktop-thumbnail.h
+#endif
+
+#include <glib.h>
+#include <glib-object.h>
+#include <time.h>
+#include <gdk-pixbuf/gdk-pixbuf.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+ GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL,
+ GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE
+} GnomeDesktopThumbnailSize;
+
+#define GNOME_TYPE_THUMBNAIL_FACTORY (gnome_desktop_thumbnail_factory_get_type ())
+#define GNOME_DESKTOP_THUMBNAIL_FACTORY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GNOME_TYPE_THUMBNAIL_FACTORY, GnomeDesktopThumbnailFactory))
+#define GNOME_DESKTOP_THUMBNAIL_FACTORY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GNOME_TYPE_THUMBNAIL_FACTORY, GnomeDesktopThumbnailFactoryClass))
+#define GNOME_IS_THUMBNAIL_FACTORY(obj) (G_TYPE_INSTANCE_CHECK_TYPE ((obj), GNOME_TYPE_THUMBNAIL_FACTORY))
+#define GNOME_IS_THUMBNAIL_FACTORY_CLASS(klass) (G_TYPE_CLASS_CHECK_CLASS_TYPE ((klass), GNOME_TYPE_THUMBNAIL_FACTORY))
+
+typedef struct _GnomeDesktopThumbnailFactory GnomeDesktopThumbnailFactory;
+typedef struct _GnomeDesktopThumbnailFactoryClass GnomeDesktopThumbnailFactoryClass;
+typedef struct _GnomeDesktopThumbnailFactoryPrivate GnomeDesktopThumbnailFactoryPrivate;
+
+struct _GnomeDesktopThumbnailFactory {
+ GObject parent;
+
+ GnomeDesktopThumbnailFactoryPrivate *priv;
+};
+
+struct _GnomeDesktopThumbnailFactoryClass {
+ GObjectClass parent;
+};
+
+GType gnome_desktop_thumbnail_factory_get_type (void);
+GnomeDesktopThumbnailFactory *gnome_desktop_thumbnail_factory_new (GnomeDesktopThumbnailSize size);
+
+char * gnome_desktop_thumbnail_factory_lookup (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ time_t mtime);
+
+gboolean gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ time_t mtime);
+gboolean gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ const char *mime_type,
+ time_t mtime);
+GdkPixbuf * gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ const char *mime_type);
+void gnome_desktop_thumbnail_factory_save_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ GdkPixbuf *thumbnail,
+ const char *uri,
+ time_t original_mtime);
+void gnome_desktop_thumbnail_factory_create_failed_thumbnail (GnomeDesktopThumbnailFactory *factory,
+ const char *uri,
+ time_t mtime);
+
+
+/* Thumbnailing utils: */
+gboolean gnome_desktop_thumbnail_has_uri (GdkPixbuf *pixbuf,
+ const char *uri);
+gboolean gnome_desktop_thumbnail_is_valid (GdkPixbuf *pixbuf,
+ const char *uri,
+ time_t mtime);
+char * gnome_desktop_thumbnail_md5 (const char *uri);
+char * gnome_desktop_thumbnail_path_for_uri (const char *uri,
+ GnomeDesktopThumbnailSize size);
+
+
+/* Pixbuf utils */
+
+GdkPixbuf *gnome_desktop_thumbnail_scale_down_pixbuf (GdkPixbuf *pixbuf,
+ int dest_width,
+ int dest_height);
+
+G_END_DECLS
+
+#endif /* GNOME_DESKTOP_THUMBNAIL_H */
Modified: trunk/libgnome-desktop/test-ditem.c
==============================================================================
--- trunk/libgnome-desktop/test-ditem.c (original)
+++ trunk/libgnome-desktop/test-ditem.c Tue Oct 7 19:12:18 2008
@@ -18,13 +18,9 @@
#include <config.h>
#include <string.h>
-#include <libgnome/libgnome.h>
-#include <libgnomeui/libgnomeui.h>
+#include <unistd.h>
#include <libgnome/gnome-desktop-item.h>
-/*
-#include <libgnomeui/gnome-ditem-edit.h>
-*/
#include <locale.h>
#include <stdlib.h>
@@ -149,9 +145,7 @@
file = g_strdup (argv[1]);
- gnome_program_init ("test-ditem", "0.01",
- LIBGNOMEUI_MODULE,
- argc, argv, NULL);
+ gtk_init (&argc, &argv);
if (launch)
launch_item (file);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]