diff options
37 files changed, 1133 insertions, 180 deletions
@@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.67 for indicator-sound 0.5.9. +# Generated by GNU Autoconf 2.67 for indicator-sound 0.6.0. # # Report bugs to <conor.curran@canonical.com>. # @@ -761,8 +761,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='indicator-sound' PACKAGE_TARNAME='indicator-sound' -PACKAGE_VERSION='0.5.9' -PACKAGE_STRING='indicator-sound 0.5.9' +PACKAGE_VERSION='0.6.0' +PACKAGE_STRING='indicator-sound 0.6.0' PACKAGE_BUGREPORT='conor.curran@canonical.com' PACKAGE_URL='' @@ -1564,7 +1564,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures indicator-sound 0.5.9 to adapt to many kinds of systems. +\`configure' configures indicator-sound 0.6.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1634,7 +1634,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of indicator-sound 0.5.9:";; + short | recursive ) echo "Configuration of indicator-sound 0.6.0:";; esac cat <<\_ACEOF @@ -1767,7 +1767,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -indicator-sound configure 0.5.9 +indicator-sound configure 0.6.0 generated by GNU Autoconf 2.67 Copyright (C) 2010 Free Software Foundation, Inc. @@ -2136,7 +2136,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by indicator-sound $as_me 0.5.9, which was +It was created by indicator-sound $as_me 0.6.0, which was generated by GNU Autoconf 2.67. Invocation command line was $ $0 $@ @@ -2956,7 +2956,7 @@ fi # Define the identity of the package. PACKAGE=indicator-sound - VERSION=0.5.9 + VERSION=0.6.0 cat >>confdefs.h <<_ACEOF @@ -12131,7 +12131,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 @@ -14349,7 +14349,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by indicator-sound $as_me 0.5.9, which was +This file was extended by indicator-sound $as_me 0.6.0, which was generated by GNU Autoconf 2.67. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14415,7 +14415,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -indicator-sound config.status 0.5.9 +indicator-sound config.status 0.6.0 configured by $0, generated by GNU Autoconf 2.67, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index d42f574..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 @@ -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/Makefile.am b/src/Makefile.am index 63d6d5a..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 @@ -65,7 +67,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 \ @@ -85,7 +87,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 +98,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/Makefile.in b/src/Makefile.in index 74d3cc9..df50c00 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -78,6 +78,7 @@ am_libsoundmenu_la_OBJECTS = libsoundmenu_la-indicator-sound.lo \ libsoundmenu_la-metadata-widget.lo \ libsoundmenu_la-title-widget.lo \ libsoundmenu_la-volume-widget.lo \ + libsoundmenu_la-voip-input-widget.lo \ libsoundmenu_la-gen-sound-service.xml.lo libsoundmenu_la_OBJECTS = $(am_libsoundmenu_la_OBJECTS) AM_V_lt = $(am__v_lt_$(V)) @@ -107,6 +108,7 @@ am_indicator_sound_service_OBJECTS = \ indicator_sound_service-active-sink.$(OBJEXT) \ indicator_sound_service-sound-service-dbus.$(OBJEXT) \ indicator_sound_service-slider-menu-item.$(OBJEXT) \ + indicator_sound_service-voip-input-menu-item.$(OBJEXT) \ indicator_sound_service-mute-menu-item.$(OBJEXT) \ indicator_sound_service-gen-sound-service.xml.$(OBJEXT) \ $(am__objects_1) @@ -329,6 +331,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 @@ -367,7 +371,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 \ @@ -382,7 +386,7 @@ music_bridge_APIFILES = \ # Sound Service C ############################### indicator_sound_service_SOURCES = \ - common-defs.h \ + common-defs.h \ sound-service.h \ sound-service.c \ pulseaudio-mgr.h \ @@ -393,6 +397,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 \ @@ -569,12 +575,14 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-sound-service.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-title-menu-item.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-transport-menu-item.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/indicator_sound_service-voip-input-menu-item.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-gen-sound-service.xml.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-indicator-sound.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-metadata-widget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-sound-state-manager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-title-widget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-transport-widget.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-voip-input-widget.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/libsoundmenu_la-volume-widget.Plo@am__quote@ .c.o: @@ -649,6 +657,14 @@ libsoundmenu_la-volume-widget.lo: volume-widget.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -c -o libsoundmenu_la-volume-widget.lo `test -f 'volume-widget.c' || echo '$(srcdir)/'`volume-widget.c +libsoundmenu_la-voip-input-widget.lo: voip-input-widget.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -MT libsoundmenu_la-voip-input-widget.lo -MD -MP -MF $(DEPDIR)/libsoundmenu_la-voip-input-widget.Tpo -c -o libsoundmenu_la-voip-input-widget.lo `test -f 'voip-input-widget.c' || echo '$(srcdir)/'`voip-input-widget.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsoundmenu_la-voip-input-widget.Tpo $(DEPDIR)/libsoundmenu_la-voip-input-widget.Plo +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='voip-input-widget.c' object='libsoundmenu_la-voip-input-widget.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -c -o libsoundmenu_la-voip-input-widget.lo `test -f 'voip-input-widget.c' || echo '$(srcdir)/'`voip-input-widget.c + libsoundmenu_la-gen-sound-service.xml.lo: gen-sound-service.xml.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(libsoundmenu_la_CFLAGS) $(CFLAGS) -MT libsoundmenu_la-gen-sound-service.xml.lo -MD -MP -MF $(DEPDIR)/libsoundmenu_la-gen-sound-service.xml.Tpo -c -o libsoundmenu_la-gen-sound-service.xml.lo `test -f 'gen-sound-service.xml.c' || echo '$(srcdir)/'`gen-sound-service.xml.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/libsoundmenu_la-gen-sound-service.xml.Tpo $(DEPDIR)/libsoundmenu_la-gen-sound-service.xml.Plo @@ -737,6 +753,22 @@ indicator_sound_service-slider-menu-item.obj: slider-menu-item.c @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -c -o indicator_sound_service-slider-menu-item.obj `if test -f 'slider-menu-item.c'; then $(CYGPATH_W) 'slider-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/slider-menu-item.c'; fi` +indicator_sound_service-voip-input-menu-item.o: voip-input-menu-item.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -MT indicator_sound_service-voip-input-menu-item.o -MD -MP -MF $(DEPDIR)/indicator_sound_service-voip-input-menu-item.Tpo -c -o indicator_sound_service-voip-input-menu-item.o `test -f 'voip-input-menu-item.c' || echo '$(srcdir)/'`voip-input-menu-item.c +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_sound_service-voip-input-menu-item.Tpo $(DEPDIR)/indicator_sound_service-voip-input-menu-item.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='voip-input-menu-item.c' object='indicator_sound_service-voip-input-menu-item.o' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -c -o indicator_sound_service-voip-input-menu-item.o `test -f 'voip-input-menu-item.c' || echo '$(srcdir)/'`voip-input-menu-item.c + +indicator_sound_service-voip-input-menu-item.obj: voip-input-menu-item.c +@am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -MT indicator_sound_service-voip-input-menu-item.obj -MD -MP -MF $(DEPDIR)/indicator_sound_service-voip-input-menu-item.Tpo -c -o indicator_sound_service-voip-input-menu-item.obj `if test -f 'voip-input-menu-item.c'; then $(CYGPATH_W) 'voip-input-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/voip-input-menu-item.c'; fi` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_sound_service-voip-input-menu-item.Tpo $(DEPDIR)/indicator_sound_service-voip-input-menu-item.Po +@am__fastdepCC_FALSE@ $(AM_V_CC) @AM_BACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='voip-input-menu-item.c' object='indicator_sound_service-voip-input-menu-item.obj' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -c -o indicator_sound_service-voip-input-menu-item.obj `if test -f 'voip-input-menu-item.c'; then $(CYGPATH_W) 'voip-input-menu-item.c'; else $(CYGPATH_W) '$(srcdir)/voip-input-menu-item.c'; fi` + indicator_sound_service-mute-menu-item.o: mute-menu-item.c @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(indicator_sound_service_CFLAGS) $(CFLAGS) -MT indicator_sound_service-mute-menu-item.o -MD -MP -MF $(DEPDIR)/indicator_sound_service-mute-menu-item.Tpo -c -o indicator_sound_service-mute-menu-item.o `test -f 'mute-menu-item.c' || echo '$(srcdir)/'`mute-menu-item.c @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/indicator_sound_service-mute-menu-item.Tpo $(DEPDIR)/indicator_sound_service-mute-menu-item.Po diff --git a/src/active-sink.c b/src/active-sink.c index b7954be..a78d33e 100644 --- a/src/active-sink.c +++ b/src/active-sink.c @@ -21,7 +21,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #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; @@ -52,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 @@ -72,6 +72,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 +80,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); @@ -121,6 +123,32 @@ active_sink_populate (ActiveSink* sink, } 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) { @@ -168,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) { @@ -219,7 +254,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; @@ -279,6 +314,26 @@ 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); + 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* active_sink_new (SoundServiceDbus* service) { @@ -287,7 +342,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..57b3079 100644 --- a/src/active-sink.h +++ b/src/active-sink.h @@ -50,21 +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); - gboolean active_sink_is_populated (ActiveSink* sink); -void active_sink_determine_blocking_state (ActiveSink* self); - gint active_sink_get_index (ActiveSink* self); -SoundState active_sink_get_state (ActiveSink* self); - void active_sink_deactivate (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, gboolean visible); +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/common-defs.h b/src/common-defs.h index 63d9d40..2184a48 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -31,13 +31,17 @@ typedef enum { AVAILABLE }SoundState; - +#define NOT_ACTIVE -1 #define DBUSMENU_PROPERTY_EMPTY -1 /* DBUS Custom Items */ #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_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/fetch-file.c b/src/fetch-file.c index 3a7fc9b..47f0558 100644 --- a/src/fetch-file.c +++ b/src/fetch-file.c @@ -1,4 +1,4 @@ -/* fetch-file.c generated by valac 0.11.5, the Vala compiler +/* fetch-file.c generated by valac 0.11.6, the Vala compiler * generated from fetch-file.vala, do not modify */ /* diff --git a/src/freedesktop-interfaces.c b/src/freedesktop-interfaces.c index 49d0be2..b687cc8 100644 --- a/src/freedesktop-interfaces.c +++ b/src/freedesktop-interfaces.c @@ -1,4 +1,4 @@ -/* freedesktop-interfaces.c generated by valac 0.11.5, the Vala compiler +/* freedesktop-interfaces.c generated by valac 0.11.6, the Vala compiler * generated from freedesktop-interfaces.vala, do not modify */ /* diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 7e5ebc7..2466550 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -32,12 +32,12 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #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; @@ -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, @@ -191,6 +195,9 @@ get_menu (IndicatorObject * io) 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); dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), @@ -401,8 +408,53 @@ 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; +} +/** + * 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, + 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); + + 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 = 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; } @@ -441,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; diff --git a/src/metadata-menu-item.c b/src/metadata-menu-item.c index cda3934..aa93700 100644 --- a/src/metadata-menu-item.c +++ b/src/metadata-menu-item.c @@ -1,4 +1,4 @@ -/* metadata-menu-item.c generated by valac 0.11.5, the Vala compiler +/* metadata-menu-item.c generated by valac 0.11.6, the Vala compiler * generated from metadata-menu-item.vala, do not modify */ /* diff --git a/src/mpris2-controller.c b/src/mpris2-controller.c index 08d0722..aabbfb7 100644 --- a/src/mpris2-controller.c +++ b/src/mpris2-controller.c @@ -1,4 +1,4 @@ -/* mpris2-controller.c generated by valac 0.11.5, the Vala compiler +/* mpris2-controller.c generated by valac 0.11.6, the Vala compiler * generated from mpris2-controller.vala, do not modify */ /* diff --git a/src/mpris2-interfaces.c b/src/mpris2-interfaces.c index 3243404..8aa2079 100644 --- a/src/mpris2-interfaces.c +++ b/src/mpris2-interfaces.c @@ -1,4 +1,4 @@ -/* mpris2-interfaces.c generated by valac 0.11.5, the Vala compiler +/* mpris2-interfaces.c generated by valac 0.11.6, the Vala compiler * generated from mpris2-interfaces.vala, do not modify */ /* diff --git a/src/mpris2-watcher.c b/src/mpris2-watcher.c index 7b362d8..f93a528 100644 --- a/src/mpris2-watcher.c +++ b/src/mpris2-watcher.c @@ -1,4 +1,4 @@ -/* mpris2-watcher.c generated by valac 0.11.5, the Vala compiler +/* mpris2-watcher.c generated by valac 0.11.6, the Vala compiler * generated from mpris2-watcher.vala, do not modify */ /* diff --git a/src/music-player-bridge.c b/src/music-player-bridge.c index fe42ce4..0e5585c 100644 --- a/src/music-player-bridge.c +++ b/src/music-player-bridge.c @@ -1,4 +1,4 @@ -/* music-player-bridge.c generated by valac 0.11.5, the Vala compiler +/* music-player-bridge.c generated by valac 0.11.6, the Vala compiler * generated from music-player-bridge.vala, do not modify */ /* @@ -150,6 +150,7 @@ GType mpris2_watcher_get_type (void) G_GNUC_CONST; enum { MUSIC_PLAYER_BRIDGE_DUMMY_PROPERTY }; +#define MUSIC_PLAYER_BRIDGE_DEVICE_ITEMS_COUNT 3 MusicPlayerBridge* music_player_bridge_new (void); MusicPlayerBridge* music_player_bridge_construct (GType object_type); static void music_player_bridge_on_blacklist_update (MusicPlayerBridge* self, gchar** blacklist, int blacklist_length1); @@ -206,7 +207,7 @@ MusicPlayerBridge* music_player_bridge_new (void) { static void music_player_bridge_on_blacklist_update (MusicPlayerBridge* self, gchar** blacklist, int blacklist_length1) { g_return_if_fail (self != NULL); - g_debug ("music-player-bridge.vala:43: some blacklist update"); + g_debug ("music-player-bridge.vala:45: some blacklist update"); { gchar** s_collection; int s_collection_length1; @@ -230,7 +231,7 @@ static void music_player_bridge_on_blacklist_update (MusicPlayerBridge* self, gc if (_tmp3_) { gpointer _tmp4_ = NULL; PlayerController* _tmp5_; - g_debug ("music-player-bridge.vala:48: Apparently %s is now blacklisted - remove" \ + g_debug ("music-player-bridge.vala:50: Apparently %s is now blacklisted - remove" \ " thy self", key); _tmp4_ = gee_abstract_map_get ((GeeAbstractMap*) self->priv->registered_clients, key); _tmp5_ = (PlayerController*) _tmp4_; @@ -283,13 +284,13 @@ static void music_player_bridge_try_to_add_inactive_familiar_clients (MusicPlaye } _tmp2_ = gee_abstract_list_get ((GeeAbstractList*) _desktop_list, _desktop_index); desktop = (gchar*) _tmp2_; - g_debug ("music-player-bridge.vala:60: interested client found : %s", desktop); + g_debug ("music-player-bridge.vala:62: interested client found : %s", desktop); _tmp3_ = g_strconcat (desktop, ".desktop", NULL); _tmp4_ = _tmp3_; _tmp5_ = music_player_bridge_create_app_info (_tmp4_); app_info = (_tmp6_ = _tmp5_, _g_free0 (_tmp4_), _tmp6_); if (app_info == NULL) { - g_warning ("music-player-bridge.vala:63: Could not create app_info for path %s \n" \ + g_warning ("music-player-bridge.vala:65: Could not create app_info for path %s \n" \ " Getting out of here ", desktop); _g_object_unref0 (app_info); _g_free0 (desktop); @@ -320,12 +321,12 @@ static gint music_player_bridge_calculate_menu_position (MusicPlayerBridge* self g_return_val_if_fail (self != NULL, 0); _tmp0_ = gee_map_get_size ((GeeMap*) self->priv->registered_clients); if (_tmp0_ == 0) { - result = 2; + result = MUSIC_PLAYER_BRIDGE_DEVICE_ITEMS_COUNT; return result; } else { gint _tmp1_; _tmp1_ = gee_map_get_size ((GeeMap*) self->priv->registered_clients); - result = 2 + (_tmp1_ * PLAYER_CONTROLLER_WIDGET_QUANTITY); + result = MUSIC_PLAYER_BRIDGE_DEVICE_ITEMS_COUNT + (_tmp1_ * PLAYER_CONTROLLER_WIDGET_QUANTITY); return result; } } @@ -380,7 +381,7 @@ void music_player_bridge_client_has_become_available (MusicPlayerBridge* self, c _tmp0_ = g_strcmp0 (desktop, "") == 0; } if (_tmp0_) { - g_warning ("music-player-bridge.vala:94: Client %s attempting to register without " \ + g_warning ("music-player-bridge.vala:96: Client %s attempting to register without " \ "desktop entry being set on the mpris root", dbus_name); return; } @@ -388,17 +389,17 @@ void music_player_bridge_client_has_become_available (MusicPlayerBridge* self, c _tmp3_ = _tmp2_; _tmp3__length1 = _tmp1_; if ((_tmp4_ = _vala_string_array_contains (_tmp3_, _tmp1_, desktop), _tmp3_ = (_vala_array_free (_tmp3_, _tmp3__length1, (GDestroyNotify) g_free), NULL), _tmp4_)) { - g_debug ("music-player-bridge.vala:99: Client %s attempting to register but I'm " \ -"afraid it is blacklisted", desktop); + g_debug ("music-player-bridge.vala:101: Client %s attempting to register but I'm" \ +" afraid it is blacklisted", desktop); return; } - g_debug ("music-player-bridge.vala:104: client_has_become_available %s", desktop); + g_debug ("music-player-bridge.vala:106: client_has_become_available %s", desktop); _tmp5_ = g_strconcat (desktop, ".desktop", NULL); _tmp6_ = _tmp5_; _tmp7_ = music_player_bridge_create_app_info (_tmp6_); app_info = (_tmp8_ = _tmp7_, _g_free0 (_tmp6_), _tmp8_); if (app_info == NULL) { - g_warning ("music-player-bridge.vala:107: Could not create app_info for path %s \n" \ + g_warning ("music-player-bridge.vala:109: Could not create app_info for path %s \n" \ " Getting out of here ", desktop); _g_object_unref0 (app_info); return; @@ -414,7 +415,7 @@ void music_player_bridge_client_has_become_available (MusicPlayerBridge* self, c PlayerController* _tmp15_ = NULL; PlayerController* _tmp16_; PlayerController* ctrl; - g_debug ("music-player-bridge.vala:115: New client has registered that we have n" \ + g_debug ("music-player-bridge.vala:117: New client has registered that we have n" \ "ot seen before: %s", dbus_name); _tmp12_ = music_player_bridge_fetch_icon_name (desktop); _tmp13_ = _tmp12_; @@ -422,10 +423,10 @@ void music_player_bridge_client_has_become_available (MusicPlayerBridge* self, c _tmp15_ = player_controller_new (self->priv->root_menu, app_info, dbus_name, _tmp13_, _tmp14_, &use_playlists, PLAYER_CONTROLLER_STATE_READY); ctrl = (_tmp16_ = _tmp15_, _g_free0 (_tmp13_), _tmp16_); gee_abstract_map_set ((GeeAbstractMap*) self->priv->registered_clients, mpris_key, ctrl); - g_debug ("music-player-bridge.vala:124: Have not seen this %s before, new contro" \ + g_debug ("music-player-bridge.vala:126: Have not seen this %s before, new contro" \ "ller created.", desktop); settings_manager_add_interested (self->priv->settings_manager, desktop); - g_debug ("music-player-bridge.vala:126: application added to the interested list"); + g_debug ("music-player-bridge.vala:128: application added to the interested list"); _g_object_unref0 (ctrl); } else { gpointer _tmp17_ = NULL; @@ -451,7 +452,7 @@ void music_player_bridge_client_has_become_available (MusicPlayerBridge* self, c _tmp24_ = (PlayerController*) _tmp23_; player_controller_activate (_tmp24_, dbus_name); _g_object_unref0 (_tmp24_); - g_debug ("music-player-bridge.vala:132: Application has already registered - awa" \ + g_debug ("music-player-bridge.vala:134: Application has already registered - awa" \ "ken the hibernation: %s \n", dbus_name); } _g_free0 (mpris_key); @@ -462,14 +463,14 @@ void music_player_bridge_client_has_become_available (MusicPlayerBridge* self, c void music_player_bridge_client_has_vanished (MusicPlayerBridge* self, const gchar* mpris_root_interface) { g_return_if_fail (self != NULL); g_return_if_fail (mpris_root_interface != NULL); - g_debug ("music-player-bridge.vala:138: MusicPlayerBridge -> client with dbus in" \ + g_debug ("music-player-bridge.vala:140: MusicPlayerBridge -> client with dbus in" \ "terface %s has vanished", mpris_root_interface); if (self->priv->root_menu != NULL) { gchar* _tmp0_; gchar* _tmp1_ = NULL; gchar* mpris_key; gboolean _tmp2_ = FALSE; - g_debug ("music-player-bridge.vala:141: attempt to remove %s", mpris_root_interface); + g_debug ("music-player-bridge.vala:143: attempt to remove %s", mpris_root_interface); _tmp0_ = g_strdup (mpris_root_interface); _tmp1_ = music_player_bridge_determine_key (_tmp0_); mpris_key = _tmp1_; @@ -487,7 +488,7 @@ void music_player_bridge_client_has_vanished (MusicPlayerBridge* self, const gch _tmp5_ = (PlayerController*) _tmp4_; player_controller_hibernate (_tmp5_); _g_object_unref0 (_tmp5_); - g_debug ("music-player-bridge.vala:145: Successively offlined client %s", mpris_key); + g_debug ("music-player-bridge.vala:147: Successively offlined client %s", mpris_key); } _g_free0 (mpris_key); } @@ -547,7 +548,7 @@ static GAppInfo* music_player_bridge_create_app_info (const gchar* desktop) { _tmp1_ = info == NULL; } if (_tmp1_) { - g_warning ("music-player-bridge.vala:164: Could not create a desktopappinfo instan" \ + g_warning ("music-player-bridge.vala:166: Could not create a desktopappinfo instan" \ "ce from app: %s", desktop); result = NULL; _g_object_unref0 (info); @@ -602,7 +603,7 @@ static gchar* music_player_bridge_fetch_icon_name (const gchar* desktop) { GError * _error_; _error_ = _inner_error_; _inner_error_ = NULL; - g_warning ("music-player-bridge.vala:180: Error loading keyfile - FileError"); + g_warning ("music-player-bridge.vala:182: Error loading keyfile - FileError"); result = NULL; _g_error_free0 (_error_); _g_key_file_free0 (desktop_keyfile); @@ -615,7 +616,7 @@ static gchar* music_player_bridge_fetch_icon_name (const gchar* desktop) { GError * _error_; _error_ = _inner_error_; _inner_error_ = NULL; - g_warning ("music-player-bridge.vala:184: Error loading keyfile - KeyFileError"); + g_warning ("music-player-bridge.vala:186: Error loading keyfile - KeyFileError"); result = NULL; _g_error_free0 (_error_); _g_key_file_free0 (desktop_keyfile); @@ -652,7 +653,7 @@ static gchar* music_player_bridge_fetch_icon_name (const gchar* desktop) { GError * _error_; _error_ = _inner_error_; _inner_error_ = NULL; - g_warning ("music-player-bridge.vala:193: Error trying to fetch the icon name from" \ + g_warning ("music-player-bridge.vala:195: Error trying to fetch the icon name from" \ " the keyfile"); result = NULL; _g_error_free0 (_error_); @@ -710,7 +711,7 @@ static gchar* music_player_bridge_determine_key (gchar* desktop_or_interface) { _g_free0 (_result_); _result_ = _tmp8_; } - g_debug ("music-player-bridge.vala:216: determine key result = %s", _result_); + g_debug ("music-player-bridge.vala:218: determine key result = %s", _result_); result = _result_; temp = (_vala_array_free (temp, temp_length1, (GDestroyNotify) g_free), NULL); tokens = (_vala_array_free (tokens, tokens_length1, (GDestroyNotify) g_free), NULL); diff --git a/src/music-player-bridge.h b/src/music-player-bridge.h index 4c98ac7..dd0f816 100644 --- a/src/music-player-bridge.h +++ b/src/music-player-bridge.h @@ -1,4 +1,4 @@ -/* music-player-bridge.h generated by valac 0.11.5, the Vala compiler, do not modify */ +/* music-player-bridge.h generated by valac 0.11.6, the Vala compiler, do not modify */ #ifndef __MUSIC_PLAYER_BRIDGE_H__ 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<string, PlayerController> 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/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/player-controller.c b/src/player-controller.c index 84bb0c1..9b1e7bb 100644 --- a/src/player-controller.c +++ b/src/player-controller.c @@ -1,4 +1,4 @@ -/* player-controller.c generated by valac 0.11.5, the Vala compiler +/* player-controller.c generated by valac 0.11.6, the Vala compiler * generated from player-controller.vala, do not modify */ /* diff --git a/src/player-item.c b/src/player-item.c index b974b67..c9f0e74 100644 --- a/src/player-item.c +++ b/src/player-item.c @@ -1,4 +1,4 @@ -/* player-item.c generated by valac 0.11.5, the Vala compiler +/* player-item.c generated by valac 0.11.6, the Vala compiler * generated from player-item.vala, do not modify */ /* @@ -316,8 +316,6 @@ gboolean player_item_populated (PlayerItem* self, GeeHashSet* attrs) { gpointer _tmp2_ = NULL; gchar* prop; gint _tmp3_; - gint value_int; - gint _tmp4_; _tmp1_ = gee_iterator_next (_prop_it); if (!_tmp1_) { break; @@ -325,9 +323,7 @@ gboolean player_item_populated (PlayerItem* self, GeeHashSet* attrs) { _tmp2_ = gee_iterator_get (_prop_it); prop = (gchar*) _tmp2_; _tmp3_ = dbusmenu_menuitem_property_get_int ((DbusmenuMenuitem*) self, prop); - value_int = _tmp3_; - _tmp4_ = dbusmenu_menuitem_property_get_int ((DbusmenuMenuitem*) self, prop); - if (_tmp4_ != PLAYER_ITEM_EMPTY) { + if (_tmp3_ != PLAYER_ITEM_EMPTY) { result = TRUE; _g_free0 (prop); _g_object_unref0 (_prop_it); 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/playlists-menu-item.c b/src/playlists-menu-item.c index d38004c..a465a8d 100644 --- a/src/playlists-menu-item.c +++ b/src/playlists-menu-item.c @@ -1,4 +1,4 @@ -/* playlists-menu-item.c generated by valac 0.11.5, the Vala compiler +/* playlists-menu-item.c generated by valac 0.11.6, the Vala compiler * generated from playlists-menu-item.vala, do not modify */ /* diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index 3aed1f1..76102e4 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -19,9 +19,9 @@ with this program. If not, see <http://www.gnu.org/licenses/>. /**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) @@ -47,10 +47,22 @@ 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_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, @@ -64,6 +76,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; @@ -152,6 +165,25 @@ 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) ); +} + +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 /**********************************************************************************************************************/ @@ -163,19 +195,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{ @@ -185,9 +219,36 @@ pm_subscribed_events_callback (pa_context *c, userdata) ); } 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; + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + active_sink_deactivate_voip_source (sink, FALSE); + } + 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 ("sink input event"); + if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { + 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); + // 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)); @@ -206,6 +267,7 @@ pm_subscribed_events_callback (pa_context *c, } + static void pm_context_state_callback (pa_context *c, void *userdata) { @@ -244,6 +306,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"); @@ -261,7 +324,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, @@ -276,24 +340,46 @@ 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 for the source + } pa_operation_unref(operation); } @@ -335,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); } } @@ -356,12 +446,30 @@ 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; } + 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); 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 ... 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 + // from the sink input ensure our voip item is using the right source. + } + } + + // And finally check for the mute blocking state if (active_sink_get_index (a_sink) == info->sink){ active_sink_determine_blocking_state (a_sink); } @@ -404,3 +512,66 @@ 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; + } + // 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); + } +} + +static void +pm_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; + } + // 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; + } + 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/pulseaudio-mgr.h b/src/pulseaudio-mgr.h index c0ab9c0..d61117d 100644 --- a/src/pulseaudio-mgr.h +++ b/src/pulseaudio-mgr.h @@ -22,6 +22,8 @@ with this program. If not, see <http://www.gnu.org/licenses/>. 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/settings-manager.c b/src/settings-manager.c index d383b4f..7536ced 100644 --- a/src/settings-manager.c +++ b/src/settings-manager.c @@ -1,4 +1,4 @@ -/* settings-manager.c generated by valac 0.11.5, the Vala compiler +/* settings-manager.c generated by valac 0.11.6, the Vala compiler * generated from settings-manager.vala, do not modify */ /* @@ -71,7 +71,6 @@ void settings_manager_clear_list (SettingsManager* self); void settings_manager_add_interested (SettingsManager* self, const gchar* app_desktop_name); static void _vala_array_add1 (gchar*** array, int* length, int* size, gchar* value); static void settings_manager_on_blacklist_event (SettingsManager* self); -static void settings_manager_reveal_contents (SettingsManager* self); static void g_cclosure_user_marshal_VOID__BOXED_INT (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data); static GObject * settings_manager_constructor (GType type, guint n_construct_properties, GObjectConstructParam * construct_properties); static void _settings_manager_on_blacklist_event_g_settings_changed (GSettings* _sender, const gchar* key, gpointer self); @@ -243,67 +242,6 @@ static void settings_manager_on_blacklist_event (SettingsManager* self) { } -static void settings_manager_reveal_contents (SettingsManager* self) { - gchar** _tmp0_; - gchar** _tmp1_ = NULL; - gchar** already_interested; - gint already_interested_length1; - gint _already_interested_size_; - gchar** _tmp3_; - gchar** _tmp4_ = NULL; - gchar** blacklisted; - gint blacklisted_length1; - gint _blacklisted_size_; - g_return_if_fail (self != NULL); - _tmp1_ = _tmp0_ = g_settings_get_strv (self->priv->settings, "interested-media-players"); - already_interested = _tmp1_; - already_interested_length1 = _vala_array_length (_tmp0_); - _already_interested_size_ = _vala_array_length (_tmp0_); - { - gchar** s_collection; - int s_collection_length1; - int s_it; - s_collection = already_interested; - s_collection_length1 = already_interested_length1; - for (s_it = 0; s_it < already_interested_length1; s_it = s_it + 1) { - gchar* _tmp2_; - gchar* s; - _tmp2_ = g_strdup (s_collection[s_it]); - s = _tmp2_; - { - g_debug ("settings-manager.vala:79: client %s is in interested array", s); - _g_free0 (s); - } - } - } - _tmp4_ = _tmp3_ = g_settings_get_strv (self->priv->settings, "blacklisted-media-players"); - blacklisted = _tmp4_; - blacklisted_length1 = _vala_array_length (_tmp3_); - _blacklisted_size_ = _vala_array_length (_tmp3_); - { - gchar** s_collection; - int s_collection_length1; - int s_it; - s_collection = blacklisted; - s_collection_length1 = blacklisted_length1; - for (s_it = 0; s_it < blacklisted_length1; s_it = s_it + 1) { - gchar* _tmp5_; - gchar* s; - _tmp5_ = g_strdup (s_collection[s_it]); - s = _tmp5_; - { - g_debug ("settings-manager.vala:84: client %s is in blacklisted array", s); - _g_free0 (s); - } - } - } - g_debug ("settings-manager.vala:87: interested array size = %i", already_interested_length1); - g_debug ("settings-manager.vala:88: blacklisted array size = %i", blacklisted_length1); - blacklisted = (_vala_array_free (blacklisted, blacklisted_length1, (GDestroyNotify) g_free), NULL); - already_interested = (_vala_array_free (already_interested, already_interested_length1, (GDestroyNotify) g_free), NULL); -} - - static void g_cclosure_user_marshal_VOID__BOXED_INT (GClosure * closure, GValue * return_value, guint n_param_values, const GValue * param_values, gpointer invocation_hint, gpointer marshal_data) { typedef void (*GMarshalFunc_VOID__BOXED_INT) (gpointer data1, gpointer arg_1, gint arg_2, gpointer data2); register GMarshalFunc_VOID__BOXED_INT callback; 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/sound-service-dbus.c b/src/sound-service-dbus.c index 58367f4..9be39c7 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -157,14 +157,18 @@ 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 + // 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); - 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..c79b9f6 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/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,23 +151,13 @@ 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 diff --git a/src/title-menu-item.c b/src/title-menu-item.c index 66c38e5..2d6a7e8 100644 --- a/src/title-menu-item.c +++ b/src/title-menu-item.c @@ -1,4 +1,4 @@ -/* title-menu-item.c generated by valac 0.11.5, the Vala compiler +/* title-menu-item.c generated by valac 0.11.6, the Vala compiler * generated from title-menu-item.vala, do not modify */ /* diff --git a/src/transport-menu-item.c b/src/transport-menu-item.c index 05b5bb9..036b5d4 100644 --- a/src/transport-menu-item.c +++ b/src/transport-menu-item.c @@ -1,4 +1,4 @@ -/* transport-menu-item.c generated by valac 0.11.5, the Vala compiler +/* transport-menu-item.c generated by valac 0.11.6, the Vala compiler * generated from transport-menu-item.vala, do not modify */ /* diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c new file mode 100644 index 0000000..a742654 --- /dev/null +++ b/src/voip-input-menu-item.c @@ -0,0 +1,277 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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 <http://www.gnu.org/licenses/>. +*/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib/gi18n.h> +#include "voip-input-menu-item.h" +#include "common-defs.h" +#include "pulseaudio-mgr.h" + +typedef struct _VoipInputMenuItemPrivate VoipInputMenuItemPrivate; + +struct _VoipInputMenuItemPrivate { + ActiveSink* a_sink; + pa_cvolume volume; + gint mute; + guint32 volume_steps; + pa_channel_map channel_map; + pa_volume_t base_volume; + 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)) + +/* 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); +// 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 +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); + +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 ); + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (self); + dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(self), + DBUSMENU_MENUITEM_PROP_VISIBLE, + FALSE ); + + priv->source_index = NOT_ACTIVE; + priv->sink_input_index = NOT_ACTIVE; + priv->client_index = NOT_ACTIVE; + priv->mute = NOT_ACTIVE; +} + +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); + } + + 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)); + 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->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); + } + } +} + +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->source_index == NOT_ACTIVE){ + priv->base_volume = source->base_volume; + priv->volume_steps = source->n_volume_steps; + priv->channel_map = source->channel_map; + 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); + 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; + +} + +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 != NOT_ACTIVE && + priv->source_index != NOT_ACTIVE){ + return FALSE; + } + + priv->sink_input_index = sink_input_index; + priv->client_index = client_index; + + 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) +{ + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); + return priv->source_index != NOT_ACTIVE; +} + +gint +voip_input_menu_item_get_index (VoipInputMenuItem* item) +{ + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); + 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; +} + +/** + * 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, gboolean visible) +{ + VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); + 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 = NOT_ACTIVE; + priv->sink_input_index = 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->source_index == NOT_ACTIVE && 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 ); +} + +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..6f4ed85 --- /dev/null +++ b/src/voip-input-menu-item.h @@ -0,0 +1,70 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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 <http://www.gnu.org/licenses/>. +*/ +#ifndef __VOIP_INPUT_MENU_ITEM_H__ +#define __VOIP_INPUT_MENU_ITEM_H__ + +#include <glib.h> +#include <pulse/pulseaudio.h> +#include <libdbusmenu-glib/menuitem.h> +#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, + 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_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); + +gint voip_input_menu_item_get_sink_input_index (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); + +G_END_DECLS + +#endif + diff --git a/src/voip-input-widget.c b/src/voip-input-widget.c new file mode 100644 index 0000000..9b29feb --- /dev/null +++ b/src/voip-input-widget.c @@ -0,0 +1,279 @@ + +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +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 <http://www.gnu.org/licenses/>. +*/ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include <glib/gi18n.h> +#include <math.h> +#include <glib.h> +#include "voip-input-widget.h" +#include "common-defs.h" +#include <libido/idoscalemenuitem.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) +{ + 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-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-high"); + 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_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; + gdouble update = g_variant_get_double (value); + //g_debug("volume-widget - update level with value %f", update); + 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 +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_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; + 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 +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 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) +{ + 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); + + 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; +} + +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 <conor.curran@canonical.com> + +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 <http://www.gnu.org/licenses/>. +*/ +#ifndef __VOIP_INPUT_WIDGET_H__ +#define __VOIP_INPUT_WIDGET_H__ + +#include <glib.h> +#include <glib-object.h> +#include <libdbusmenu-gtk/menuitem.h> + +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 + |