diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | README | 8 | ||||
-rw-r--r-- | configure.ac | 25 | ||||
-rw-r--r-- | plugins/odf-thumbnailer/odf-thumbnailer.c | 2 | ||||
-rw-r--r-- | tumblerd/Makefile.am | 47 | ||||
-rw-r--r-- | tumblerd/main.c | 129 | ||||
-rw-r--r-- | tumblerd/tumbler-cache-service-dbus.xml | 7 | ||||
-rw-r--r-- | tumblerd/tumbler-cache-service.c | 280 | ||||
-rw-r--r-- | tumblerd/tumbler-cache-service.h | 22 | ||||
-rw-r--r-- | tumblerd/tumbler-manager-dbus.xml | 5 | ||||
-rw-r--r-- | tumblerd/tumbler-manager.c | 201 | ||||
-rw-r--r-- | tumblerd/tumbler-manager.h | 16 | ||||
-rw-r--r-- | tumblerd/tumbler-service-dbus.xml | 10 | ||||
-rw-r--r-- | tumblerd/tumbler-service.c | 555 | ||||
-rw-r--r-- | tumblerd/tumbler-service.h | 26 | ||||
-rw-r--r-- | tumblerd/tumbler-specialized-thumbnailer.c | 260 | ||||
-rw-r--r-- | tumblerd/tumbler-specialized-thumbnailer.h | 6 | ||||
-rw-r--r-- | tumblerd/tumbler-utils.h | 24 |
18 files changed, 779 insertions, 848 deletions
@@ -1,3 +1,7 @@ +0.1.90 +====== +- Tumbler relies now on gdbus instead of dbus-glib + 0.1.31 ====== - Use $XDG_CACHE_HOME/thumbnails as per spec change (bug #10613) @@ -22,11 +22,9 @@ Required packages Tumbler depends on the following packages: - * glib-2.0 >= 2.16.0 - * gio-2.0 >= 2.16.0 - * gthread-2.0 >= 2.16.0 - * dbus-1 >= 1.0.0 - * dbus-glib-1 >= 0.72 + * glib-2.0 >= 2.26.0 + * gio-2.0 >= 2.26.0 + * gthread-2.0 >= 2.26.0 Tumbler can optionally use the following packages: diff --git a/configure.ac b/configure.ac index a8dc277..9956e96 100644 --- a/configure.ac +++ b/configure.ac @@ -25,7 +25,7 @@ m4_define([tumbler_verinfo], [0:0:0]) m4_define([tumbler_version_api_major], [1]) m4_define([tumbler_version_major], [0]) m4_define([tumbler_version_minor], [1]) -m4_define([tumbler_version_micro], [31]) +m4_define([tumbler_version_micro], [90]) m4_define([tumbler_version], [tumbler_version_major().tumbler_version_minor().tumbler_version_micro()]) dnl *************************** @@ -129,25 +129,24 @@ dnl ************************* GTK_DOC_CHECK(1.9) dnl *********************************** -dnl *** Check for dbus-binding-tool *** +dnl *** Check for gdbus-codegen *** dnl *********************************** -AC_ARG_VAR([DBUS_BINDING_TOOL], [Tool to generate C bindings from XML D-Bus interface definitions]) -AC_PATH_PROG([DBUS_BINDING_TOOL], [dbus-binding-tool], [no]) -if test x"$DBUS_BINDING_TOOL" = x"no"; then - AC_MSG_ERROR([could not find dbus-binding-tool in \$PATH. You can run - ./configure DBUS_BINDING_TOOL=/path/to/dbus-binding-tool to define +AC_ARG_VAR([GDBUS_CODEGEN], [D-Bus code and documentation generator from XML D-Bus interface definitions]) +AC_PATH_PROG([GDBUS_CODEGEN], [gdbus-codegen], [no]) +if test x"$GDBUS_CODEGEN" = x"no"; then + AC_MSG_ERROR([could not find gdbus-codegen in \$PATH. You can run + ./configure GDBUS_CODEGEN=/path/to/gdbus-codegen to define a custom location for it.]) fi dnl *********************************** dnl *** Check for required packages *** dnl *********************************** -PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.16.0]) -PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.16.0]) -PKG_CHECK_MODULES([GMODULE], [gmodule-2.0 >= 2.10.0]) -PKG_CHECK_MODULES([GTHREAD], [gthread-2.0 >= 2.16.0]) -PKG_CHECK_MODULES([DBUS], [dbus-1 >= 1.0.0]) -PKG_CHECK_MODULES([DBUS_GLIB], [dbus-glib-1 >= 0.72]) +PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.26.0]) +PKG_CHECK_MODULES([GIO], [gio-2.0 >= 2.26.0]) +PKG_CHECK_MODULES([GIO_UNIX], [gio-unix-2.0 >= 2.26.0]) +PKG_CHECK_MODULES([GMODULE], [gmodule-2.0 >= 2.26.0]) +PKG_CHECK_MODULES([GTHREAD], [gthread-2.0 >= 2.26.0]) dnl ************************* dnl *** Check for plugins *** diff --git a/plugins/odf-thumbnailer/odf-thumbnailer.c b/plugins/odf-thumbnailer/odf-thumbnailer.c index 6a8b219..31ed9db 100644 --- a/plugins/odf-thumbnailer/odf-thumbnailer.c +++ b/plugins/odf-thumbnailer/odf-thumbnailer.c @@ -261,7 +261,7 @@ odf_thumbnailer_create_msole (GsfInfile *infile, /* read meta data from stream */ meta_data = gsf_doc_meta_data_new (); - err = gsf_msole_metadata_read (summary, meta_data); + err = gsf_doc_meta_data_read_from_msole (meta_data, summary); g_object_unref (summary); if (err != NULL) { diff --git a/tumblerd/Makefile.am b/tumblerd/Makefile.am index 6dfd249..b1ac6a8 100644 --- a/tumblerd/Makefile.am +++ b/tumblerd/Makefile.am @@ -24,9 +24,13 @@ tumblerd_PROGRAMS = \ tumblerd tumblerd_built_sources = \ - tumbler-cache-service-dbus-bindings.h \ - tumbler-manager-dbus-bindings.h \ - tumbler-service-dbus-bindings.h + tumbler-manager-gdbus.c \ + tumbler-manager-gdbus.h \ + tumbler-service-gdbus.c \ + tumbler-service-gdbus.h \ + tumbler-cache-service-gdbus.h \ + tumbler-cache-service-gdbus.c + tumblerd_SOURCES = \ main.c \ @@ -57,10 +61,9 @@ tumblerd_CFLAGS = \ -DPACKAGE_LOCALE_DIR=\"$(localedir)\" \ -DG_LOG_DOMAIN=\"tumblerd\" \ -I$(top_srcdir) \ - $(DBUS_CFLAGS) \ - $(DBUS_GLIB_CFLAGS) \ $(GDK_PIXBUF_CFLAGS) \ $(GIO_CFLAGS) \ + $(GIO_UNIX_CFLAGS) \ $(GLIB_CFLAGS) \ $(GTHREAD_CFLAGS) \ $(PLATFORM_CFLAGS) \ @@ -74,10 +77,9 @@ tumblerd_DEPENDENCIES = \ $(top_builddir)/tumbler/libtumbler-$(TUMBLER_VERSION_API).la tumblerd_LDADD = \ - $(DBUS_LIBS) \ - $(DBUS_GLIB_LIBS) \ $(GDK_PIXBUF_LIBS) \ $(GIO_LIBS) \ + $(GIO_UNIX_LIBS) \ $(GLIB_LIBS) \ $(GTHREAD_LIBS) \ $(top_builddir)/tumbler/libtumbler-$(TUMBLER_VERSION_API).la @@ -114,11 +116,26 @@ DISTCLEANFILES = \ BUILT_SOURCES = \ $(tumblerd_built_sources) -tumbler-cache-service-dbus-bindings.h: tumbler-cache-service-dbus.xml Makefile - $(AM_V_GEN) $(DBUS_BINDING_TOOL) --mode=glib-server --prefix=tumbler_cache_service $< > $@ - -tumbler-manager-dbus-bindings.h: tumbler-manager-dbus.xml Makefile - $(AM_V_GEN) $(DBUS_BINDING_TOOL) --mode=glib-server --prefix=tumbler_manager $< > $@ - -tumbler-service-dbus-bindings.h: tumbler-service-dbus.xml Makefile - $(AM_V_GEN) $(DBUS_BINDING_TOOL) --mode=glib-server --prefix=tumbler_service $< > $@ +tumbler-manager-gdbus.h: +tumbler-manager-gdbus.c: tumbler-manager-dbus.xml Makefile + $(AM_V_GEN) $(GDBUS_CODEGEN) \ + --interface-prefix org.freedesktop.thumbnails.Manager1 \ + --c-namespace Tumbler \ + --generate-c-code tumbler-manager-gdbus \ + $(srcdir)/tumbler-manager-dbus.xml + +tumbler-service-gdbus.h: +tumbler-service-gdbus.c: tumbler-service-dbus.xml Makefile + $(AM_V_GEN) $(GDBUS_CODEGEN) \ + --interface-prefix org.freedesktop.thumbnails.Thumbnailer1 \ + --c-namespace Tumbler \ + --generate-c-code tumbler-service-gdbus \ + $(srcdir)/tumbler-service-dbus.xml + +tumbler-cache-service-gdbus.h: +tumbler-cache-service-gdbus.c: tumbler-cache-service-dbus.xml Makefile + $(AM_V_GEN) $(GDBUS_CODEGEN) \ + --interface-prefix org.freedesktop.thumbnails.Cache1 \ + --c-namespace Tumbler \ + --generate-c-code tumbler-cache-service-gdbus \ + $(srcdir)/tumbler-cache-service-dbus.xml
\ No newline at end of file diff --git a/tumblerd/main.c b/tumblerd/main.c index 8249fb2..73b5af2 100644 --- a/tumblerd/main.c +++ b/tumblerd/main.c @@ -1,7 +1,8 @@ /* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2009-2012 Jannis Pohlmann <jannis@xfce.org> - * + * Copyright (c) 2015 Ali Abdallah <ali@xfce.org> + * * 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 @@ -38,8 +39,6 @@ #include <glib/gi18n.h> #include <glib-object.h> -#include <dbus/dbus-glib.h> - #include <tumbler/tumbler.h> #include <tumblerd/tumbler-cache-service.h> @@ -214,7 +213,17 @@ locations_from_strv (gchar **array) return locations; } +static void +on_dbus_name_lost (GDBusConnection *connection, + const gchar *name, + gpointer user_data) +{ + GMainLoop *main_loop; + g_critical (_("Name %s lost on the message dbus, exiting."),name); + main_loop = (GMainLoop*)user_data; + g_main_loop_quit(main_loop); +} int main (int argc, @@ -222,7 +231,7 @@ main (int argc, { TumblerLifecycleManager *lifecycle_manager; TumblerProviderFactory *provider_factory; - DBusGConnection *connection; + GDBusConnection *connection; TumblerRegistry *registry; TumblerManager *manager; TumblerService *service; @@ -268,21 +277,17 @@ main (int argc, g_thread_init (NULL); #endif - /* initial the D-Bus threading system */ - dbus_g_thread_init (); - - /* try to connect to the D-Bus session bus */ - connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - /* print an error and exit if the connection could not be established */ - if (connection == NULL) + connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); + + if (error != NULL) { - g_warning (_("Failed to connect to the D-Bus session bus: %s"), error->message); + g_critical ("error getting session bus: %s", error->message); g_error_free (error); - - return EXIT_FAILURE; + + return EXIT_FAILURE; } - + /* create the lifecycle manager */ lifecycle_manager = tumbler_lifecycle_manager_new (); @@ -369,49 +374,57 @@ main (int argc, goto exit_tumbler; } - /* try to start the service and exit if that fails */ - if (!tumbler_cache_service_start (cache_service, &error)) - { - g_warning (_("Failed to start the thumbnail cache service: %s"), error->message); - g_error_free (error); - - /* service already running, exit gracefully to not break clients */ - goto exit_tumbler; - } - - /* try to start the service and exit if that fails */ - if (!tumbler_manager_start (manager, &error)) - { - g_warning (_("Failed to start the thumbnailer manager: %s"), error->message); - g_error_free (error); - - /* service already running, exit gracefully to not break clients */ - goto exit_tumbler; - } - - /* try to start the service and exit if that fails */ - if (!tumbler_service_start (service, &error)) - { - g_warning (_("Failed to start the thumbnailer service: %s"), error->message); - g_error_free (error); - - /* service already running, exit gracefully to not break clients */ - goto exit_tumbler; - } - /* create a new main loop */ main_loop = g_main_loop_new (NULL, FALSE); - - /* quit the main loop when the lifecycle manager asks us to shut down */ - g_signal_connect (lifecycle_manager, "shutdown", - G_CALLBACK (shutdown_tumbler), main_loop); - - /* start the lifecycle manager */ - tumbler_lifecycle_manager_start (lifecycle_manager); - - /* enter the main loop, thereby making the tumbler service available */ - g_main_loop_run (main_loop); - + + + /* Acquire the cache service dbus name */ + g_bus_own_name_on_connection (connection, + "org.freedesktop.thumbnails.Cache1", + G_BUS_NAME_OWNER_FLAGS_REPLACE, + NULL, /* We dont need to do anything on name acquired*/ + on_dbus_name_lost, + main_loop, + NULL); + + /* Acquire the manager dbus name */ + g_bus_own_name_on_connection (connection, + "org.freedesktop.thumbnails.Manager1", + G_BUS_NAME_OWNER_FLAGS_REPLACE, + NULL, /* We dont need to do anything on name acquired*/ + on_dbus_name_lost, + main_loop, + NULL); + + /* Acquire the thumbnailer service dbus name */ + g_bus_own_name_on_connection (connection, + "org.freedesktop.thumbnails.Thumbnailer1", + G_BUS_NAME_OWNER_FLAGS_REPLACE, + NULL, /* We dont need to do anything on name acquired*/ + on_dbus_name_lost, + main_loop, + NULL); + + /* check to see if all services are successfully exported on the bus */ + if (tumbler_manager_is_exported(manager) && + tumbler_service_is_exported(service) && + tumbler_cache_service_is_exported(cache_service)) + { + /* Let the manager initializes the thumbnailer + * directory objects, directory monitors */ + tumbler_manager_load (manager); + + /* quit the main loop when the lifecycle manager asks us to shut down */ + g_signal_connect (lifecycle_manager, "shutdown", + G_CALLBACK (shutdown_tumbler), main_loop); + + /* start the lifecycle manager */ + tumbler_lifecycle_manager_start (lifecycle_manager); + + /* enter the main loop, thereby making the tumbler service available */ + g_main_loop_run (main_loop); + } + exit_tumbler: /* shut our services down and release all objects */ @@ -421,8 +434,8 @@ main (int argc, g_object_unref (registry); g_object_unref (lifecycle_manager); - /* disconnect from the D-Bus session bus */ - dbus_g_connection_unref (connection); + /* free the dbus session bus connection */ + g_object_unref (connection); /* we're done, all fine */ return retval; diff --git a/tumblerd/tumbler-cache-service-dbus.xml b/tumblerd/tumbler-cache-service-dbus.xml index 92ffa42..f297f38 100644 --- a/tumblerd/tumbler-cache-service-dbus.xml +++ b/tumblerd/tumbler-cache-service-dbus.xml @@ -1,25 +1,24 @@ <?xml version="1.0" encoding="UTF-8"?> <node name="/org/freedesktop/thumbnails/Cache1"> + <interface name="org.freedesktop.thumbnails.Cache1"> + <annotation name="org.gtk.GDBus.C.Name" value="ExportedCacheService" /> <method name="Move"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> <arg type="as" name="from_uris" direction="in" /> <arg type="as" name="to_uris" direction="in" /> </method> <method name="Copy"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> <arg type="as" name="from_uris" direction="in" /> <arg type="as" name="to_uris" direction="in" /> </method> <method name="Delete"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> + <arg type="as" name="uris" direction="in" /> </method> <method name="Cleanup"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> <arg type="as" name="base_uris" direction="in" /> <arg type="u" name="since" direction="in" /> </method> diff --git a/tumblerd/tumbler-cache-service.c b/tumblerd/tumbler-cache-service.c index ab00645..79ceff6 100644 --- a/tumblerd/tumbler-cache-service.c +++ b/tumblerd/tumbler-cache-service.c @@ -25,19 +25,18 @@ #include <glib.h> #include <glib/gi18n.h> #include <glib-object.h> - -#include <dbus/dbus.h> -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> +#include <gio/gio.h> #include <tumbler/tumbler.h> #include <tumblerd/tumbler-component.h> #include <tumblerd/tumbler-cache-service.h> -#include <tumblerd/tumbler-cache-service-dbus-bindings.h> +#include <tumblerd/tumbler-cache-service-gdbus.h> #include <tumblerd/tumbler-utils.h> - +#define THUMBNAILER_CACHE_PATH "/org/freedesktop/thumbnails/Cache1" +#define THUMBNAILER_CACHE_SERVICE "org.freedesktop.thumbnails.Cache1" +#define THUMBNAILER_CACHE_IFACE "org.freedesktop.thumbnails.Cache1" typedef struct _MoveRequest MoveRequest; typedef struct _CopyRequest CopyRequest; @@ -76,6 +75,28 @@ static void tumbler_cache_service_cleanup_thread (gpointer data, +static gboolean tumbler_cache_service_cleanup (TumblerExportedCacheService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *base_uris, + guint32 since, + TumblerCacheService *service); +static gboolean tumbler_cache_service_delete (TumblerExportedCacheService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + TumblerCacheService *service); + +static gboolean tumbler_cache_service_copy (TumblerExportedCacheService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *from_uris, + const gchar *const *to_uris, + TumblerCacheService *service); + +static gboolean tumbler_cache_service_move (TumblerExportedCacheService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *from_uris, + const gchar *const *to_uris, + TumblerCacheService *service); + struct _TumblerCacheServiceClass { TumblerComponentClass __parent__; @@ -83,45 +104,51 @@ struct _TumblerCacheServiceClass struct _TumblerCacheService { - TumblerComponent __parent__; - - DBusGConnection *connection; + TumblerComponent __parent__; - TumblerCache *cache; + GDBusConnection *connection; + TumblerExportedCacheService *skeleton; + gboolean dbus_interface_exported; + + TumblerCache *cache; - GThreadPool *move_pool; - GThreadPool *copy_pool; - GThreadPool *delete_pool; - GThreadPool *cleanup_pool; + GThreadPool *move_pool; + GThreadPool *copy_pool; + GThreadPool *delete_pool; + GThreadPool *cleanup_pool; - TUMBLER_MUTEX (mutex); + TUMBLER_MUTEX (mutex); }; struct _MoveRequest { - gchar **from_uris; - gchar **to_uris; - DBusGMethodInvocation *context; + TumblerExportedCacheService *skeleton; + gchar **from_uris; + gchar **to_uris; + GDBusMethodInvocation *invocation; }; struct _CopyRequest { - gchar **from_uris; - gchar **to_uris; - DBusGMethodInvocation *context; + TumblerExportedCacheService *skeleton; + gchar **from_uris; + gchar **to_uris; + GDBusMethodInvocation *invocation; }; struct _DeleteRequest { - gchar **uris; - DBusGMethodInvocation *context; + TumblerExportedCacheService *skeleton; + gchar **uris; + GDBusMethodInvocation *invocation; }; struct _CleanupRequest { - guint32 since; - gchar **base_uris; - DBusGMethodInvocation *context; + TumblerExportedCacheService *skeleton; + guint32 since; + gchar **base_uris; + GDBusMethodInvocation *invocation; }; @@ -142,9 +169,10 @@ tumbler_cache_service_class_init (TumblerCacheServiceClass *klass) gobject_class->set_property = tumbler_cache_service_set_property; g_object_class_install_property (gobject_class, PROP_CONNECTION, - g_param_spec_pointer ("connection", + g_param_spec_object ("connection", "connection", "connection", + G_TYPE_DBUS_CONNECTION, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); } @@ -163,6 +191,7 @@ static void tumbler_cache_service_constructed (GObject *object) { TumblerCacheService *service = TUMBLER_CACHE_SERVICE (object); + GError *error = NULL; /* chain up to parent classes */ if (G_OBJECT_CLASS (tumbler_cache_service_parent_class)->constructed != NULL) @@ -178,15 +207,36 @@ tumbler_cache_service_constructed (GObject *object) service, 1, FALSE, NULL); service->cleanup_pool = g_thread_pool_new (tumbler_cache_service_cleanup_thread, service, 1, FALSE, NULL); - + + service->skeleton = tumbler_exported_cache_service_skeleton_new(); + /* everything's fine, install the cache type D-Bus info */ - dbus_g_object_type_install_info (G_OBJECT_TYPE (service), - &dbus_glib_tumbler_cache_service_object_info); - - /* register the cache instance as a handler of the cache interface */ - dbus_g_connection_register_g_object (service->connection, - "/org/freedesktop/thumbnails/Cache1", - G_OBJECT (service)); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON(service->skeleton), + service->connection, + THUMBNAILER_CACHE_PATH, + &error); + if (error != NULL) + { + g_critical ("error exporting thumbnail cache service on session bus: %s", error->message); + g_error_free (error); + service->dbus_interface_exported = FALSE; + } + else + { + service->dbus_interface_exported = TRUE; + + g_signal_connect (service->skeleton, "handle-move", + G_CALLBACK(tumbler_cache_service_move), service); + + g_signal_connect (service->skeleton, "handle-copy", + G_CALLBACK(tumbler_cache_service_copy), service); + + g_signal_connect (service->skeleton, "handle-delete", + G_CALLBACK(tumbler_cache_service_delete), service); + + g_signal_connect (service->skeleton, "handle-cleanup", + G_CALLBACK(tumbler_cache_service_cleanup), service); + } } @@ -204,7 +254,18 @@ tumbler_cache_service_finalize (GObject *object) if (service->cache != NULL) g_object_unref (service->cache); - dbus_g_connection_unref (service->connection); + /* Unexport from dbus */ + if (service->dbus_interface_exported) + g_dbus_interface_skeleton_unexport_from_connection + ( + G_DBUS_INTERFACE_SKELETON (service->skeleton), + service->connection + ); + + /* release the Skeleton object */ + g_object_unref (service->skeleton); + + g_object_unref (service->connection); tumbler_mutex_free (service->mutex); @@ -224,7 +285,7 @@ tumbler_cache_service_get_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - g_value_set_pointer (value, service->connection); + g_value_set_object (value, service->connection); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -245,7 +306,7 @@ tumbler_cache_service_set_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - service->connection = dbus_g_connection_ref (g_value_get_pointer (value)); + service->connection = g_object_ref (g_value_get_object (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); @@ -274,7 +335,7 @@ tumbler_cache_service_move_thread (gpointer data, (const gchar *const *)request->to_uris); } - dbus_g_method_return (request->context); + tumbler_exported_cache_service_complete_move (request->skeleton, request->invocation); g_strfreev (request->from_uris); g_strfreev (request->to_uris); @@ -308,7 +369,7 @@ tumbler_cache_service_copy_thread (gpointer data, (const gchar *const *)request->to_uris); } - dbus_g_method_return (request->context); + tumbler_exported_cache_service_complete_copy (request->skeleton, request->invocation); g_strfreev (request->from_uris); g_strfreev (request->to_uris); @@ -338,7 +399,7 @@ tumbler_cache_service_delete_thread (gpointer data, if (service->cache != NULL) tumbler_cache_delete (service->cache, (const gchar *const *)request->uris); - dbus_g_method_return (request->context); + tumbler_exported_cache_service_complete_delete (request->skeleton, request->invocation); g_strfreev (request->uris); g_slice_free (DeleteRequest, request); @@ -371,7 +432,7 @@ tumbler_cache_service_cleanup_thread (gpointer data, request->since); } - dbus_g_method_return (request->context); + tumbler_exported_cache_service_complete_cleanup (request->skeleton, request->invocation); g_strfreev (request->base_uris); g_slice_free (CleanupRequest, request); @@ -386,7 +447,7 @@ tumbler_cache_service_cleanup_thread (gpointer data, TumblerCacheService * -tumbler_cache_service_new (DBusGConnection *connection, +tumbler_cache_service_new (GDBusConnection *connection, TumblerLifecycleManager *lifecycle_manager) { return g_object_new (TUMBLER_TYPE_CACHE_SERVICE, @@ -397,58 +458,20 @@ tumbler_cache_service_new (DBusGConnection *connection, -gboolean -tumbler_cache_service_start (TumblerCacheService *service, - GError **error) -{ - DBusConnection *connection; - gint result; - - g_return_val_if_fail (TUMBLER_IS_CACHE_SERVICE (service), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - tumbler_mutex_lock (service->mutex); - - /* get the native D-Bus connection */ - connection = dbus_g_connection_get_connection (service->connection); - - /* request ownership for the cache interface */ - result = dbus_bus_request_name (connection, "org.freedesktop.thumbnails.Cache1", - DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL); - - /* check if that failed */ - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - if (error != NULL) - { - g_set_error (error, DBUS_GERROR, DBUS_GERROR_FAILED, - _("Another thumbnail cache service is already running")); - } - - tumbler_mutex_unlock (service->mutex); - - return FALSE; - } - - tumbler_mutex_unlock (service->mutex); - - return TRUE; -} - - -void -tumbler_cache_service_move (TumblerCacheService *service, - const gchar *const *from_uris, - const gchar *const *to_uris, - DBusGMethodInvocation *context) +gboolean +tumbler_cache_service_move (TumblerExportedCacheService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *from_uris, + const gchar *const *to_uris, + TumblerCacheService *service) { MoveRequest *request; - dbus_async_return_if_fail (TUMBLER_IS_CACHE_SERVICE (service), context); - dbus_async_return_if_fail (from_uris != NULL, context); - dbus_async_return_if_fail (to_uris != NULL, context); - dbus_async_return_if_fail (g_strv_length ((gchar **)from_uris) == g_strv_length ((gchar **)to_uris), context); + g_dbus_async_return_val_if_fail (TUMBLER_IS_CACHE_SERVICE (service), invocation, FALSE); + g_dbus_async_return_val_if_fail (from_uris != NULL, invocation, FALSE); + g_dbus_async_return_val_if_fail (to_uris != NULL, invocation, FALSE); + g_dbus_async_return_val_if_fail (g_strv_length ((gchar **)from_uris) == g_strv_length ((gchar **)to_uris), invocation, FALSE); /* prevent the lifecycle manager to shut tumbler down before the * move request has been processed */ @@ -457,29 +480,32 @@ tumbler_cache_service_move (TumblerCacheService *service, request = g_slice_new0 (MoveRequest); request->from_uris = g_strdupv ((gchar **)from_uris); request->to_uris = g_strdupv ((gchar **)to_uris); - request->context = context; + request->invocation = invocation; g_thread_pool_push (service->move_pool, request, NULL); /* try to keep tumbler alive */ tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); + + return TRUE; } -void -tumbler_cache_service_copy (TumblerCacheService *service, - const gchar *const *from_uris, - const gchar *const *to_uris, - DBusGMethodInvocation *context) +gboolean +tumbler_cache_service_copy (TumblerExportedCacheService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *from_uris, + const gchar *const *to_uris, + TumblerCacheService *service) { CopyRequest *request; - - dbus_async_return_if_fail (TUMBLER_IS_CACHE_SERVICE (service), context); - dbus_async_return_if_fail (from_uris != NULL, context); - dbus_async_return_if_fail (to_uris != NULL, context); - dbus_async_return_if_fail (g_strv_length ((gchar **)from_uris) == g_strv_length ((gchar **)to_uris), context); - + + g_dbus_async_return_val_if_fail (TUMBLER_IS_CACHE_SERVICE (service), invocation, FALSE); + g_dbus_async_return_val_if_fail (from_uris != NULL, invocation, FALSE); + g_dbus_async_return_val_if_fail (to_uris != NULL, invocation, FALSE); + g_dbus_async_return_val_if_fail (g_strv_length ((gchar **)from_uris) == g_strv_length ((gchar **)to_uris), invocation, FALSE); + /* prevent the lifecycle manager to shut tumbler down before the * copy request has been processed */ tumbler_component_increment_use_count (TUMBLER_COMPONENT (service)); @@ -487,25 +513,28 @@ tumbler_cache_service_copy (TumblerCacheService *service, request = g_slice_new0 (CopyRequest); request->from_uris = g_strdupv ((gchar **)from_uris); request->to_uris = g_strdupv ((gchar **)to_uris); - request->context = context; + request->invocation = invocation; g_thread_pool_push (service->copy_pool, request, NULL); /* try to keep tumbler alive */ tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); + + return TRUE; } -void -tumbler_cache_service_delete (TumblerCacheService *service, - const gchar *const *uris, - DBusGMethodInvocation *context) +gboolean +tumbler_cache_service_delete (TumblerExportedCacheService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + TumblerCacheService *service) { DeleteRequest *request; - - dbus_async_return_if_fail (TUMBLER_IS_CACHE_SERVICE (service), context); - dbus_async_return_if_fail (uris != NULL, context); + + g_dbus_async_return_val_if_fail (TUMBLER_IS_CACHE_SERVICE (service), invocation, FALSE); + g_dbus_async_return_val_if_fail (uris != NULL, invocation, FALSE); /* prevent the lifecycle manager to shut tumbler down before the * delete request has been processed */ @@ -513,26 +542,29 @@ tumbler_cache_service_delete (TumblerCacheService *service, request = g_slice_new0 (DeleteRequest); request->uris = g_strdupv ((gchar **)uris); - request->context = context; + request->invocation = invocation; g_thread_pool_push (service->delete_pool, request, NULL); /* try to keep tumbler alive */ tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); + + return TRUE; } -void -tumbler_cache_service_cleanup (TumblerCacheService *service, - const gchar *const *base_uris, - guint32 since, - DBusGMethodInvocation *context) +gboolean +tumbler_cache_service_cleanup (TumblerExportedCacheService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *base_uris, + guint32 since, + TumblerCacheService *service) { CleanupRequest *request; - dbus_async_return_if_fail (TUMBLER_IS_CACHE_SERVICE (service), context); - + g_dbus_async_return_val_if_fail (TUMBLER_IS_CACHE_SERVICE (service), invocation, FALSE); + /* prevent the lifecycle manager to shut tumbler down before the * cleanup request has been processed */ tumbler_component_increment_use_count (TUMBLER_COMPONENT (service)); @@ -540,10 +572,18 @@ tumbler_cache_service_cleanup (TumblerCacheService *service, request = g_slice_new0 (CleanupRequest); request->base_uris = g_strdupv ((gchar **)base_uris); request->since = since; - request->context = context; + request->invocation = invocation; g_thread_pool_push (service->cleanup_pool, request, NULL); /* try to keep tumbler alive */ tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); + + return TRUE; +} + +gboolean tumbler_cache_service_is_exported (TumblerCacheService *service) +{ + g_return_val_if_fail (TUMBLER_IS_CACHE_SERVICE(service), FALSE); + return service->dbus_interface_exported; } diff --git a/tumblerd/tumbler-cache-service.h b/tumblerd/tumbler-cache-service.h index 476781f..4d04e25 100644 --- a/tumblerd/tumbler-cache-service.h +++ b/tumblerd/tumbler-cache-service.h @@ -23,8 +23,6 @@ #include <glib-object.h> -#include <dbus/dbus-glib.h> - #include <tumblerd/tumbler-lifecycle-manager.h> G_BEGIN_DECLS; @@ -41,26 +39,10 @@ typedef struct _TumblerCacheService TumblerCacheService; GType tumbler_cache_service_get_type (void) G_GNUC_CONST; -TumblerCacheService *tumbler_cache_service_new (DBusGConnection *connection, +TumblerCacheService *tumbler_cache_service_new (GDBusConnection *connection, TumblerLifecycleManager *lifecycle_manager) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean tumbler_cache_service_start (TumblerCacheService *service, - GError **error); -void tumbler_cache_service_move (TumblerCacheService *service, - const gchar *const *from_uris, - const gchar *const *to_uris, - DBusGMethodInvocation *context); -void tumbler_cache_service_copy (TumblerCacheService *service, - const gchar *const *from_uris, - const gchar *const *to_uris, - DBusGMethodInvocation *context); -void tumbler_cache_service_delete (TumblerCacheService *service, - const gchar *const *uris, - DBusGMethodInvocation *context); -void tumbler_cache_service_cleanup (TumblerCacheService *service, - const gchar *const *uri_prefix, - guint32 since, - DBusGMethodInvocation *context); +gboolean tumbler_cache_service_is_exported (TumblerCacheService *service); G_END_DECLS; diff --git a/tumblerd/tumbler-manager-dbus.xml b/tumblerd/tumbler-manager-dbus.xml index f56d422..dc492e7 100644 --- a/tumblerd/tumbler-manager-dbus.xml +++ b/tumblerd/tumbler-manager-dbus.xml @@ -1,10 +1,13 @@ <?xml version="1.0" encoding="UTF-8"?> <node name="/org/freedesktop/thumbnails/Manager1"> <interface name="org.freedesktop.thumbnails.Manager1"> + + <annotation name="org.gtk.GDBus.C.Name" value="ExportedManager" /> + <method name="Register"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> <arg type="s" name="uri_scheme" direction="in" /> <arg type="s" name="mime_type" direction="in" /> </method> + </interface> </node> diff --git a/tumblerd/tumbler-manager.c b/tumblerd/tumbler-manager.c index db5d64e..9f837c2 100644 --- a/tumblerd/tumbler-manager.c +++ b/tumblerd/tumbler-manager.c @@ -1,6 +1,7 @@ /* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org> + * Copyright (c) 2015 Ali Abdallah <ali@xfce.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -36,18 +37,13 @@ #include <gio/gio.h> -#include <dbus/dbus.h> -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> - #include <tumblerd/tumbler-component.h> #include <tumblerd/tumbler-manager.h> -#include <tumblerd/tumbler-manager-dbus-bindings.h> +#include <tumblerd/tumbler-manager-gdbus.h> #include <tumblerd/tumbler-specialized-thumbnailer.h> #include <tumblerd/tumbler-utils.h> - /* Property identifiers */ enum { @@ -73,6 +69,11 @@ static void tumbler_manager_set_property (GObject *obj guint prop_id, const GValue *value, GParamSpec *pspec); +static gboolean tumbler_manager_register_cb (TumblerExportedManager *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *uri_schemes, + const gchar *const *mime_types, + TumblerManager *manager); static void tumbler_manager_monitor_unref (GFileMonitor *monitor, TumblerManager *manager); static void tumbler_manager_load_thumbnailers (TumblerManager *manager, @@ -105,9 +106,12 @@ struct _TumblerManagerClass struct _TumblerManager { TumblerComponent __parent__; - - DBusGConnection *connection; - TumblerRegistry *registry; + GDBusConnection *connection; + TumblerExportedManager *skeleton; + + gboolean dbus_interface_exported; + + TumblerRegistry *registry; /* Directory and monitor objects for the thumbnailer dirs in * XDG_DATA_HOME and XDG_DATA_DIRS */ @@ -157,7 +161,7 @@ static void tumbler_manager_class_init (TumblerManagerClass *klass) { GObjectClass *gobject_class; - + gobject_class = G_OBJECT_CLASS (klass); gobject_class->constructed = tumbler_manager_constructed; gobject_class->finalize = tumbler_manager_finalize; @@ -165,11 +169,12 @@ tumbler_manager_class_init (TumblerManagerClass *klass) gobject_class->set_property = tumbler_manager_set_property; g_object_class_install_property (gobject_class, PROP_CONNECTION, - g_param_spec_pointer ("connection", - "connection", - "connection", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_object ("connection", + "connection", + "connection", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_REGISTRY, g_param_spec_object ("registry", @@ -205,20 +210,32 @@ tumbler_manager_init (TumblerManager *manager) static void tumbler_manager_constructed (GObject *object) { - TumblerManager *manager = TUMBLER_MANAGER (object); + TumblerManager *manager; + GError *error = NULL; + + manager = TUMBLER_MANAGER (object); - /* everything's fine, install the manager type D-Bus info */ - dbus_g_object_type_install_info (G_OBJECT_TYPE (manager), - &dbus_glib_tumbler_manager_object_info); + manager->skeleton = tumbler_exported_manager_skeleton_new (); - /* register the manager instance as a handler of the manager interface */ - dbus_g_connection_register_g_object (manager->connection, - "/org/freedesktop/thumbnails/Manager1", - G_OBJECT (manager)); + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON(manager->skeleton), + manager->connection, + "/org/freedesktop/thumbnails/Manager1", + &error); + + if (error != NULL) + { + g_critical ("error exporting thumbnail manager on session bus: %s", error->message); + g_error_free (error); + manager->dbus_interface_exported = FALSE; + } + else + { + manager->dbus_interface_exported = TRUE; + g_signal_connect(manager->skeleton, "handle-register", + G_CALLBACK(tumbler_manager_register_cb), manager); + } } - - static void tumbler_manager_finalize (GObject *object) { @@ -241,9 +258,20 @@ tumbler_manager_finalize (GObject *object) /* release the registry */ g_object_unref (manager->registry); - /* release the D-Bus connection object */ - dbus_g_connection_unref (manager->connection); + /* Unexport from dbus */ + if (manager->dbus_interface_exported) + g_dbus_interface_skeleton_unexport_from_connection + ( + G_DBUS_INTERFACE_SKELETON (manager->skeleton), + manager->connection + ); + /* release the Skeleton object */ + g_object_unref (manager->skeleton); + + /* release the D-Bus connection object */ + g_object_unref (manager->connection); + tumbler_mutex_unlock (manager->mutex); /* destroy the mutex */ @@ -265,7 +293,7 @@ tumbler_manager_get_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - g_value_set_pointer (value, manager->connection); + g_value_set_object (value, manager->connection); break; case PROP_REGISTRY: g_value_set_object (value, manager->registry); @@ -289,7 +317,7 @@ tumbler_manager_set_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - manager->connection = dbus_g_connection_ref (g_value_get_pointer (value)); + manager->connection = g_object_ref (g_value_get_object (value)); break; case PROP_REGISTRY: manager->registry = g_value_dup_object (value); @@ -300,7 +328,38 @@ tumbler_manager_set_property (GObject *object, } } - +static gboolean +tumbler_manager_register_cb (TumblerExportedManager *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *uri_schemes, + const gchar *const *mime_types, + TumblerManager *manager) +{ + TumblerThumbnailer *thumbnailer; + const gchar *sender_name; + + g_return_val_if_fail (TUMBLER_IS_MANAGER (manager), FALSE); + g_return_val_if_fail (uri_schemes != NULL, FALSE); + g_return_val_if_fail (mime_types != NULL, FALSE); + + sender_name = g_dbus_method_invocation_get_sender (invocation); + + tumbler_mutex_lock (manager->mutex); + + thumbnailer = tumbler_specialized_thumbnailer_new_foreign (manager->connection, + sender_name, uri_schemes, + mime_types); + + tumbler_registry_add (manager->registry, thumbnailer); + + g_object_unref (thumbnailer); + + tumbler_mutex_unlock (manager->mutex); + + tumbler_exported_manager_complete_register(skeleton, invocation); + + return TRUE; +} static void tumbler_manager_monitor_unref (GFileMonitor *monitor, @@ -1176,7 +1235,7 @@ tumbler_manager_load_thumbnailers (TumblerManager *manager, * directory objects, directory monitors, override infos and thumbnailer * infos. */ -static void +void tumbler_manager_load (TumblerManager *manager) { const gchar *const *data_dirs; @@ -1827,7 +1886,7 @@ dump_thumbnailers (TumblerManager *manager) TumblerManager * -tumbler_manager_new (DBusGConnection *connection, +tumbler_manager_new (GDBusConnection *connection, TumblerLifecycleManager *lifecycle_manager, TumblerRegistry *registry) { @@ -1838,81 +1897,9 @@ tumbler_manager_new (DBusGConnection *connection, NULL); } - - -gboolean -tumbler_manager_start (TumblerManager *manager, - GError **error) +gboolean tumbler_manager_is_exported (TumblerManager *manager) { - DBusConnection *connection; - gint result; - g_return_val_if_fail (TUMBLER_IS_MANAGER (manager), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - tumbler_mutex_lock (manager->mutex); - - /* get the native D-Bus connection */ - connection = dbus_g_connection_get_connection (manager->connection); - - /* request ownership for the manager interface */ - result = dbus_bus_request_name (connection, "org.freedesktop.thumbnails.Manager1", - DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL); - - /* check if that failed */ - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - if (error != NULL) - { - g_set_error (error, DBUS_GERROR, DBUS_GERROR_FAILED, - _("Another thumbnailer manager is already running")); - } - - tumbler_mutex_unlock (manager->mutex); - - /* i can't work like this! */ - return FALSE; - } - - tumbler_mutex_unlock (manager->mutex); - - /* load thumbnailers installed into the system permanently */ - tumbler_manager_load (manager); - - /* done initializing and loading all permanent thumbnailers */ - return TRUE; -} - - - -void -tumbler_manager_register (TumblerManager *manager, - const gchar *const *uri_schemes, - const gchar *const *mime_types, - DBusGMethodInvocation *context) -{ - TumblerThumbnailer *thumbnailer; - gchar *sender_name; - - dbus_async_return_if_fail (TUMBLER_IS_MANAGER (manager), context); - dbus_async_return_if_fail (uri_schemes != NULL, context); - dbus_async_return_if_fail (mime_types != NULL, context); - - sender_name = dbus_g_method_get_sender (context); - - tumbler_mutex_lock (manager->mutex); - - thumbnailer = tumbler_specialized_thumbnailer_new_foreign (manager->connection, - sender_name, uri_schemes, - mime_types); - - tumbler_registry_add (manager->registry, thumbnailer); - - g_object_unref (thumbnailer); - - tumbler_mutex_unlock (manager->mutex); - - g_free (sender_name); - - dbus_g_method_return (context); + + return manager->dbus_interface_exported; } diff --git a/tumblerd/tumbler-manager.h b/tumblerd/tumbler-manager.h index cc11bd1..d0bd741 100644 --- a/tumblerd/tumbler-manager.h +++ b/tumblerd/tumbler-manager.h @@ -1,6 +1,7 @@ /* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org> + * Copyright (c) 2015 Ali Abdallah <ali@xfce.org> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -21,8 +22,6 @@ #ifndef __TUMBLER_MANAGER_H__ #define __TUMBLER_MANAGER_H__ -#include <dbus/dbus-glib.h> - #include <tumblerd/tumbler-lifecycle-manager.h> #include <tumblerd/tumbler-registry.h> @@ -40,17 +39,12 @@ typedef struct _TumblerManager TumblerManager; GType tumbler_manager_get_type (void) G_GNUC_CONST; -TumblerManager *tumbler_manager_new (DBusGConnection *connection, +TumblerManager *tumbler_manager_new (GDBusConnection *connection, TumblerLifecycleManager *lifecycle_manager, TumblerRegistry *registry) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean tumbler_manager_start (TumblerManager *manager, - GError **error); -void tumbler_manager_register (TumblerManager *manager, - const gchar *const *uri_schemes, - const gchar *const *mime_types, - DBusGMethodInvocation *context); -void tumbler_manager_get_supported (TumblerManager *manager, - DBusGMethodInvocation *context); +void tumbler_manager_load (TumblerManager *manager); + +gboolean tumbler_manager_is_exported (TumblerManager *manager); G_END_DECLS; diff --git a/tumblerd/tumbler-service-dbus.xml b/tumblerd/tumbler-service-dbus.xml index 9076691..4aa77ec 100644 --- a/tumblerd/tumbler-service-dbus.xml +++ b/tumblerd/tumbler-service-dbus.xml @@ -1,8 +1,10 @@ <?xml version="1.0" encoding="UTF-8"?> <node name="/org/freedesktop/thumbnails/Thumbnailer1"> - <interface name="org.freedesktop.thumbnails.Thumbnailer1"> + <interface name="org.freedesktop.thumbnails.Thumbnailer1"> + + <annotation name="org.gtk.GDBus.C.Name" value="ExportedService" /> + <method name="Queue"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> <arg type="as" name="uris" direction="in" /> <arg type="as" name="mime_types" direction="in" /> <arg type="s" name="flavor" direction="in" /> @@ -12,23 +14,19 @@ </method> <method name="Dequeue"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true"/> <arg type="u" name="handle" direction="in" /> </method> <method name="GetSupported"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true" /> <arg type="as" name="uri_schemes" direction="out" /> <arg type="as" name="mime_types" direction="out" /> </method> <method name="GetSchedulers"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true" /> <arg type="as" name="schedulers" direction="out" /> </method> <method name="GetFlavors"> - <annotation name="org.freedesktop.DBus.GLib.Async" value="true" /> <arg type="as" name="flavors" direction="out" /> </method> diff --git a/tumblerd/tumbler-service.c b/tumblerd/tumbler-service.c index d46a2db..929a125 100644 --- a/tumblerd/tumbler-service.c +++ b/tumblerd/tumbler-service.c @@ -1,7 +1,8 @@ /* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org> - * + * Copyright (c) 2015 Ali Abdallah <ali@xfce.org> + * * 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 @@ -28,20 +29,15 @@ #include <gio/gio.h> -#include <dbus/dbus.h> -#include <dbus/dbus-glib.h> -#include <dbus/dbus-glib-lowlevel.h> - #include <tumbler/tumbler.h> #include <tumblerd/tumbler-component.h> #include <tumblerd/tumbler-scheduler.h> #include <tumblerd/tumbler-service.h> -#include <tumblerd/tumbler-service-dbus-bindings.h> #include <tumblerd/tumbler-lifo-scheduler.h> #include <tumblerd/tumbler-group-scheduler.h> #include <tumblerd/tumbler-utils.h> - +#include <tumblerd/tumbler-service-gdbus.h> #define THUMBNAILER_PATH "/org/freedesktop/thumbnails/Thumbnailer1" @@ -50,15 +46,6 @@ -/* signal identifiers */ -enum -{ - SIGNAL_ERROR, - SIGNAL_FINISHED, - SIGNAL_READY, - SIGNAL_STARTED, - LAST_SIGNAL, -}; /* property identifiers */ enum @@ -84,6 +71,27 @@ static void tumbler_service_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec); +static gboolean tumbler_service_queue_cb (TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + const gchar *const *mime_hints, + const gchar *flavor_name, + const gchar *scheduler_name, + guint handle_to_dequeue, + TumblerService *service); +static gboolean tumbler_service_dequeue_cb (TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + guint handle, + TumblerService *service); +static gboolean tumbler_service_get_schedulers_cb(TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + TumblerService *service); +static gboolean tumbler_service_get_supported_cb(TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + TumblerService *service); +static gboolean tumbler_service_get_flavors_cb (TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + TumblerService *service); static void tumbler_service_scheduler_error (TumblerScheduler *scheduler, guint handle, const gchar *const *failed_uris, @@ -118,14 +126,17 @@ struct _TumblerServiceClass struct _TumblerService { - TumblerComponent __parent__; + TumblerComponent __parent__; - DBusGConnection *connection; - TumblerRegistry *registry; - TUMBLER_MUTEX (mutex); - GList *schedulers; + GDBusConnection *connection; + TumblerExportedService *skeleton; + gboolean dbus_interface_exported; + + TumblerRegistry *registry; + TUMBLER_MUTEX (mutex); + GList *schedulers; - GVolumeMonitor *volume_monitor; + GVolumeMonitor *volume_monitor; }; struct _SchedulerIdleInfo @@ -141,9 +152,6 @@ struct _SchedulerIdleInfo -static guint tumbler_service_signals[LAST_SIGNAL]; - - G_DEFINE_TYPE (TumblerService, tumbler_service, TUMBLER_TYPE_COMPONENT); @@ -161,11 +169,12 @@ tumbler_service_class_init (TumblerServiceClass *klass) gobject_class->set_property = tumbler_service_set_property; g_object_class_install_property (gobject_class, PROP_CONNECTION, - g_param_spec_pointer ("connection", - "connection", - "connection", - G_PARAM_READWRITE | - G_PARAM_CONSTRUCT_ONLY)); + g_param_spec_object ("connection", + "connection", + "connection", + G_TYPE_DBUS_CONNECTION, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT_ONLY)); g_object_class_install_property (gobject_class, PROP_REGISTRY, g_param_spec_object ("registry", @@ -174,57 +183,6 @@ tumbler_service_class_init (TumblerServiceClass *klass) TUMBLER_TYPE_REGISTRY, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); - - tumbler_service_signals[SIGNAL_ERROR] = - g_signal_new ("error", - TUMBLER_TYPE_SERVICE, - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - tumbler_marshal_VOID__UINT_POINTER_INT_STRING, - G_TYPE_NONE, - 4, - G_TYPE_UINT, - G_TYPE_STRV, - G_TYPE_INT, - G_TYPE_STRING); - - tumbler_service_signals[SIGNAL_FINISHED] = - g_signal_new ("finished", - TUMBLER_TYPE_SERVICE, - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, - 1, - G_TYPE_UINT); - - tumbler_service_signals[SIGNAL_READY] = - g_signal_new ("ready", - TUMBLER_TYPE_SERVICE, - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - g_cclosure_marshal_VOID__POINTER, - G_TYPE_NONE, - 1, - G_TYPE_STRV); - - tumbler_service_signals[SIGNAL_STARTED] = - g_signal_new ("started", - TUMBLER_TYPE_SERVICE, - G_SIGNAL_RUN_LAST, - 0, - NULL, - NULL, - g_cclosure_marshal_VOID__UINT, - G_TYPE_NONE, - 1, - G_TYPE_UINT); } @@ -281,7 +239,8 @@ tumbler_service_constructed (GObject *object) { TumblerScheduler *scheduler; TumblerService *service = TUMBLER_SERVICE (object); - + GError *error = NULL; + /* chain up to parent classes */ if (G_OBJECT_CLASS (tumbler_service_parent_class)->constructed != NULL) (G_OBJECT_CLASS (tumbler_service_parent_class)->constructed) (object); @@ -297,13 +256,37 @@ tumbler_service_constructed (GObject *object) g_object_unref (scheduler); /* everything is fine, install the generic thumbnailer D-Bus info */ - dbus_g_object_type_install_info (G_OBJECT_TYPE (service), - &dbus_glib_tumbler_service_object_info); - - /* register the service instance as a handler of this interface */ - dbus_g_connection_register_g_object (service->connection, - THUMBNAILER_PATH, - G_OBJECT (service)); + service->skeleton = tumbler_exported_service_skeleton_new(); + + g_dbus_interface_skeleton_export (G_DBUS_INTERFACE_SKELETON(service->skeleton), + service->connection, + THUMBNAILER_PATH, + &error); + if (error != NULL) + { + g_critical ("error exporting thumbnail service on session bus: %s", error->message); + g_error_free (error); + service->dbus_interface_exported = FALSE; + } + else + { + service->dbus_interface_exported = TRUE; + + g_signal_connect (service->skeleton, "handle-queue", + G_CALLBACK(tumbler_service_queue_cb), service); + + g_signal_connect (service->skeleton, "handle-dequeue", + G_CALLBACK(tumbler_service_dequeue_cb), service); + + g_signal_connect (service->skeleton, "handle-get-supported", + G_CALLBACK(tumbler_service_get_supported_cb), service); + + g_signal_connect (service->skeleton, "handle-get-schedulers", + G_CALLBACK(tumbler_service_get_schedulers_cb), service); + + g_signal_connect (service->skeleton, "handle-get-flavors", + G_CALLBACK(tumbler_service_get_flavors_cb), service); + } } @@ -326,8 +309,20 @@ tumbler_service_finalize (GObject *object) /* release the reference on the thumbnailer registry */ g_object_unref (service->registry); - - dbus_g_connection_unref (service->connection); + + /* Unexport from dbus */ + if (service->dbus_interface_exported) + g_dbus_interface_skeleton_unexport_from_connection + ( + G_DBUS_INTERFACE_SKELETON (service->skeleton), + service->connection + ); + + /* release the Skeleton object */ + g_object_unref (service->skeleton); + + /* release the D-Bus connection object */ + g_object_unref (service->connection); tumbler_mutex_free (service->mutex); @@ -347,7 +342,7 @@ tumbler_service_get_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - g_value_set_pointer (value, service->connection); + g_value_set_object (value, service->connection); break; case PROP_REGISTRY: g_value_set_object (value, service->registry); @@ -371,7 +366,7 @@ tumbler_service_set_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - service->connection = dbus_g_connection_ref (g_value_get_pointer (value)); + service->connection = g_object_ref (g_value_get_object (value)); break; case PROP_REGISTRY: service->registry = g_value_dup_object (value); @@ -388,10 +383,7 @@ static gboolean tumbler_service_error_idle (gpointer user_data) { SchedulerIdleInfo *info = user_data; - DBusMessageIter iter; - DBusMessageIter strv_iter; - DBusMessage *message; - guint n; + GVariant *signal_variant; g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (TUMBLER_IS_SCHEDULER (info->scheduler), FALSE); @@ -400,38 +392,22 @@ tumbler_service_error_idle (gpointer user_data) g_return_val_if_fail (info->origin != NULL && *info->origin != '\0', FALSE); g_return_val_if_fail (TUMBLER_IS_SERVICE (info->service), FALSE); - /* create a D-Bus message for the error signal */ - message = dbus_message_new_signal (THUMBNAILER_PATH, THUMBNAILER_IFACE, "Error"); - - /* define the destination (the thumbnailer client) if possible */ - if (info->origin) - dbus_message_set_destination (message, info->origin); - - /* append the request handle */ - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &info->handle); - - /* start the URI string array */ - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, - DBUS_TYPE_STRING_AS_STRING, &strv_iter); - - /* insert all failed URIs into the array */ - for (n = 0; info->uris[n] != NULL; n++) - dbus_message_iter_append_basic (&strv_iter, DBUS_TYPE_STRING, &info->uris[n]); - - /* finish the URI string array */ - dbus_message_iter_close_container (&iter, &strv_iter); - - /* append the error code and error message */ - dbus_message_iter_append_basic (&iter, DBUS_TYPE_INT32, &info->error_code); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &info->message); - + /* signal variant */ + signal_variant = g_variant_ref_sink (g_variant_new ("(u^asis)", + info->handle, + info->uris, + info->error_code, + info->message)); /* send the signal message over D-Bus */ - dbus_connection_send (dbus_g_connection_get_connection (info->service->connection), - message, NULL); + g_dbus_connection_emit_signal (info->service->connection, + info->origin, + THUMBNAILER_PATH, + THUMBNAILER_IFACE, + "Error", + signal_variant, + NULL); - /* free the allocated D-Bus message */ - dbus_message_unref (message); + g_variant_unref (signal_variant); scheduler_idle_info_free (info); @@ -476,30 +452,24 @@ static gboolean tumbler_service_finished_idle (gpointer user_data) { SchedulerIdleInfo *info = user_data; - DBusMessageIter iter; - DBusMessage *message; + GVariant *signal_variant; g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (info->origin != NULL && *info->origin != '\0', FALSE); g_return_val_if_fail (TUMBLER_IS_SERVICE (info->service), FALSE); - - /* create a D-Bus message for the finished signal */ - message = dbus_message_new_signal (THUMBNAILER_PATH, THUMBNAILER_IFACE, "Finished"); - - /* define the destination (the thumbnailer client) if possible */ - if (info->origin) - dbus_message_set_destination (message, info->origin); - - /* append the request handle */ - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &info->handle); - + + signal_variant = g_variant_ref_sink (g_variant_new ("(u)", + info->handle)); /* send the signal message over D-Bus */ - dbus_connection_send (dbus_g_connection_get_connection (info->service->connection), - message, NULL); + g_dbus_connection_emit_signal (info->service->connection, + info->origin, + THUMBNAILER_PATH, + THUMBNAILER_IFACE, + "Finished", + signal_variant, + NULL); - /* free the allocated D-Bus message */ - dbus_message_unref (message); + g_variant_unref (signal_variant); /* allow the lifecycle manager to shut down the service again (unless there * are other requests still being processed) */ @@ -540,10 +510,7 @@ static gboolean tumbler_service_ready_idle (gpointer user_data) { SchedulerIdleInfo *info = user_data; - DBusMessageIter iter; - DBusMessageIter strv_iter; - DBusMessage *message; - guint n; + GVariant *signal_variant; g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (TUMBLER_IS_SCHEDULER (info->scheduler), FALSE); @@ -551,36 +518,21 @@ tumbler_service_ready_idle (gpointer user_data) g_return_val_if_fail (info->origin != NULL && *info->origin != '\0', FALSE); g_return_val_if_fail (TUMBLER_IS_SERVICE (info->service), FALSE); - /* create a D-Bus message for the ready signal */ - message = dbus_message_new_signal (THUMBNAILER_PATH, THUMBNAILER_IFACE, "Ready"); - - /* define the destination (the thumbnailer client) if possible */ - if (info->origin) - dbus_message_set_destination (message, info->origin); - - dbus_message_iter_init_append (message, &iter); - - /* append the request handle */ - dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &info->handle); - - /* start the URI string array */ - dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, - DBUS_TYPE_STRING_AS_STRING, &strv_iter); - - /* insert all URIs into the array for which we have thumbnails now */ - for (n = 0; info->uris[n] != NULL; n++) - dbus_message_iter_append_basic (&strv_iter, DBUS_TYPE_STRING, &info->uris[n]); - - /* finish the URI string array */ - dbus_message_iter_close_container (&iter, &strv_iter); - + signal_variant = g_variant_ref_sink (g_variant_new ("(u^as)", + info->handle, + info->uris)); + /* send the signal message over D-Bus */ - dbus_connection_send (dbus_g_connection_get_connection (info->service->connection), - message, NULL); - - /* free the allocated D-Bus message */ - dbus_message_unref (message); - + g_dbus_connection_emit_signal (info->service->connection, + info->origin, + THUMBNAILER_PATH, + THUMBNAILER_IFACE, + "Ready", + signal_variant, + NULL); + + g_variant_unref (signal_variant); + scheduler_idle_info_free (info); return FALSE; @@ -619,32 +571,27 @@ static gboolean tumbler_service_started_idle (gpointer user_data) { SchedulerIdleInfo *info = user_data; - DBusMessageIter iter; - DBusMessage *message; - + GVariant *signal_variant; + g_return_val_if_fail (info != NULL, FALSE); g_return_val_if_fail (TUMBLER_IS_SCHEDULER (info->scheduler), FALSE); g_return_val_if_fail (info->origin != NULL && *info->origin != '\0', FALSE); g_return_val_if_fail (TUMBLER_IS_SERVICE (info->service), FALSE); - /* create a D-Bus message for the started signal */ - message = dbus_message_new_signal (THUMBNAILER_PATH, THUMBNAILER_IFACE, "Started"); - - /* define the destination (the thumbnailer client) if possible */ - if (info->origin) - dbus_message_set_destination (message, info->origin); - - /* append the request handle */ - dbus_message_iter_init_append (message, &iter); - dbus_message_iter_append_basic (&iter, DBUS_TYPE_UINT32, &info->handle); - + signal_variant = g_variant_ref_sink (g_variant_new ("(u)", info->handle)); + + /* send the signal message over D-Bus */ - dbus_connection_send (dbus_g_connection_get_connection (info->service->connection), - message, NULL); - - /* free the allocated D-Bus message */ - dbus_message_unref (message); - + g_dbus_connection_emit_signal (info->service->connection, + info->origin, + THUMBNAILER_PATH, + THUMBNAILER_IFACE, + "Started", + signal_variant, + NULL); + + g_variant_unref (signal_variant); + scheduler_idle_info_free (info); return FALSE; @@ -717,7 +664,7 @@ scheduler_idle_info_free (SchedulerIdleInfo *info) TumblerService * -tumbler_service_new (DBusGConnection *connection, +tumbler_service_new (GDBusConnection *connection, TumblerLifecycleManager *lifecycle_manager, TumblerRegistry *registry) { @@ -730,54 +677,16 @@ tumbler_service_new (DBusGConnection *connection, -gboolean -tumbler_service_start (TumblerService *service, - GError **error) -{ - DBusConnection *connection; - gint result; - - g_return_val_if_fail (TUMBLER_IS_SERVICE (service), FALSE); - g_return_val_if_fail (error == NULL || *error == NULL, FALSE); - - tumbler_mutex_lock (service->mutex); - - /* get the native D-Bus connection */ - connection = dbus_g_connection_get_connection (service->connection); - - /* request ownership for the generic thumbnailer interface */ - result = dbus_bus_request_name (connection, THUMBNAILER_SERVICE, - DBUS_NAME_FLAG_DO_NOT_QUEUE, NULL); - - /* check if that failed */ - if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) - { - if (error != NULL) - { - g_set_error (error, DBUS_GERROR, DBUS_GERROR_FAILED, - _("Another generic thumbnailer is already running")); - } - - tumbler_mutex_unlock (service->mutex); - - return FALSE; - } - - tumbler_mutex_unlock (service->mutex); - - return TRUE; -} - - -void -tumbler_service_queue (TumblerService *service, - const gchar *const *uris, - const gchar *const *mime_hints, - const gchar *flavor_name, - const gchar *scheduler_name, - guint handle_to_dequeue, - DBusGMethodInvocation *context) +static gboolean +tumbler_service_queue_cb (TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + const gchar *const *uris, + const gchar *const *mime_hints, + const gchar *flavor_name, + const gchar *scheduler_name, + guint handle_to_dequeue, + TumblerService *service) { TumblerSchedulerRequest *scheduler_request; TumblerThumbnailFlavor *flavor; @@ -787,13 +696,13 @@ tumbler_service_queue (TumblerService *service, TumblerCache *cache; GList *iter; gchar *name; - gchar *origin; + const gchar *origin; guint handle; guint length; - dbus_async_return_if_fail (TUMBLER_IS_SERVICE (service), context); - dbus_async_return_if_fail (uris != NULL, context); - dbus_async_return_if_fail (mime_hints != NULL, context); + g_dbus_async_return_val_if_fail (TUMBLER_IS_SERVICE (service), invocation, FALSE); + g_dbus_async_return_val_if_fail (uris != NULL, invocation, FALSE); + g_dbus_async_return_val_if_fail (mime_hints != NULL, invocation, FALSE); tumbler_mutex_lock (service->mutex); @@ -816,7 +725,7 @@ tumbler_service_queue (TumblerService *service, thumbnailers = tumbler_registry_get_thumbnailer_array (service->registry, infos, length); - origin = dbus_g_method_get_sender (context); + origin = g_dbus_method_invocation_get_sender (invocation); /* allocate a scheduler request */ scheduler_request = tumbler_scheduler_request_new (infos, thumbnailers, @@ -825,7 +734,6 @@ tumbler_service_queue (TumblerService *service, /* release the file info array */ tumbler_file_info_array_free (infos); - g_free (origin); /* get the request handle */ handle = scheduler_request->handle; @@ -885,24 +793,25 @@ tumbler_service_queue (TumblerService *service, tumbler_thumbnailer_array_free (thumbnailers, length); tumbler_mutex_unlock (service->mutex); - - dbus_g_method_return (context, handle); - + + tumbler_exported_service_complete_queue(skeleton, invocation, handle); + /* try to keep tumbler alive */ tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); + + return TRUE; } -void -tumbler_service_dequeue (TumblerService *service, - guint handle, - DBusGMethodInvocation *context) +static gboolean +tumbler_service_dequeue_cb (TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + guint handle, + TumblerService *service) { GList *iter; - dbus_async_return_if_fail (TUMBLER_IS_SERVICE (service), context); - tumbler_mutex_lock (service->mutex); if (handle != 0) @@ -918,22 +827,70 @@ tumbler_service_dequeue (TumblerService *service, tumbler_mutex_unlock (service->mutex); - dbus_g_method_return (context); - + tumbler_exported_service_complete_dequeue(skeleton, invocation); + /* keep tumbler alive */ tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); + + return TRUE; +} + + + +static gboolean +tumbler_service_get_schedulers_cb (TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + TumblerService *service) +{ + gchar **supported_schedulers; + GList *iter; + guint n = 0; + + tumbler_mutex_lock (service->mutex); + + /* allocate an error for the schedulers */ + supported_schedulers = g_new0 (gchar *, g_list_length (service->schedulers) + 2); + + /* always prepend the "default" scheduler */ + supported_schedulers[n++] = g_strdup ("default"); + + /* append all supported scheduler names */ + for (iter = service->schedulers; iter != NULL; iter = iter->next) + { + supported_schedulers[n++] = + tumbler_scheduler_get_name (TUMBLER_SCHEDULER (iter->data)); + } + + tumbler_mutex_unlock (service->mutex); + + /* NULL-terminate the array */ + supported_schedulers[n] = NULL; + + /* return the scheduler array to the caller */ + tumbler_exported_service_complete_get_schedulers (skeleton, + invocation, + (const char* const*)supported_schedulers); + + /* free the array */ + g_strfreev (supported_schedulers); + + /* try to keep tumbler alive */ + tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); + + return TRUE; } -void -tumbler_service_get_supported (TumblerService *service, - DBusGMethodInvocation *context) +static gboolean +tumbler_service_get_supported_cb (TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + TumblerService *service) { const gchar *const *mime_types; const gchar *const *uri_schemes; - dbus_async_return_if_fail (TUMBLER_IS_SERVICE (service), context); + g_dbus_async_return_val_if_fail (TUMBLER_IS_SERVICE (service), invocation, FALSE); tumbler_mutex_lock (service->mutex); @@ -943,17 +900,20 @@ tumbler_service_get_supported (TumblerService *service, tumbler_mutex_unlock (service->mutex); /* return the arrays to the caller */ - dbus_g_method_return (context, uri_schemes, mime_types); + tumbler_exported_service_complete_get_supported(skeleton, invocation, uri_schemes, mime_types); /* try to keep tumbler alive */ tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); + + return TRUE; } -void -tumbler_service_get_flavors (TumblerService *service, - DBusGMethodInvocation *context) +static gboolean +tumbler_service_get_flavors_cb (TumblerExportedService *skeleton, + GDBusMethodInvocation *invocation, + TumblerService *service) { TumblerCache *cache; const gchar **flavor_strings; @@ -971,9 +931,9 @@ tumbler_service_get_flavors (TumblerService *service, for (iter = flavors, n = 0; iter != NULL; iter = iter->next, ++n) flavor_strings[n] = tumbler_thumbnail_flavor_get_name (iter->data); flavor_strings[n] = NULL; - - dbus_g_method_return (context, flavor_strings); - + + tumbler_exported_service_complete_get_flavors (skeleton, invocation, flavor_strings); + g_free (flavor_strings); g_list_foreach (flavors, (GFunc) g_object_unref, NULL); @@ -985,53 +945,22 @@ tumbler_service_get_flavors (TumblerService *service, { flavor_strings = g_new0 (const gchar *, 1); flavor_strings[0] = NULL; - - dbus_g_method_return (context, flavor_strings); + + tumbler_exported_service_complete_get_flavors (skeleton, invocation, flavor_strings); g_free (flavor_strings); } /* try to keep tumbler alive */ tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); -} - - -void -tumbler_service_get_schedulers (TumblerService *service, - DBusGMethodInvocation *context) -{ - gchar **supported_schedulers; - GList *iter; - guint n = 0; - - dbus_async_return_if_fail (TUMBLER_IS_SERVICE (service), context); - - tumbler_mutex_lock (service->mutex); - - /* allocate an error for the schedulers */ - supported_schedulers = g_new0 (gchar *, g_list_length (service->schedulers) + 2); - - /* always prepend the "default" scheduler */ - supported_schedulers[n++] = g_strdup ("default"); - - /* append all supported scheduler names */ - for (iter = service->schedulers; iter != NULL; iter = iter->next) - { - supported_schedulers[n++] = - tumbler_scheduler_get_name (TUMBLER_SCHEDULER (iter->data)); - } - - tumbler_mutex_unlock (service->mutex); - /* NULL-terminate the array */ - supported_schedulers[n] = NULL; + return TRUE; +} - /* return the scheduler array to the caller */ - dbus_g_method_return (context, supported_schedulers); - /* free the array */ - g_strfreev (supported_schedulers); - /* try to keep tumbler alive */ - tumbler_component_keep_alive (TUMBLER_COMPONENT (service), NULL); +gboolean tumbler_service_is_exported (TumblerService *service) +{ + g_return_val_if_fail (TUMBLER_IS_SERVICE(service), FALSE); + return service->dbus_interface_exported; } diff --git a/tumblerd/tumbler-service.h b/tumblerd/tumbler-service.h index d2d4bed..63f95dc 100644 --- a/tumblerd/tumbler-service.h +++ b/tumblerd/tumbler-service.h @@ -1,7 +1,8 @@ /* vi:set et ai sw=2 sts=2 ts=2: */ /*- * Copyright (c) 2009-2011 Jannis Pohlmann <jannis@xfce.org> - * + * Copyright (c) 2015 Ali Abdallah <ali@xfce.org> + * * 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 @@ -21,8 +22,6 @@ #ifndef __TUMBLER_SERVICE_H__ #define __TUMBLER_SERVICE_H__ -#include <dbus/dbus-glib.h> - #include <tumblerd/tumbler-lifecycle-manager.h> #include <tumblerd/tumbler-registry.h> @@ -40,27 +39,10 @@ typedef struct _TumblerService TumblerService; GType tumbler_service_get_type (void) G_GNUC_CONST; -TumblerService *tumbler_service_new (DBusGConnection *connection, +TumblerService *tumbler_service_new (GDBusConnection *connection, TumblerLifecycleManager *lifecycle_manager, TumblerRegistry *registry) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -gboolean tumbler_service_start (TumblerService *service, - GError **error); -void tumbler_service_queue (TumblerService *service, - const gchar *const *uris, - const gchar *const *mime_hints, - const gchar *flavor_name, - const gchar *scheduler_name, - guint handle_to_dequeue, - DBusGMethodInvocation *context); -void tumbler_service_dequeue (TumblerService *service, - guint handle, - DBusGMethodInvocation *context); -void tumbler_service_get_schedulers (TumblerService *service, - DBusGMethodInvocation *context); -void tumbler_service_get_supported (TumblerService *service, - DBusGMethodInvocation *context); -void tumbler_service_get_flavors (TumblerService *service, - DBusGMethodInvocation *context); +gboolean tumbler_service_is_exported (TumblerService *service); G_END_DECLS; diff --git a/tumblerd/tumbler-specialized-thumbnailer.c b/tumblerd/tumbler-specialized-thumbnailer.c index 955a021..8db164a 100644 --- a/tumblerd/tumbler-specialized-thumbnailer.c +++ b/tumblerd/tumbler-specialized-thumbnailer.c @@ -66,9 +66,10 @@ 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_destroyed (DBusGProxy *proxy, - TumblerSpecializedThumbnailer *thumbnailer); +static void tumbler_specialized_thumbnailer_proxy_name_owner_changed (GDBusProxy *proxy, + GParamSpec *spec, + TumblerSpecializedThumbnailer *thumbnailer); struct _TumblerSpecializedThumbnailerClass @@ -80,8 +81,8 @@ struct _TumblerSpecializedThumbnailer { TumblerAbstractThumbnailer __parent__; - DBusGConnection *connection; - DBusGProxy *proxy; + GDBusConnection *connection; + GDBusProxy *proxy; gboolean foreign; guint64 modified; @@ -146,18 +147,19 @@ tumbler_specialized_thumbnailer_class_init (TumblerSpecializedThumbnailerClass * g_object_class_install_property (gobject_class, PROP_CONNECTION, - g_param_spec_pointer ("connection", - "connection", - "connection", - G_PARAM_CONSTRUCT_ONLY | - G_PARAM_READWRITE)); + g_param_spec_object ("connection", + "connection", + "connection", + G_TYPE_DBUS_CONNECTION, + G_PARAM_CONSTRUCT_ONLY | + G_PARAM_READWRITE)); g_object_class_install_property (gobject_class, PROP_PROXY, g_param_spec_object ("proxy", "proxy", "proxy", - DBUS_TYPE_G_PROXY, + G_TYPE_DBUS_PROXY, G_PARAM_READABLE)); g_object_class_install_property (gobject_class, @@ -177,26 +179,6 @@ tumbler_specialized_thumbnailer_class_init (TumblerSpecializedThumbnailerClass * 0, G_MAXUINT64, 0, G_PARAM_CONSTRUCT_ONLY | G_PARAM_READWRITE)); - - 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 (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); - } @@ -226,29 +208,20 @@ tumbler_specialized_thumbnailer_constructed (GObject *object) /* chain up to parent classes */ if (G_OBJECT_CLASS (tumbler_specialized_thumbnailer_parent_class)->constructed != NULL) (G_OBJECT_CLASS (tumbler_specialized_thumbnailer_parent_class)->constructed) (object); - + thumbnailer->proxy = - dbus_g_proxy_new_for_name (thumbnailer->connection, - thumbnailer->name, - thumbnailer->object_path, - "org.freedesktop.thumbnails.SpecializedThumbnailer1"); - - dbus_g_proxy_add_signal (thumbnailer->proxy, "Ready", - G_TYPE_UINT, G_TYPE_STRING, - G_TYPE_INVALID); - - dbus_g_proxy_add_signal (thumbnailer->proxy, "Error", - 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); - + g_dbus_proxy_new_sync (thumbnailer->connection, + G_DBUS_PROXY_FLAGS_NONE, + NULL, + thumbnailer->name, + thumbnailer->object_path, + "org.freedesktop.thumbnails.SpecializedThumbnailer1", + NULL, + NULL); + if (thumbnailer->foreign) { - g_signal_connect (thumbnailer->proxy, "destroy", - G_CALLBACK (tumbler_specialized_thumbnailer_proxy_destroyed), + g_signal_connect (thumbnailer->proxy, "notify::g-name-owner", + G_CALLBACK (tumbler_specialized_thumbnailer_proxy_name_owner_changed), thumbnailer); } } @@ -268,8 +241,8 @@ tumbler_specialized_thumbnailer_finalize (GObject *object) g_object_unref (thumbnailer->proxy); - dbus_g_connection_unref (thumbnailer->connection); - + g_object_unref (thumbnailer->connection); + (*G_OBJECT_CLASS (tumbler_specialized_thumbnailer_parent_class)->finalize) (object); } @@ -286,7 +259,7 @@ tumbler_specialized_thumbnailer_get_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - g_value_set_pointer (value, dbus_g_connection_ref (thumbnailer->connection)); + g_value_set_object (value, g_object_ref (thumbnailer->connection)); break; case PROP_NAME: g_value_set_string (value, thumbnailer->name); @@ -322,7 +295,7 @@ tumbler_specialized_thumbnailer_set_property (GObject *object, switch (prop_id) { case PROP_CONNECTION: - thumbnailer->connection = dbus_g_connection_ref (g_value_get_pointer (value)); + thumbnailer->connection = g_object_ref (g_value_get_object (value)); break; case PROP_NAME: thumbnailer->name = g_value_dup_string (value); @@ -344,56 +317,65 @@ tumbler_specialized_thumbnailer_set_property (GObject *object, -static void -specialized_error (DBusGProxy *proxy, - guint handle, - gchar *uri, - gint error_code, - gchar *error_msg, - gpointer user_data) -{ - SpecializedInfo *info = user_data; - - if (info->handle == handle) - g_signal_emit_by_name (info->thumbnailer, "error", uri, error_code, error_msg); -} - - - -static void -specialized_ready (DBusGProxy *proxy, - guint handle, - gchar *uri, - gpointer user_data) -{ - SpecializedInfo *info = user_data; - - if (info->handle == handle) - g_signal_emit_by_name (info->thumbnailer, "ready", uri); -} - - -static void -specialized_finished (DBusGProxy *proxy, - guint handle, - gpointer user_data) +static void +thumbnailer_proxy_g_signal_cb (GDBusProxy *proxy, + gchar *sender_name, + gchar *signal_name, + GVariant *parameters, + gpointer user_data) { - SpecializedInfo *info = user_data; - - if (info->handle == handle) + SpecializedInfo *info = user_data; + guint handle; + + if (strcmp (signal_name, "Finished") == 0) { - tumbler_mutex_lock (info->mutex); + if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(u)"))) + { + g_variant_get (parameters, "(&u)", &handle); + if (info->handle == handle) + { + tumbler_mutex_lock (info->mutex); #if GLIB_CHECK_VERSION (2, 32, 0) - g_cond_broadcast (&info->condition); + g_cond_broadcast (&info->condition); #else - g_cond_broadcast (info->condition); + g_cond_broadcast (info->condition); #endif - info->had_callback = TRUE; - tumbler_mutex_unlock (info->mutex); + info->had_callback = TRUE; + tumbler_mutex_unlock (info->mutex); + } + } + } + else if (strcmp (signal_name, "Ready") == 0) + { + if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(us)"))) + { + const gchar *uri; + g_variant_get (parameters, "(u&s)", &handle, &uri); + if (info->handle == handle) + { + g_signal_emit_by_name (info->thumbnailer, "ready", uri); + } + } + } + else if (strcmp (signal_name, "Error") == 0) + { + if (g_variant_is_of_type (parameters, G_VARIANT_TYPE ("(usis)"))) + { + const gchar *uri, *error_msg; + gint error_code; + + g_variant_get (parameters, "(u&si&s)", &handle, &uri, &error_code, &error_msg); + if (info->handle == handle) + { + g_signal_emit_by_name (info->thumbnailer, "error", uri, error_code, error_msg); + } + } } } + + static void tumbler_specialized_thumbnailer_create (TumblerThumbnailer *thumbnailer, GCancellable *cancellable, @@ -408,11 +390,13 @@ tumbler_specialized_thumbnailer_create (TumblerThumbnailer *thumbnailer, #endif TumblerThumbnail *thumbnail; TumblerThumbnailFlavor *flavor; + GVariant *result; const gchar *flavor_name; const gchar *uri; GError *error = NULL; gchar *message; - + int handler_id; + g_return_if_fail (TUMBLER_IS_SPECIALIZED_THUMBNAILER (thumbnailer)); uri = tumbler_file_info_get_uri (info); @@ -433,36 +417,29 @@ tumbler_specialized_thumbnailer_create (TumblerThumbnailer *thumbnailer, 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, "Queue", - 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); + handler_id = g_signal_connect (s->proxy, "g-signal", + G_CALLBACK(thumbnailer_proxy_g_signal_cb), &info); + + result = g_dbus_proxy_call_sync (s->proxy, + "Queue", + g_variant_new("(sssb)", + uri, + sinfo.mime_type, + flavor_name, + /* TODO: Get this bool from scheduler type */ + FALSE), + G_DBUS_CALL_FLAGS_NONE, + 100000000, /* 100 seconds worth of timeout */ + NULL, + &error); if (error == NULL) { - /* 100 seconds worth of timeout */ + /*Get the return handle */ + g_variant_get (result, "(u)", &sinfo.handle); + g_variant_unref (result); + + /* 100 seconds worth of timeout */ #if GLIB_CHECK_VERSION (2, 32, 0) end_time = g_get_monotonic_time () + 100 * G_TIME_SPAN_SECOND; #else @@ -497,18 +474,8 @@ tumbler_specialized_thumbnailer_create (TumblerThumbnailer *thumbnailer, g_free (message); g_clear_error (&error); } - - dbus_g_proxy_disconnect_signal (s->proxy, "Finished", - G_CALLBACK (specialized_finished), - &sinfo); - - dbus_g_proxy_disconnect_signal (s->proxy, "Ready", - G_CALLBACK (specialized_ready), - &sinfo); - - dbus_g_proxy_disconnect_signal (s->proxy, "Error", - G_CALLBACK (specialized_error), - &sinfo); + + g_signal_handler_disconnect (s->proxy, handler_id); #if GLIB_CHECK_VERSION (2, 32, 0) g_cond_clear (&sinfo.condition); @@ -518,19 +485,26 @@ tumbler_specialized_thumbnailer_create (TumblerThumbnailer *thumbnailer, } static void -tumbler_specialized_thumbnailer_proxy_destroyed (DBusGProxy *proxy, - TumblerSpecializedThumbnailer *thumbnailer) +tumbler_specialized_thumbnailer_proxy_name_owner_changed (GDBusProxy *proxy, + GParamSpec *spec, + TumblerSpecializedThumbnailer *thumbnailer) { - g_return_if_fail (DBUS_IS_G_PROXY (proxy)); + gchar *name_owner; + g_return_if_fail (G_IS_DBUS_PROXY (proxy)); g_return_if_fail (TUMBLER_IS_SPECIALIZED_THUMBNAILER (thumbnailer)); - - g_signal_emit_by_name (thumbnailer, "unregister"); + + name_owner = g_dbus_proxy_get_name_owner (proxy); + if (name_owner == NULL) + { + g_signal_emit_by_name (thumbnailer, "unregister"); + } + g_free(name_owner); } TumblerThumbnailer * -tumbler_specialized_thumbnailer_new (DBusGConnection *connection, +tumbler_specialized_thumbnailer_new (GDBusConnection *connection, const gchar *name, const gchar *object_path, const gchar *const *uri_schemes, @@ -557,7 +531,7 @@ tumbler_specialized_thumbnailer_new (DBusGConnection *connection, TumblerThumbnailer * -tumbler_specialized_thumbnailer_new_foreign (DBusGConnection *connection, +tumbler_specialized_thumbnailer_new_foreign (GDBusConnection *connection, const gchar *name, const gchar *const *uri_schemes, const gchar *const *mime_types) diff --git a/tumblerd/tumbler-specialized-thumbnailer.h b/tumblerd/tumbler-specialized-thumbnailer.h index 97c922f..61d2751 100644 --- a/tumblerd/tumbler-specialized-thumbnailer.h +++ b/tumblerd/tumbler-specialized-thumbnailer.h @@ -21,8 +21,6 @@ #ifndef __TUMBLER_SPECIALIZED_THUMBNAILER_H__ #define __TUMBLER_SPECIALIZED_THUMBNAILER_H__ -#include <dbus/dbus-glib-lowlevel.h> - #include <tumbler/tumbler.h> G_BEGIN_DECLS @@ -39,13 +37,13 @@ typedef struct _TumblerSpecializedThumbnailer TumblerSpecializedThumbnailer GType tumbler_specialized_thumbnailer_get_type (void) G_GNUC_CONST; -TumblerThumbnailer *tumbler_specialized_thumbnailer_new (DBusGConnection *connection, +TumblerThumbnailer *tumbler_specialized_thumbnailer_new (GDBusConnection *connection, const gchar *name, const gchar *object_path, const gchar *const *uri_schemes, const gchar *const *mime_types, guint64 modified) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; -TumblerThumbnailer *tumbler_specialized_thumbnailer_new_foreign (DBusGConnection *connection, +TumblerThumbnailer *tumbler_specialized_thumbnailer_new_foreign (GDBusConnection *connection, const gchar *name, const gchar *const *uri_scheme, const gchar *const *mime_type) G_GNUC_MALLOC G_GNUC_WARN_UNUSED_RESULT; diff --git a/tumblerd/tumbler-utils.h b/tumblerd/tumbler-utils.h index 6d02d9d..584e845 100644 --- a/tumblerd/tumbler-utils.h +++ b/tumblerd/tumbler-utils.h @@ -21,26 +21,40 @@ #ifndef __TUMBLER_UTILS_H__ #define __TUMBLER_UTILS_H__ -#include <dbus/dbus.h> -#include <dbus/dbus-glib.h> +#include <gio/gio.h> G_BEGIN_DECLS -#define dbus_async_return_if_fail(expr, context) \ +#define g_dbus_async_return_if_fail(expr, invocation) \ G_STMT_START{ \ if (G_UNLIKELY (!(expr))) \ { \ GError *dbus_async_return_if_fail_error = NULL; \ \ - g_set_error (&dbus_async_return_if_fail_error, DBUS_GERROR, DBUS_GERROR_FAILED, \ + g_set_error (&dbus_async_return_if_fail_error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, \ "Assertion \"%s\" failed", #expr); \ - dbus_g_method_return_error (context, dbus_async_return_if_fail_error); \ + g_dbus_method_invocation_return_gerror (invocation, dbus_async_return_if_fail_error);\ g_clear_error (&dbus_async_return_if_fail_error); \ \ return; \ } \ }G_STMT_END +#define g_dbus_async_return_val_if_fail(expr, invocation,val) \ + G_STMT_START{ \ + if (G_UNLIKELY (!(expr))) \ + { \ + GError *dbus_async_return_if_fail_error = NULL; \ + \ + g_set_error (&dbus_async_return_if_fail_error, G_DBUS_ERROR, G_DBUS_ERROR_FAILED, \ + "Assertion \"%s\" failed", #expr); \ + g_dbus_method_invocation_return_gerror (invocation, dbus_async_return_if_fail_error);\ + g_clear_error (&dbus_async_return_if_fail_error); \ + \ + return (val); \ + } \ + }G_STMT_END + #if GLIB_CHECK_VERSION (2, 32, 0) #define TUMBLER_MUTEX(mtx) GMutex mtx #define tumbler_mutex_free(mtx) g_mutex_clear (&(mtx)) |