aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorConor Curran <conor.curran@canonical.com>2011-02-17 15:17:31 +0000
committerConor Curran <conor.curran@canonical.com>2011-02-17 15:17:31 +0000
commitc1fdbb5237dd04d6508fafc7d4af67645d4c66c5 (patch)
tree5c84250d8132f71c9db5f3f5d843d00e20a3ccf6
parent3c5c6dc46b738371bd2c0d6afe12f5a9bb168cf6 (diff)
downloadayatana-indicator-sound-c1fdbb5237dd04d6508fafc7d4af67645d4c66c5.tar.gz
ayatana-indicator-sound-c1fdbb5237dd04d6508fafc7d4af67645d4c66c5.tar.bz2
ayatana-indicator-sound-c1fdbb5237dd04d6508fafc7d4af67645d4c66c5.zip
back end plugged together for proof of concept
-rw-r--r--src/active-sink.c28
-rw-r--r--src/active-sink.h9
-rw-r--r--src/pulseaudio-mgr.c99
-rw-r--r--src/voip-input-menu-item.c62
-rw-r--r--src/voip-input-menu-item.h8
5 files changed, 162 insertions, 44 deletions
diff --git a/src/active-sink.c b/src/active-sink.c
index 6b0063d..4cf8dc0 100644
--- a/src/active-sink.c
+++ b/src/active-sink.c
@@ -87,6 +87,21 @@ active_sink_init (ActiveSink *self)
slider_menu_item_enable (priv->volume_slider_menuitem, FALSE);
}
+void
+active_sink_activate_voip_item (ActiveSink* self)
+{
+ ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self);
+ voip_input_menu_item_enable (priv->voip_input_menu_item, TRUE);
+}
+
+void
+active_sink_deactivate_voip_source (ActiveSink* self)
+{
+ ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self);
+ voip_input_menu_item_enable (priv->voip_input_menu_item, FALSE);
+}
+
+
static void
active_sink_dispose (GObject *object)
{
@@ -286,7 +301,20 @@ void
active_sink_update_voip_input_source (ActiveSink* self, const pa_source_info* update)
{
ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self);
+ voip_input_menu_item_update (priv->voip_input_menu_item, update);
+}
+gboolean
+active_sink_is_voip_source_populated (ActiveSink* self)
+{
+ ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self);
+ return voip_input_menu_item_is_populated (priv->voip_input_menu_item);
+}
+
+gint active_sink_get_source_index (ActiveSink* self)
+{
+ ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self);
+ return voip_input_menu_item_get_index (priv->voip_input_menu_item);
}
ActiveSink*
diff --git a/src/active-sink.h b/src/active-sink.h
index 6b13058..5c6b31a 100644
--- a/src/active-sink.h
+++ b/src/active-sink.h
@@ -52,16 +52,21 @@ GType active_sink_get_type (void) G_GNUC_CONST;
void active_sink_populate (ActiveSink* sink, const pa_sink_info* update);
void active_sink_update (ActiveSink* sink, const pa_sink_info* update);
-void active_sink_update_voip_input (ActiveSink* sink, const pa_source_info* update);
+void active_sink_update_voip_input_source (ActiveSink* sink, const pa_source_info* update);
+void active_sink_activate_voip_item (ActiveSink* sink);
+gboolean active_sink_is_voip_source_populated (ActiveSink* sink);
gboolean active_sink_is_populated (ActiveSink* sink);
+
void active_sink_determine_blocking_state (ActiveSink* self);
gint active_sink_get_index (ActiveSink* self);
+gint active_sink_get_source_index (ActiveSink* self);
+
SoundState active_sink_get_state (ActiveSink* self);
void active_sink_deactivate (ActiveSink* self);
-
+void active_sink_deactivate_voip_source (ActiveSink* self);
void active_sink_update_mute (ActiveSink* self, gboolean mute_update);
void active_sink_update_volume (ActiveSink* self, gdouble percent);
void active_sink_ensure_sink_is_unmuted (ActiveSink* self);
diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c
index 78feeb3..05b2c8e 100644
--- a/src/pulseaudio-mgr.c
+++ b/src/pulseaudio-mgr.c
@@ -59,6 +59,10 @@ static void pm_source_info_callback (pa_context *c,
const pa_source_info *info,
int eol,
void *userdata);
+static void pm_update_source_info_callback (pa_context *c,
+ const pa_source_info *info,
+ int eol,
+ void *userdata);
static void pm_sink_input_info_callback (pa_context *c,
const pa_sink_input_info *info,
int eol,
@@ -172,19 +176,21 @@ pm_subscribed_events_callback (pa_context *c,
uint32_t index,
void* userdata)
{
+ if (IS_ACTIVE_SINK (userdata) == FALSE){
+ g_critical ("subscribed events callback - our userdata is not what we think it should be");
+ return;
+ }
+ ActiveSink* sink = ACTIVE_SINK (userdata);
+
switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
case PA_SUBSCRIPTION_EVENT_SINK:
- if (IS_ACTIVE_SINK (userdata) == FALSE){
- g_warning ("subscribed events callback - our userdata is not what we think it should be");
- return;
- }
- ActiveSink* sink = ACTIVE_SINK (userdata);
+
// We don't care about any other sink other than the active one.
if (index != active_sink_get_index (sink))
- return;
+ return;
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
- active_sink_deactivate (ACTIVE_SINK (userdata));
+ active_sink_deactivate (sink);
}
else{
@@ -194,12 +200,27 @@ pm_subscribed_events_callback (pa_context *c,
userdata) );
}
break;
+ case PA_SUBSCRIPTION_EVENT_SOURCE:
+ // We don't care about any other sink other than the active one.
+ if (index != active_sink_get_source_index (sink))
+ return;
+ if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
+ active_sink_deactivate_voip_source (sink);
+ }
+ else{
+ pa_operation_unref (pa_context_get_source_info_by_index (c,
+ index,
+ pm_update_source_info_callback,
+ userdata) );
+ }
+ break;
case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
// We don't care about sink input removals.
if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) {
-
+ g_debug ("Just saw a sink input removal event");
}
- else{
+ else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) {
+ // Determine if its a VOIP app or a maybe blocking state.
pa_operation_unref (pa_context_get_sink_input_info (c,
index,
pm_sink_input_info_callback, userdata));
@@ -256,6 +277,7 @@ pm_context_state_callback (pa_context *c, void *userdata)
if (!(o = pa_context_subscribe (c, (pa_subscription_mask_t)
(PA_SUBSCRIPTION_MASK_SINK|
+ PA_SUBSCRIPTION_MASK_SOURCE|
PA_SUBSCRIPTION_MASK_SINK_INPUT|
PA_SUBSCRIPTION_MASK_SERVER), NULL, NULL))) {
g_warning("pa_context_subscribe() failed");
@@ -273,7 +295,8 @@ pm_context_state_callback (pa_context *c, void *userdata)
/**
After startup we go straight for the server info to see if it has details of
- the default sink. If so it makes things much easier.
+ the default sink and source. Normally these are valid, if there is none set
+ fetch the list of each and try to determine the sink.
**/
static void
pm_server_info_callback (pa_context *c,
@@ -326,9 +349,8 @@ pm_server_info_callback (pa_context *c,
pm_source_info_callback,
userdata))) {
g_warning("pa_context_get_sink_info_list() failed");
- // TODO: call some input deactivate method on active sink
+ // TODO: call some input deactivate method for the source
}
-
pa_operation_unref(operation);
}
@@ -392,21 +414,28 @@ pm_sink_input_info_callback (pa_context *c,
return;
}
+ if (IS_ACTIVE_SINK (userdata) == FALSE){
+ g_warning ("sink input info callback - our user data is not what we think it should be");
+ return;
+ }
+ // Check if this is Voip sink input
gint result = pa_proplist_contains (info->proplist, PA_PROP_MEDIA_ROLE);
if (result == 1){
g_debug ("Sink input info has media role property");
const char* value = pa_proplist_gets (info->proplist, PA_PROP_MEDIA_ROLE);
- if (g_strcmp0 (value, "phone")) {
+ g_debug ("prop role = %s", value);
+ if (g_strcmp0 (value, "phone") == 0) {
g_debug ("And yes its a VOIP app ...");
+ // TODO to start with we will assume our source is the same as what this 'client'
+ // is pointing at. This should probably be more intelligent :
+ // query for the list of source output info's and going on the name of the client
+ // from the sink input ensure our voip item is using the right source.
+
}
//g_free (value);
}
- if (IS_ACTIVE_SINK (userdata) == FALSE){
- g_warning ("sink input info callback - our user data is not what we think it should be");
- return;
- }
-
+ // And finally check for the mute blocking state
ActiveSink* a_sink = ACTIVE_SINK (userdata);
if (active_sink_get_index (a_sink) == info->sink){
active_sink_determine_blocking_state (a_sink);
@@ -465,8 +494,8 @@ pm_default_source_info_callback (pa_context *c,
g_warning ("Default sink info callback - our user data is not what we think it should be");
return;
}
- g_debug ("server has handed us a default sink");
- //active_sink_update_source (ACTIVE_SINK (userdata), info);
+ g_debug ("server has handed us a default source");
+ active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info);
}
}
@@ -476,5 +505,35 @@ pm_source_info_callback (pa_context *c,
int eol,
void *userdata)
{
+ if (eol > 0) {
+ return;
+ }
+ else {
+ if (IS_ACTIVE_SINK (userdata) == FALSE){
+ g_warning ("Default sink info callback - our user data is not what we think it should be");
+ return;
+ }
+ // For now we will take the first available
+ if (active_sink_is_voip_source_populated (ACTIVE_SINK (userdata)) == FALSE){
+ active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info);
+ }
+ }
+}
+static void
+pm_update_source_info_callback (pa_context *c,
+ const pa_source_info *info,
+ int eol,
+ void *userdata)
+{
+ if (eol > 0) {
+ return;
+ }
+ else {
+ if (IS_ACTIVE_SINK (userdata) == FALSE){
+ g_warning ("Default sink info callback - our user data is not what we think it should be");
+ return;
+ }
+ active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info);
+ }
} \ No newline at end of file
diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c
index 51ddd95..e904503 100644
--- a/src/voip-input-menu-item.c
+++ b/src/voip-input-menu-item.c
@@ -1,5 +1,5 @@
/*
-Copyright 2010 Canonical Ltd.
+Copyright 2011 Canonical Ltd.
Authors:
Conor Curran <conor.curran@canonical.com>
@@ -33,6 +33,8 @@ struct _VoipInputMenuItemPrivate {
guint32 volume_steps;
pa_channel_map channel_map;
pa_volume_t base_volume;
+ gint index;
+ gint sink_input_index;
};
#define VOIP_INPUT_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemPrivate))
@@ -68,6 +70,12 @@ voip_input_menu_item_init (VoipInputMenuItem *self)
dbusmenu_menuitem_property_set( DBUSMENU_MENUITEM(self),
DBUSMENU_MENUITEM_PROP_TYPE,
DBUSMENU_VOIP_INPUT_MENUITEM_TYPE );
+ VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (self);
+ dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(self),
+ DBUSMENU_MENUITEM_PROP_VISIBLE,
+ FALSE );
+
+ priv->index = -1;
}
static void
@@ -107,40 +115,58 @@ handle_event (DbusmenuMenuitem * mi,
}
void
-voip_input_menu_item_update_(VoipInputMenuItem* item,
+voip_input_menu_item_update (VoipInputMenuItem* item,
const pa_source_info* source)
{
+ VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item);
+ // only overwrite the constants of each source if the device has changed
+ if (priv->index != source->index){
+ priv->base_volume = source->base_volume;
+ priv->volume_steps = source->n_volume_steps;
+ priv->channel_map = source->channel_map;
+ }
+ priv->volume = source->volume;
+ priv->mute = source->mute;
+/*
+ GVariant* new_volume = g_variant_new_double(update);
+ dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(item),
+ DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL,
+ new_volume);
+*/
}
-void
-voip_input_menu_item_update_source_details (VoipInputMenuItem* item,
- const pa_source_info* source)
+gboolean
+voip_input_menu_item_is_populated (VoipInputMenuItem* item)
{
VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item);
- priv->base_volume = source->base_volume;
- priv->volume_steps = source->n_volume_steps;
- priv->channel_map = source->channel_map;
- priv->volume = source->volume;
- priv->mute = source->mute;
+ return priv->index != -1;
}
+gint
+voip_input_menu_item_get_index (VoipInputMenuItem* item)
+{
+ VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item);
+ return priv->index;
+}
-/*
-voip_input_menu_item_update (VoipInputMenuItem* item,
- gdouble update)
+void
+voip_input_menu_item_deactivate (VoipInputMenuItem* item)
{
- GVariant* new_volume = g_variant_new_double(update);
- dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(item),
- DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL,
- new_volume);
+ VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item);
+ priv->index = -1;
}
-*/
void
voip_input_menu_item_enable (VoipInputMenuItem* item,
gboolean active)
{
+ VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item);
+ if (priv->index != -1){
+ if (active == TRUE)
+ g_warning ("Tried to enable the VOIP menuitem but we don't have an active source");
+ active = FALSE;
+ }
dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item),
DBUSMENU_MENUITEM_PROP_VISIBLE,
active );
diff --git a/src/voip-input-menu-item.h b/src/voip-input-menu-item.h
index ad70289..70dc9fa 100644
--- a/src/voip-input-menu-item.h
+++ b/src/voip-input-menu-item.h
@@ -1,5 +1,5 @@
/*
-Copyright 2010 Canonical Ltd.
+Copyright 2011 Canonical Ltd.
Authors:
Conor Curran <conor.curran@canonical.com>
@@ -48,10 +48,10 @@ GType voip_input_menu_item_get_type (void);
void voip_input_menu_item_update (VoipInputMenuItem* item,
const pa_source_info* source);
-void voip_input_menu_item_update_source_details (VoipInputMenuItem* item,
- const pa_source_info* source);
-
void voip_input_menu_item_enable (VoipInputMenuItem* item, gboolean active);
+gboolean voip_input_menu_item_is_populated (VoipInputMenuItem* item);
+gint voip_input_menu_item_get_index (VoipInputMenuItem* item);
+void voip_input_menu_item_deactivate (VoipInputMenuItem* item);
VoipInputMenuItem* voip_input_menu_item_new (ActiveSink* sink);