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;
+}
openSUSE Build Service is sponsored by