aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorConor Curran <conor.curran@canonical.com>2010-02-17 17:25:44 +0000
committerConor Curran <conor.curran@canonical.com>2010-02-17 17:25:44 +0000
commit0bc2668c7bffba29b021779230507b36a2fcc8ed (patch)
treebba2c0717c24dd463a0477333ef24038a3c47998 /src
parent59cf6bdba1c4206a9587c9b642a427e6db1a2f2c (diff)
downloadayatana-indicator-sound-0bc2668c7bffba29b021779230507b36a2fcc8ed.tar.gz
ayatana-indicator-sound-0bc2668c7bffba29b021779230507b36a2fcc8ed.tar.bz2
ayatana-indicator-sound-0bc2668c7bffba29b021779230507b36a2fcc8ed.zip
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
Diffstat (limited to 'src')
-rw-r--r--src/pulse-manager.c111
1 files 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;
}
}