aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConor Curran <conor.curran@canonical.com>2010-02-08 14:42:30 +0000
committerConor Curran <conor.curran@canonical.com>2010-02-08 14:42:30 +0000
commitf9ef87f71c488f6791e32b1cf7205fb65db81ce8 (patch)
treea3891347530ef81463595a2332ede9fc5161c1b0
parent470e751be8af2da3bbc69a1115d2ce19590cac5a (diff)
downloadayatana-indicator-sound-f9ef87f71c488f6791e32b1cf7205fb65db81ce8.tar.gz
ayatana-indicator-sound-f9ef87f71c488f6791e32b1cf7205fb65db81ce8.tar.bz2
ayatana-indicator-sound-f9ef87f71c488f6791e32b1cf7205fb65db81ce8.zip
automatic volume updates in progress
-rw-r--r--src/common-defs.h2
-rw-r--r--src/indicator-sound.c9
-rw-r--r--src/pulse-manager.c59
-rw-r--r--src/sound-service-dbus.c18
-rw-r--r--src/sound-service-dbus.h2
-rw-r--r--src/sound-service.xml3
6 files changed, 89 insertions, 4 deletions
diff --git a/src/common-defs.h b/src/common-defs.h
index 6cacb49..a06b1b3 100644
--- a/src/common-defs.h
+++ b/src/common-defs.h
@@ -1,6 +1,6 @@
/* constants used for signals on the dbus. This file is shared between client and server implementation */
#define SIGNAL_SINK_INPUT_WHILE_MUTED "SinkInputWhileMuted"
-#define METHOD_SET_SINK_VOLUME "SetSinkVolume"
+#define SIGNAL_UPDATE_SINK_VOLUME "UpdateSinkVolume"
// DBUS items
#define DBUSMENU_SLIDER_MENUITEM_TYPE "x-canonical-ido-slider-item"
diff --git a/src/indicator-sound.c b/src/indicator-sound.c
index 2b20c48..9ceebd1 100644
--- a/src/indicator-sound.c
+++ b/src/indicator-sound.c
@@ -90,6 +90,7 @@ static gboolean slider_value_changed_event_cb(GtkRange *range, gpointer user_da
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);
+void catch_signal_sink_volume_update(DBusGProxy * proxy, gint sink_volume, gpointer userdata);
/****Volume States 'members' ***/
static const gint STATE_MUTED = 0;
@@ -192,6 +193,9 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u
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_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_UPDATE_SINK_VOLUME, G_TYPE_INT, G_TYPE_INVALID);
+ dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_UPDATE_SINK_VOLUME, G_CALLBACK(catch_signal_sink_volume_update), NULL, NULL);
+
}
} else {
@@ -207,6 +211,11 @@ static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gint sink_in
g_debug("signal caught - I don't believe it ! with index %i and value %i", sink_index, value);
}
+void catch_signal_sink_volume_update(DBusGProxy * proxy, gint sink_volume, gpointer userdata)
+{
+ g_debug("signal caught - update sink volume with value : %i", sink_volume);
+}
+
static void
indicator_sound_dispose (GObject *object)
{
diff --git a/src/pulse-manager.c b/src/pulse-manager.c
index dbf30a0..87f20ae 100644
--- a/src/pulse-manager.c
+++ b/src/pulse-manager.c
@@ -19,6 +19,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink_inf
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 destroy_sink_info(void *value);
/*
@@ -204,7 +205,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in
}
else{
- g_debug("About to add an item to our hash");
+ g_debug("About to add an item to our hash");
sink_info *value;
value = g_new0(sink_info, 1);
value->index = value->device_index = sink->index;
@@ -217,7 +218,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in
value->base_volume = sink->base_volume;
value->channel_map = sink->channel_map;
g_hash_table_insert(sink_hash, GINT_TO_POINTER(sink->index), value);
- g_debug("After adding an item to our hash");
+ g_debug("After adding an item to our hash");
}
}
@@ -254,7 +255,54 @@ static void pulse_sink_input_info_callback(pa_context *c, const pa_sink_input_in
g_debug("\n SINK INPUT INFO sink index : %d \n", info->sink);
check_sink_input_while_muted_event(info->sink);
}
-}
+}
+
+static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, void *userdata)
+{
+ if (eol > 0) {
+ if (pa_context_errno(c) == PA_ERR_NOENTITY)
+ return;
+ g_warning("Sink INPUT info callback failure");
+ return;
+ }
+
+ GList *keys = g_hash_table_get_keys(sink_hash);
+ gint position = g_list_index(keys, GINT_TO_POINTER(info->index));
+/* gboolean update_ui_vol = FALSE;*/
+ if(position >= 0) // => index is within the keys of the hash.
+ {
+ // TODO : update sinks hash with new details and if default send over dbus the update. in reverse order.
+ //gint sink_index = GPOINTER_TO_INT(g_list_nth_data(keys, position));
+ sink_info *s = g_hash_table_lookup(sink_hash, GINT_TO_POINTER(info->index));
+ g_debug("attempting to update sink with name %s", s->name);
+ s->name = g_strdup(info->name);
+ 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);
+ s->mute = !!info->mute;
+/* int equal = pa_cvolume_equal(&s->volume, &info->volume);*/
+/* update_ui_vol = (equal != 0); */
+/* g_debug("Are the volumes the same %i", equal); */
+ s->volume = info->volume;
+ s->base_volume = info->base_volume;
+ s->channel_map = info->channel_map;
+ if(DEFAULT_SINK_INDEX == s->index/* && update_ui_vol == TRUE*/)
+ {
+ //update the UI
+ pa_volume_t vol = pa_cvolume_avg(&s->volume);
+ g_debug("about to update ui with linear volume of %f", pa_sw_volume_to_linear(vol));
+ sound_service_dbus_update_sink_volume(dbus_service, vol * 100);
+ }
+ }
+ else
+ {
+ 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.
+ }
+}
+
static void pulse_server_info_callback(pa_context *c, const pa_server_info *info, void *userdata)
{
@@ -290,6 +338,11 @@ static void pulse_server_info_callback(pa_context *c, const pa_server_info *info
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
+ } else {
+ pa_operation_unref(pa_context_get_sink_info_by_index(c, index, update_sink_info, userdata));
+ }
//g_debug("Event sink for %i", index);
break;
case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c
index 5e22dae..9a325fe 100644
--- a/src/sound-service-dbus.c
+++ b/src/sound-service-dbus.c
@@ -43,6 +43,7 @@ struct _SoundServiceDbusPrivate
/* Signals */
enum {
SINK_INPUT_WHILE_MUTED,
+ SINK_VOLUME_UPDATE,
LAST_SIGNAL
};
@@ -81,6 +82,14 @@ sound_service_dbus_class_init (SoundServiceDbusClass *klass)
NULL, NULL,
_sound_service_marshal_VOID__INT_BOOLEAN,
G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_BOOLEAN);
+
+ signals[SINK_VOLUME_UPDATE] = g_signal_new("sink-volume-update",
+ G_TYPE_FROM_CLASS (klass),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__INT,
+ G_TYPE_NONE, 1, G_TYPE_INT);
}
/**
@@ -116,6 +125,15 @@ void sound_service_dbus_sink_input_while_muted(SoundServiceDbus* obj, gint sink_
value);
}
+void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gint sink_volume)
+{
+ g_debug("Emitting signal: UPDATE_SINK_VOLUME, with sink_volme %i", sink_volume);
+ g_signal_emit(obj,
+ signals[SINK_VOLUME_UPDATE],
+ 0,
+ sink_volume);
+}
+
void set_pa_sinks_hash(SoundServiceDbus *self, GHashTable *sinks)
{
SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self);
diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h
index eea6d26..bb4fbe8 100644
--- a/src/sound-service-dbus.h
+++ b/src/sound-service-dbus.h
@@ -51,12 +51,14 @@ 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);
+ void (* sink_volume_update) (SoundServiceDbus *self, gint sink_volume);
};
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_update_sink_volume(SoundServiceDbus* obj, gint sink_volume);
void set_pa_sinks_hash(SoundServiceDbus *self, GHashTable *sinks);
// DBUS METHODS
diff --git a/src/sound-service.xml b/src/sound-service.xml
index 26d83e5..0a35690 100644
--- a/src/sound-service.xml
+++ b/src/sound-service.xml
@@ -13,6 +13,9 @@ Our respective UI element should listen to this and therefore will be updated wi
<arg name="sink_index" type="x" direction="out"/>
<arg name="mute_value" type="b" direction="out"/>
</signal>
+ <signal name="SinkVolumeUpdate">
+ <arg name="volume_percent" type="x" direction="out"/>
+ </signal>
</interface>
</node>