From fe11e6ad36166f9e5e7279ffc59249dd7788360a Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 16 Feb 2011 18:37:15 +0000 Subject: moving towards a voip input item --- src/Makefile.am | 4 +- src/active-sink.c | 17 ++++-- src/active-sink.h | 1 + src/common-defs.h | 3 ++ src/pulseaudio-mgr.c | 84 +++++++++++++++++++++++++++-- src/sound-service-dbus.c | 6 ++- src/sound-service-dbus.h | 3 +- src/sound-service.c | 2 + src/voip-input-menu-item.c | 130 +++++++++++++++++++++++++++++++++++++++++++++ src/voip-input-menu-item.h | 58 ++++++++++++++++++++ 10 files changed, 296 insertions(+), 12 deletions(-) create mode 100644 src/voip-input-menu-item.c create mode 100644 src/voip-input-menu-item.h diff --git a/src/Makefile.am b/src/Makefile.am index 23bda3d..228e6a3 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -85,7 +85,7 @@ music_bridge_vala.stamp $(music_bridge_APIFILES): $(music_bridge_VALASOURCES) # Sound Service C ############################### indicator_sound_service_SOURCES = \ - common-defs.h \ + common-defs.h \ sound-service.h \ sound-service.c \ pulseaudio-mgr.h \ @@ -96,6 +96,8 @@ indicator_sound_service_SOURCES = \ sound-service-dbus.c \ slider-menu-item.h \ slider-menu-item.c \ + voip-input-menu-item.h \ + voip-input-menu-item.c \ mute-menu-item.h \ mute-menu-item.c \ gen-sound-service.xml.h \ diff --git a/src/active-sink.c b/src/active-sink.c index b7954be..6b0063d 100644 --- a/src/active-sink.c +++ b/src/active-sink.c @@ -21,7 +21,7 @@ with this program. If not, see . #include "active-sink.h" #include "slider-menu-item.h" #include "mute-menu-item.h" - +#include "voip-input-menu-item.h" #include "pulseaudio-mgr.h" typedef struct _ActiveSinkPrivate ActiveSinkPrivate; @@ -30,7 +30,8 @@ struct _ActiveSinkPrivate { SliderMenuItem* volume_slider_menuitem; MuteMenuItem* mute_menuitem; - SoundState current_sound_state; + VoipInputMenuItem* voip_input_menu_item; + SoundState current_sound_state; SoundServiceDbus* service; gint index; gchar* name; @@ -72,6 +73,7 @@ active_sink_init (ActiveSink *self) ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); priv->mute_menuitem = NULL; priv->volume_slider_menuitem = NULL; + priv->voip_input_menu_item = NULL; priv->current_sound_state = UNAVAILABLE; priv->index = -1; priv->name = NULL; @@ -79,6 +81,7 @@ active_sink_init (ActiveSink *self) // Init our menu items. priv->mute_menuitem = g_object_new (MUTE_MENU_ITEM_TYPE, NULL); + priv->voip_input_menu_item = g_object_new (VOIP_INPUT_MENU_ITEM_TYPE, NULL);; priv->volume_slider_menuitem = slider_menu_item_new (self); mute_menu_item_enable (priv->mute_menuitem, FALSE); slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); @@ -279,6 +282,13 @@ active_sink_get_state (ActiveSink* self) return priv->current_sound_state; } +void +active_sink_update_voip_input_source (ActiveSink* self, const pa_source_info* update) +{ + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + +} + ActiveSink* active_sink_new (SoundServiceDbus* service) { @@ -287,7 +297,8 @@ active_sink_new (SoundServiceDbus* service) priv->service = service; sound_service_dbus_build_sound_menu (service, mute_menu_item_get_button (priv->mute_menuitem), - DBUSMENU_MENUITEM (priv->volume_slider_menuitem)); + DBUSMENU_MENUITEM (priv->volume_slider_menuitem), + DBUSMENU_MENUITEM (priv->voip_input_menu_item)); pm_establish_pulse_connection (sink); return sink; } diff --git a/src/active-sink.h b/src/active-sink.h index ab05ebc..6b13058 100644 --- a/src/active-sink.h +++ b/src/active-sink.h @@ -52,6 +52,7 @@ 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); gboolean active_sink_is_populated (ActiveSink* sink); void active_sink_determine_blocking_state (ActiveSink* self); diff --git a/src/common-defs.h b/src/common-defs.h index 63d9d40..1a6e435 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -38,6 +38,9 @@ typedef enum { #define DBUSMENU_VOLUME_MENUITEM_TYPE "x-canonical-ido-volume-type" #define DBUSMENU_VOLUME_MENUITEM_LEVEL "x-canonical-ido-volume-level" +#define DBUSMENU_VOIP_INPUT_MENUITEM_TYPE "x-canonical-ido-voip-input-type" +#define DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL "x-canonical-ido-voip-input-level" + #define DBUSMENU_MUTE_MENUITEM_TYPE "x-canonical-sound-menu-mute-type" #define DBUSMENU_MUTE_MENUITEM_VALUE "x-canonical-sound-menu-mute-value" diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index 3aed1f1..78feeb3 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -47,10 +47,18 @@ static void pm_default_sink_info_callback (pa_context *c, const pa_sink_info *info, int eol, void *userdata); +static void pm_default_source_info_callback (pa_context *c, + const pa_source_info *info, + int eol, + void *userdata); static void pm_sink_info_callback (pa_context *c, const pa_sink_info *sink, int eol, void *userdata); +static void pm_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, @@ -64,6 +72,7 @@ static void pm_toggle_mute_for_every_sink_callback (pa_context *c, int eol, void* userdata); + static gboolean reconnect_to_pulse (gpointer user_data); static gint connection_attempts = 0; @@ -187,7 +196,10 @@ pm_subscribed_events_callback (pa_context *c, 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) { + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + + } + else{ pa_operation_unref (pa_context_get_sink_input_info (c, index, pm_sink_input_info_callback, userdata)); @@ -276,24 +288,47 @@ pm_server_info_callback (pa_context *c, active_sink_deactivate (ACTIVE_SINK (userdata)); return; } + // Go for the default sink if (info->default_sink_name != NULL) { g_debug ("default sink name from the server ain't null'"); if (!(operation = pa_context_get_sink_info_by_name (c, info->default_sink_name, pm_default_sink_info_callback, userdata) )) { - } - else{ + g_warning("pa_context_get_sink_info_by_namet() failed"); + active_sink_deactivate (ACTIVE_SINK (userdata)); pa_operation_unref(operation); return; } - } + } // If there is no default sink, try to determine a sink from the list of sinks else if (!(operation = pa_context_get_sink_info_list(c, pm_sink_info_callback, - NULL))) { + userdata))) { g_warning("pa_context_get_sink_info_list() failed"); + active_sink_deactivate (ACTIVE_SINK (userdata)); + pa_operation_unref(operation); return; } + // And the source + if (info->default_source_name != NULL) { + g_debug ("default source name from the server is not null'"); + if (!(operation = pa_context_get_source_info_by_name (c, + info->default_source_name, + pm_default_source_info_callback, + userdata) )) { + g_warning("pa_context_get_default_source_info() failed"); + // TODO: call some input deactivate method on active sink + pa_operation_unref(operation); + return; + } + } + else if (!(operation = pa_context_get_source_info_list(c, + pm_source_info_callback, + userdata))) { + g_warning("pa_context_get_sink_info_list() failed"); + // TODO: call some input deactivate method on active sink + } + pa_operation_unref(operation); } @@ -356,6 +391,17 @@ pm_sink_input_info_callback (pa_context *c, g_warning("\n Sink input info callback : SINK INPUT INFO IS NULL BUT EOL was not POSITIVE!!!"); return; } + + 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 ("And yes its a VOIP app ..."); + } + //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; @@ -404,3 +450,31 @@ pm_toggle_mute_for_every_sink_callback (pa_context *c, } } +// Source info related callbacks +static void +pm_default_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; + } + g_debug ("server has handed us a default sink"); + //active_sink_update_source (ACTIVE_SINK (userdata), info); + } +} + +static void +pm_source_info_callback (pa_context *c, + const pa_source_info *info, + int eol, + void *userdata) +{ + +} \ No newline at end of file diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 58367f4..1acaebb 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -157,14 +157,16 @@ sound_service_dbus_create_root_item (SoundServiceDbus* self) void sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, DbusmenuMenuitem* mute_item, - DbusmenuMenuitem* slider_item) + DbusmenuMenuitem* slider_item, + DbusmenuMenuitem* voip_input_menu_item) { SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); // Mute button dbusmenu_menuitem_child_append (priv->root_menuitem, mute_item); - g_debug ("just about to add the slider %i", DBUSMENU_IS_MENUITEM(slider_item)); dbusmenu_menuitem_child_append (priv->root_menuitem, slider_item); + g_debug ("just about to add the slider %i", DBUSMENU_IS_MENUITEM(slider_item)); + dbusmenu_menuitem_child_append (priv->root_menuitem, voip_input_menu_item); // Separator DbusmenuMenuitem* separator = dbusmenu_menuitem_new(); diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h index cdc4608..9b19a5e 100644 --- a/src/sound-service-dbus.h +++ b/src/sound-service-dbus.h @@ -57,7 +57,8 @@ DbusmenuMenuitem* sound_service_dbus_create_root_item (SoundServiceDbus* self); void sound_service_dbus_update_sound_state (SoundServiceDbus* self, SoundState new_state); void sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, DbusmenuMenuitem* mute_item, - DbusmenuMenuitem* slider_item); + DbusmenuMenuitem* slider_item, + DbusmenuMenuitem* voip_input_menu_item); G_END_DECLS diff --git a/src/sound-service.c b/src/sound-service.c index cfc0b7e..9f44624 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -39,8 +39,10 @@ service_shutdown (IndicatorService *service, gpointer user_data) { if (mainloop != NULL) { g_debug("Service shutdown !"); +/* close_pulse_activites(); g_main_loop_quit(mainloop); +*/ } return; } diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c new file mode 100644 index 0000000..209629e --- /dev/null +++ b/src/voip-input-menu-item.c @@ -0,0 +1,130 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include "voip-input-menu-item.h" +#include "common-defs.h" + +typedef struct _VoipInputMenuItemPrivate VoipInputMenuItemPrivate; + +struct _VoipInputMenuItemPrivate { + ActiveSink* a_sink; +}; + +#define VOIP_INPUT_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemPrivate)) + +/* Prototypes */ +static void voip_input_menu_item_class_init (VoipInputMenuItemClass *klass); +static void voip_input_menu_item_init (VoipInputMenuItem *self); +static void voip_input_menu_item_dispose (GObject *object); +static void voip_input_menu_item_finalize (GObject *object); +static void handle_event (DbusmenuMenuitem * mi, const gchar * name, + GVariant * value, guint timestamp); + +G_DEFINE_TYPE (VoipInputMenuItem, voip_input_menu_item, DBUSMENU_TYPE_MENUITEM); + +static void +voip_input_menu_item_class_init (VoipInputMenuItemClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (VoipInputMenuItemPrivate)); + + object_class->dispose = voip_input_menu_item_dispose; + object_class->finalize = voip_input_menu_item_finalize; + + DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass); + mclass->handle_event = handle_event; +} + +static void +voip_input_menu_item_init (VoipInputMenuItem *self) +{ + g_debug("Building new Slider Menu Item"); + dbusmenu_menuitem_property_set( DBUSMENU_MENUITEM(self), + DBUSMENU_MENUITEM_PROP_TYPE, + DBUSMENU_VOIP_INPUT_MENUITEM_TYPE ); +} + +static void +voip_input_menu_item_dispose (GObject *object) +{ + G_OBJECT_CLASS (voip_input_menu_item_parent_class)->dispose (object); + return; +} + +static void +voip_input_menu_item_finalize (GObject *object) +{ + G_OBJECT_CLASS (voip_input_menu_item_parent_class)->finalize (object); +} + +static void +handle_event (DbusmenuMenuitem * mi, + const gchar * name, + GVariant * value, + guint timestamp) +{ + GVariant* input = NULL; + input = value; + if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT) == TRUE) { + input = g_variant_get_variant(value); + } + + gboolean volume_input = g_variant_get_double(input); + if (value != NULL){ + if (IS_VOIP_INPUT_MENU_ITEM (mi)) { + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (VOIP_INPUT_MENU_ITEM (mi)); + g_debug ("Handle event in the voip input level backend instance - %f", volume_input); + //active_sink_update_volume (priv->a_sink, volume_input); + //active_sink_ensure_sink_is_unmuted (priv->a_sink); + } + } +} + +void +voip_input_menu_item_update (VoipInputMenuItem* item, + gdouble update) +{ + 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_enable (VoipInputMenuItem* item, + gboolean active) +{ + dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item), + DBUSMENU_MENUITEM_PROP_VISIBLE, + active ); +} + +VoipInputMenuItem* +voip_input_menu_item_new (ActiveSink* sink) +{ + VoipInputMenuItem *self = g_object_new(VOIP_INPUT_MENU_ITEM_TYPE, NULL); + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (self); + priv->a_sink = sink; + return self; +} \ No newline at end of file diff --git a/src/voip-input-menu-item.h b/src/voip-input-menu-item.h new file mode 100644 index 0000000..296f22c --- /dev/null +++ b/src/voip-input-menu-item.h @@ -0,0 +1,58 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ +#ifndef __VOIP_INPUT_MENU_ITEM_H__ +#define __VOIP_INPUT_MENU_ITEM_H__ + +#include +#include + +#include +#include "active-sink.h" + +G_BEGIN_DECLS + +#define VOIP_INPUT_MENU_ITEM_TYPE (voip_input_menu_item_get_type ()) +#define VOIP_INPUT_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItem)) +#define VOIP_INPUT_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemClass)) +#define IS_VOIP_INPUT_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOIP_INPUT_MENU_ITEM_TYPE)) +#define IS_VOIP_INPUT_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOIP_INPUT_MENU_ITEM_TYPE)) +#define VOIP_INPUT_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemClass)) + +typedef struct _VoipInputMenuItem VoipInputMenuItem; +typedef struct _VoipInputMenuItemClass VoipInputMenuItemClass; + +struct _VoipInputMenuItemClass { + DbusmenuMenuitemClass parent_class; +}; + +struct _VoipInputMenuItem { + DbusmenuMenuitem parent; +}; + +GType voip_input_menu_item_get_type (void); + +void voip_input_menu_item_update(VoipInputMenuItem* item, gdouble update); +void voip_input_menu_item_enable(VoipInputMenuItem* item, gboolean active); + +VoipInputMenuItem* voip_input_menu_item_new (ActiveSink* sink); + +G_END_DECLS + +#endif + -- cgit v1.2.3