Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
home:rhabacker:linkedprojecttest
mingw32-gnome-desktop
gnome-desktop-2.32.1-windows.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File gnome-desktop-2.32.1-windows.patch of Package mingw32-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; +}
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor