From e49d9d7a50ceed482551c8197434ea01ab56e62c Mon Sep 17 00:00:00 2001 From: Ken VanDine Date: Fri, 11 Feb 2011 10:21:00 -0500 Subject: ported to libnotify >= 0.7 --- configure.ac | 2 +- src/indicator-sound.c | 2 -- src/sound-state-manager.c | 12 +----------- src/sound-state-manager.h | 2 -- 4 files changed, 2 insertions(+), 16 deletions(-) diff --git a/configure.ac b/configure.ac index d42f574..7788c58 100644 --- a/configure.ac +++ b/configure.ac @@ -35,7 +35,7 @@ PULSE_AUDIO_REQUIRED_VERSION=0.9.19 INDICATOR_DISPLAY_OBJECTS=0.1.11 DBUSMENUGLIB_REQUIRED_VERSION=0.3.9 GIO_2_0_REQUIRED_VERSION=2.25.13 -LIBNOTIFY_REQUIRED_VERSION=0.5.0 +LIBNOTIFY_REQUIRED_VERSION=0.7.0 PKG_CHECK_MODULES(APPLET, gtk+-2.0 >= $GTK_REQUIRED_VERSION indicator >= $INDICATOR_REQUIRED_VERSION diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 7e5ebc7..96ab89b 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -401,8 +401,6 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, newitem, menu_volume_item, parent); - sound_state_manager_attach_notification_to_volume_widget (priv->state_manager, - volume_widget); return TRUE; } diff --git a/src/sound-state-manager.c b/src/sound-state-manager.c index a592711..0958763 100644 --- a/src/sound-state-manager.c +++ b/src/sound-state-manager.c @@ -151,22 +151,12 @@ sound_state_manager_notification_init (SoundStateManager* self) } if (has_notify_osd) { - priv->notification = notify_notification_new(PACKAGE_NAME, NULL, NULL, NULL); + priv->notification = notify_notification_new(PACKAGE_NAME, NULL, NULL); notify_notification_set_hint_string(priv->notification, "x-canonical-private-synchronous", ""); } } -void -sound_state_manager_attach_notification_to_volume_widget (SoundStateManager *self, - GtkWidget* volume_widget) -{ - SoundStateManagerPrivate* priv = SOUND_STATE_MANAGER_GET_PRIVATE(self); - if (priv->notification) - notify_notification_attach_to_widget(priv->notification, volume_widget); -} - - void sound_state_manager_show_notification (SoundStateManager *self, double value) diff --git a/src/sound-state-manager.h b/src/sound-state-manager.h index 0b919cb..9287897 100644 --- a/src/sound-state-manager.h +++ b/src/sound-state-manager.h @@ -61,8 +61,6 @@ void sound_state_manager_get_state_cb (GObject *object, void sound_state_manager_show_notification (SoundStateManager *self, double value); -void sound_state_manager_attach_notification_to_volume_widget (SoundStateManager *self, - GtkWidget* volume_widget); G_END_DECLS -- cgit v1.2.3 From f21b7129d4758ad7a187a2375b9c65cf20d2e70f Mon Sep 17 00:00:00 2001 From: Ken VanDine Date: Fri, 11 Feb 2011 10:22:10 -0500 Subject: updated to handle the Dbusmenu-Glib-0.4 rename to Dbusmenu-0.4 --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Makefile.am b/src/Makefile.am index 63d6d5a..23bda3d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -65,7 +65,7 @@ music_bridge_VALAFLAGS = \ --vapidir=./ \ --thread \ --pkg gee-1.0 \ - --pkg Dbusmenu-Glib-0.4 \ + --pkg Dbusmenu-0.4 \ --pkg common-defs \ --pkg gio-2.0 \ --pkg gio-unix-2.0 \ -- cgit v1.2.3 From 60c1b7158a58e89c9a1a57eae17028fb4f9f4425 Mon Sep 17 00:00:00 2001 From: Luke Yelavich Date: Mon, 14 Feb 2011 17:39:57 +1100 Subject: Add accessible_desc support --- po/POTFILES.in | 1 + src/indicator-sound.c | 18 +++++++++++++++++- src/volume-widget.c | 22 ++++++++++++++++++++-- src/volume-widget.h | 3 ++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 9cceace..2f68d1a 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,3 +1,4 @@ [encoding: UTF-8] +src/indicator-sound.c src/mute-menu-item.c src/sound-service-dbus.c diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 7e5ebc7..e390623 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -20,6 +20,7 @@ with this program. If not, see . #include #include #include +#include #include #include #include @@ -66,6 +67,7 @@ G_DEFINE_TYPE (IndicatorSound, indicator_sound, INDICATOR_OBJECT_TYPE); static GtkLabel * get_label (IndicatorObject * io); static GtkImage * get_icon (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); +static const gchar * get_accessible_desc (IndicatorObject * io); static void indicator_sound_scroll (IndicatorObject* io, gint delta, IndicatorScrollDirection direction); @@ -117,6 +119,7 @@ indicator_sound_class_init (IndicatorSoundClass *klass) io_class->get_label = get_label; io_class->get_image = get_icon; io_class->get_menu = get_menu; + io_class->get_accessible_desc = get_accessible_desc; io_class->scroll = indicator_sound_scroll; } @@ -207,6 +210,19 @@ get_menu (IndicatorObject * io) return GTK_MENU(menu); } +static const gchar * +get_accessible_desc (IndicatorObject * io) +{ + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(io); + + if (priv->volume_widget != NULL){ + return g_strdup_printf(_("Volume (%'.0f%%)"), volume_widget_get_current_volume(priv->volume_widget)); + } + + return NULL; +} + + static void connection_changed (IndicatorServiceManager * sm, gboolean connected, @@ -382,8 +398,8 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - volume_widget = volume_widget_new (newitem); io = g_object_get_data (G_OBJECT (client), "indicator"); + volume_widget = volume_widget_new (newitem, io); IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); priv->volume_widget = volume_widget; diff --git a/src/volume-widget.c b/src/volume-widget.c index ceebec5..247dfe6 100644 --- a/src/volume-widget.c +++ b/src/volume-widget.c @@ -37,6 +37,7 @@ struct _VolumeWidgetPrivate DbusmenuMenuitem* twin_item; GtkWidget* ido_volume_slider; gboolean grabbed; + IndicatorObject* indicator; }; #define VOLUME_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOLUME_WIDGET_TYPE, VolumeWidgetPrivate)) @@ -137,6 +138,11 @@ volume_widget_property_update( DbusmenuMenuitem* item, gchar* property, gdouble update = g_variant_get_double (value); //g_debug("volume-widget - update level with value %f", update); gtk_range_set_value(range, update); + g_signal_emit(G_OBJECT(priv->indicator), + INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, + 0, + (IndicatorObjectEntry *)indicator_object_get_entries(INDICATOR_OBJECT(priv->indicator))->data, + TRUE); } } } @@ -156,6 +162,11 @@ volume_widget_set_twin_item(VolumeWidget* self, GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); GtkRange *range = (GtkRange*)slider; gtk_range_set_value(range, initial_level); + g_signal_emit(G_OBJECT(priv->indicator), + INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, + 0, + (IndicatorObjectEntry *)indicator_object_get_entries(INDICATOR_OBJECT(priv->indicator))->data, + TRUE); } static gboolean @@ -196,6 +207,11 @@ volume_widget_update(VolumeWidget* self, gdouble update) gdouble clamped = CLAMP(update, 0, 100); GVariant* new_volume = g_variant_new_double(clamped); dbusmenu_menuitem_handle_event (priv->twin_item, "update", new_volume, 0); + g_signal_emit(G_OBJECT(priv->indicator), + INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, + 0, + (IndicatorObjectEntry *)indicator_object_get_entries(INDICATOR_OBJECT(priv->indicator))->data, + TRUE); } GtkWidget* @@ -251,10 +267,12 @@ volume_widget_get_current_volume ( GtkWidget *widget ) * volume_widget_new: * @returns: a new #VolumeWidget. **/ -GtkWidget* -volume_widget_new(DbusmenuMenuitem *item) +GtkWidget* +volume_widget_new(DbusmenuMenuitem *item, IndicatorObject* io) { GtkWidget* widget = g_object_new(VOLUME_WIDGET_TYPE, NULL); + VolumeWidgetPrivate* priv = VOLUME_WIDGET_GET_PRIVATE(VOLUME_WIDGET(widget)); + priv->indicator = io; volume_widget_set_twin_item((VolumeWidget*)widget, item); return widget; } diff --git a/src/volume-widget.h b/src/volume-widget.h index 072cfde..50ef377 100644 --- a/src/volume-widget.h +++ b/src/volume-widget.h @@ -22,6 +22,7 @@ with this program. If not, see . #include #include #include +#include G_BEGIN_DECLS @@ -44,7 +45,7 @@ struct _VolumeWidget { }; GType volume_widget_get_type (void) G_GNUC_CONST; -GtkWidget* volume_widget_new(DbusmenuMenuitem* twin_item); +GtkWidget* volume_widget_new(DbusmenuMenuitem *item, IndicatorObject* io); GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self); void volume_widget_update(VolumeWidget* self, gdouble update); void volume_widget_tidy_up (GtkWidget *widget); -- cgit v1.2.3 From 5d32cec559249cb0e3b0a85ecdc8e0a5dc1ab199 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 16 Feb 2011 11:20:21 +0000 Subject: reverted luke's work until indicator object is updated --- po/POTFILES.in | 1 - src/indicator-sound.c | 18 +----------------- src/volume-widget.c | 22 ++-------------------- src/volume-widget.h | 3 +-- 4 files changed, 4 insertions(+), 40 deletions(-) diff --git a/po/POTFILES.in b/po/POTFILES.in index 2f68d1a..9cceace 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -1,4 +1,3 @@ [encoding: UTF-8] -src/indicator-sound.c src/mute-menu-item.c src/sound-service-dbus.c diff --git a/src/indicator-sound.c b/src/indicator-sound.c index f020bb8..96ab89b 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -20,7 +20,6 @@ with this program. If not, see . #include #include #include -#include #include #include #include @@ -67,7 +66,6 @@ G_DEFINE_TYPE (IndicatorSound, indicator_sound, INDICATOR_OBJECT_TYPE); static GtkLabel * get_label (IndicatorObject * io); static GtkImage * get_icon (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); -static const gchar * get_accessible_desc (IndicatorObject * io); static void indicator_sound_scroll (IndicatorObject* io, gint delta, IndicatorScrollDirection direction); @@ -119,7 +117,6 @@ indicator_sound_class_init (IndicatorSoundClass *klass) io_class->get_label = get_label; io_class->get_image = get_icon; io_class->get_menu = get_menu; - io_class->get_accessible_desc = get_accessible_desc; io_class->scroll = indicator_sound_scroll; } @@ -210,19 +207,6 @@ get_menu (IndicatorObject * io) return GTK_MENU(menu); } -static const gchar * -get_accessible_desc (IndicatorObject * io) -{ - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(io); - - if (priv->volume_widget != NULL){ - return g_strdup_printf(_("Volume (%'.0f%%)"), volume_widget_get_current_volume(priv->volume_widget)); - } - - return NULL; -} - - static void connection_changed (IndicatorServiceManager * sm, gboolean connected, @@ -398,8 +382,8 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + volume_widget = volume_widget_new (newitem); io = g_object_get_data (G_OBJECT (client), "indicator"); - volume_widget = volume_widget_new (newitem, io); IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); priv->volume_widget = volume_widget; diff --git a/src/volume-widget.c b/src/volume-widget.c index 247dfe6..ceebec5 100644 --- a/src/volume-widget.c +++ b/src/volume-widget.c @@ -37,7 +37,6 @@ struct _VolumeWidgetPrivate DbusmenuMenuitem* twin_item; GtkWidget* ido_volume_slider; gboolean grabbed; - IndicatorObject* indicator; }; #define VOLUME_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOLUME_WIDGET_TYPE, VolumeWidgetPrivate)) @@ -138,11 +137,6 @@ volume_widget_property_update( DbusmenuMenuitem* item, gchar* property, gdouble update = g_variant_get_double (value); //g_debug("volume-widget - update level with value %f", update); gtk_range_set_value(range, update); - g_signal_emit(G_OBJECT(priv->indicator), - INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, - 0, - (IndicatorObjectEntry *)indicator_object_get_entries(INDICATOR_OBJECT(priv->indicator))->data, - TRUE); } } } @@ -162,11 +156,6 @@ volume_widget_set_twin_item(VolumeWidget* self, GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_volume_slider); GtkRange *range = (GtkRange*)slider; gtk_range_set_value(range, initial_level); - g_signal_emit(G_OBJECT(priv->indicator), - INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, - 0, - (IndicatorObjectEntry *)indicator_object_get_entries(INDICATOR_OBJECT(priv->indicator))->data, - TRUE); } static gboolean @@ -207,11 +196,6 @@ volume_widget_update(VolumeWidget* self, gdouble update) gdouble clamped = CLAMP(update, 0, 100); GVariant* new_volume = g_variant_new_double(clamped); dbusmenu_menuitem_handle_event (priv->twin_item, "update", new_volume, 0); - g_signal_emit(G_OBJECT(priv->indicator), - INDICATOR_OBJECT_SIGNAL_ACCESSIBLE_DESC_UPDATE_ID, - 0, - (IndicatorObjectEntry *)indicator_object_get_entries(INDICATOR_OBJECT(priv->indicator))->data, - TRUE); } GtkWidget* @@ -267,12 +251,10 @@ volume_widget_get_current_volume ( GtkWidget *widget ) * volume_widget_new: * @returns: a new #VolumeWidget. **/ -GtkWidget* -volume_widget_new(DbusmenuMenuitem *item, IndicatorObject* io) +GtkWidget* +volume_widget_new(DbusmenuMenuitem *item) { GtkWidget* widget = g_object_new(VOLUME_WIDGET_TYPE, NULL); - VolumeWidgetPrivate* priv = VOLUME_WIDGET_GET_PRIVATE(VOLUME_WIDGET(widget)); - priv->indicator = io; volume_widget_set_twin_item((VolumeWidget*)widget, item); return widget; } diff --git a/src/volume-widget.h b/src/volume-widget.h index 50ef377..072cfde 100644 --- a/src/volume-widget.h +++ b/src/volume-widget.h @@ -22,7 +22,6 @@ with this program. If not, see . #include #include #include -#include G_BEGIN_DECLS @@ -45,7 +44,7 @@ struct _VolumeWidget { }; GType volume_widget_get_type (void) G_GNUC_CONST; -GtkWidget* volume_widget_new(DbusmenuMenuitem *item, IndicatorObject* io); +GtkWidget* volume_widget_new(DbusmenuMenuitem* twin_item); GtkWidget* volume_widget_get_ido_slider(VolumeWidget* self); void volume_widget_update(VolumeWidget* self, gdouble update); void volume_widget_tidy_up (GtkWidget *widget); -- cgit v1.2.3 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 From 3c5c6dc46b738371bd2c0d6afe12f5a9bb168cf6 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 16 Feb 2011 20:41:58 +0000 Subject: need to encapsulate more --- src/voip-input-menu-item.c | 30 ++++++++++++++++++++++++++++-- src/voip-input-menu-item.h | 11 +++++++---- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c index 209629e..51ddd95 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -27,7 +27,12 @@ with this program. If not, see . typedef struct _VoipInputMenuItemPrivate VoipInputMenuItemPrivate; struct _VoipInputMenuItemPrivate { - ActiveSink* a_sink; + ActiveSink* a_sink; + pa_cvolume volume; + gint mute; + guint32 volume_steps; + pa_channel_map channel_map; + pa_volume_t base_volume; }; #define VOIP_INPUT_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemPrivate)) @@ -102,6 +107,26 @@ handle_event (DbusmenuMenuitem * mi, } 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) +{ + 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; +} + + +/* voip_input_menu_item_update (VoipInputMenuItem* item, gdouble update) { @@ -110,10 +135,11 @@ voip_input_menu_item_update (VoipInputMenuItem* item, DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, new_volume); } +*/ void voip_input_menu_item_enable (VoipInputMenuItem* item, - gboolean active) + gboolean active) { dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item), DBUSMENU_MENUITEM_PROP_VISIBLE, diff --git a/src/voip-input-menu-item.h b/src/voip-input-menu-item.h index 296f22c..ad70289 100644 --- a/src/voip-input-menu-item.h +++ b/src/voip-input-menu-item.h @@ -20,8 +20,7 @@ with this program. If not, see . #define __VOIP_INPUT_MENU_ITEM_H__ #include -#include - +#include #include #include "active-sink.h" @@ -47,8 +46,12 @@ struct _VoipInputMenuItem { 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); +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); VoipInputMenuItem* voip_input_menu_item_new (ActiveSink* sink); -- cgit v1.2.3 From c1fdbb5237dd04d6508fafc7d4af67645d4c66c5 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 17 Feb 2011 15:17:31 +0000 Subject: back end plugged together for proof of concept --- src/active-sink.c | 28 +++++++++++++ src/active-sink.h | 9 ++++- src/pulseaudio-mgr.c | 99 ++++++++++++++++++++++++++++++++++++---------- src/voip-input-menu-item.c | 62 ++++++++++++++++++++--------- src/voip-input-menu-item.h | 8 ++-- 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 @@ -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 @@ -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); -- cgit v1.2.3 From 6ad2bc640794ad3d78c401e4e9391169446db619 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 17 Feb 2011 16:07:28 +0000 Subject: voip widget added --- src/Makefile.am | 2 + src/indicator-sound.c | 44 +++++++++ src/voip-input-widget.c | 252 ++++++++++++++++++++++++++++++++++++++++++++++++ src/voip-input-widget.h | 55 +++++++++++ 4 files changed, 353 insertions(+) create mode 100644 src/voip-input-widget.c create mode 100644 src/voip-input-widget.h diff --git a/src/Makefile.am b/src/Makefile.am index 228e6a3..7525d71 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -20,6 +20,8 @@ libsoundmenu_la_SOURCES = \ title-widget.h \ volume-widget.c \ volume-widget.h \ + voip-input-widget.c \ + voip-input-widget.h \ gen-sound-service.xml.h \ gen-sound-service.xml.c \ dbus-shared-names.h diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 96ab89b..138c5ac 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -79,6 +79,10 @@ static gboolean new_volume_slider_widget (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, gpointer user_data); +static gboolean new_voip_slider_widget (DbusmenuMenuitem * newitem, + DbusmenuMenuitem * parent, + DbusmenuClient * client, + gpointer user_data); static gboolean new_transport_widget (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client, @@ -190,6 +194,9 @@ get_menu (IndicatorObject * io) dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), DBUSMENU_VOLUME_MENUITEM_TYPE, new_volume_slider_widget); + dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), + DBUSMENU_VOIP_INPUT_MENUITEM_TYPE, + new_voip_slider_widget); dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), DBUSMENU_TRANSPORT_MENUITEM_TYPE, new_transport_widget); @@ -403,6 +410,43 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, parent); return TRUE; } +static gboolean +new_voip_slider_widget (DbusmenuMenuitem * newitem, + DbusmenuMenuitem * parent, + DbusmenuClient * client, + gpointer user_data) +{ + g_debug("indicator-sound: new_voip_slider_widget"); +/* + GtkWidget* voip_widget = NULL; + IndicatorObject *io = NULL; + + + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + + volume_widget = volume_widget_new (newitem); + io = g_object_get_data (G_OBJECT (client), "indicator"); + IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); + priv->volume_widget = volume_widget; + + GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); + + gtk_widget_show_all(ido_slider_widget); + // register the style callback on this widget with state manager's style change + // handler (needs to remake the blocking animation for each style). + g_signal_connect (ido_slider_widget, "style-set", + G_CALLBACK(sound_state_manager_style_changed_cb), + priv->state_manager); + + GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget); + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), + newitem, + menu_volume_item, + parent); +*/ + return TRUE; +} /*******************************************************************/ //UI callbacks diff --git a/src/voip-input-widget.c b/src/voip-input-widget.c new file mode 100644 index 0000000..4933d7b --- /dev/null +++ b/src/voip-input-widget.c @@ -0,0 +1,252 @@ + +/* +Copyright 2011 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 +#include +#include "voip-input-widget.h" +#include "common-defs.h" +#include +//#include "indicator-sound.h" + +typedef struct _VoipInputWidgetPrivate VoipInputWidgetPrivate; + +struct _VoipInputWidgetPrivate +{ + DbusmenuMenuitem* twin_item; + GtkWidget* ido_voip_input_slider; + gboolean grabbed; +}; + +#define VOIP_INPUT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetPrivate)) + +/* Prototypes */ +static void voip_input_widget_class_init (VoipInputWidgetClass *klass); +static void voip_input_widget_init (VoipInputWidget *self); +static void voip_input_widget_dispose (GObject *object); +static void voip_input_widget_finalize (GObject *object); +static void voip_input_widget_set_twin_item( VoipInputWidget* self, + DbusmenuMenuitem* twin_item); +static void voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, + GVariant* value, gpointer userdata ); + +static gboolean voip_input_widget_change_value_cb (GtkRange *range, + GtkScrollType scroll, + gdouble value, + gpointer user_data); +static gboolean voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data); +static void voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data); +static void voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data); +static void voip_input_widget_parent_changed (GtkWidget *widget, gpointer user_data); + +G_DEFINE_TYPE (VoipInputWidget, voip_input_widget, G_TYPE_OBJECT); + + +static void +voip_input_widget_class_init (VoipInputWidgetClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (VoipInputWidgetPrivate)); + + gobject_class->dispose = voip_input_widget_dispose; + gobject_class->finalize = voip_input_widget_finalize; +} + +static void +voip_input_widget_init (VoipInputWidget *self) +{ + //g_debug("VoipInputWidget::voip_input_widget_init"); + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); + + priv->ido_voip_input_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1); + g_object_ref (priv->ido_voip_input_slider); + ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_voip_input_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); + g_object_set(priv->ido_voip_input_slider, "reverse-scroll-events", TRUE, NULL); + + g_signal_connect (priv->ido_voip_input_slider, + "notify::parent", G_CALLBACK (voip_input_widget_parent_changed), + NULL); + + GtkWidget* voip_input_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); + + g_signal_connect(voip_input_widget, "change-value", G_CALLBACK(voip_input_widget_change_value_cb), self); + g_signal_connect(voip_input_widget, "value-changed", G_CALLBACK(voip_input_widget_value_changed_cb), self); + g_signal_connect(priv->ido_voip_input_slider, "slider-grabbed", G_CALLBACK(voip_input_widget_slider_grabbed), self); + g_signal_connect(priv->ido_voip_input_slider, "slider-released", G_CALLBACK(voip_input_widget_slider_released), self); + + GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); + GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-low-zero-panel"); + gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU); + g_object_unref(primary_gicon); + + GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); + GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-high-panel"); + gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); + g_object_unref(secondary_gicon); + + GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (voip_input_widget)); + gtk_adjustment_set_step_increment(adj, 4); +} + +static void +voip_input_widget_dispose (GObject *object) +{ + G_OBJECT_CLASS (voip_input_widget_parent_class)->dispose (object); +} + +static void +voip_input_widget_finalize (GObject *object) +{ + G_OBJECT_CLASS (voip_input_widget_parent_class)->finalize (object); +} + +static void +voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, + GVariant* value, gpointer userdata) +{ + g_return_if_fail (IS_VOIP_INPUT_WIDGET (userdata)); + VoipInputWidget* mitem = VOIP_INPUT_WIDGET(userdata); + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); + //g_debug("scrub-widget::property_update for prop %s", property); + if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_LEVEL, property) == 0){ + if(priv->grabbed == FALSE){ + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); + GtkRange *range = (GtkRange*)slider; + gdouble update = g_variant_get_double (value); + //g_debug("volume-widget - update level with value %f", update); + gtk_range_set_value(range, update); + } + } +} + +static void +voip_input_widget_set_twin_item(VoipInputWidget* self, + DbusmenuMenuitem* twin_item) +{ + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); + priv->twin_item = twin_item; + g_object_ref(priv->twin_item); + g_signal_connect(G_OBJECT(twin_item), "property-changed", + G_CALLBACK(voip_input_widget_property_update), self); + gdouble initial_level = g_variant_get_double (dbusmenu_menuitem_property_get_variant(twin_item, + DBUSMENU_VOLUME_MENUITEM_LEVEL)); + //g_debug("voip_input_widget_set_twin_item initial level = %f", initial_level); + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); + GtkRange *range = (GtkRange*)slider; + gtk_range_set_value(range, initial_level); +} + +static gboolean +voip_input_widget_change_value_cb (GtkRange *range, + GtkScrollType scroll, + gdouble new_value, + gpointer user_data) +{ + g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); + VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); + voip_input_widget_update(mitem, new_value); + return FALSE; +} + +/* + We only want this callback to catch mouse icon press events + which set the slider to 0 or 100. Ignore all other events. +*/ +static gboolean +voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data) +{ + g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); + VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); + gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100); + + if(current_value == 0 || current_value == 100){ + voip_input_widget_update(mitem, current_value); + } + return FALSE; +} + +void +voip_input_widget_update(VoipInputWidget* self, gdouble update) +{ + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); + gdouble clamped = CLAMP(update, 0, 100); + GVariant* new_volume = g_variant_new_double(clamped); + dbusmenu_menuitem_handle_event (priv->twin_item, "update", new_volume, 0); +} + +GtkWidget* +voip_input_widget_get_ido_slider(VoipInputWidget* self) +{ + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); + return priv->ido_voip_input_slider; +} + +static void +voip_input_widget_parent_changed (GtkWidget *widget, + gpointer user_data) +{ + gtk_widget_set_size_request (widget, 200, -1); + //g_debug("voip_input_widget_parent_changed"); +} + +static void +voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data) +{ + VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); + priv->grabbed = TRUE; +} + +static void +voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data) +{ + VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); + priv->grabbed = FALSE; +} + +void +voip_input_widget_tidy_up (GtkWidget *widget) +{ + VoipInputWidget* mitem = VOIP_INPUT_WIDGET(widget); + VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); + gtk_widget_destroy (priv->ido_voip_input_slider); +} + +/** + * voip_input_widget_new: + * @returns: a new #VoipInputWidget. + **/ +GtkWidget* +voip_input_widget_new(DbusmenuMenuitem *item) +{ + GtkWidget* widget = g_object_new(VOIP_INPUT_WIDGET_TYPE, NULL); + voip_input_widget_set_twin_item((VoipInputWidget*)widget, item); + return widget; +} + + diff --git a/src/voip-input-widget.h b/src/voip-input-widget.h new file mode 100644 index 0000000..29912f0 --- /dev/null +++ b/src/voip-input-widget.h @@ -0,0 +1,55 @@ +/* +Copyright 2011 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_WIDGET_H__ +#define __VOIP_INPUT_WIDGET_H__ + +#include +#include +#include + +G_BEGIN_DECLS + +#define VOIP_INPUT_WIDGET_TYPE (voip_input_widget_get_type ()) +#define VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidget)) +#define VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass)) +#define IS_VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOIP_INPUT_WIDGET_TYPE)) +#define IS_VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOIP_INPUT_WIDGET_TYPE)) +#define VOIP_INPUT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass)) + +typedef struct _VoipInputWidget VoipInputWidget; +typedef struct _VoipInputWidgetClass VoipInputWidgetClass; + +struct _VoipInputWidgetClass { + GObjectClass parent_class; +}; + +struct _VoipInputWidget { + GObject parent; +}; + +GType voip_input_widget_get_type (void) G_GNUC_CONST; +GtkWidget* voip_input_widget_new(DbusmenuMenuitem* twin_item); +GtkWidget* voip_input_widget_get_ido_slider(VoipInputWidget* self); +void voip_input_widget_update(VoipInputWidget* self, gdouble update); +void voip_input_widget_tidy_up (GtkWidget *widget); + +G_END_DECLS + +#endif + -- cgit v1.2.3 From 4bebcafef41b3dbc6b4f3f3e2f6382d82390335f Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 17 Feb 2011 18:54:58 +0000 Subject: getting there --- src/active-sink.c | 2 +- src/common-defs.h | 2 +- src/indicator-sound.c | 32 +++++++++++++++++++++----------- src/music-player-bridge.vala | 8 +++++--- src/player-item.vala | 3 +-- src/pulseaudio-mgr.c | 8 +++++--- src/sound-service-dbus.c | 2 ++ src/voip-input-menu-item.c | 35 ++++++++++++++++++++++++++--------- src/voip-input-widget.c | 15 ++++++++------- 9 files changed, 70 insertions(+), 37 deletions(-) diff --git a/src/active-sink.c b/src/active-sink.c index 4cf8dc0..d97419b 100644 --- a/src/active-sink.c +++ b/src/active-sink.c @@ -237,7 +237,7 @@ active_sink_get_state_from_volume (ActiveSink* self) return state; } -static pa_cvolume +pa_cvolume active_sink_construct_mono_volume (const pa_cvolume* vol) { pa_cvolume new_volume; diff --git a/src/common-defs.h b/src/common-defs.h index 1a6e435..a0c097c 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -31,7 +31,7 @@ typedef enum { AVAILABLE }SoundState; - +#define DEVICE_NOT_ACTIVE -1 #define DBUSMENU_PROPERTY_EMPTY -1 /* DBUS Custom Items */ diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 138c5ac..ef803e4 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -32,12 +32,12 @@ with this program. If not, see . #include "metadata-widget.h" #include "title-widget.h" #include "volume-widget.h" - +#include "voip-input-widget.h" #include "dbus-shared-names.h" +#include "sound-state-manager.h" #include "gen-sound-service.xml.h" #include "common-defs.h" -#include "sound-state-manager.h" typedef struct _IndicatorSoundPrivate IndicatorSoundPrivate; @@ -410,6 +410,15 @@ new_volume_slider_widget(DbusmenuMenuitem * newitem, parent); return TRUE; } +/** + * new_voip_slider_widget + * Create the voip menu item widget, must of the time this widget will be hidden. + * @param newitem + * @param parent + * @param client + * @param user_data + * @return + */ static gboolean new_voip_slider_widget (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, @@ -417,34 +426,35 @@ new_voip_slider_widget (DbusmenuMenuitem * newitem, gpointer user_data) { g_debug("indicator-sound: new_voip_slider_widget"); -/* GtkWidget* voip_widget = NULL; - IndicatorObject *io = NULL; - + //IndicatorObject *io = NULL; g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - volume_widget = volume_widget_new (newitem); - io = g_object_get_data (G_OBJECT (client), "indicator"); - IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); - priv->volume_widget = volume_widget; + voip_widget = voip_input_widget_new (newitem); +/* + / io = g_object_get_data (G_OBJECT (client), "indicator"); +*/ + //IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); + //priv->volume_widget = volume_widget; - GtkWidget* ido_slider_widget = volume_widget_get_ido_slider(VOLUME_WIDGET(priv->volume_widget)); + GtkWidget* ido_slider_widget = voip_input_widget_get_ido_slider(VOIP_INPUT_WIDGET(voip_widget)); gtk_widget_show_all(ido_slider_widget); // register the style callback on this widget with state manager's style change // handler (needs to remake the blocking animation for each style). +/* g_signal_connect (ido_slider_widget, "style-set", G_CALLBACK(sound_state_manager_style_changed_cb), priv->state_manager); +*/ GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_item, parent); -*/ return TRUE; } diff --git a/src/music-player-bridge.vala b/src/music-player-bridge.vala index c6c9913..b5932fa 100644 --- a/src/music-player-bridge.vala +++ b/src/music-player-bridge.vala @@ -23,11 +23,13 @@ using GLib; public class MusicPlayerBridge : GLib.Object { + const int DEVICE_ITEMS_COUNT = 3; + private SettingsManager settings_manager; private Dbusmenu.Menuitem root_menu; private HashMap registered_clients; private Mpris2Watcher watcher; - + public MusicPlayerBridge() { } @@ -79,10 +81,10 @@ public class MusicPlayerBridge : GLib.Object private int calculate_menu_position() { if(this.registered_clients.size == 0){ - return 2; + return DEVICE_ITEMS_COUNT; } else{ - return (2 + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY)); + return (DEVICE_ITEMS_COUNT + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY)); } } diff --git a/src/player-item.vala b/src/player-item.vala index e146d4a..9d07bf7 100644 --- a/src/player-item.vala +++ b/src/player-item.vala @@ -94,9 +94,8 @@ public class PlayerItem : Dbusmenu.Menuitem { foreach(string prop in attrs){ //debug("populated ? - prop: %s", prop); - int value_int = property_get_int(prop); if(property_get_int(prop) != EMPTY){ - //debug("populated - prop %s and value %i", prop, value_int); + //debug("populated - prop %s and value %i", prop, property_get_int(prop)); return true; } } diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index 05b2c8e..211933b 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -201,6 +201,7 @@ pm_subscribed_events_callback (pa_context *c, } break; case PA_SUBSCRIPTION_EVENT_SOURCE: + g_debug ("Looks like source event of some description"); // We don't care about any other sink other than the active one. if (index != active_sink_get_source_index (sink)) return; @@ -420,23 +421,23 @@ pm_sink_input_info_callback (pa_context *c, } // Check if this is Voip sink input gint result = pa_proplist_contains (info->proplist, PA_PROP_MEDIA_ROLE); + ActiveSink* a_sink = ACTIVE_SINK (userdata); + if (result == 1){ g_debug ("Sink input info has media role property"); const char* value = pa_proplist_gets (info->proplist, PA_PROP_MEDIA_ROLE); g_debug ("prop role = %s", value); if (g_strcmp0 (value, "phone") == 0) { g_debug ("And yes its a VOIP app ..."); + active_sink_activate_voip_item (a_sink); // 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); } // 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); } @@ -534,6 +535,7 @@ pm_update_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 ("Got a source update for %s , index %i", info->name, info->index); active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info); } } \ No newline at end of file diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 1acaebb..9be39c7 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -163,6 +163,8 @@ sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); // Mute button + // TODO this additions should be fixed position, i.e. add via position and not just append + // be explicit as it is fixed. dbusmenu_menuitem_child_append (priv->root_menuitem, mute_item); dbusmenu_menuitem_child_append (priv->root_menuitem, slider_item); g_debug ("just about to add the slider %i", DBUSMENU_IS_MENUITEM(slider_item)); diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c index e904503..203fed4 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -46,6 +46,10 @@ 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); +// This method should really be shared between this and the volume slider obj +// perfectly static - wait until the device mgr wrapper is properly sorted and +// then consolidate +static pa_cvolume voip_input_menu_item_construct_mono_volume (const pa_cvolume* vol); G_DEFINE_TYPE (VoipInputMenuItem, voip_input_menu_item, DBUSMENU_TYPE_MENUITEM); @@ -75,7 +79,7 @@ voip_input_menu_item_init (VoipInputMenuItem *self) DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE ); - priv->index = -1; + priv->index = DEVICE_NOT_ACTIVE; } static void @@ -114,26 +118,39 @@ handle_event (DbusmenuMenuitem * mi, } } +static pa_cvolume +voip_input_menu_item_construct_mono_volume (const pa_cvolume* vol) +{ + pa_cvolume new_volume; + pa_cvolume_init(&new_volume); + new_volume.channels = 1; + pa_volume_t max_vol = pa_cvolume_max(vol); + pa_cvolume_set(&new_volume, 1, max_vol); + return new_volume; +} + void 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){ + if (priv->index == DEVICE_NOT_ACTIVE){ priv->base_volume = source->base_volume; priv->volume_steps = source->n_volume_steps; priv->channel_map = source->channel_map; + priv->index = source->index; } - priv->volume = source->volume; + priv->volume = voip_input_menu_item_construct_mono_volume (&source->volume); priv->mute = source->mute; -/* + + pa_volume_t vol = pa_cvolume_max (&source->volume); + gdouble update = ((gdouble) vol * 100) / PA_VOLUME_NORM; + GVariant* new_volume = g_variant_new_double(update); dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(item), DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, new_volume); -*/ - } gboolean @@ -155,6 +172,7 @@ voip_input_menu_item_deactivate (VoipInputMenuItem* item) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); priv->index = -1; + voip_input_menu_item_enable (item, FALSE); } void @@ -162,9 +180,8 @@ 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"); + if (priv->index == -1 && 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), diff --git a/src/voip-input-widget.c b/src/voip-input-widget.c index 4933d7b..5ce7601 100644 --- a/src/voip-input-widget.c +++ b/src/voip-input-widget.c @@ -130,7 +130,7 @@ voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, VoipInputWidget* mitem = VOIP_INPUT_WIDGET(userdata); VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); //g_debug("scrub-widget::property_update for prop %s", property); - if(g_ascii_strcasecmp(DBUSMENU_VOLUME_MENUITEM_LEVEL, property) == 0){ + if(g_ascii_strcasecmp(DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, property) == 0){ if(priv->grabbed == FALSE){ GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); GtkRange *range = (GtkRange*)slider; @@ -142,8 +142,8 @@ voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, } static void -voip_input_widget_set_twin_item(VoipInputWidget* self, - DbusmenuMenuitem* twin_item) +voip_input_widget_set_twin_item (VoipInputWidget* self, + DbusmenuMenuitem* twin_item) { VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); priv->twin_item = twin_item; @@ -151,7 +151,7 @@ voip_input_widget_set_twin_item(VoipInputWidget* self, g_signal_connect(G_OBJECT(twin_item), "property-changed", G_CALLBACK(voip_input_widget_property_update), self); gdouble initial_level = g_variant_get_double (dbusmenu_menuitem_property_get_variant(twin_item, - DBUSMENU_VOLUME_MENUITEM_LEVEL)); + DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL)); //g_debug("voip_input_widget_set_twin_item initial level = %f", initial_level); GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); GtkRange *range = (GtkRange*)slider; @@ -160,9 +160,9 @@ voip_input_widget_set_twin_item(VoipInputWidget* self, static gboolean voip_input_widget_change_value_cb (GtkRange *range, - GtkScrollType scroll, - gdouble new_value, - gpointer user_data) + GtkScrollType scroll, + gdouble new_value, + gpointer user_data) { g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); @@ -170,6 +170,7 @@ voip_input_widget_change_value_cb (GtkRange *range, return FALSE; } + /* We only want this callback to catch mouse icon press events which set the slider to 0 or 100. Ignore all other events. -- cgit v1.2.3 From 8263f9aed8c1c66cfe7a7749a4d78c096165acd3 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 17 Feb 2011 19:58:09 +0000 Subject: enough for one day --- src/pulseaudio-mgr.c | 20 ++++++++++++++++---- src/pulseaudio-mgr.h | 1 + src/voip-input-menu-item.c | 12 ++++++++++-- src/voip-input-widget.c | 3 +-- 4 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index 211933b..1cfe7af 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -19,9 +19,9 @@ with this program. If not, see . /**Notes * - * Approach now is to set up the communication channels then query the server - * fetch its default sink. If this fails then fetch the list of sinks and take - * the first one which is not the auto-null sink. + * Approach now is to set up the communication channels, query the server + * fetch its default sink/source. If this fails then fetch the list of sinks/sources + * and take the first one which is not the auto-null sink. * TODO: need to handle the situation where one chink in this linear chain breaks * i.e. start off the process again and count the attempts (note different to reconnect attempts) @@ -165,6 +165,16 @@ pm_update_mute (gboolean update) GINT_TO_POINTER (update))); } +void +pm_update_mic_gain (gint source_index, pa_cvolume new_gain) +{ + pa_operation_unref (pa_context_set_source_volume_by_index (pulse_context, + source_index, + &new_gain, + NULL, + NULL) ); +} + /**********************************************************************************************************************/ // Pulse-Audio asychronous call-backs /**********************************************************************************************************************/ @@ -217,10 +227,12 @@ pm_subscribed_events_callback (pa_context *c, break; case PA_SUBSCRIPTION_EVENT_SINK_INPUT: // We don't care about sink input removals. + g_debug ("sink input event"); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - g_debug ("Just saw a sink input removal event"); + g_debug ("Just saw a sink input removal event - index = %i", index); } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { + g_debug ("some new sink input event ? - index = %i", index); // Determine if its a VOIP app or a maybe blocking state. pa_operation_unref (pa_context_get_sink_input_info (c, index, diff --git a/src/pulseaudio-mgr.h b/src/pulseaudio-mgr.h index c0ab9c0..a93cf92 100644 --- a/src/pulseaudio-mgr.h +++ b/src/pulseaudio-mgr.h @@ -22,6 +22,7 @@ with this program. If not, see . void pm_establish_pulse_connection (ActiveSink* active_sink); void close_pulse_activites(); void pm_update_volume (gint sink_index, pa_cvolume new_volume); +void pm_update_mic_gain (gint source_index, pa_cvolume new_gain); void pm_update_mute (gboolean update); diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c index 203fed4..54e12e6 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -23,6 +23,7 @@ with this program. If not, see . #include #include "voip-input-menu-item.h" #include "common-defs.h" +#include "pulseaudio-mgr.h" typedef struct _VoipInputMenuItemPrivate VoipInputMenuItemPrivate; @@ -107,11 +108,18 @@ handle_event (DbusmenuMenuitem * mi, input = g_variant_get_variant(value); } - gboolean volume_input = g_variant_get_double(input); + gboolean percent = 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); + g_debug ("Handle event in the voip input level backend instance - %f", percent); + pa_cvolume new_volume; + pa_cvolume_init(&new_volume); + new_volume.channels = 1; + pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100); + pa_cvolume_set(&new_volume, 1, new_volume_value); + + pm_update_mic_gain (priv->index, new_volume); //active_sink_update_volume (priv->a_sink, volume_input); //active_sink_ensure_sink_is_unmuted (priv->a_sink); } diff --git a/src/voip-input-widget.c b/src/voip-input-widget.c index 5ce7601..fa58d21 100644 --- a/src/voip-input-widget.c +++ b/src/voip-input-widget.c @@ -28,7 +28,6 @@ with this program. If not, see . #include "voip-input-widget.h" #include "common-defs.h" #include -//#include "indicator-sound.h" typedef struct _VoipInputWidgetPrivate VoipInputWidgetPrivate; @@ -102,7 +101,7 @@ voip_input_widget_init (VoipInputWidget *self) g_object_unref(primary_gicon); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); - GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-high-panel"); + GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone"); gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); g_object_unref(secondary_gicon); -- cgit v1.2.3 From d8cc480485f8f46142298341ef5336a0572be5b4 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 18 Feb 2011 13:05:58 +0000 Subject: all working nicely, custom mute behaviour needed --- src/active-sink.c | 25 ++++++++++++++--- src/active-sink.h | 31 ++++++++++++--------- src/mute-menu-item.c | 1 + src/pulseaudio-mgr.c | 12 ++++++--- src/voip-input-menu-item.c | 67 ++++++++++++++++++++++++++++++++++++++-------- src/voip-input-menu-item.h | 10 ++++++- src/voip-input-widget.c | 4 +-- 7 files changed, 117 insertions(+), 33 deletions(-) diff --git a/src/active-sink.c b/src/active-sink.c index d97419b..2e212e7 100644 --- a/src/active-sink.c +++ b/src/active-sink.c @@ -53,7 +53,6 @@ static pa_cvolume active_sink_construct_mono_volume (const pa_cvolume* vol); static void active_sink_volume_update (ActiveSink* self, gdouble percent); static void active_sink_mute_update (ActiveSink* self, gboolean muted); - G_DEFINE_TYPE (ActiveSink, active_sink, G_TYPE_OBJECT); static void @@ -88,17 +87,28 @@ active_sink_init (ActiveSink *self) } void -active_sink_activate_voip_item (ActiveSink* self) +active_sink_activate_voip_item (ActiveSink* self, gint sink_input_index, gint client_index) { ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - voip_input_menu_item_enable (priv->voip_input_menu_item, TRUE); + if (voip_input_menu_item_is_interested (priv->voip_input_menu_item, + sink_input_index, + client_index)){ + 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); + voip_input_menu_item_deactivate_source (priv->voip_input_menu_item); +} + +void +active_sink_deactivate_voip_client (ActiveSink* self) +{ + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + voip_input_menu_item_deactivate_voip_client (priv->voip_input_menu_item); } @@ -186,6 +196,13 @@ active_sink_update_volume (ActiveSink* self, gdouble percent) } +gint +active_sink_get_current_sink_input_index (ActiveSink* sink) +{ + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (sink); + return voip_input_menu_item_get_sink_input_index (priv->voip_input_menu_item); +} + static void active_sink_mute_update (ActiveSink* self, gboolean muted) { diff --git a/src/active-sink.h b/src/active-sink.h index 5c6b31a..52f0e47 100644 --- a/src/active-sink.h +++ b/src/active-sink.h @@ -50,27 +50,34 @@ struct _ActiveSinkClass { GType active_sink_get_type (void) G_GNUC_CONST; +/** + * TODO + * Refactor this to become a device manager obj basically acting as wrapper for + * the communication between pulseaudio-mgr and the individual items. + * First steps collapse slider/volume related stuff into slider-menu-item. + */ + +// Sink related 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_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); +// source and sinkinput/client related for VOIP functionality +void active_sink_update_voip_input_source (ActiveSink* sink, const pa_source_info* update); +void active_sink_activate_voip_item (ActiveSink* sink, gint sink_input_index, gint client_index); +gint active_sink_get_current_sink_input_index (ActiveSink* sink); +gboolean active_sink_is_voip_source_populated (ActiveSink* sink); +gint active_sink_get_source_index (ActiveSink* self); +void active_sink_determine_blocking_state (ActiveSink* self); +void active_sink_deactivate_voip_source (ActiveSink* self); +void active_sink_deactivate_voip_client (ActiveSink* self); +SoundState active_sink_get_state (ActiveSink* self); + ActiveSink* active_sink_new (SoundServiceDbus* service); G_END_DECLS diff --git a/src/mute-menu-item.c b/src/mute-menu-item.c index 8409b9f..2876be3 100644 --- a/src/mute-menu-item.c +++ b/src/mute-menu-item.c @@ -61,6 +61,7 @@ mute_menu_item_init (MuteMenuItem *self) { g_debug("Building new Mute Menu Item"); MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE(self); + priv->button = NULL; priv->button = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set_bool (priv->button, DBUSMENU_MENUITEM_PROP_VISIBLE, diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index 1cfe7af..8f7a290 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -229,7 +229,13 @@ pm_subscribed_events_callback (pa_context *c, // We don't care about sink input removals. g_debug ("sink input event"); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - g_debug ("Just saw a sink input removal event - index = %i", index); + gint cached_index = active_sink_get_current_sink_input_index (sink); + + g_debug ("Just saw a sink input removal event - index = %i and cached index = %i", index, cached_index); + + if (index == cached_index){ + active_sink_deactivate_voip_client (sink); + } } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { g_debug ("some new sink input event ? - index = %i", index); @@ -440,8 +446,8 @@ pm_sink_input_info_callback (pa_context *c, const char* value = pa_proplist_gets (info->proplist, PA_PROP_MEDIA_ROLE); g_debug ("prop role = %s", value); if (g_strcmp0 (value, "phone") == 0) { - g_debug ("And yes its a VOIP app ..."); - active_sink_activate_voip_item (a_sink); + g_debug ("And yes its a VOIP app ... sink input index = %i", info->index); + active_sink_activate_voip_item (a_sink, (gint)info->index, (gint)info->client); // 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 diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c index 54e12e6..498fb77 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -34,8 +34,9 @@ struct _VoipInputMenuItemPrivate { guint32 volume_steps; pa_channel_map channel_map; pa_volume_t base_volume; - gint index; + gint source_index; gint sink_input_index; + gint client_index; }; #define VOIP_INPUT_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemPrivate)) @@ -80,7 +81,9 @@ voip_input_menu_item_init (VoipInputMenuItem *self) DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE ); - priv->index = DEVICE_NOT_ACTIVE; + priv->source_index = DEVICE_NOT_ACTIVE; + priv->sink_input_index = DEVICE_NOT_ACTIVE; + priv->client_index = DEVICE_NOT_ACTIVE; } static void @@ -108,7 +111,7 @@ handle_event (DbusmenuMenuitem * mi, input = g_variant_get_variant(value); } - gboolean percent = g_variant_get_double(input); + gdouble percent = 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)); @@ -119,7 +122,7 @@ handle_event (DbusmenuMenuitem * mi, pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100); pa_cvolume_set(&new_volume, 1, new_volume_value); - pm_update_mic_gain (priv->index, new_volume); + pm_update_mic_gain (priv->source_index, new_volume); //active_sink_update_volume (priv->a_sink, volume_input); //active_sink_ensure_sink_is_unmuted (priv->a_sink); } @@ -143,11 +146,11 @@ voip_input_menu_item_update (VoipInputMenuItem* item, { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); // only overwrite the constants of each source if the device has changed - if (priv->index == DEVICE_NOT_ACTIVE){ + if (priv->source_index == DEVICE_NOT_ACTIVE){ priv->base_volume = source->base_volume; priv->volume_steps = source->n_volume_steps; priv->channel_map = source->channel_map; - priv->index = source->index; + priv->source_index = source->index; } priv->volume = voip_input_menu_item_construct_mono_volume (&source->volume); priv->mute = source->mute; @@ -161,34 +164,76 @@ voip_input_menu_item_update (VoipInputMenuItem* item, new_volume); } +gboolean +voip_input_menu_item_is_interested (VoipInputMenuItem* item, + gint sink_input_index, + gint client_index) +{ + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); + // Check to make sure we are not handling another voip beforehand and that we + // have an active sink (might need to match up at start up) + if (priv->sink_input_index != DEVICE_NOT_ACTIVE && + priv->source_index != DEVICE_NOT_ACTIVE){ + return FALSE; + } + + priv->sink_input_index = sink_input_index; + + g_debug ("vimi - siindex = %i", sink_input_index); + g_debug ("vimi - siindex stored = %i", priv->sink_input_index); + + priv->client_index = client_index; + + return TRUE; +} + + gboolean voip_input_menu_item_is_populated (VoipInputMenuItem* item) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - return priv->index != -1; + return priv->source_index != DEVICE_NOT_ACTIVE; } gint voip_input_menu_item_get_index (VoipInputMenuItem* item) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - return priv->index; + return priv->source_index; +} + +gint +voip_input_menu_item_get_sink_input_index (VoipInputMenuItem* item) +{ + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); + + return priv->sink_input_index; +} + +void +voip_input_menu_item_deactivate_source (VoipInputMenuItem* item) +{ + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); + priv->source_index = DEVICE_NOT_ACTIVE; + voip_input_menu_item_enable (item, FALSE); } void -voip_input_menu_item_deactivate (VoipInputMenuItem* item) +voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - priv->index = -1; + priv->client_index = DEVICE_NOT_ACTIVE; + priv->sink_input_index = DEVICE_NOT_ACTIVE; voip_input_menu_item_enable (item, FALSE); } + void voip_input_menu_item_enable (VoipInputMenuItem* item, gboolean active) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - if (priv->index == -1 && active == TRUE) { + if (priv->source_index == DEVICE_NOT_ACTIVE && active == TRUE) { g_warning ("Tried to enable the VOIP menuitem but we don't have an active source ??"); active = FALSE; } diff --git a/src/voip-input-menu-item.h b/src/voip-input-menu-item.h index 70dc9fa..5a62393 100644 --- a/src/voip-input-menu-item.h +++ b/src/voip-input-menu-item.h @@ -49,9 +49,17 @@ 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_enable (VoipInputMenuItem* item, gboolean active); +gboolean voip_input_menu_item_is_interested (VoipInputMenuItem* item, + gint sink_input_index, + gint client_index); gboolean voip_input_menu_item_is_populated (VoipInputMenuItem* item); +// TODO rename get source index gint voip_input_menu_item_get_index (VoipInputMenuItem* item); -void voip_input_menu_item_deactivate (VoipInputMenuItem* item); + +gint voip_input_menu_item_get_sink_input_index (VoipInputMenuItem* item); + +void voip_input_menu_item_deactivate_source (VoipInputMenuItem* item); +void voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item); VoipInputMenuItem* voip_input_menu_item_new (ActiveSink* sink); diff --git a/src/voip-input-widget.c b/src/voip-input-widget.c index fa58d21..de06c7c 100644 --- a/src/voip-input-widget.c +++ b/src/voip-input-widget.c @@ -96,12 +96,12 @@ voip_input_widget_init (VoipInputWidget *self) g_signal_connect(priv->ido_voip_input_slider, "slider-released", G_CALLBACK(voip_input_widget_slider_released), self); GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); - GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-volume-low-zero-panel"); + GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone"); gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU); g_object_unref(primary_gicon); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); - GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone"); + GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone-high"); gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); g_object_unref(secondary_gicon); -- cgit v1.2.3 From fca4da8d8a9dd24d8abdf2a92cf19a0c6d596e48 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 18 Feb 2011 15:38:45 +0000 Subject: fully functional voip feature landed --- src/common-defs.h | 1 + src/voip-input-menu-item.c | 18 +++++++++++++----- src/voip-input-widget.c | 43 +++++++++++++++++++++++++++++++++++-------- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/src/common-defs.h b/src/common-defs.h index a0c097c..1a4e71e 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -40,6 +40,7 @@ typedef enum { #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_VOIP_INPUT_MENUITEM_MUTE "x-canonical-ido-voip-input-mute" #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/voip-input-menu-item.c b/src/voip-input-menu-item.c index 498fb77..337420b 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -48,6 +48,7 @@ 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); +// TODO: // This method should really be shared between this and the volume slider obj // perfectly static - wait until the device mgr wrapper is properly sorted and // then consolidate @@ -84,6 +85,7 @@ voip_input_menu_item_init (VoipInputMenuItem *self) priv->source_index = DEVICE_NOT_ACTIVE; priv->sink_input_index = DEVICE_NOT_ACTIVE; priv->client_index = DEVICE_NOT_ACTIVE; + priv->mute = 0; } static void @@ -153,6 +155,17 @@ voip_input_menu_item_update (VoipInputMenuItem* item, priv->source_index = source->index; } priv->volume = voip_input_menu_item_construct_mono_volume (&source->volume); + + // Only send over the mute updates if the state has changed. + if (priv->mute != source->mute){ + g_debug ("voip menu item - update - mute = %i", priv->mute); + + GVariant* new_mute_update = g_variant_new_int32 (source->mute); + dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(item), + DBUSMENU_VOIP_INPUT_MENUITEM_MUTE, + new_mute_update); + } + priv->mute = source->mute; pa_volume_t vol = pa_cvolume_max (&source->volume); @@ -178,10 +191,6 @@ voip_input_menu_item_is_interested (VoipInputMenuItem* item, } priv->sink_input_index = sink_input_index; - - g_debug ("vimi - siindex = %i", sink_input_index); - g_debug ("vimi - siindex stored = %i", priv->sink_input_index); - priv->client_index = client_index; return TRUE; @@ -227,7 +236,6 @@ voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item) voip_input_menu_item_enable (item, FALSE); } - void voip_input_menu_item_enable (VoipInputMenuItem* item, gboolean active) diff --git a/src/voip-input-widget.c b/src/voip-input-widget.c index de06c7c..9b29feb 100644 --- a/src/voip-input-widget.c +++ b/src/voip-input-widget.c @@ -76,7 +76,6 @@ voip_input_widget_class_init (VoipInputWidgetClass *klass) static void voip_input_widget_init (VoipInputWidget *self) { - //g_debug("VoipInputWidget::voip_input_widget_init"); VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); priv->ido_voip_input_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1); @@ -122,8 +121,8 @@ voip_input_widget_finalize (GObject *object) } static void -voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, - GVariant* value, gpointer userdata) +voip_input_widget_property_update (DbusmenuMenuitem* item, gchar* property, + GVariant* value, gpointer userdata) { g_return_if_fail (IS_VOIP_INPUT_WIDGET (userdata)); VoipInputWidget* mitem = VOIP_INPUT_WIDGET(userdata); @@ -138,6 +137,24 @@ voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, gtk_range_set_value(range, update); } } + if(g_ascii_strcasecmp(DBUSMENU_VOIP_INPUT_MENUITEM_MUTE, property) == 0){ + if(priv->grabbed == FALSE){ + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); + GtkRange *range = (GtkRange*)slider; + gint update = g_variant_get_int32 (value); + gdouble level; + if (update == 1){ + level = 0; + } + else{ + level = g_variant_get_double (dbusmenu_menuitem_property_get_variant (priv->twin_item, + DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL)); + } + gtk_range_set_value(range, level); + + g_debug ("voip-item-widget - update mute with value %i", update); + } + } } static void @@ -155,6 +172,12 @@ voip_input_widget_set_twin_item (VoipInputWidget* self, GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); GtkRange *range = (GtkRange*)slider; gtk_range_set_value(range, initial_level); + + gint mute = g_variant_get_int32 (dbusmenu_menuitem_property_get_variant (priv->twin_item, + DBUSMENU_VOIP_INPUT_MENUITEM_MUTE)); + if (mute == 1){ + gtk_range_set_value (range, 0.0); + } } static gboolean @@ -170,10 +193,12 @@ voip_input_widget_change_value_cb (GtkRange *range, } -/* - We only want this callback to catch mouse icon press events - which set the slider to 0 or 100. Ignore all other events. -*/ +/** + * We only want this callback to catch mouse icon press events which set the + * slider to 0 or 100. Ignore all other events including the new Mute behaviour + * (slider to go to 0 on mute without setting the level to 0 and return to + * previous level on unmute) + **/ static gboolean voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data) { @@ -183,7 +208,9 @@ voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data) GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100); - if(current_value == 0 || current_value == 100){ + gint mute = g_variant_get_int32 (dbusmenu_menuitem_property_get_variant (priv->twin_item, + DBUSMENU_VOIP_INPUT_MENUITEM_MUTE)); + if ((current_value == 0 && mute != 1) || current_value == 100 ){ voip_input_widget_update(mitem, current_value); } return FALSE; -- cgit v1.2.3 From 5882cc24cda26ab021224c66abf579b6b603617b Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 18 Feb 2011 16:22:58 +0000 Subject: and unmutes on slider activation --- src/pulseaudio-mgr.c | 10 ++++++++++ src/pulseaudio-mgr.h | 1 + src/voip-input-menu-item.c | 22 +++++++++++++--------- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index 8f7a290..e319793 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -175,6 +175,15 @@ pm_update_mic_gain (gint source_index, pa_cvolume new_gain) NULL) ); } +void +pm_update_mic_mute (gint source_index, gint mute_update) +{ + pa_operation_unref (pa_context_set_source_mute_by_index (pulse_context, + source_index, + mute_update, + NULL, + NULL)); +} /**********************************************************************************************************************/ // Pulse-Audio asychronous call-backs /**********************************************************************************************************************/ @@ -258,6 +267,7 @@ pm_subscribed_events_callback (pa_context *c, } + static void pm_context_state_callback (pa_context *c, void *userdata) { diff --git a/src/pulseaudio-mgr.h b/src/pulseaudio-mgr.h index a93cf92..d61117d 100644 --- a/src/pulseaudio-mgr.h +++ b/src/pulseaudio-mgr.h @@ -23,6 +23,7 @@ void pm_establish_pulse_connection (ActiveSink* active_sink); void close_pulse_activites(); void pm_update_volume (gint sink_index, pa_cvolume new_volume); void pm_update_mic_gain (gint source_index, pa_cvolume new_gain); +void pm_update_mic_mute (gint source_index, int mute_update); void pm_update_mute (gboolean update); diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c index 337420b..19bc92d 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -85,7 +85,7 @@ voip_input_menu_item_init (VoipInputMenuItem *self) priv->source_index = DEVICE_NOT_ACTIVE; priv->sink_input_index = DEVICE_NOT_ACTIVE; priv->client_index = DEVICE_NOT_ACTIVE; - priv->mute = 0; + priv->mute = DEVICE_NOT_ACTIVE; } static void @@ -125,6 +125,10 @@ handle_event (DbusmenuMenuitem * mi, pa_cvolume_set(&new_volume, 1, new_volume_value); pm_update_mic_gain (priv->source_index, new_volume); + // finally unmute if needed + if (priv->mute == 1) { + pm_update_mic_mute (priv->source_index, 0); + } //active_sink_update_volume (priv->a_sink, volume_input); //active_sink_ensure_sink_is_unmuted (priv->a_sink); } @@ -155,8 +159,15 @@ voip_input_menu_item_update (VoipInputMenuItem* item, priv->source_index = source->index; } priv->volume = voip_input_menu_item_construct_mono_volume (&source->volume); - + pa_volume_t vol = pa_cvolume_max (&source->volume); + gdouble update = ((gdouble) vol * 100) / PA_VOLUME_NORM; + + GVariant* new_volume = g_variant_new_double(update); + dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(item), + DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, + new_volume); // Only send over the mute updates if the state has changed. + // in this order - volume first mute last!! if (priv->mute != source->mute){ g_debug ("voip menu item - update - mute = %i", priv->mute); @@ -168,13 +179,6 @@ voip_input_menu_item_update (VoipInputMenuItem* item, priv->mute = source->mute; - pa_volume_t vol = pa_cvolume_max (&source->volume); - gdouble update = ((gdouble) vol * 100) / PA_VOLUME_NORM; - - GVariant* new_volume = g_variant_new_double(update); - dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(item), - DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, - new_volume); } gboolean -- cgit v1.2.3 From 9a424c26c67544aafdd7cff2d66519b1c72e8aa0 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 18 Feb 2011 16:56:17 +0000 Subject: bug free afaics ... --- src/active-sink.c | 4 ++-- src/active-sink.h | 2 +- src/common-defs.h | 2 +- src/pulseaudio-mgr.c | 16 ++++++++++++---- src/settings-manager.vala | 2 ++ src/voip-input-menu-item.c | 36 +++++++++++++++++++++--------------- src/voip-input-menu-item.h | 2 +- 7 files changed, 40 insertions(+), 24 deletions(-) diff --git a/src/active-sink.c b/src/active-sink.c index 2e212e7..ce0e135 100644 --- a/src/active-sink.c +++ b/src/active-sink.c @@ -98,10 +98,10 @@ active_sink_activate_voip_item (ActiveSink* self, gint sink_input_index, gint cl } void -active_sink_deactivate_voip_source (ActiveSink* self) +active_sink_deactivate_voip_source (ActiveSink* self, gboolean visible) { ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - voip_input_menu_item_deactivate_source (priv->voip_input_menu_item); + voip_input_menu_item_deactivate_source (priv->voip_input_menu_item, visible); } void diff --git a/src/active-sink.h b/src/active-sink.h index 52f0e47..57b3079 100644 --- a/src/active-sink.h +++ b/src/active-sink.h @@ -74,7 +74,7 @@ gint active_sink_get_current_sink_input_index (ActiveSink* sink); gboolean active_sink_is_voip_source_populated (ActiveSink* sink); gint active_sink_get_source_index (ActiveSink* self); void active_sink_determine_blocking_state (ActiveSink* self); -void active_sink_deactivate_voip_source (ActiveSink* self); +void active_sink_deactivate_voip_source (ActiveSink* self, gboolean visible); void active_sink_deactivate_voip_client (ActiveSink* self); SoundState active_sink_get_state (ActiveSink* self); diff --git a/src/common-defs.h b/src/common-defs.h index 1a4e71e..2184a48 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -31,7 +31,7 @@ typedef enum { AVAILABLE }SoundState; -#define DEVICE_NOT_ACTIVE -1 +#define NOT_ACTIVE -1 #define DBUSMENU_PROPERTY_EMPTY -1 /* DBUS Custom Items */ diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index e319793..76102e4 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -225,7 +225,7 @@ pm_subscribed_events_callback (pa_context *c, 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); + active_sink_deactivate_voip_source (sink, FALSE); } else{ pa_operation_unref (pa_context_get_source_info_by_index (c, @@ -421,8 +421,12 @@ pm_default_sink_info_callback (pa_context *c, 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"); + } + // Only repopulate if there is a change with regards the index + if (active_sink_get_index (ACTIVE_SINK (userdata)) == info->index) + return; + + g_debug ("Pulse Server has handed us a new default sink"); active_sink_populate (ACTIVE_SINK (userdata), info); } } @@ -523,7 +527,11 @@ 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 source"); + // If there is an index change we need to change our cached source + if (active_sink_get_source_index (ACTIVE_SINK (userdata)) == info->index) + return; + g_debug ("Pulse Server has handed us a new default source"); + active_sink_deactivate_voip_source (ACTIVE_SINK (userdata), TRUE); active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info); } } diff --git a/src/settings-manager.vala b/src/settings-manager.vala index 057a47b..6800423 100644 --- a/src/settings-manager.vala +++ b/src/settings-manager.vala @@ -71,6 +71,7 @@ public class SettingsManager : GLib.Object // Convenient debug method inorder to provide visability over // the contents of both interested and blacklisted containers in its gsettings +/** private void reveal_contents() { var already_interested = this.settings.get_strv ("interested-media-players"); @@ -87,4 +88,5 @@ public class SettingsManager : GLib.Object debug ("interested array size = %i", already_interested.length); debug ("blacklisted array size = %i", blacklisted.length); } +**/ } diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c index 19bc92d..b98be8d 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -82,10 +82,10 @@ voip_input_menu_item_init (VoipInputMenuItem *self) DBUSMENU_MENUITEM_PROP_VISIBLE, FALSE ); - priv->source_index = DEVICE_NOT_ACTIVE; - priv->sink_input_index = DEVICE_NOT_ACTIVE; - priv->client_index = DEVICE_NOT_ACTIVE; - priv->mute = DEVICE_NOT_ACTIVE; + priv->source_index = NOT_ACTIVE; + priv->sink_input_index = NOT_ACTIVE; + priv->client_index = NOT_ACTIVE; + priv->mute = NOT_ACTIVE; } static void @@ -152,7 +152,7 @@ voip_input_menu_item_update (VoipInputMenuItem* item, { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); // only overwrite the constants of each source if the device has changed - if (priv->source_index == DEVICE_NOT_ACTIVE){ + if (priv->source_index == NOT_ACTIVE){ priv->base_volume = source->base_volume; priv->volume_steps = source->n_volume_steps; priv->channel_map = source->channel_map; @@ -170,7 +170,6 @@ voip_input_menu_item_update (VoipInputMenuItem* item, // in this order - volume first mute last!! if (priv->mute != source->mute){ g_debug ("voip menu item - update - mute = %i", priv->mute); - GVariant* new_mute_update = g_variant_new_int32 (source->mute); dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(item), DBUSMENU_VOIP_INPUT_MENUITEM_MUTE, @@ -189,8 +188,8 @@ voip_input_menu_item_is_interested (VoipInputMenuItem* item, VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); // Check to make sure we are not handling another voip beforehand and that we // have an active sink (might need to match up at start up) - if (priv->sink_input_index != DEVICE_NOT_ACTIVE && - priv->source_index != DEVICE_NOT_ACTIVE){ + if (priv->sink_input_index != NOT_ACTIVE && + priv->source_index != NOT_ACTIVE){ return FALSE; } @@ -205,7 +204,7 @@ gboolean voip_input_menu_item_is_populated (VoipInputMenuItem* item) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - return priv->source_index != DEVICE_NOT_ACTIVE; + return priv->source_index != NOT_ACTIVE; } gint @@ -223,20 +222,27 @@ voip_input_menu_item_get_sink_input_index (VoipInputMenuItem* item) return priv->sink_input_index; } +/** + * If the pulse server informs of a default source change + * or the source in question is removed. + * @param item + */ void -voip_input_menu_item_deactivate_source (VoipInputMenuItem* item) +voip_input_menu_item_deactivate_source (VoipInputMenuItem* item, gboolean visible) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - priv->source_index = DEVICE_NOT_ACTIVE; - voip_input_menu_item_enable (item, FALSE); + priv->source_index = NOT_ACTIVE; + dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item), + DBUSMENU_MENUITEM_PROP_VISIBLE, + visible ); } void voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - priv->client_index = DEVICE_NOT_ACTIVE; - priv->sink_input_index = DEVICE_NOT_ACTIVE; + priv->client_index = NOT_ACTIVE; + priv->sink_input_index = NOT_ACTIVE; voip_input_menu_item_enable (item, FALSE); } @@ -245,7 +251,7 @@ voip_input_menu_item_enable (VoipInputMenuItem* item, gboolean active) { VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); - if (priv->source_index == DEVICE_NOT_ACTIVE && active == TRUE) { + if (priv->source_index == NOT_ACTIVE && active == TRUE) { g_warning ("Tried to enable the VOIP menuitem but we don't have an active source ??"); active = FALSE; } diff --git a/src/voip-input-menu-item.h b/src/voip-input-menu-item.h index 5a62393..5a39d8a 100644 --- a/src/voip-input-menu-item.h +++ b/src/voip-input-menu-item.h @@ -58,7 +58,7 @@ gint voip_input_menu_item_get_index (VoipInputMenuItem* item); gint voip_input_menu_item_get_sink_input_index (VoipInputMenuItem* item); -void voip_input_menu_item_deactivate_source (VoipInputMenuItem* item); +void voip_input_menu_item_deactivate_source (VoipInputMenuItem* item, gboolean visible); void voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item); VoipInputMenuItem* voip_input_menu_item_new (ActiveSink* sink); -- cgit v1.2.3 From 80afbbce02c5d31fc4375b84c8647628333b7cc2 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 18 Feb 2011 17:11:08 +0000 Subject: the last bug really --- src/active-sink.c | 52 +++++++++++++++++++++++----------------------- src/voip-input-menu-item.c | 7 +++++++ src/voip-input-menu-item.h | 1 + 3 files changed, 34 insertions(+), 26 deletions(-) diff --git a/src/active-sink.c b/src/active-sink.c index ce0e135..a78d33e 100644 --- a/src/active-sink.c +++ b/src/active-sink.c @@ -86,32 +86,6 @@ active_sink_init (ActiveSink *self) slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); } -void -active_sink_activate_voip_item (ActiveSink* self, gint sink_input_index, gint client_index) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - if (voip_input_menu_item_is_interested (priv->voip_input_menu_item, - sink_input_index, - client_index)){ - voip_input_menu_item_enable (priv->voip_input_menu_item, TRUE); - } -} - -void -active_sink_deactivate_voip_source (ActiveSink* self, gboolean visible) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - voip_input_menu_item_deactivate_source (priv->voip_input_menu_item, visible); -} - -void -active_sink_deactivate_voip_client (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - voip_input_menu_item_deactivate_voip_client (priv->voip_input_menu_item); -} - - static void active_sink_dispose (GObject *object) { @@ -148,6 +122,32 @@ active_sink_populate (ActiveSink* sink, g_debug ("Active sink has been populated - volume %f", volume_percent); } +void +active_sink_activate_voip_item (ActiveSink* self, gint sink_input_index, gint client_index) +{ + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + if (voip_input_menu_item_is_interested (priv->voip_input_menu_item, + sink_input_index, + client_index)){ + voip_input_menu_item_enable (priv->voip_input_menu_item, TRUE); + } +} + +void +active_sink_deactivate_voip_source (ActiveSink* self, gboolean visible) +{ + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + visible &= voip_input_menu_item_is_active (priv->voip_input_menu_item); + voip_input_menu_item_deactivate_source (priv->voip_input_menu_item, visible); +} + +void +active_sink_deactivate_voip_client (ActiveSink* self) +{ + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + voip_input_menu_item_deactivate_voip_client (priv->voip_input_menu_item); +} + void active_sink_update (ActiveSink* sink, const pa_sink_info* update) diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c index b98be8d..a742654 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -199,6 +199,13 @@ voip_input_menu_item_is_interested (VoipInputMenuItem* item, return TRUE; } +gboolean +voip_input_menu_item_is_active (VoipInputMenuItem* item) +{ + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); + return (priv->sink_input_index != NOT_ACTIVE && priv->client_index != NOT_ACTIVE); +} + gboolean voip_input_menu_item_is_populated (VoipInputMenuItem* item) diff --git a/src/voip-input-menu-item.h b/src/voip-input-menu-item.h index 5a39d8a..6f4ed85 100644 --- a/src/voip-input-menu-item.h +++ b/src/voip-input-menu-item.h @@ -52,6 +52,7 @@ void voip_input_menu_item_enable (VoipInputMenuItem* item, gboolean active); gboolean voip_input_menu_item_is_interested (VoipInputMenuItem* item, gint sink_input_index, gint client_index); +gboolean voip_input_menu_item_is_active (VoipInputMenuItem* item); gboolean voip_input_menu_item_is_populated (VoipInputMenuItem* item); // TODO rename get source index gint voip_input_menu_item_get_index (VoipInputMenuItem* item); -- cgit v1.2.3 From e2ac5884b9c759c71f0ef2c07bdedf2e32c940bd Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 18 Feb 2011 17:19:28 +0000 Subject: remove ctrl left & right shortcut as requested --- src/indicator-sound.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index ef803e4..2466550 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -493,19 +493,23 @@ key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data) switch (event->keyval) { case GDK_Right: digested = TRUE; +/* if (event->state & GDK_CONTROL_MASK) { new_value = 100; } else { +*/ new_value = current_value + five_percent; - } + //} break; case GDK_Left: digested = TRUE; +/* if (event->state & GDK_CONTROL_MASK) { new_value = 0; } else { +*/ new_value = current_value - five_percent; - } + //} break; case GDK_plus: digested = TRUE; -- cgit v1.2.3 From 223ff23be530c865da8a8b90d18ca77c36af6e35 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 18 Feb 2011 17:20:04 +0000 Subject: tidy up --- src/sound-service.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound-service.c b/src/sound-service.c index 9f44624..c79b9f6 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -39,10 +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; } -- cgit v1.2.3 From fec38bea8091cc778bdbb236ed4c854b9cdcb34d Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 18 Feb 2011 18:01:13 +0000 Subject: bumped for new release --- configure.ac | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/configure.ac b/configure.ac index 7788c58..b1864dc 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ -AC_INIT(indicator-sound, 0.5.9, conor.curran@canonical.com) +AC_INIT(indicator-sound, 0.6.0, conor.curran@canonical.com) AC_PREREQ(2.53) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(indicator-sound, 0.5.9) +AM_INIT_AUTOMAKE(indicator-sound, 0.6.0) AM_MAINTAINER_MODE -- cgit v1.2.3