diff options
Diffstat (limited to 'src/sound-service-dbus.c')
-rw-r--r-- | src/sound-service-dbus.c | 233 |
1 files changed, 161 insertions, 72 deletions
diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 0760247..c574705 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -3,7 +3,7 @@ * * Authors: * Conor Curran <conor.curran@canonical.com> - * Cody Russell <crussell@canonical.com> + * Ted Gould <ted.gould@canonical.com> * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License version 3, as published @@ -22,22 +22,28 @@ #include "config.h" #endif -#include <dbus/dbus-glib.h> +#include <gio/gio.h> +#include "gen-indicator-service.xml.h" #include "dbus-shared-names.h" #include "sound-service-dbus.h" #include "common-defs.h" #include "pulse-manager.h" // DBUS methods -static gboolean sound_service_dbus_get_sink_mute(SoundServiceDbus* service, gboolean* mute_input, GError** gerror); -static gboolean sound_service_dbus_get_sink_availability(SoundServiceDbus* service, gboolean* availability_input, GError** gerror); +static void bus_method_call (GDBusConnection * connection, + const gchar * sender, + const gchar * path, + const gchar * interface, + const gchar * method, + GVariant * params, + GDBusMethodInvocation * invocation, + gpointer user_data); -#include "sound-service-server.h" typedef struct _SoundServiceDbusPrivate SoundServiceDbusPrivate; struct _SoundServiceDbusPrivate { - DBusGConnection *connection; + GDBusConnection *connection; gboolean mute; gboolean sink_availability; }; @@ -50,6 +56,8 @@ enum { LAST_SIGNAL }; +static GDBusNodeInfo * node_info = NULL; +static GDBusInterfaceInfo * interface_info = NULL; static guint signals[LAST_SIGNAL] = { 0 }; @@ -74,31 +82,50 @@ sound_service_dbus_class_init (SoundServiceDbusClass *klass) object_class->finalize = sound_service_dbus_finalize; g_assert(klass != NULL); - dbus_g_object_type_install_info(SOUND_SERVICE_DBUS_TYPE, - &dbus_glib__sound_service_server_object_info); - - signals[SINK_INPUT_WHILE_MUTED] = g_signal_new("sink-input-while-muted", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - - signals[SINK_MUTE_UPDATE] = g_signal_new("sink-mute-update", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN); - signals[SINK_AVAILABLE_UPDATE] = g_signal_new("sink-available-update", - G_TYPE_FROM_CLASS (klass), - G_SIGNAL_RUN_LAST, - 0, - NULL, NULL, - g_cclosure_marshal_VOID__BOOLEAN, - G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + dbus_g_object_type_install_info (SOUND_SERVICE_DBUS_TYPE, + &dbus_glib__sound_service_server_object_info); + + signals[SINK_INPUT_WHILE_MUTED] = g_signal_new ("sink-input-while-muted", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + signals[SINK_MUTE_UPDATE] = g_signal_new ("sink-mute-update", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + signals[SINK_AVAILABLE_UPDATE] = g_signal_new ("sink-available-update", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + if (node_info == NULL) { + GError * error = NULL; + + node_info = g_dbus_node_info_new_for_xml(_indicator_service, &error); + if (error != NULL) { + g_error("Unable to parse Indicator Service Interface description: %s", + error->message); + g_error_free(error); + } + } + + if (interface_info == NULL) { + interface_info = g_dbus_node_info_lookup_interface (node_info, + INDICATOR_SOUND_SERVICE_DBUS_INTERFACE); + + if (interface_info == NULL) { + g_error("Unable to find interface '" INDICATOR_SOUND_SERVICE_DBUS_INTERFACE "'"); + } + } } static void @@ -112,20 +139,29 @@ sound_service_dbus_init (SoundServiceDbus *self) priv->sink_availability = FALSE; /* Fetch the session bus */ - priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + priv->connection = g_bus_get_sync (DBUS_BUS_SESSION, NULL, &error); if (error != NULL) { - g_error("sound-service-dbus:Unable to connect to the session bus when creating indicator sound service : %s", error->message); + g_error("sound-service-dbus:Unable to connect to the session bus when + creating indicator sound service : %s", error->message); g_error_free(error); return; } /* register the service on it */ - dbus_g_connection_register_g_object(priv->connection, - INDICATOR_SOUND_SERVICE_DBUS_OBJECT, - G_OBJECT(self)); + g_dbus_connection_register_object (priv->connection, + INDICATOR_SOUND_SERVICE_DBUS_OBJECT, + interface_info, + NULL, + NULL, + NULL, + &error); + if (error != NULL) { + g_error("Unable to register the object to DBus: %s", error->message); + g_error_free(error); + return; + } } - static void sound_service_dbus_dispose (GObject *object) { @@ -140,60 +176,113 @@ sound_service_dbus_finalize (GObject *object) return; } - -static gboolean sound_service_dbus_get_sink_mute (SoundServiceDbus *self, gboolean *mute_input, GError** gerror) -{ - SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); - g_debug("Get sink mute - sound service dbus!, about to send over mute_value of %i", priv->mute); - *mute_input = priv->mute; - return TRUE; +/* A method has been called from our dbus inteface. Figure out what it + is and dispatch it. */ +static void +bus_method_call (GDBusConnection * connection, + const gchar * sender, + const gchar * path, + const gchar * interface, + const gchar * method, + GVariant * params, + GDBusMethodInvocation * invocation, + gpointer user_data) +{ + IndicatorService * service = INDICATOR_SERVICE(user_data); + GVariant * retval = NULL; + + if (g_strcmp0(method, "GetSinkMute") == 0) { + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); + g_debug("Get sink mute - sound service dbus!, + about to send over mute_value of %i", priv->mute); + retval = g_variant_new_boolean (priv->mute); + } + else if (g_strcmp0(method, "GetSinkAvailability") == 0) { + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); + g_debug("Get sink availability - sound service dbus!, + about to send over availability_value of %i", priv->sink_availability); + retval = g_variant_new_boolean (priv->sink_availability); + } + else { + g_warning("Calling method '%s' on the sound service but it's unknown", method); + } + g_dbus_method_invocation_return_value(invocation, retval); } -static gboolean sound_service_dbus_get_sink_availability (SoundServiceDbus *self, gboolean *availability_input, GError** gerror) -{ - SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); - g_debug("Get sink availability - sound service dbus!, about to send over availability_value of %i", priv->sink_availability); - *availability_input = priv->sink_availability; - return TRUE; -} /** SIGNALS Utility methods to emit signals from the service into the ether. **/ -void sound_service_dbus_sink_input_while_muted(SoundServiceDbus* obj, gboolean block_value) +void sound_service_dbus_sink_input_while_muted(SoundServiceDbus* obj, + gboolean block_value) { - /* g_debug("Emitting signal: SINK_INPUT_WHILE_MUTED, with block_value: %i", block_value);*/ - g_signal_emit(obj, - signals[SINK_INPUT_WHILE_MUTED], - 0, - block_value); + g_debug("Emitting signal: SINK_INPUT_WHILE_MUTED, with block_value: %i", + block_value); + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj); + GVariant* v_output = g_variant_new_boolean (block_value); + + GError * error = NULL; + + g_dbus_connection_emit_signal( priv->connection, + INDICATOR_SOUND_DBUS_NAME, + INDICATOR_SOUND_DBUS_OBJECT, + INDICATOR_SOUND_SERVICE_DBUS_INTERFACE, + "SinkInputWhileMuted", + v_output, + &error ); + if (error != NULL) { + g_error("Unable to emit signal 'sinkinputwhilemuted' because : %s", error->message); + g_error_free(error); + return; + } } -void sound_service_dbus_update_sink_mute(SoundServiceDbus* obj, gboolean sink_mute) +void sound_service_dbus_update_sink_mute(SoundServiceDbus* obj, + gboolean sink_mute) { - /* g_debug("Emitting signal: SINK_MUTE_UPDATE, with sink mute %i", sink_mute);*/ - + g_debug("Emitting signal: SINK_MUTE_UPDATE, with sink mute %i", sink_mute); SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj); - priv->mute = sink_mute; + GVariant* v_output = g_variant_new_boolean (sink_mute); - g_signal_emit(obj, - signals[SINK_MUTE_UPDATE], - 0, - priv->mute); + GError * error = NULL; + + g_dbus_connection_emit_signal( priv->connection, + INDICATOR_SOUND_DBUS_NAME, + INDICATOR_SOUND_DBUS_OBJECT, + INDICATOR_SOUND_SERVICE_DBUS_INTERFACE, + "SinkMuteUpdate", + v_output, + &error ); + if (error != NULL) { + g_error("Unable to emit signal 'sinkmuteupdate' because : %s", error->message); + g_error_free(error); + return; + } } -void sound_service_dbus_update_sink_availability(SoundServiceDbus* obj, gboolean sink_availability) +void sound_service_dbus_update_sink_availability(SoundServiceDbus* obj, + gboolean sink_availability) { /* g_debug("Emitting signal: SINK_AVAILABILITY_UPDATE, with value %i", sink_availability);*/ - + g_debug("Emitting signal: SinkAvailableUpdate, with %i", sink_availability); SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj); - priv->sink_availability = sink_availability; + GVariant* v_output = g_variant_new_boolean (sink_availability); + + GError * error = NULL; - g_signal_emit(obj, - signals[SINK_AVAILABLE_UPDATE], - 0, - priv->sink_availability); + g_dbus_connection_emit_signal( priv->connection, + INDICATOR_SOUND_DBUS_NAME, + INDICATOR_SOUND_DBUS_OBJECT, + INDICATOR_SOUND_SERVICE_DBUS_INTERFACE, + "SinkAvailableUpdate", + v_output, + &error ); + if (error != NULL) { + g_error("Unable to emit signal 'SinkAvailableUpdate' because : %s", error->message); + g_error_free(error); + return; + } } |