From f9ef87f71c488f6791e32b1cf7205fb65db81ce8 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 8 Feb 2010 14:42:30 +0000 Subject: automatic volume updates in progress --- src/common-defs.h | 2 +- src/indicator-sound.c | 9 ++++++++ src/pulse-manager.c | 59 +++++++++++++++++++++++++++++++++++++++++++++--- src/sound-service-dbus.c | 18 +++++++++++++++ src/sound-service-dbus.h | 2 ++ src/sound-service.xml | 3 +++ 6 files changed, 89 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/common-defs.h b/src/common-defs.h index 6cacb49..a06b1b3 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -1,6 +1,6 @@ /* constants used for signals on the dbus. This file is shared between client and server implementation */ #define SIGNAL_SINK_INPUT_WHILE_MUTED "SinkInputWhileMuted" -#define METHOD_SET_SINK_VOLUME "SetSinkVolume" +#define SIGNAL_UPDATE_SINK_VOLUME "UpdateSinkVolume" // DBUS items #define DBUSMENU_SLIDER_MENUITEM_TYPE "x-canonical-ido-slider-item" diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 2b20c48..9ceebd1 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -90,6 +90,7 @@ static gboolean slider_value_changed_event_cb(GtkRange *range, gpointer user_da static DBusGProxy *sound_dbus_proxy = NULL; static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata); static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gint sink_index, gboolean value, gpointer userdata); +void catch_signal_sink_volume_update(DBusGProxy * proxy, gint sink_volume, gpointer userdata); /****Volume States 'members' ***/ static const gint STATE_MUTED = 0; @@ -192,6 +193,9 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u g_debug("about to connect to the signals"); dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_INT, G_TYPE_BOOLEAN, G_TYPE_INVALID); dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL); + dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_UPDATE_SINK_VOLUME, G_TYPE_INT, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_UPDATE_SINK_VOLUME, G_CALLBACK(catch_signal_sink_volume_update), NULL, NULL); + } } else { @@ -207,6 +211,11 @@ static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gint sink_in g_debug("signal caught - I don't believe it ! with index %i and value %i", sink_index, value); } +void catch_signal_sink_volume_update(DBusGProxy * proxy, gint sink_volume, gpointer userdata) +{ + g_debug("signal caught - update sink volume with value : %i", sink_volume); +} + static void indicator_sound_dispose (GObject *object) { diff --git a/src/pulse-manager.c b/src/pulse-manager.c index dbf30a0..87f20ae 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -19,6 +19,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink_inf static void context_success_callback(pa_context *c, int success, void *userdata); static void pulse_sink_input_info_callback(pa_context *c, const pa_sink_input_info *info, int eol, void *userdata); static void pulse_server_info_callback(pa_context *c, const pa_server_info *info, void *userdata); +static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, void *userdata); static void destroy_sink_info(void *value); /* @@ -204,7 +205,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in } else{ - g_debug("About to add an item to our hash"); + g_debug("About to add an item to our hash"); sink_info *value; value = g_new0(sink_info, 1); value->index = value->device_index = sink->index; @@ -217,7 +218,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in value->base_volume = sink->base_volume; value->channel_map = sink->channel_map; g_hash_table_insert(sink_hash, GINT_TO_POINTER(sink->index), value); - g_debug("After adding an item to our hash"); + g_debug("After adding an item to our hash"); } } @@ -254,7 +255,54 @@ static void pulse_sink_input_info_callback(pa_context *c, const pa_sink_input_in g_debug("\n SINK INPUT INFO sink index : %d \n", info->sink); check_sink_input_while_muted_event(info->sink); } -} +} + +static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, void *userdata) +{ + if (eol > 0) { + if (pa_context_errno(c) == PA_ERR_NOENTITY) + return; + g_warning("Sink INPUT info callback failure"); + return; + } + + GList *keys = g_hash_table_get_keys(sink_hash); + gint position = g_list_index(keys, GINT_TO_POINTER(info->index)); +/* gboolean update_ui_vol = FALSE;*/ + if(position >= 0) // => index is within the keys of the hash. + { + // TODO : update sinks hash with new details and if default send over dbus the update. in reverse order. + //gint sink_index = GPOINTER_TO_INT(g_list_nth_data(keys, position)); + sink_info *s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(info->index)); + g_debug("attempting to update sink with name %s", s->name); + s->name = g_strdup(info->name); + s->description = g_strdup(info->description); + s->icon_name = g_strdup(pa_proplist_gets(info->proplist, PA_PROP_DEVICE_ICON_NAME)); + s->active_port = (info->active_port != NULL); + s->mute = !!info->mute; +/* int equal = pa_cvolume_equal(&s->volume, &info->volume);*/ +/* update_ui_vol = (equal != 0); */ +/* g_debug("Are the volumes the same %i", equal); */ + s->volume = info->volume; + s->base_volume = info->base_volume; + s->channel_map = info->channel_map; + if(DEFAULT_SINK_INDEX == s->index/* && update_ui_vol == TRUE*/) + { + //update the UI + pa_volume_t vol = pa_cvolume_avg(&s->volume); + g_debug("about to update ui with linear volume of %f", pa_sw_volume_to_linear(vol)); + sound_service_dbus_update_sink_volume(dbus_service, vol * 100); + } + } + else + { + g_debug("attempting to add new sink with name %s", info->name); + //sink_info *s; + //s = g_new0(sink_info, 1); + //update the sinks hash with new sink. + } +} + static void pulse_server_info_callback(pa_context *c, const pa_server_info *info, void *userdata) { @@ -290,6 +338,11 @@ static void pulse_server_info_callback(pa_context *c, const pa_server_info *info static void subscribed_events_callback(pa_context *c, enum pa_subscription_event_type t, uint32_t index, void *userdata){ switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { case PA_SUBSCRIPTION_EVENT_SINK: + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + //TODO handle the remove event + } else { + pa_operation_unref(pa_context_get_sink_info_by_index(c, index, update_sink_info, userdata)); + } //g_debug("Event sink for %i", index); break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 5e22dae..9a325fe 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -43,6 +43,7 @@ struct _SoundServiceDbusPrivate /* Signals */ enum { SINK_INPUT_WHILE_MUTED, + SINK_VOLUME_UPDATE, LAST_SIGNAL }; @@ -81,6 +82,14 @@ sound_service_dbus_class_init (SoundServiceDbusClass *klass) NULL, NULL, _sound_service_marshal_VOID__INT_BOOLEAN, G_TYPE_NONE, 2, G_TYPE_INT, 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__INT, + G_TYPE_NONE, 1, G_TYPE_INT); } /** @@ -116,6 +125,15 @@ void sound_service_dbus_sink_input_while_muted(SoundServiceDbus* obj, gint sink_ value); } +void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gint sink_volume) +{ + g_debug("Emitting signal: UPDATE_SINK_VOLUME, with sink_volme %i", sink_volume); + g_signal_emit(obj, + signals[SINK_VOLUME_UPDATE], + 0, + sink_volume); +} + void set_pa_sinks_hash(SoundServiceDbus *self, GHashTable *sinks) { SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h index eea6d26..bb4fbe8 100644 --- a/src/sound-service-dbus.h +++ b/src/sound-service-dbus.h @@ -51,12 +51,14 @@ struct _SoundServiceDbusClass { GObjectClass parent_class; /* Signals -> outward messages to the DBUS and beyond*/ void (* sink_input_while_muted) (SoundServiceDbus *self, gint sink_index, gboolean is_muted, gpointer sound_data); + void (* sink_volume_update) (SoundServiceDbus *self, gint sink_volume); }; GType sound_service_dbus_get_type (void) G_GNUC_CONST; // Utility methods to get the messages across into the sound-service-dbus void sound_service_dbus_sink_input_while_muted (SoundServiceDbus* obj, gint sink_index, gboolean value); +void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gint sink_volume); void set_pa_sinks_hash(SoundServiceDbus *self, GHashTable *sinks); // DBUS METHODS diff --git a/src/sound-service.xml b/src/sound-service.xml index 26d83e5..0a35690 100644 --- a/src/sound-service.xml +++ b/src/sound-service.xml @@ -13,6 +13,9 @@ Our respective UI element should listen to this and therefore will be updated wi + + + -- cgit v1.2.3