File gnome-desktop-2.32.1-windows.patch of Package mingw64-gnome-desktop
diff --git a/configure.in b/configure.in
index 13e1b2f..484cd66 100644
--- a/configure.in
+++ b/configure.in
@@ -50,6 +50,20 @@ GNOME_MICRO=gnome_micro
GNOME_DISTRIBUTOR="GNOME.Org"
GNOME_DATE=`date +"%Y-%m-%d"`
+AC_MSG_CHECKING([for Win32])
+case "$host" in
+*-mingw*)
+ os_win32=yes
+ enable_x11=no
+ enable_python=no
+ ;;
+*)
+ os_win32=no
+ ;;
+esac
+AC_MSG_RESULT([$os_win32])
+AM_CONDITIONAL(OS_WIN32, [test $os_win32 = yes])
+
AC_ARG_WITH(gnome_distributor, [ --with-gnome-distributor=DISTRIBUTOR Specify name of GNOME distributor])
if test "x$with_gnome_distributor" != x ; then
@@ -153,6 +167,10 @@ AC_SUBST(STARTUP_NOTIFICATION_PACKAGE)
dnl we need x11 for GnomeBG
+AC_ARG_ENABLE(x11, [ --disable-x11 disable depending on X11],,enable_x11=yes)
+AM_CONDITIONAL(ENABLE_X11, test $enable_x11 = yes)
+
+if test $enable_x11 = yes; then
PKG_CHECK_MODULES(XLIB, x11,
X11_PACKAGE=x11,
[X11_PACKAGE=
@@ -163,6 +181,7 @@ PKG_CHECK_MODULES(XLIB, x11,
XLIB_LIBS="$X_PRE_LIBS $X_LIBS -lX11 $X_EXTRA_LIBS"
XLIB_CFLAGS=$X_CFLAGS
fi])
+fi
AC_SUBST(X11_PACKAGE)
AC_SUBST(XLIB_CFLAGS)
AC_SUBST(XLIB_LIBS)
@@ -188,8 +207,13 @@ dnl pkg-config dependency checks
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 $RANDR_PACKAGE)
+AC_ARG_ENABLE(python, [ --disable-python disable depending on Python],, enable_python=yes)
+AM_CONDITIONAL(ENABLE_PYTHON, test $enable_python = yes)
+
+if test $enable_python = yes; then
dnl for gnome-about
AM_PATH_PYTHON
+fi
dnl gnome-doc-utils stuff
diff --git a/libgnome-desktop/Makefile.am b/libgnome-desktop/Makefile.am
index 5b3fe90..f1a0b11 100644
--- a/libgnome-desktop/Makefile.am
+++ b/libgnome-desktop/Makefile.am
@@ -10,22 +10,37 @@ INCLUDES = \
lib_LTLIBRARIES = libgnome-desktop-2.la
-noinst_PROGRAMS = test-ditem
-libgnome_desktop_2_la_SOURCES = \
+noinst_PROGRAMS = test-thumbnail
+
+if !OS_WIN32
+noinst_PROGRAMS += test-ditem
+endif
+
+if !OS_WIN32
+PLATFORM_SOURCES = \
gnome-desktop-item.c \
gnome-desktop-utils.c \
- gnome-desktop-thumbnail.c \
- gnome-thumbnail-pixbuf-utils.c \
+ display-name.c \
+ edid-parse.c \
+ edid.h
+endif
+
+if ENABLE_X11
+X11_SOURCES = \
gnome-bg.c \
gnome-bg-crossfade.c \
- display-name.c \
gnome-rr.c \
gnome-rr-config.c \
gnome-rr-labeler.c \
- gnome-rr-private.h \
- edid-parse.c \
- edid.h \
+ gnome-rr-private.h
+endif
+
+libgnome_desktop_2_la_SOURCES = \
+ $(PLATFORM_SOURCES) \
+ gnome-desktop-thumbnail.c \
+ gnome-thumbnail-pixbuf-utils.c \
+ $(X11_SOURCES) \
private.h
libgnome_desktop_2_la_LIBADD = \
@@ -36,6 +51,11 @@ libgnome_desktop_2_la_LDFLAGS = \
-version-info $(LT_VERSION) \
-no-undefined
+if OS_WIN32
+libgnome_desktop_2_la_LIBADD += -lole32
+libgnome_desktop_2_la_LDFLAGS += -export-symbols-regex "^gnome_desktop_thumbnail.*"
+endif
+
test_ditem_SOURCES = \
test-ditem.c
@@ -44,6 +64,14 @@ test_ditem_LDADD = \
$(XLIB_LIBS) \
$(GNOME_DESKTOP_LIBS)
+test_thumbnail_SOURCES = \
+ test-thumbnail.c
+
+test_thumbnail_LDADD = \
+ libgnome-desktop-2.la \
+ $(XLIB_LIBS) \
+ $(GNOME_DESKTOP_LIBS)
+
pkgconfigdir = $(libdir)/pkgconfig
pkgconfig_DATA = gnome-desktop-2.0.pc
diff --git a/libgnome-desktop/gnome-desktop-thumbnail.c b/libgnome-desktop/gnome-desktop-thumbnail.c
index 9660307..60955a0 100644
--- a/libgnome-desktop/gnome-desktop-thumbnail.c
+++ b/libgnome-desktop/gnome-desktop-thumbnail.c
@@ -33,11 +33,10 @@
#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 <gdk/gdk.h>
#define GNOME_DESKTOP_USE_UNSTABLE_API
#include "libgnomeui/gnome-desktop-thumbnail.h"
@@ -45,16 +44,174 @@
#include <gconf/gconf-client.h>
#include <glib/gstdio.h>
-#define SECONDS_BETWEEN_STATS 10
+#ifdef G_OS_WIN32
+#define INITGUID
+#include <windows.h>
+
+#define COBJMACROS
+
+#ifdef _MSC_VER
+#include <shobjidl.h>
+#include <thumbcache.h>
+#else
+#if 1
+ #include <shobjidl.h>
+#else
+
+/* MinGW, lack of headers, pick out stuff from public documentation */
+
+/* From mingw-w64's shobjidl.h */
+
+ typedef ULONG SFGAOF;
+
+typedef struct IShellItem IShellItem;
+
+ typedef enum __MIDL_IShellItem_0001 {
+ SIGDN_NORMALDISPLAY = 0,SIGDN_PARENTRELATIVEPARSING = 0x80018001,SIGDN_PARENTRELATIVEFORADDRESSBAR = 0x8001c001,
+ SIGDN_DESKTOPABSOLUTEPARSING = 0x80028000,SIGDN_PARENTRELATIVEEDITING = 0x80031001,SIGDN_DESKTOPABSOLUTEEDITING = 0x8004c000,
+ SIGDN_FILESYSPATH = 0x80058000,SIGDN_URL = 0x80068000
+ } SIGDN;
+
+ typedef DWORD SICHINTF;
+
+ typedef struct IShellItemVtbl {
+ BEGIN_INTERFACE
+ HRESULT (WINAPI *QueryInterface)(IShellItem *This,REFIID riid,void **ppvObject);
+ ULONG (WINAPI *AddRef)(IShellItem *This);
+ ULONG (WINAPI *Release)(IShellItem *This);
+ HRESULT (WINAPI *BindToHandler)(IShellItem *This,IBindCtx *pbc,REFGUID rbhid,REFIID riid,void **ppvOut);
+ HRESULT (WINAPI *GetParent)(IShellItem *This,IShellItem **ppsi);
+ HRESULT (WINAPI *GetDisplayName)(IShellItem *This,SIGDN sigdnName,LPOLESTR *ppszName);
+ HRESULT (WINAPI *GetAttributes)(IShellItem *This,SFGAOF sfgaoMask,SFGAOF *psfgaoAttribs);
+ HRESULT (WINAPI *Compare)(IShellItem *This,IShellItem *psi,SICHINTF hint,int *piOrder);
+ END_INTERFACE
+ } IShellItemVtbl;
+ struct IShellItem {
+ CONST_VTBL struct IShellItemVtbl *lpVtbl;
+ };
+
+#endif /* __MINGW64_VERSION_MAJOR */
+
+/* Boilerplate and based on public documentation from:
+ * http://msdn.microsoft.com/en-us/library/bb774628%28VS.85%29.aspx
+ * http://msdn.microsoft.com/en-us/library/bb775173%28VS.85%29.aspx
+ * http://msdn.microsoft.com/en-us/library/bb759843%28VS.85%29.aspx
+ */
+
+typedef struct ISharedBitmap ISharedBitmap;
+
+/* Correct enum values unknown, this is the order documented */
+typedef enum {
+ WTSAT_UNKNOWN,
+ WTSAT_RGB,
+ WTSAT_ARGB
+} WTS_ALPHATYPE;
+
+ typedef struct ISharedBitmapVtbl {
+ BEGIN_INTERFACE
+ /* IUnknown methods */
+ HRESULT (WINAPI *QueryInterface)(ISharedBitmap *This,REFIID riid,void **ppvObject);
+ ULONG (WINAPI *AddRef)(ISharedBitmap *This);
+ ULONG (WINAPI *Release)(ISharedBitmap *This);
+
+ /* ISharedBitmap methods */
+ /* OK so MS doesn't publicly document the order of methods
+ * in the vtable, for that I had to peek in the SDK header.
+ * But just for the order, the prototypes of the methods is
+ * publicly documented.
+ */
+ HRESULT (WINAPI *GetSharedBitmap)(ISharedBitmap *This,
+ HBITMAP *phbm);
+ HRESULT (WINAPI *GetSize)(ISharedBitmap *This,
+ SIZE *pSize);
+ HRESULT (WINAPI *GetFormat)(ISharedBitmap *This,
+ WTS_ALPHATYPE *pat);
+ HRESULT (WINAPI *InitializeBitmap)(ISharedBitmap *This,
+ HBITMAP hbm,
+ WTS_ALPHATYPE wtsAT);
+ HRESULT (WINAPI *Detach)(ISharedBitmap *This,
+ HBITMAP *phbm);
+ END_INTERFACE
+ } ISharedBitmapVtbl;
+ struct ISharedBitmap {
+ CONST_VTBL struct ISharedBitmapVtbl *lpVtbl;
+ };
+
+typedef struct IThumbnailCache IThumbnailCache;
+
+typedef enum {
+ WTS_EXTRACT = 0x00000000,
+ WTS_SCALETOREQUESTEDSIZE = 0x00000040
+} WTS_FLAGS;
+
+typedef enum {
+ WTS_DEFAULT = 0x00000000,
+ WTS_LOWQUALITY = 0x00000001,
+ WTS_CACHED = 0x00000002
+} WTS_CACHEFLAGS;
+
+typedef struct tagTHUMBNAILID {
+ BYTE rgbKey[16];
+} WTS_THUMBNAILID;
+
+ typedef struct IThumbnailCacheVtbl {
+ BEGIN_INTERFACE
+ /* IUnknown methods */
+ HRESULT (WINAPI *QueryInterface)(IThumbnailCache *This,REFIID riid,void **ppvObject);
+ ULONG (WINAPI *AddRef)(IThumbnailCache *This);
+ ULONG (WINAPI *Release)(IThumbnailCache *This);
+
+ /* IThumbnailCache methods */
+ HRESULT (WINAPI *GetThumbnail)(IThumbnailCache *This,
+ IShellItem *pShellItem,
+ UINT cxyRequestedThumbSize,
+ WTS_FLAGS flags,
+ ISharedBitmap **ppvThumb,
+ WTS_CACHEFLAGS *pOutFlags,
+ WTS_THUMBNAILID *pThumbnailID);
+ HRESULT (WINAPI *GetThumbnailByID)(IThumbnailCache *This,
+ WTS_THUMBNAILID thumbnailID,
+ UINT cxyRequestedThumbSize,
+ ISharedBitmap **ppvThumb,
+ WTS_CACHEFLAGS *pOutFlags);
+ END_INTERFACE
+ } IThumbnailCacheVtbl;
+ struct IThumbnailCache {
+ CONST_VTBL struct IThumbnailCacheVtbl *lpVtbl;
+ };
+
+/* These IID and CLSID values not publicly documented but can't really
+ * be copyright protected, so gleaned from SDK headers.
+ */
+
+/* f676c15d-596a-4ce2-8234-33996f445db1 */
+DEFINE_GUID(IID_IThumbnailCache, 0xf676c15d, 0x596a, 0x4ce2, 0x82, 0x34, 0x33, 0x99, 0x6f, 0x44, 0x5d, 0xb1);
+
+/* 50ef4544-ac9f-4a8e-b21b-8a26180db13f */
+DEFINE_GUID(CLSID_LocalThumbnailCache, 0x50ef4544, 0xac9f, 0x4a8e, 0xb2, 0x1b, 0x8a, 0x26, 0x18, 0x0d, 0xb1, 0x3f);
+
+/* Determined by simple experimentation */
+#define WTS_E_FAILEDEXTRACTION 0x8004b200
+
+#endif
+
+typedef HRESULT (*tSHCreateItemFromParsingName)(PCWSTR pszPath, IBindCtx *pbc, REFIID riid, void **ppv);
+static tSHCreateItemFromParsingName pSHCreateItemFromParsingName;
+
+static IThumbnailCache *tncache;
+
+#endif /* G_OS_WIN32 */
struct _GnomeDesktopThumbnailFactoryPrivate {
GnomeDesktopThumbnailSize size;
+#ifndef G_OS_WIN32
GMutex *lock;
GHashTable *scripts_hash;
guint thumbnailers_notify;
guint reread_scheduled;
+#endif
};
static const char *appname = "gnome-thumbnail-factory";
@@ -62,9 +219,33 @@ static const char *appname = "gnome-thumbnail-factory";
static void gnome_desktop_thumbnail_factory_init (GnomeDesktopThumbnailFactory *factory);
static void gnome_desktop_thumbnail_factory_class_init (GnomeDesktopThumbnailFactoryClass *class);
-G_DEFINE_TYPE (GnomeDesktopThumbnailFactory,
+static void
+_gnome_desktop_thumbnail_factory_init (void)
+{
+#ifdef G_OS_WIN32
+ pSHCreateItemFromParsingName =
+ (tSHCreateItemFromParsingName) GetProcAddress (LoadLibrary ("shell32.dll"),
+ "SHCreateItemFromParsingName");
+
+ if (pSHCreateItemFromParsingName != NULL)
+ {
+ HRESULT hr;
+
+ CoInitialize (NULL);
+ hr = CoCreateInstance (&CLSID_LocalThumbnailCache, NULL, CLSCTX_INPROC_SERVER,
+ &IID_IThumbnailCache, (LPVOID*)&tncache);
+
+ if (hr != S_OK)
+ pSHCreateItemFromParsingName = NULL;
+ }
+#endif
+}
+
+G_DEFINE_TYPE_WITH_CODE (GnomeDesktopThumbnailFactory,
gnome_desktop_thumbnail_factory,
- G_TYPE_OBJECT)
+ G_TYPE_OBJECT,
+ _gnome_desktop_thumbnail_factory_init ();)
+
#define parent_class gnome_desktop_thumbnail_factory_parent_class
#define GNOME_DESKTOP_THUMBNAIL_FACTORY_GET_PRIVATE(object) \
@@ -81,21 +262,21 @@ typedef struct {
#define LOAD_BUFFER_SIZE 4096
static void
-size_prepared_cb (GdkPixbufLoader *loader,
+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 &&
+
+ if (info->preserve_aspect_ratio &&
(info->width > 0 || info->height > 0)) {
if (info->width < 0)
{
@@ -121,7 +302,7 @@ size_prepared_cb (GdkPixbufLoader *loader,
if (info->height > 0)
height = info->height;
}
-
+
gdk_pixbuf_loader_set_size (loader, width, height);
}
@@ -135,7 +316,7 @@ _gdk_pixbuf_new_from_uri_at_scale (const char *uri,
char buffer[LOAD_BUFFER_SIZE];
gsize bytes_read;
GdkPixbufLoader *loader;
- GdkPixbuf *pixbuf;
+ GdkPixbuf *pixbuf;
GdkPixbufAnimation *animation;
GdkPixbufAnimationIter *iter;
gboolean has_frame;
@@ -184,7 +365,7 @@ _gdk_pixbuf_new_from_uri_at_scale (const char *uri,
info.width = width;
info.height = height;
info.input_width = info.input_height = 0;
- info.preserve_aspect_ratio = preserve_aspect_ratio;
+ info.preserve_aspect_ratio = preserve_aspect_ratio;
g_signal_connect (loader, "size-prepared", G_CALLBACK (size_prepared_cb), &info);
}
@@ -256,24 +437,24 @@ gnome_desktop_thumbnail_factory_finalize (GObject *object)
{
GnomeDesktopThumbnailFactory *factory;
GnomeDesktopThumbnailFactoryPrivate *priv;
- GConfClient *client;
-
+
factory = GNOME_DESKTOP_THUMBNAIL_FACTORY (object);
priv = factory->priv;
-
+
+#ifndef G_OS_WIN32
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 ();
+ GConfClient *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);
@@ -285,11 +466,15 @@ gnome_desktop_thumbnail_factory_finalize (GObject *object)
g_mutex_free (priv->lock);
priv->lock = NULL;
}
-
+
+#endif
+
if (G_OBJECT_CLASS (parent_class)->finalize)
(* G_OBJECT_CLASS (parent_class)->finalize) (object);
}
+#ifndef G_OS_WIN32
+
/* Must be called on main thread */
static GHashTable *
read_scripts (void)
@@ -308,12 +493,12 @@ read_scripts (void)
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)
@@ -334,7 +519,7 @@ read_scripts (void)
if (mimetype != NULL)
{
mimetype++; /* skip past slash */
-
+
/* Convert '@' to slash in mimetype */
escape = strchr (mimetype, '@');
if (escape != NULL)
@@ -354,14 +539,14 @@ read_scripts (void)
}
}
g_free (enable);
-
+
g_free (subdir);
}
-
+
g_slist_free(subdirs);
g_object_unref (G_OBJECT (client));
-
+
return scripts_hash;
}
@@ -379,9 +564,9 @@ gnome_desktop_thumbnail_factory_reread_scripts (GnomeDesktopThumbnailFactory *fa
if (priv->scripts_hash != NULL)
g_hash_table_destroy (priv->scripts_hash);
-
+
priv->scripts_hash = scripts_hash;
-
+
g_mutex_unlock (priv->lock);
}
@@ -396,7 +581,7 @@ reread_idle_callback (gpointer user_data)
g_mutex_lock (priv->lock);
priv->reread_scheduled = 0;
g_mutex_unlock (priv->lock);
-
+
return FALSE;
}
@@ -416,40 +601,47 @@ schedule_reread (GConfClient* client,
priv->reread_scheduled = g_idle_add (reread_idle_callback,
factory);
}
-
+
g_mutex_unlock (priv->lock);
}
+#endif
static void
gnome_desktop_thumbnail_factory_init (GnomeDesktopThumbnailFactory *factory)
{
- GConfClient *client;
GnomeDesktopThumbnailFactoryPrivate *priv;
-
+
factory->priv = GNOME_DESKTOP_THUMBNAIL_FACTORY_GET_PRIVATE (factory);
priv = factory->priv;
priv->size = GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL;
-
- priv->scripts_hash = NULL;
-
+
+
+#ifndef G_OS_WIN32
+ {
+ GConfClient *client;
+
priv->lock = g_mutex_new ();
+ priv->scripts_hash = NULL;
+
client = gconf_client_get_default ();
gconf_client_add_dir (client,
"/desktop/gnome/thumbnailers",
GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
gnome_desktop_thumbnail_factory_reread_scripts (factory);
-
+
priv->thumbnailers_notify = gconf_client_notify_add (client, "/desktop/gnome/thumbnailers",
schedule_reread, factory, NULL,
NULL);
g_object_unref (G_OBJECT (client));
}
+#endif
+}
static void
gnome_desktop_thumbnail_factory_class_init (GnomeDesktopThumbnailFactoryClass *class)
@@ -457,7 +649,7 @@ gnome_desktop_thumbnail_factory_class_init (GnomeDesktopThumbnailFactoryClass *c
GObjectClass *gobject_class;
gobject_class = G_OBJECT_CLASS (class);
-
+
gobject_class->finalize = gnome_desktop_thumbnail_factory_finalize;
g_type_class_add_private (class, sizeof (GnomeDesktopThumbnailFactoryPrivate));
@@ -470,7 +662,7 @@ gnome_desktop_thumbnail_factory_class_init (GnomeDesktopThumbnailFactoryClass *c
* Creates a new #GnomeDesktopThumbnailFactory.
*
* This function must be called on the main thread.
- *
+ *
* Return value: a new #GnomeDesktopThumbnailFactory
*
* Since: 2.2
@@ -479,11 +671,11 @@ GnomeDesktopThumbnailFactory *
gnome_desktop_thumbnail_factory_new (GnomeDesktopThumbnailSize size)
{
GnomeDesktopThumbnailFactory *factory;
-
+
factory = g_object_new (GNOME_DESKTOP_TYPE_THUMBNAIL_FACTORY, NULL);
-
+
factory->priv->size = size;
-
+
return factory;
}
@@ -525,7 +717,7 @@ gnome_desktop_thumbnail_factory_lookup (GnomeDesktopThumbnailFactory *factory,
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",
@@ -608,6 +800,8 @@ gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (GnomeDesktopThumbnai
return res;
}
+#ifndef G_OS_WIN32
+
static gboolean
mimetype_supported_by_gdk_pixbuf (const char *mime_type)
{
@@ -633,7 +827,7 @@ mimetype_supported_by_gdk_pixbuf (const char *mime_type)
for (i = 0; mime_types[i] != NULL; i++)
g_hash_table_insert (formats_hash,
(gpointer) g_content_type_from_mime_type (mime_types[i]),
- GUINT_TO_POINTER (1));
+ GUINT_TO_POINTER (1));
g_strfreev (mime_types);
list = list->next;
@@ -651,6 +845,8 @@ mimetype_supported_by_gdk_pixbuf (const char *mime_type)
return result;
}
+#endif
+
/**
* gnome_desktop_thumbnail_factory_can_thumbnail:
* @factory: a #GnomeDesktopThumbnailFactory
@@ -673,17 +869,19 @@ gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *fac
const char *mime_type,
time_t mtime)
{
- gboolean have_script;
-
/* Don't thumbnail thumbnails */
if (uri &&
strncmp (uri, "file:/", 6) == 0 &&
strstr (uri, "/.thumbnails/") != NULL)
return FALSE;
-
+
if (!mime_type)
return FALSE;
+#ifndef G_OS_WIN32
+ {
+ gboolean have_script;
+
g_mutex_lock (factory->priv->lock);
have_script = (factory->priv->scripts_hash != NULL &&
g_hash_table_lookup (factory->priv->scripts_hash, mime_type));
@@ -695,13 +893,23 @@ gnome_desktop_thumbnail_factory_can_thumbnail (GnomeDesktopThumbnailFactory *fac
uri,
mtime);
}
-
+ }
+
return FALSE;
+
+#else
+
+ return !gnome_desktop_thumbnail_factory_has_valid_failed_thumbnail (factory,
+ uri,
+ mtime);
+#endif
}
+#ifndef G_OS_WIN32
+
static char *
expand_thumbnailing_script (const char *script,
- const int size,
+ const int size,
const char *inuri,
const char *outfile)
{
@@ -711,7 +919,7 @@ expand_thumbnailing_script (const char *script,
gboolean got_in;
str = g_string_new (NULL);
-
+
got_in = FALSE;
last = script;
while ((p = strchr (last, '%')) != NULL)
@@ -768,6 +976,8 @@ expand_thumbnailing_script (const char *script,
return NULL;
}
+#endif
+
/**
* gnome_desktop_thumbnail_factory_generate_thumbnail:
* @factory: a #GnomeDesktopThumbnailFactory
@@ -789,20 +999,18 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
const char *mime_type)
{
GdkPixbuf *pixbuf, *scaled, *tmp_pixbuf;
- char *script, *expanded_script;
+ char *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;
@@ -810,7 +1018,11 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
pixbuf = NULL;
script = NULL;
+
+#ifndef G_OS_WIN32
+
g_mutex_lock (factory->priv->lock);
+
if (factory->priv->scripts_hash != NULL)
{
script = g_hash_table_lookup (factory->priv->scripts_hash, mime_type);
@@ -818,9 +1030,12 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
script = g_strdup (script);
}
g_mutex_unlock (factory->priv->lock);
-
+
if (script)
{
+ char *tmpname;
+ char *expanded_script;
+ int exit_status;
int fd;
fd = g_file_open_tmp (".gnome_desktop_thumbnail.XXXXXX", &tmpname, NULL);
@@ -846,6 +1061,69 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
g_free (script);
}
+#else
+ if (pSHCreateItemFromParsingName != NULL)
+ {
+ gchar *filename = g_filename_from_uri (uri, NULL, NULL);
+
+ if (filename)
+ {
+ wchar_t dummy;
+ DWORD n;
+ wchar_t *wfilename;
+
+ wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ g_assert (wfilename);
+ n = GetFullPathNameW (wfilename, 0, &dummy, NULL);
+ if (n > 0)
+ {
+ HRESULT hr;
+ IShellItem *pItem;
+ wchar_t *wfullname = g_new (wchar_t, n);
+
+ hr = (*pSHCreateItemFromParsingName) (wfullname, NULL, &IID_IShellItem, (LPVOID *)&pItem);
+
+ if (hr == S_OK)
+ {
+ ISharedBitmap *pBitmap;
+ WTS_CACHEFLAGS flags;
+
+ hr = tncache->lpVtbl->GetThumbnail (tncache, pItem, size,
+ WTS_EXTRACT|WTS_SCALETOREQUESTEDSIZE,
+ &pBitmap, &flags, NULL);
+ if (hr == S_OK)
+ {
+ HBITMAP hbm;
+
+ hr = pBitmap->lpVtbl->GetSharedBitmap (pBitmap, &hbm);
+
+ if (hr == S_OK)
+ {
+ GdkDrawable *drawable =
+ GDK_DRAWABLE (gdk_pixmap_foreign_new_for_display (gdk_display_get_default (),
+ (GdkNativeWindow) hbm));
+ pixbuf = gdk_pixbuf_get_from_drawable (NULL,
+ drawable,
+ NULL,
+ 0, 0,
+ 0, 0,
+ -1, -1);
+ }
+
+ pBitmap->lpVtbl->Release (pBitmap);
+ }
+
+ pItem->lpVtbl->Release (pItem);
+ }
+
+ g_free (wfullname);
+ }
+ g_free (wfilename);
+ g_free (filename);
+ }
+ }
+#endif
+
/* Fall back to gdk-pixbuf */
if (pixbuf == NULL)
{
@@ -859,7 +1137,7 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
"gnome-original-height"));
}
}
-
+
if (pixbuf == NULL)
return NULL;
@@ -872,7 +1150,7 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
width = gdk_pixbuf_get_width (pixbuf);
height = gdk_pixbuf_get_height (pixbuf);
-
+
if (width > size || height > size)
{
const gchar *orig_width, *orig_height;
@@ -891,11 +1169,11 @@ gnome_desktop_thumbnail_factory_generate_thumbnail (GnomeDesktopThumbnailFactory
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);
@@ -937,7 +1215,7 @@ make_thumbnail_dirs (GnomeDesktopThumbnailFactory *factory)
g_free (thumbnail_dir);
g_free (image_dir);
-
+
return res;
}
@@ -981,7 +1259,7 @@ make_thumbnail_fail_dirs (GnomeDesktopThumbnailFactory *factory)
g_free (thumbnail_dir);
g_free (fail_dir);
g_free (app_dir);
-
+
return res;
}
@@ -989,9 +1267,9 @@ make_thumbnail_fail_dirs (GnomeDesktopThumbnailFactory *factory)
/**
* gnome_desktop_thumbnail_factory_save_thumbnail:
* @factory: a #GnomeDesktopThumbnailFactory
- * @thumbnail: the thumbnail as a pixbuf
+ * @thumbnail: the thumbnail as a pixbuf
* @uri: the uri of a file
- * @original_mtime: the modification time of the original 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.
@@ -1054,12 +1332,12 @@ gnome_desktop_thumbnail_factory_save_thumbnail (GnomeDesktopThumbnailFactory *fa
return;
}
close (tmp_fd);
-
- g_snprintf (mtime_str, 21, "%ld", original_mtime);
+
+ g_snprintf (mtime_str, 21, "%ld", (long)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)
+ if (width != NULL && height != NULL)
saved_ok = gdk_pixbuf_save (thumbnail,
tmp_path,
"png", NULL,
@@ -1077,7 +1355,7 @@ gnome_desktop_thumbnail_factory_save_thumbnail (GnomeDesktopThumbnailFactory *fa
"tEXt::Thumb::MTime", mtime_str,
"tEXt::Software", "GNOME::ThumbnailFactory",
NULL);
-
+
if (saved_ok)
{
@@ -1156,12 +1434,12 @@ gnome_desktop_thumbnail_factory_create_failed_thumbnail (GnomeDesktopThumbnailFa
return;
}
close (tmp_fd);
-
- g_snprintf (mtime_str, 21, "%ld", mtime);
+
+ g_snprintf (mtime_str, 21, "%ld", (long)mtime);
pixbuf = gdk_pixbuf_new (GDK_COLORSPACE_RGB, TRUE, 8, 1, 1);
saved_ok = gdk_pixbuf_save (pixbuf,
tmp_path,
- "png", NULL,
+ "png", NULL,
"tEXt::Thumb::URI", uri,
"tEXt::Thumb::MTime", mtime_str,
"tEXt::Software", "GNOME::ThumbnailFactory",
@@ -1220,13 +1498,13 @@ gnome_desktop_thumbnail_path_for_uri (const char *uri,
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;
@@ -1249,7 +1527,7 @@ 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;
@@ -1277,19 +1555,19 @@ gnome_desktop_thumbnail_is_valid (GdkPixbuf *pixbuf,
{
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;
}
diff --git a/libgnome-desktop/test-thumbnail.c b/libgnome-desktop/test-thumbnail.c
new file mode 100644
index 0000000..d528f96
--- /dev/null
+++ b/libgnome-desktop/test-thumbnail.c
@@ -0,0 +1,125 @@
+/* -*- Mode: C; c-set-style: gnu indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <config.h>
+#include <string.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+
+#define GNOME_DESKTOP_USE_UNSTABLE_API
+#include <libgnomeui/gnome-desktop-thumbnail.h>
+#undef GNOME_DESKTOP_USE_UNSTABLE_API
+
+#include <gtk/gtk.h>
+#include <glib/gstdio.h>
+
+static GnomeDesktopThumbnailFactory *tn_factory;
+
+static void
+test_thumbnail (const char *filename)
+{
+ struct stat st;
+ gchar *content_type, *mime = NULL;
+ gboolean uncertain = FALSE;
+ char *uri;
+ char *thumbnail;
+
+ if (g_stat (filename, &st) == -1) {
+ fprintf (stderr, "Could not stat %s\n", filename);
+ return;
+ }
+
+ content_type = g_content_type_guess (filename, NULL, 0, &uncertain);
+ if (content_type)
+ mime = g_content_type_get_mime_type (content_type);
+
+ if (mime == NULL) {
+ fprintf (stderr, "Could not guess MIME type of %s\n", filename);
+ return;
+ }
+
+ uri = g_filename_to_uri (filename, NULL, NULL);
+ if (uri == NULL) {
+ fprintf (stderr, "Could not convert %s to a URI\n", filename);
+ return;
+ }
+
+ thumbnail = gnome_desktop_thumbnail_factory_lookup (tn_factory, uri, st.st_mtime);
+
+ if (thumbnail != NULL) {
+ printf ("%s: existing %s\n", filename, thumbnail);
+ } else {
+ printf ("%s: no existing thumbnail\n", filename);
+
+ if (gnome_desktop_thumbnail_factory_can_thumbnail (tn_factory,
+ uri, mime, st.st_mtime)) {
+ GdkPixbuf *pixbuf =
+ gnome_desktop_thumbnail_factory_generate_thumbnail (tn_factory,
+ uri, mime);
+
+ if (pixbuf) {
+ gnome_desktop_thumbnail_factory_save_thumbnail (tn_factory,
+ pixbuf, uri,
+ st.st_mtime);
+ g_object_unref (pixbuf);
+ thumbnail = gnome_desktop_thumbnail_factory_lookup (tn_factory,
+ uri, st.st_mtime);
+ if (thumbnail != NULL)
+ printf ("%s: generated %s\n", filename, thumbnail);
+ }
+ }
+ }
+
+ g_free (thumbnail);
+ g_free (uri);
+}
+
+int
+main (int argc, char **argv)
+{
+ int i;
+ GnomeDesktopThumbnailSize size = GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL;
+
+ gtk_init (&argc, &argv);
+
+ if (argc < 2) {
+ fprintf (stderr, "Usage: test-ditem [--normal|--large] path...\n");
+ exit (1);
+ }
+
+ for (i = 1; argv[i][0] == '-'; i++) {
+ if (g_ascii_strcasecmp (argv[i], "--normal") == 0)
+ size = GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL;
+ else if (g_ascii_strcasecmp (argv[i], "--large") == 0)
+ size = GNOME_DESKTOP_THUMBNAIL_SIZE_LARGE;
+ else
+ fprintf (stderr, "Unrecognized option %s\n", argv[i]);
+ }
+
+ tn_factory = gnome_desktop_thumbnail_factory_new (size);
+
+ if (tn_factory == NULL) {
+ fprintf (stderr, "Could not create thumbnail factory\n");
+ exit (1);
+ }
+
+ for (; i < argc; i++)
+ test_thumbnail (argv[i]);
+
+ return 0;
+}