summaryrefslogtreecommitdiff
path: root/tumblerd/tumbler-specialized-thumbnailer.c
diff options
context:
space:
mode:
Diffstat (limited to 'tumblerd/tumbler-specialized-thumbnailer.c')
-rw-r--r--tumblerd/tumbler-specialized-thumbnailer.c206
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,