From b51a53a2f2c6cbe23d4f6269360699e225bd30aa Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 10 Feb 2010 11:33:36 +0000 Subject: mute init/revert now working properly plus dbus signal tidy up on the blocking message --- src/indicator-sound.c | 100 ++++++++++++++++++++++++++++++----------------- src/pulse-manager.c | 40 ++++++++++--------- src/sound-service-dbus.c | 27 +++++++++---- src/sound-service-dbus.h | 5 ++- src/sound-service.xml | 6 ++- 5 files changed, 113 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 352e0ed..e2d3116 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -83,16 +83,17 @@ static gboolean new_slider_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget); static gboolean slider_value_changed_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data); -/*static void change_speaker_image(gdouble volume_percent);*/ static void prepare_state_machine(); static void determine_state_from_volume(gdouble volume_percent); static void update_state(const gint state); -static void revert_state(); +static void fetch_volume_percent_from_dbus(); +static void fetch_mute_value_from_dbus(); +/*static void revert_state();*/ // DBUS communication 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); +static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata); static void catch_signal_sink_volume_update(DBusGProxy * proxy, gdouble volume_percent, gpointer userdata); static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata); @@ -109,6 +110,7 @@ static GtkImage *speaker_image = NULL; static gint current_state = 0; static gint previous_state = 0; static gdouble initial_volume_percent = 0; +static gboolean initial_mute = FALSE; static void indicator_sound_class_init (IndicatorSoundClass *klass) @@ -189,26 +191,16 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u g_error_free(error); } 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_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, 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_SINK_VOLUME_UPDATE, G_TYPE_DOUBLE, G_TYPE_INVALID); dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_VOLUME_UPDATE, G_CALLBACK(catch_signal_sink_volume_update), NULL, NULL); dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), NULL, NULL); - gdouble *volume_percent_input; - volume_percent_input = g_new0(gdouble, 1); - org_ayatana_indicator_sound_get_sink_volume(sound_dbus_proxy, volume_percent_input, &error); - if (error != NULL) { - g_warning("Unable to fetch volume at indicator start up: %s", error->message); - g_error_free(error); - g_free(volume_percent_input); - return; - } - initial_volume_percent = *volume_percent_input; - determine_state_from_volume(initial_volume_percent); - g_free(volume_percent_input); - g_debug("at the indicator start up and the volume percent returned from dbus method is %f", initial_volume_percent); + // Ensure we are in a coherent state with the service at start up. + fetch_volume_percent_from_dbus(); + fetch_mute_value_from_dbus(); } } else { @@ -218,9 +210,46 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u return; } -static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gint sink_index, gboolean value, gpointer userdata) +static void fetch_volume_percent_from_dbus() +{ + GError * error = NULL; + gdouble *volume_percent_input; + volume_percent_input = g_new0(gdouble, 1); + org_ayatana_indicator_sound_get_sink_volume(sound_dbus_proxy, volume_percent_input, &error); + if (error != NULL) { + g_warning("Unable to fetch VOLUME at indicator start up: %s", error->message); + g_error_free(error); + g_free(volume_percent_input); + return; + } + initial_volume_percent = *volume_percent_input; + determine_state_from_volume(initial_volume_percent); + g_free(volume_percent_input); + g_debug("at the indicator start up and the volume percent returned from dbus method is %f", initial_volume_percent); +} + +static void fetch_mute_value_from_dbus() +{ + GError * error = NULL; + gboolean *mute_input; + mute_input = g_new0(gboolean, 1); + org_ayatana_indicator_sound_get_sink_mute(sound_dbus_proxy, mute_input, &error); + if (error != NULL) { + g_warning("Unable to fetch MUTE at indicator start up: %s", error->message); + g_error_free(error); + g_free(mute_input); + return; + } + initial_mute = *mute_input; + if (initial_mute == TRUE) + update_state(STATE_MUTED); + g_free(mute_input); + g_debug("at the indicator start up and the MUTE returned from dbus method is %i", initial_mute); +} + +static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) { - g_debug("signal caught - sink input while muted with index %i and value %i", sink_index, value); + g_debug("signal caught - sink input while muted with value %i", block_value); } static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) @@ -235,16 +264,12 @@ static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_pe static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata) { //We can be sure the service won't send a mute signal unless it has changed ! + //UNMUTE's force a volume update therefore icon is updated appropriately => no need for unmute handling here. if(mute_value == TRUE) { + g_debug("signal caught - sink mute update - MUTE"); update_state(STATE_MUTED); } - else - { - g_debug("signal caught - sink mute update - about to mute state"); - revert_state(); - } - g_debug("signal caught - sink mute update with mute_value %i", mute_value); } @@ -287,24 +312,31 @@ get_icon (IndicatorObject * io) static void update_state(const gint state) { + g_debug("update state beginning - previous_state = %i", previous_state); + previous_state = current_state; + + g_debug("update state 3rd line - previous_state = %i", previous_state); + current_state = state; gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); } -static void revert_state() -{ +/*static void revert_state()*/ +/*{*/ - current_state = previous_state; - gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); - g_debug("after reverting back to previous state of %i", current_state); -} +/* g_debug("revert state beginning - previous_state = %i", previous_state);*/ +/* current_state = previous_state;*/ +/* gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state));*/ +/* gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU);*/ +/* g_debug("after reverting back to previous state of %i", current_state);*/ +/*}*/ static void determine_state_from_volume(gdouble volume_percent) { - gint state = 0; + g_debug("determine_state_from_volume - previous_state = %i", previous_state); + gint state = previous_state; if (volume_percent < 30.0 && volume_percent > 0){ state = STATE_LOW; } @@ -375,8 +407,6 @@ static gboolean slider_value_changed_event_cb(GtkRange *range, GtkScrollType scr g_value_init(&value, G_TYPE_DOUBLE); g_value_set_double(&value, clamped_input); dbusmenu_menuitem_handle_event (item, "slider_change", &value, 0); -/* change_speaker_image(slider_value);*/ -/* }*/ return FALSE; } diff --git a/src/pulse-manager.c b/src/pulse-manager.c index ae7961a..43a6f9f 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -62,15 +62,15 @@ static void destroy_sink_info(void *value) g_free(sink); } -static void test_hash(){ - guint size = 0; - size = g_hash_table_size(sink_hash); - g_debug("Size of hash = %i", size); - sink_info *s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(DEFAULT_SINK_INDEX)); - g_debug("The name of our sink is %s", s->name); - g_debug("and the max volume is %f", (gdouble)s->base_volume); +/*static void test_hash(){*/ +/* guint size = 0;*/ +/* size = g_hash_table_size(sink_hash);*/ +/* g_debug("Size of hash = %i", size);*/ +/* sink_info *s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(DEFAULT_SINK_INDEX)); */ +/* g_debug("The name of our sink is %s", s->name); */ +/* g_debug("and the max volume is %f", (gdouble)s->base_volume); */ -} +/*}*/ /* Controllers & Utilities @@ -103,9 +103,13 @@ static void check_sink_input_while_muted_event(gint sink_index) if (default_sink_is_muted(sink_index) == TRUE) { g_debug("SINKINPUTWHILEMUTED SIGNAL EVENT TO BE SENT FROM PA MANAGER"); - sound_service_dbus_sink_input_while_muted (dbus_service, sink_index, TRUE); + sound_service_dbus_sink_input_while_muted (dbus_service, TRUE); + } + else + { + // TODO is this overkill - signal will be sent alot + sound_service_dbus_sink_input_while_muted(dbus_service, FALSE); } - return; } static gdouble get_default_sink_volume() @@ -189,9 +193,8 @@ static void context_success_callback(pa_context *c, int success, void *userdata) /** On Service startup this callback will be called multiple times resulting our sinks_hash container to be filled with the available sinks. -key -> index -value -> sink_info -For now this callback it assumes it only used at startup. It may be necessary to use if sinks become available after startup +For now this callback it assumes it only used at startup. It may be necessary to use if sinks become available after startup. +Major candidate for refactoring. **/ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, int eol, void *userdata) { @@ -201,9 +204,12 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in { // Hopefully the PA server has set the default device if not default to 0 DEFAULT_SINK_INDEX = (DEFAULT_SINK_INDEX < 0) ? 0 : DEFAULT_SINK_INDEX; - test_hash(); + // TODO optimize + // Cache method returns! (unneccessary multiple utility calls) + // test_hash(); 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); } else{ @@ -304,14 +310,10 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v update_mute_ui(s->mute); } - else{ - // Reset the ui flag - // TODO: there must be a nicer way to do this - I suspect this pattern could introduce race conditions !!! - g_debug("SKIPPED UPDATING UI BECAUSE THE UI_NEEDS_UPDATE WAS FALSE!"); - } } 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); diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 00a2692..4a4a3c7 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -32,6 +32,7 @@ // DBUS methods - // TODO - other should be static and moved from the header to here 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); #include "sound-service-server.h" @@ -42,6 +43,7 @@ struct _SoundServiceDbusPrivate DBusGConnection *system_bus; DBusGConnection *connection; gdouble volume_percent; + gboolean mute; }; @@ -86,8 +88,8 @@ sound_service_dbus_class_init (SoundServiceDbusClass *klass) G_SIGNAL_RUN_LAST, 0, NULL, NULL, - _sound_service_marshal_VOID__INT_BOOLEAN, - G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_BOOLEAN); + 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), @@ -167,20 +169,25 @@ static gboolean sound_service_dbus_get_sink_volume (SoundServiceDbus *self, gdou 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; +} /** SIGNALS Utility methods to emit signals from the service into the ether. **/ -void sound_service_dbus_sink_input_while_muted(SoundServiceDbus* obj, gint sink_index, gboolean value) +void sound_service_dbus_sink_input_while_muted(SoundServiceDbus* obj, gboolean block_value) { -/* g_assert((num < LAST_SIGNAL) && (num >= 0));*/ - g_debug("Emitting signal: SINK_INPUT_WHILE_MUTED, with sink_index %i and value %i", sink_index, 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, - sink_index, - value); + block_value); } void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gdouble sink_volume) @@ -198,10 +205,14 @@ void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gdouble sink_v 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, - sink_mute); + priv->mute); } diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h index 3103d98..223f766 100644 --- a/src/sound-service-dbus.h +++ b/src/sound-service-dbus.h @@ -50,13 +50,14 @@ struct _SoundServiceDbus { 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); + // TODO - ARE THESE NECESSARY ? + void (* sink_input_while_muted) (SoundServiceDbus *self, gboolean block_value, gpointer sound_data); void (* sink_volume_update) (SoundServiceDbus *self, gdouble sink_volume, gpointer sound_data); }; 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_sink_input_while_muted (SoundServiceDbus* obj, gboolean block_value); void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gdouble sink_volume); void sound_service_dbus_update_sink_mute(SoundServiceDbus* obj, gboolean sink_mute); diff --git a/src/sound-service.xml b/src/sound-service.xml index 65d88ab..580f0e1 100644 --- a/src/sound-service.xml +++ b/src/sound-service.xml @@ -10,11 +10,15 @@ + + + + + - -- cgit v1.2.3