From 0bc2668c7bffba29b021779230507b36a2fcc8ed Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 17 Feb 2010 17:25:44 +0000 Subject: Now handles dynamic switching of sinks - filers volume signal updates on the basis of whether the original update came from the indicator and a tidy up --- src/pulse-manager.c | 111 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 22 deletions(-) diff --git a/src/pulse-manager.c b/src/pulse-manager.c index 269ac58..8fa47eb 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -43,10 +43,16 @@ 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 pulse_source_info_callback(pa_context *c, const pa_source_info *i, int eol, void *userdata); static void destroy_sink_info(void *value); static gboolean determine_sink_availability(); +/** +Refactoring notes +Push all UI updates out through update PA state in the service. +**/ + /* Entry point */ @@ -167,6 +173,13 @@ static void mute_each_sink(gpointer key, gpointer value, gpointer user_data) { sink_info *info = (sink_info*)value; pa_operation_unref(pa_context_set_sink_mute_by_index(pulse_context, info->index, GPOINTER_TO_INT(user_data), context_success_callback, NULL)); + if(GPOINTER_TO_INT(user_data) == 1){ + sound_service_dbus_update_sink_mute(dbus_service, TRUE); + } + else{ + sound_service_dbus_update_sink_volume(dbus_service, get_default_sink_volume()); + } + g_debug("in the pulse manager: mute each sink %i", GPOINTER_TO_INT(user_data)); } @@ -197,8 +210,9 @@ void set_sink_volume(gdouble percent) g_debug("new volume calculated :%f", (gdouble)new_volume); pa_cvolume dev_vol; pa_cvolume_set(&dev_vol, s->volume.channels, new_volume); - // TODO why don't you update the sink_info here with the appropriate pa_cvolume (&dev_vol) + s->volume = dev_vol; pa_operation_unref(pa_context_set_sink_volume_by_index(pulse_context, DEFAULT_SINK_INDEX, &dev_vol, NULL, NULL)); + } @@ -242,9 +256,9 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in if(device_available == TRUE) { update_pa_state(TRUE, device_available, default_sink_is_muted(), get_default_sink_volume()); - sound_service_dbus_update_sink_volume(dbus_service, get_default_sink_volume()); - sound_service_dbus_update_sink_mute(dbus_service, default_sink_is_muted()); - g_debug("default sink index : %d", DEFAULT_SINK_INDEX); + //sound_service_dbus_update_sink_volume(dbus_service, get_default_sink_volume()); + //sound_service_dbus_update_sink_mute(dbus_service, default_sink_is_muted()); + //g_debug("default sink index : %d", DEFAULT_SINK_INDEX); } else{ //Update the indicator to show PA either is not ready or has no available sink @@ -281,7 +295,17 @@ static void pulse_default_sink_info_callback(pa_context *c, const pa_sink_info * else{ DEFAULT_SINK_INDEX = info->index; g_debug("Just set the default sink index to %i", DEFAULT_SINK_INDEX); - pa_operation_unref(pa_context_get_sink_info_list(c, pulse_sink_info_callback, NULL)); + GList *keys = g_hash_table_get_keys(sink_hash); + gint position = g_list_index(keys, GINT_TO_POINTER(info->index)); + // Only update sink-list if the index is not in our already fetched list. + if(position < 0) + { + pa_operation_unref(pa_context_get_sink_info_list(c, pulse_sink_info_callback, NULL)); + } + else + { + update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume()); + } } } @@ -322,19 +346,22 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v 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); - // NASTY!! - gboolean mute_changed = s->mute != !!info->mute; s->mute = !!info->mute; + gboolean mute_changed = s->mute != !!info->mute; + gboolean volume_changed = (pa_cvolume_equal(&info->volume, &s->volume) == 0); s->volume = info->volume; s->base_volume = info->base_volume; s->channel_map = info->channel_map; if(DEFAULT_SINK_INDEX == s->index) { //update the UI - pa_volume_t vol = pa_cvolume_avg(&s->volume); - gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; - g_debug("Updating volume from PA manager with volume = %f", volume_percent); - sound_service_dbus_update_sink_volume(dbus_service, volume_percent); + if (volume_changed == TRUE) + { + pa_volume_t vol = pa_cvolume_avg(&s->volume); + gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; + g_debug("Updating volume from PA manager with volume = %f", volume_percent); + sound_service_dbus_update_sink_volume(dbus_service, volume_percent); + } if (mute_changed == TRUE) sound_service_dbus_update_sink_mute(dbus_service, s->mute); update_mute_ui(s->mute); @@ -382,24 +409,64 @@ static void pulse_server_info_callback(pa_context *c, const pa_server_info *info pa_operation_unref(operation); } -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) { +static void pulse_source_info_callback(pa_context *c, const pa_source_info *i, int eol, void *userdata) +{ + g_debug("pulse source info callback"); +} + + +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 => if its our default sink - grey out the ui with update_pa_state - } else { + g_debug("PA_SUBSCRIPTION_EVENT_SINK event triggered"); + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) + { + //TODO handle the remove event => if its our default sink - update date pa state + } else + { pa_operation_unref(pa_context_get_sink_info_by_index(c, index, update_sink_info, userdata)); } break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: - // This will be triggered when the sink receives input from a new stream - // If a playback client is paused and then resumed this will NOT trigger this event. - pa_operation_unref(pa_context_get_sink_input_info(c, index, pulse_sink_input_info_callback, userdata)); - break; + g_debug("PA_SUBSCRIPTION_EVENT_SINK_INPUT event triggered!!"); + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) + { + //TODO handle the remove event + } + else + { + pa_operation_unref(pa_context_get_sink_input_info(c, index, pulse_sink_input_info_callback, userdata)); + } + break; + case PA_SUBSCRIPTION_EVENT_SOURCE: + g_debug("PA_SUBSCRIPTION_EVENT_SOURCE of some description ???"); + + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) + { + //TODO handle the remove event + } + else + { + pa_operation *o; + if (!(o = pa_context_get_source_info_by_index(c, index, pulse_source_info_callback, userdata))) { + g_warning("pa_context_get_source_info_by_index() failed"); + return; + } + pa_operation_unref(o); + } + break; case PA_SUBSCRIPTION_EVENT_SERVER: - if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_SINK ) { - g_debug("server change of some sink type ???"); + g_debug("PA_SUBSCRIPTION_EVENT_SERVER change of some description ???"); + pa_operation *o; + if(!(o = pa_context_get_server_info(c, pulse_server_info_callback, userdata))) + { + g_warning("pa_context_get_server_info() failed"); + return; } + pa_operation_unref(o); + break; } } -- cgit v1.2.3