/* * Copyright 2010 Canonical Ltd. * * Authors: * Conor Curran <conor.curran@canonical.com> * Cody Russell <crussell@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 * by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranties of * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see <http://www.gnu.org/licenses/>. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include <dbus/dbus-glib.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_volume(SoundServiceDbus* service, gdouble* volume_percent_input, GError** gerror); 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 sound_service_dbus_set_sink_volume(SoundServiceDbus* service, const guint volume_percent, GError** gerror); #include "sound-service-server.h" typedef struct _SoundServiceDbusPrivate SoundServiceDbusPrivate; struct _SoundServiceDbusPrivate { DBusGConnection *connection; gdouble volume_percent; gboolean mute; gboolean sink_availability; }; /* Signals */ enum { SINK_INPUT_WHILE_MUTED, SINK_VOLUME_UPDATE, SINK_MUTE_UPDATE, SINK_AVAILABLE_UPDATE, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; #define SOUND_SERVICE_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUND_SERVICE_DBUS_TYPE, SoundServiceDbusPrivate)) static void sound_service_dbus_class_init (SoundServiceDbusClass *klass); static void sound_service_dbus_init (SoundServiceDbus *self); static void sound_service_dbus_dispose (GObject *object); static void sound_service_dbus_finalize (GObject *object); /* GObject Boilerplate */ G_DEFINE_TYPE (SoundServiceDbus, sound_service_dbus, G_TYPE_OBJECT); static void sound_service_dbus_class_init (SoundServiceDbusClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); g_type_class_add_private (object_class, sizeof(SoundServiceDbusPrivate)); object_class->dispose = sound_service_dbus_dispose; 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_VOLUME_UPDATE] = g_signal_new("sink-volume-update", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST, 0, NULL, NULL, g_cclosure_marshal_VOID__DOUBLE, G_TYPE_NONE, 1, G_TYPE_DOUBLE); 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); } static void sound_service_dbus_init (SoundServiceDbus *self) { GError *error = NULL; SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); priv->connection = NULL; priv->volume_percent = 0; priv->mute = FALSE; priv->sink_availability = FALSE; /* Fetch the session bus */ priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &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_free(error); return; } /* register the service on it */ dbus_g_connection_register_g_object(priv->connection, INDICATOR_SOUND_SERVICE_DBUS_OBJECT, G_OBJECT(self)); } static void sound_service_dbus_dispose (GObject *object) { G_OBJECT_CLASS (sound_service_dbus_parent_class)->dispose (object); return; } static void sound_service_dbus_finalize (GObject *object) { G_OBJECT_CLASS (sound_service_dbus_parent_class)->finalize (object); return; } /** DBUS Method Callbacks **/ static void sound_service_dbus_set_sink_volume(SoundServiceDbus* service, const guint volume_percent, GError** gerror) { g_debug("in the set sink volume method in the sound service dbus!, with volume_percent of %i", volume_percent); set_sink_volume(volume_percent); } static gboolean sound_service_dbus_get_sink_volume (SoundServiceDbus *self, gdouble *volume_percent_input, GError** gerror) { SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); g_debug("Get sink volume method in the sound service dbus!, about to send over volume percent of %f", priv->volume_percent); *volume_percent_input = priv->volume_percent; return TRUE; } 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; } 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) { /* 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); } void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gdouble sink_volume) { SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj); priv->volume_percent = sink_volume; /* g_debug("Emitting signal: SINK_VOLUME_UPDATE, with sink_volme %f", priv->volume_percent);*/ g_signal_emit(obj, signals[SINK_VOLUME_UPDATE], 0, priv->volume_percent); } 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);*/ SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj); priv->mute = sink_mute; g_signal_emit(obj, signals[SINK_MUTE_UPDATE], 0, priv->mute); } void sound_service_dbus_update_sink_availability(SoundServiceDbus* obj, gboolean sink_availability) { /* g_debug("Emitting signal: SINK_AVAILABILITY_UPDATE, with value %i", sink_availability);*/ SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj); priv->sink_availability = sink_availability; g_signal_emit(obj, signals[SINK_AVAILABLE_UPDATE], 0, priv->sink_availability); }