diff options
Diffstat (limited to 'tumblerd/tumbler-specialized-thumbnailer.c')
-rw-r--r-- | tumblerd/tumbler-specialized-thumbnailer.c | 206 |
1 files changed, 152 insertions, 54 deletions
diff --git a/tumblerd/tumbler-specialized-thumbnailer.c b/tumblerd/tumbler-specialized-thumbnailer.c index 6e4f5e5..b819c71 100644 --- a/tumblerd/tumbler-specialized-thumbnailer.c +++ b/tumblerd/tumbler-specialized-thumbnailer.c @@ -26,6 +26,7 @@ #include <glib-object.h> #include <tumbler/tumbler.h> +#include <tumbler/tumbler-marshal.h> #include <tumblerd/tumbler-specialized-thumbnailer.h> @@ -45,6 +46,10 @@ enum +typedef struct _SpecializedInfo SpecializedInfo; + + + static void tumbler_specialized_thumbnailer_iface_init (TumblerThumbnailerIface *iface); static void tumbler_specialized_thumbnailer_constructed (GObject *object); static void tumbler_specialized_thumbnailer_finalize (GObject *object); @@ -59,14 +64,6 @@ static void tumbler_specialized_thumbnailer_set_property (GObject static void tumbler_specialized_thumbnailer_create (TumblerThumbnailer *thumbnailer, GCancellable *cancellable, TumblerFileInfo *info); -static void tumbler_specialized_thumbnailer_proxy_ready (DBusGProxy *proxy, - const gchar *uri, - TumblerSpecializedThumbnailer *thumbnailer); -static void tumbler_specialized_thumbnailer_proxy_error (DBusGProxy *proxy, - const gchar *uri, - gint error_code, - const gchar *message, - TumblerSpecializedThumbnailer *thumbnailer); static void tumbler_specialized_thumbnailer_proxy_destroyed (DBusGProxy *proxy, TumblerSpecializedThumbnailer *thumbnailer); @@ -91,6 +88,17 @@ struct _TumblerSpecializedThumbnailer gchar *object_path; }; +struct _SpecializedInfo +{ + TumblerThumbnailer *thumbnailer; + GCond *condition; + GMutex *mutex; + const gchar *uri; + const gchar *mime_type; + gboolean had_callback; + guint handle; +}; + G_DEFINE_TYPE_WITH_CODE (TumblerSpecializedThumbnailer, @@ -164,17 +172,25 @@ tumbler_specialized_thumbnailer_class_init (TumblerSpecializedThumbnailerClass * G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); - dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__STRING, + dbus_g_object_register_marshaller (tumbler_marshal_VOID__UINT_STRING, G_TYPE_NONE, + G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID); - - dbus_g_object_register_marshaller (tumbler_marshal_VOID__STRING_INT_STRING, + + dbus_g_object_register_marshaller (g_cclosure_marshal_VOID__UINT, + G_TYPE_NONE, + G_TYPE_UINT, + G_TYPE_INVALID); + + dbus_g_object_register_marshaller (tumbler_marshal_VOID__UINT_STRING_INT_STRING, G_TYPE_NONE, + G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID); + } @@ -212,22 +228,23 @@ tumbler_specialized_thumbnailer_constructed (GObject *object) "org.freedesktop.thumbnails.SpecializedThumbnailer1"); dbus_g_proxy_add_signal (thumbnailer->proxy, "Ready", - G_TYPE_STRING, G_TYPE_INVALID); + G_TYPE_UINT, G_TYPE_STRING, + G_TYPE_INVALID); dbus_g_proxy_add_signal (thumbnailer->proxy, "Error", - G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING, G_TYPE_INVALID); - - dbus_g_proxy_connect_signal (thumbnailer->proxy, "Ready", - G_CALLBACK (tumbler_specialized_thumbnailer_proxy_ready), - thumbnailer, NULL); - - dbus_g_proxy_connect_signal (thumbnailer->proxy, "Error", - G_CALLBACK (tumbler_specialized_thumbnailer_proxy_error), - thumbnailer, NULL); - - g_signal_connect (thumbnailer->proxy, "destroy", - G_CALLBACK (tumbler_specialized_thumbnailer_proxy_destroyed), - thumbnailer); + G_TYPE_UINT, G_TYPE_STRING, + G_TYPE_INT, G_TYPE_STRING, + G_TYPE_INVALID); + + dbus_g_proxy_add_signal (thumbnailer->proxy, "Finished", + G_TYPE_UINT, + G_TYPE_INVALID); + + if (thumbnailer->foreign) { + g_signal_connect (thumbnailer->proxy, "destroy", + G_CALLBACK (tumbler_specialized_thumbnailer_proxy_destroyed), + thumbnailer); + } } @@ -240,14 +257,6 @@ tumbler_specialized_thumbnailer_finalize (GObject *object) g_free (thumbnailer->name); g_free (thumbnailer->object_path); - dbus_g_proxy_disconnect_signal (thumbnailer->proxy, "Ready", - G_CALLBACK (tumbler_specialized_thumbnailer_proxy_ready), - thumbnailer); - - dbus_g_proxy_disconnect_signal (thumbnailer->proxy, "Error", - G_CALLBACK (tumbler_specialized_thumbnailer_proxy_error), - thumbnailer); - g_signal_handlers_disconnect_matched (thumbnailer->proxy, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, thumbnailer); @@ -330,45 +339,134 @@ tumbler_specialized_thumbnailer_set_property (GObject *object, static void -tumbler_specialized_thumbnailer_create (TumblerThumbnailer *thumbnailer, - GCancellable *cancellable, - TumblerFileInfo *info) +specialized_error (DBusGProxy *proxy, + guint handle, + gchar *uri, + gint error_code, + gchar *error_msg, + gpointer user_data) { - /* TODO */ + SpecializedInfo *info = user_data; + + if (info->handle == handle) + g_signal_emit_by_name (info->thumbnailer, "error", uri, error_code, error_msg); } static void -tumbler_specialized_thumbnailer_proxy_ready (DBusGProxy *proxy, - const gchar *uri, - TumblerSpecializedThumbnailer *thumbnailer) +specialized_ready (DBusGProxy *proxy, + guint handle, + gchar *uri, + gpointer user_data) { - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (uri != NULL); - g_return_if_fail (TUMBLER_IS_SPECIALIZED_THUMBNAILER (thumbnailer)); + SpecializedInfo *info = user_data; - g_signal_emit_by_name (thumbnailer, "ready", uri); + if (info->handle == handle) + g_signal_emit_by_name (info->thumbnailer, "ready", uri); } static void -tumbler_specialized_thumbnailer_proxy_error (DBusGProxy *proxy, - const gchar *uri, - gint error_code, - const gchar *message, - TumblerSpecializedThumbnailer *thumbnailer) +specialized_finished (DBusGProxy *proxy, + guint handle, + gpointer user_data) { - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); - g_return_if_fail (uri != NULL); - g_return_if_fail (message != NULL); - g_return_if_fail (TUMBLER_IS_SPECIALIZED_THUMBNAILER (thumbnailer)); + SpecializedInfo *info = user_data; - g_signal_emit_by_name (thumbnailer, "error", uri, error_code, message); + if (info->handle == handle) + { + g_mutex_lock (info->mutex); + g_cond_broadcast (info->condition); + info->had_callback = TRUE; + g_mutex_unlock (info->mutex); + } } +static void +tumbler_specialized_thumbnailer_create (TumblerThumbnailer *thumbnailer, + GCancellable *cancellable, + TumblerFileInfo *info) +{ + TumblerSpecializedThumbnailer *s; + SpecializedInfo sinfo; + GTimeVal timev; + TumblerThumbnail *thumbnail; + TumblerThumbnailFlavor *flavor; + const gchar *flavor_name; + const gchar *uri; + GError *error = NULL; + gchar *message; + + g_return_if_fail (TUMBLER_IS_SPECIALIZED_THUMBNAILER (thumbnailer)); + + uri = tumbler_file_info_get_uri (info); + thumbnail = tumbler_file_info_get_thumbnail (info); + flavor = tumbler_thumbnail_get_flavor (thumbnail); + flavor_name = tumbler_thumbnail_flavor_get_name (flavor); + + s = TUMBLER_SPECIALIZED_THUMBNAILER (thumbnailer); + + sinfo.condition = g_cond_new (); + sinfo.had_callback = FALSE; + sinfo.mutex = g_mutex_new (); + sinfo.uri = uri; + sinfo.mime_type = tumbler_file_info_get_mime_type (info); + sinfo.thumbnailer = thumbnailer; + + dbus_g_proxy_connect_signal (s->proxy, "Finished", + G_CALLBACK (specialized_finished), + &sinfo, + NULL); + + dbus_g_proxy_connect_signal (s->proxy, "Ready", + G_CALLBACK (specialized_ready), + &sinfo, + NULL); + + dbus_g_proxy_connect_signal (s->proxy, "Error", + G_CALLBACK (specialized_error), + &sinfo, + NULL); + + dbus_g_proxy_call_with_timeout (s->proxy, "Create", + 100000000, /* 100 seconds worth of timeout */ + &error, + G_TYPE_STRING, uri, + G_TYPE_STRING, sinfo.mime_type, + G_TYPE_STRING, flavor_name, + /* TODO: Get this bool from scheduler type */ + G_TYPE_BOOLEAN, FALSE, + G_TYPE_INVALID, + G_TYPE_UINT, &sinfo.handle, + G_TYPE_INVALID); + + if (error == NULL) + { + g_get_current_time (&timev); + + /* 100 seconds worth of timeout */ + g_time_val_add (&timev, 100000000); + + g_mutex_lock (sinfo.mutex); + /* we are a thread, so the mainloop will still be + * be running to receive the error and ready signals */ + if (!sinfo.had_callback) + g_cond_timed_wait (sinfo.condition, sinfo.mutex, &timev); + + g_mutex_unlock (sinfo.mutex); + } + else + { + message = g_strdup_printf ("Failed to call the specialized thumbnailer: %s", + error->message); + g_signal_emit_by_name (thumbnailer, "error", uri, 1, message); + g_free (message); + g_clear_error (&error); + } +} static void tumbler_specialized_thumbnailer_proxy_destroyed (DBusGProxy *proxy, |