aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConor Curran <conor.curran@canonical.com>2010-02-10 11:33:36 +0000
committerConor Curran <conor.curran@canonical.com>2010-02-10 11:33:36 +0000
commitb51a53a2f2c6cbe23d4f6269360699e225bd30aa (patch)
tree83aa9969c1b85175bda295c29d4c208075301f7a
parentd15e61753ff8d715f60d074eb280bdb89d8f00ee (diff)
downloadayatana-indicator-sound-b51a53a2f2c6cbe23d4f6269360699e225bd30aa.tar.gz
ayatana-indicator-sound-b51a53a2f2c6cbe23d4f6269360699e225bd30aa.tar.bz2
ayatana-indicator-sound-b51a53a2f2c6cbe23d4f6269360699e225bd30aa.zip
mute init/revert now working properly plus dbus signal tidy up on the blocking message
-rw-r--r--src/indicator-sound.c100
-rw-r--r--src/pulse-manager.c40
-rw-r--r--src/sound-service-dbus.c27
-rw-r--r--src/sound-service-dbus.h5
-rw-r--r--src/sound-service.xml6
5 files changed, 113 insertions, 65 deletions
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 @@
<arg type='d' name='volume_percent_input' direction="out"/>
</method>
+ <method name = "GetSinkMute">
+ <annotation name="org.freedesktop.DBus.GLib.CSymbol" value="sound_service_dbus_get_sink_mute"/>
+ <arg type='b' name='mute_input' direction="out"/>
+ </method>
+
<!-- Will need to hook up another signal which monitors for volume change
Our respective UI element should listen to this and therefore will be updated with accurate setting-->
<!-- Triggered when a sink is muted but the input has been sent to that sink -->
<signal name="SinkInputWhileMuted">
- <arg name="sink_index" type="x" direction="out"/>
<arg name="block_value" type="b" direction="out"/>
</signal>