diff options
author | Conor Curran <conor.curran@canonical.com> | 2010-03-02 19:36:53 +0000 |
---|---|---|
committer | Conor Curran <conor.curran@canonical.com> | 2010-03-02 19:36:53 +0000 |
commit | 4bde209ef0f8ad381d70b2ade7eb3cf834eed074 (patch) | |
tree | 389a1d11d72ff8566ae83000e24579138c454733 /src/pulse-manager.c | |
parent | be2b2e73044d5ba0c656431f0d19723af6b55946 (diff) | |
download | ayatana-indicator-sound-4bde209ef0f8ad381d70b2ade7eb3cf834eed074.tar.gz ayatana-indicator-sound-4bde209ef0f8ad381d70b2ade7eb3cf834eed074.tar.bz2 ayatana-indicator-sound-4bde209ef0f8ad381d70b2ade7eb3cf834eed074.zip |
one big refactor
Diffstat (limited to 'src/pulse-manager.c')
-rw-r--r-- | src/pulse-manager.c | 79 |
1 files changed, 60 insertions, 19 deletions
diff --git a/src/pulse-manager.c b/src/pulse-manager.c index 9b9d7cd..4594d2f 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -26,12 +26,10 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <pulse/gccmacro.h> #include "pulse-manager.h" -#include "sound-service.h" - +#include "dbus-menu-manager.h" static GHashTable *sink_hash = NULL; static SoundServiceDbus *dbus_service = NULL; -// Until we find a satisfactory default sink this index should remain < 0 static gint DEFAULT_SINK_INDEX = -1; static gboolean pa_server_available = FALSE; // PA related @@ -46,6 +44,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v 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(); +static void reconnect_to_pulse(); /** @@ -65,14 +64,19 @@ void establish_pulse_activities(SoundServiceDbus *service) g_assert(pulse_context); sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info); + // Establish event callback registration pa_context_set_state_callback(pulse_context, context_state_callback, NULL); - pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); + // BUILD MENU ANYWHO - it will be updated + dbus_menu_manager_update_pa_state(FALSE, FALSE, FALSE, 0); + + pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL); } void close_pulse_activites() { - if (pulse_context){ + if (pulse_context != NULL){ + g_debug("freeing the pulse context"); pa_context_unref(pulse_context); pulse_context = NULL; } @@ -82,6 +86,30 @@ void close_pulse_activites() g_debug("I just closed communication with Pulse"); } +/** +reconnect_to_pulse() +In the event of Pulseaudio flapping in the wind handle gracefully without +memory leaks ! +*/ +static void reconnect_to_pulse() +{ + // reset + if (pulse_context != NULL){ + g_debug("freeing the pulse context"); + pa_context_unref(pulse_context); + pulse_context = NULL; + } + g_hash_table_destroy(sink_hash); + + // reconnect + pulse_context = pa_context_new(pa_glib_mainloop_get_api(pa_main_loop), "ayatana.indicator.sound"); + g_assert(pulse_context); + sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info); + // Establish event callback registration + pa_context_set_state_callback(pulse_context, context_state_callback, NULL); + dbus_menu_manager_update_pa_state(FALSE, FALSE, FALSE, 0); + pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL); +} static void destroy_sink_info(void *value) { @@ -186,6 +214,8 @@ Use the base volume stored in the sink struct to calculate actual linear volumes */ void set_sink_volume(gdouble percent) { + if(pa_server_available == FALSE) + return; g_debug("in the pulse manager:set_sink_volume with percent %f", percent); if(DEFAULT_SINK_INDEX < 0) { @@ -245,12 +275,15 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in gboolean device_available = determine_sink_availability(); if(device_available == TRUE) { - update_pa_state(TRUE, device_available, default_sink_is_muted(), get_default_sink_volume()); + dbus_menu_manager_update_pa_state(TRUE, + device_available, + default_sink_is_muted(), + get_default_sink_volume()); } else{ //Update the indicator to show PA either is not ready or has no available sink g_warning("Cannot find a suitable default sink ..."); - update_pa_state(FALSE, device_available, TRUE, 0); + dbus_menu_manager_update_pa_state(FALSE, device_available, TRUE, 0); } } else{ @@ -291,7 +324,7 @@ static void pulse_default_sink_info_callback(pa_context *c, const pa_sink_info * } else { - update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume()); + dbus_menu_manager_update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume()); } } } @@ -354,7 +387,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v { g_debug("Updating Mute from PA manager with mute = %i", s->mute); sound_service_dbus_update_sink_mute(dbus_service, s->mute); - update_mute_ui(s->mute); + dbus_menu_manager_update_mute_ui(s->mute); if(s->mute == FALSE){ pa_volume_t vol = pa_cvolume_avg(&s->volume); gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; @@ -366,12 +399,20 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v } else { - // TODO ADD new sink - part of big refactor - 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. - } + sink_info *value; + value = g_new0(sink_info, 1); + value->index = value->device_index = info->index; + value->name = g_strdup(info->name); + value->description = g_strdup(info->description); + value->icon_name = g_strdup(pa_proplist_gets(info->proplist, PA_PROP_DEVICE_ICON_NAME)); + value->active_port = (info->active_port != NULL); + value->mute = !!info->mute; + value->volume = info->volume; + value->base_volume = info->base_volume; + value->channel_map = info->channel_map; + g_hash_table_insert(sink_hash, GINT_TO_POINTER(value->index), value); + g_debug("pulse-manager:update_sink_info -> After adding a new sink to our hash"); + } } @@ -382,7 +423,7 @@ static void pulse_server_info_callback(pa_context *c, const pa_server_info *info if (info == NULL) { g_warning("No server - get the hell out of here"); - update_pa_state(FALSE, FALSE, TRUE, 0); + dbus_menu_manager_update_pa_state(FALSE, FALSE, TRUE, 0); pa_server_available = FALSE; return; } @@ -474,7 +515,7 @@ static void context_state_callback(pa_context *c, void *userdata) { g_debug("unconnected"); break; case PA_CONTEXT_CONNECTING: - g_debug("connecting"); + g_debug("connecting - waiting for the server to become available"); break; case PA_CONTEXT_AUTHORIZING: g_debug("authorizing"); @@ -484,8 +525,8 @@ static void context_state_callback(pa_context *c, void *userdata) { break; case PA_CONTEXT_FAILED: g_warning("FAILED to retrieve context - Is PulseAudio Daemon running ?"); - //Update the indicator to show PA either is not ready or has no available sink - update_pa_state(FALSE, FALSE, TRUE, 0); + pa_server_available = FALSE; + reconnect_to_pulse(); break; case PA_CONTEXT_TERMINATED: g_debug("context terminated"); |