aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xconfigure22
-rw-r--r--configure.ac6
-rw-r--r--src/Makefile.am8
-rw-r--r--src/Makefile.in36
-rw-r--r--src/active-sink.c66
-rw-r--r--src/active-sink.h25
-rw-r--r--src/common-defs.h6
-rw-r--r--src/fetch-file.c2
-rw-r--r--src/freedesktop-interfaces.c2
-rw-r--r--src/indicator-sound.c68
-rw-r--r--src/metadata-menu-item.c2
-rw-r--r--src/mpris2-controller.c2
-rw-r--r--src/mpris2-interfaces.c2
-rw-r--r--src/mpris2-watcher.c2
-rw-r--r--src/music-player-bridge.c49
-rw-r--r--src/music-player-bridge.h2
-rw-r--r--src/music-player-bridge.vala8
-rw-r--r--src/mute-menu-item.c1
-rw-r--r--src/player-controller.c2
-rw-r--r--src/player-item.c8
-rw-r--r--src/player-item.vala3
-rw-r--r--src/playlists-menu-item.c2
-rw-r--r--src/pulseaudio-mgr.c209
-rw-r--r--src/pulseaudio-mgr.h2
-rw-r--r--src/settings-manager.c64
-rw-r--r--src/settings-manager.vala2
-rw-r--r--src/sound-service-dbus.c8
-rw-r--r--src/sound-service-dbus.h3
-rw-r--r--src/sound-service.c2
-rw-r--r--src/sound-state-manager.c12
-rw-r--r--src/sound-state-manager.h2
-rw-r--r--src/title-menu-item.c2
-rw-r--r--src/transport-menu-item.c2
-rw-r--r--src/voip-input-menu-item.c277
-rw-r--r--src/voip-input-menu-item.h70
-rw-r--r--src/voip-input-widget.c279
-rw-r--r--src/voip-input-widget.h55
37 files changed, 1133 insertions, 180 deletions
diff --git a/configure b/configure
index d6c0451..89cc1f9 100755
--- a/configure
+++ b/configure
@@ -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
+