From c879c510dbef95deea70687d59c2013005bf946d Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 24 Feb 2010 14:19:01 +0000 Subject: unit tests for the indicator side added --- Makefile.am | 1 + configure.ac | 1 + src/indicator-sound.c | 282 ++++++++++++++++++++++--------------------- tests/Makefile.am | 23 ++++ tests/test-indicator-sound.c | 113 +++++++++++++++++ 5 files changed, 282 insertions(+), 138 deletions(-) create mode 100644 tests/Makefile.am create mode 100644 tests/test-indicator-sound.c diff --git a/Makefile.am b/Makefile.am index 141bb71..357fa33 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,6 +2,7 @@ SUBDIRS = \ src \ data \ + tests \ po EXTRA_DIST = autogen.sh diff --git a/configure.ac b/configure.ac index 48022e2..c83df5c 100644 --- a/configure.ac +++ b/configure.ac @@ -127,6 +127,7 @@ AC_OUTPUT([ Makefile src/Makefile data/Makefile +tests/Makefile po/Makefile.in ]) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index acacddc..ffe7acb 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -100,13 +100,15 @@ static void fetch_mute_value_from_dbus(); static void prepare_state_machine(); static void determine_state_from_volume(gdouble volume_percent); static void update_state(const gint state); + static const gint STATE_MUTED = 0; static const gint STATE_ZERO = 1; static const gint STATE_LOW = 2; static const gint STATE_MEDIUM = 3; static const gint STATE_HIGH = 4; static const gint STATE_MUTED_WHILE_INPUT = 5; -static const gint STATE_SINKS_NONE = 5; +static const gint STATE_SINKS_NONE = 6; + static GHashTable *volume_states = NULL; static GtkImage *speaker_image = NULL; static GtkWidget* primary_image = NULL; @@ -115,6 +117,7 @@ static gint previous_state = 0; static gdouble initial_volume_percent = 0; static gboolean initial_mute = FALSE; +// Construction static void indicator_sound_class_init (IndicatorSoundClass *klass) { @@ -147,21 +150,91 @@ static void indicator_sound_init (IndicatorSound *self) return; } +static void +indicator_sound_dispose (GObject *object) +{ + IndicatorSound * self = INDICATOR_SOUND(object); -/* -Prepare states Array. -*/ -static void prepare_state_machine() + if (self->service != NULL) { + g_object_unref(G_OBJECT(self->service)); + self->service = NULL; + } + g_hash_table_destroy(volume_states); + G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object); + return; +} + +static void +indicator_sound_finalize (GObject *object) { - // TODO we need three more images - volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-zero-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel")); - g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel")); + G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object); + return; +} + +static GtkLabel * +get_label (IndicatorObject * io) +{ + return NULL; +} + +static GtkImage * +get_icon (IndicatorObject * io) +{ + gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); + //g_debug("At start-up attempting to set the image to %s", current_name); + speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU)); + gtk_widget_show(GTK_WIDGET(speaker_image)); + return speaker_image; +} + +/* Indicator based function to get the menu for the whole + applet. This starts up asking for the parts of the menu + from the various services. */ +static GtkMenu * +get_menu (IndicatorObject * io) +{ + DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT); + DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu); + dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item); + + // register Key-press listening on the menu widget as the slider does not allow this. + g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL); + + return GTK_MENU(menu); +} + +/** +new_slider_item: +Create a new dBusMenu Slider item. +**/ +static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) +{ + g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); + g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); + + volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 0.5); + g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL); + + GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider); + + dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent); + g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider); + + // register slider changes listening on the range + GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); + g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); + // alternative callback mechanism which i could use again at some point. +/* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */ + + // Set images on the ido + primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); + gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); + GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); + gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU); + + gtk_widget_show_all(volume_slider); + + return TRUE; } static void @@ -205,6 +278,63 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u return; } + + + +/* +Prepare states Array. +*/ +static void prepare_state_machine() +{ + // TODO we need three more images + volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-low-zero-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_LOW), g_strdup("audio-volume-low-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MEDIUM), g_strdup("audio-volume-medium-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_HIGH), g_strdup("audio-volume-high-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT), g_strdup("audio-volume-muted-blocking-panel")); + g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel")); +} + + + +static void update_state(const gint state) +{ +/* g_debug("update state beginning - previous_state = %i", previous_state);*/ + + previous_state = current_state; + +/* g_debug("update state 3rd line - previous_state = %i", previous_state);*/ + + current_state = state; + gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); + gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); +} + + +static void determine_state_from_volume(gdouble volume_percent) +{ +/* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/ + + gint state = previous_state; + if (volume_percent < 30.0 && volume_percent > 0){ + state = STATE_LOW; + } + else if(volume_percent < 70.0 && volume_percent >= 30.0){ + state = STATE_MEDIUM; + } + else if(volume_percent >= 70.0){ + state = STATE_HIGH; + } + else if(volume_percent == 0.0){ + state = STATE_ZERO; + } + update_state(state); +} + + + static void fetch_volume_percent_from_dbus() { GError * error = NULL; @@ -270,130 +400,6 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value g_debug("signal caught - sink mute update with mute value: %i", mute_value); gtk_widget_set_sensitive(volume_slider, !mute_value); } - - -static void -indicator_sound_dispose (GObject *object) -{ - IndicatorSound * self = INDICATOR_SOUND(object); - - if (self->service != NULL) { - g_object_unref(G_OBJECT(self->service)); - self->service = NULL; - } - g_hash_table_destroy(volume_states); - G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object); - return; -} - -static void -indicator_sound_finalize (GObject *object) -{ - G_OBJECT_CLASS (indicator_sound_parent_class)->finalize (object); - return; -} - -static GtkLabel * -get_label (IndicatorObject * io) -{ - return NULL; -} - -static GtkImage * -get_icon (IndicatorObject * io) -{ - gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - g_debug("At start-up attempting to set the image to %s", current_name); - speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU)); - gtk_widget_show(GTK_WIDGET(speaker_image)); - return speaker_image; -} - -static void update_state(const gint state) -{ -/* g_debug("update state beginning - previous_state = %i", previous_state);*/ - - previous_state = current_state; - -/* g_debug("update state 3rd line - previous_state = %i", previous_state);*/ - - current_state = state; - gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); -} - - -static void determine_state_from_volume(gdouble volume_percent) -{ -/* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/ - - gint state = previous_state; - if (volume_percent < 30.0 && volume_percent > 0){ - state = STATE_LOW; - } - else if(volume_percent < 70.0 && volume_percent > 30.0){ - state = STATE_MEDIUM; - } - else if(volume_percent > 70.0){ - state = STATE_HIGH; - } - else if(volume_percent == 0.0){ - state = STATE_ZERO; - } - update_state(state); -} - - -/* Indicator based function to get the menu for the whole - applet. This starts up asking for the parts of the menu - from the various services. */ -static GtkMenu * -get_menu (IndicatorObject * io) -{ - DbusmenuGtkMenu *menu = dbusmenu_gtkmenu_new(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_OBJECT); - DbusmenuGtkClient *client = dbusmenu_gtkmenu_get_client(menu); - dbusmenu_client_add_type_handler(DBUSMENU_CLIENT(client), DBUSMENU_SLIDER_MENUITEM_TYPE, new_slider_item); - - // register Key-press listening on the menu widget as the slider does not allow this. - g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL); - - return GTK_MENU(menu); -} - -/** -new_slider_item: -Create a new dBusMenu Slider item, register the -**/ -static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client) -{ - g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); - g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); - - volume_slider = ido_scale_menu_item_new_with_range ("Volume", initial_volume_percent, 0, 100, 0.5); - g_object_set(volume_slider, "reverse-scroll-events", TRUE, NULL); - - GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider); - - dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent); - g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider); - - // register slider changes listening on the range - GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); - g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); - // alternative callback mechanism which i could use again at some point. -/* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */ - - // Set images on the ido - primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); - GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU); - - gtk_widget_show_all(volume_slider); - - return TRUE; -} - /** slider_prop_change_cb: Whenever we have a property change on a DbusmenuMenuitem this will be called. diff --git a/tests/Makefile.am b/tests/Makefile.am new file mode 100644 index 0000000..05e1bd0 --- /dev/null +++ b/tests/Makefile.am @@ -0,0 +1,23 @@ + +check_PROGRAMS = \ + test-indicator-sound + +TESTS = +DISTCLEANFILES = $(TESTS) + +######################################### +## test-indicator-sound +######################################### +test_indicator_sound_SOURCES = \ + test-indicator-sound.c + +test_indicator_sound_CFLAGS = \ + $(APPLET_CFLAGS) \ + -Wall -Werror \ + -I$(srcdir) \ + -DBUILD_DIR="\"$(builddir)\"" + +test_indicator_sound_LDADD = \ + $(APPLET_LIBS) \ + $(INDICATORDIR)/libsoundmenu.la + diff --git a/tests/test-indicator-sound.c b/tests/test-indicator-sound.c new file mode 100644 index 0000000..81fc966 --- /dev/null +++ b/tests/test-indicator-sound.c @@ -0,0 +1,113 @@ +/* +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +/*#include */ +/*#include */ +/*#include */ +/*#include */ +/*#include */ +/*#include */ +/*#include */ + +/*#include */ +/*#include */ + +/*#include */ +/*#include */ +/*#include */ + +#include +#include "../src/indicator-sound.c" + + +void test_libindicator_sound_init() +{ + IndicatorObject * sound_menu = indicator_object_new_from_file("/home/ronoc/canonical/repos/branches/indicator-sound/tests-indicator-sound/indicator-sound/src/.libs/libsoundmenu.so"); + g_assert(sound_menu != NULL); + g_object_unref(G_OBJECT(sound_menu)); +} + +void test_libindicator_determine_state() +{ + IndicatorObject * sound_menu = indicator_object_new_from_file("/home/ronoc/canonical/repos/branches/indicator-sound/tests-indicator-sound/indicator-sound/src/.libs/libsoundmenu.so"); + get_icon(sound_menu); + + determine_state_from_volume(40); + g_assert(current_state == STATE_MEDIUM); + + determine_state_from_volume(0); + g_assert(current_state == STATE_ZERO); + + determine_state_from_volume(15); + g_assert(current_state == STATE_LOW); + + determine_state_from_volume(70); + g_assert(current_state == STATE_HIGH); + + g_object_unref(G_OBJECT(sound_menu)); +} + +void test_libindicator_image_names() +{ + prepare_state_machine(); + + gchar* muted_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED)); + g_assert(g_ascii_strncasecmp("audio-volume-muted-panel", muted_name, strlen("audio-volume-muted-panel")) == 0); + + gchar* zero_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)); + g_assert(g_ascii_strncasecmp("audio-volume-low-zero-panel", zero_name, strlen("audio-volume-low-zero-panel")) == 0); + + gchar* low_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_LOW)); + g_assert(g_ascii_strncasecmp("audio-volume-low-panel", low_name, strlen("audio-volume-low-panel")) == 0); + + gchar* medium_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MEDIUM)); + g_assert(g_ascii_strncasecmp("audio-volume-medium-panel", medium_name, strlen("audio-volume-medium-panel")) == 0); + + gchar* high_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)); + g_assert(g_ascii_strncasecmp("audio-volume-high-panel", high_name, strlen("audio-volume-high-panel")) == 0); + + gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + g_assert(g_ascii_strncasecmp("audio-volume-muted-blocking-panel", blocked_name, strlen("audio-volume-muted-blocking-panel")) == 0); + + gchar* none_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE)); + g_assert(g_ascii_strncasecmp("audio-output-none-panel", none_name, strlen("audio-output-none-panel")) == 0); + + // tidy up + g_hash_table_destroy(volume_states); +} + + +void test_libindicator_mute_switching() +{ + +} + + +gint main (gint argc, gchar * argv[]) +{ + g_type_init(); + g_test_init(&argc, &argv, NULL); + + g_test_add_func("/indicator-sound/indicator-sound/init", test_libindicator_sound_init); + g_test_add_func("/indicator-sound/indicator-sound/state_machine", test_libindicator_determine_state); + g_test_add_func("/indicator-sound/indicator-sound/image_names", test_libindicator_image_names); + + return g_test_run (); +} + -- cgit v1.2.3 From a7952974571bf697b218cedacacd118e2e05e97e Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 25 Feb 2010 14:12:05 +0000 Subject: fixes --- tests/Makefile.am | 36 ++++++++++++++++++++++++++++++++++-- tests/run-xvfb.sh | 8 ++++++++ tests/test-indicator-sound.c | 19 ++----------------- 3 files changed, 44 insertions(+), 19 deletions(-) create mode 100644 tests/run-xvfb.sh diff --git a/tests/Makefile.am b/tests/Makefile.am index 05e1bd0..dadc1e4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -10,14 +10,46 @@ DISTCLEANFILES = $(TESTS) ######################################### test_indicator_sound_SOURCES = \ test-indicator-sound.c - + test_indicator_sound_CFLAGS = \ $(APPLET_CFLAGS) \ -Wall -Werror \ -I$(srcdir) \ - -DBUILD_DIR="\"$(builddir)\"" + -DBUILD_DIR="\"$(INDICATORDIR)"\" test_indicator_sound_LDADD = \ $(APPLET_LIBS) \ $(INDICATORDIR)/libsoundmenu.la +#DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf + +#test-indicator-sound-dbus: test-indicator-sound-dbus-client test-indicator-sound-dbus-server Makefile.am +# @echo "#!/bin/sh" > test-indicator-sound-dbus +# @echo $(DBUS_RUNNER) --task ./test-indicator-sound-dbus-client --task-name Client --task ./test-indicator-sound-dbus-server --task-name Server --ignore-return >> test-indicator-sound-dbus +# @chmod +x test-libappindicator-dbus + +#TESTS += test-libappindicator-dbus + +XVFB_RUN=". $(srcdir)/run-xvfb.sh" + +EXTRA_DIST = run-xvfb.sh + + +############################# +# Test stuff +############################# + +#XML_REPORT = loader-check-results.xml +#HTML_REPORT = loader-check-results.html + +#loader-tester: test-loader libsoundmenu.la Makefile +# @echo "#!/bin/bash" > loader-tester +# @echo $(XVFB_RUN) >> $@ +# @echo gtester -k --verbose -o=$(XML_REPORT) ./test-loader >> loader-tester +# @chmod +x loader-tester + +#TESTS += loader-tester +#DISTCLEANFILES += loader-tester + +#DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT) + diff --git a/tests/run-xvfb.sh b/tests/run-xvfb.sh new file mode 100644 index 0000000..63b6f0d --- /dev/null +++ b/tests/run-xvfb.sh @@ -0,0 +1,8 @@ +if [ "$DISPLAY" == "" ]; then +Xvfb -ac -noreset -screen 0 800x600x16 -help 2>/dev/null 1>&2 +XID=`for id in 101 102 103 104 105 106 107 197 199 211 223 227 293 307 308 309 310 311 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 4703 4721 4723 4729 4733 4751 9973 9974 9975 9976 9977 9978 9979 9980 9981 9982 9983 9984 9985 9986 9987 9988 9989 9990 9991 9992 9993 9994 9995 9996 9997 9998 9999 ; do test -e /tmp/.X$id-lock || { echo $id; exit 0; }; done; exit 1` +{ Xvfb -ac -noreset -screen 0 800x600x16 :$XID -screen 0 800x600x16 -nolisten tcp -auth /dev/null >/dev/null 2>&1 & trap "kill -15 $! " 0 HUP INT QUIT TRAP USR1 PIPE TERM ; } || { echo "Gtk+Tests:ERROR: Failed to start Xvfb environment for X11 target tests."; exit 1; } +DISPLAY=:$XID +export DISPLAY +echo Setting display: $DISPLAY +fi diff --git a/tests/test-indicator-sound.c b/tests/test-indicator-sound.c index 81fc966..0885bb5 100644 --- a/tests/test-indicator-sound.c +++ b/tests/test-indicator-sound.c @@ -17,35 +17,20 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -/*#include */ -/*#include */ -/*#include */ -/*#include */ -/*#include */ -/*#include */ -/*#include */ - -/*#include */ -/*#include */ - -/*#include */ -/*#include */ -/*#include */ - #include #include "../src/indicator-sound.c" void test_libindicator_sound_init() { - IndicatorObject * sound_menu = indicator_object_new_from_file("/home/ronoc/canonical/repos/branches/indicator-sound/tests-indicator-sound/indicator-sound/src/.libs/libsoundmenu.so"); + IndicatorObject * sound_menu = indicator_object_new_from_file(BUILD_DIR "/.libs/libsoundmenu.so"); g_assert(sound_menu != NULL); g_object_unref(G_OBJECT(sound_menu)); } void test_libindicator_determine_state() { - IndicatorObject * sound_menu = indicator_object_new_from_file("/home/ronoc/canonical/repos/branches/indicator-sound/tests-indicator-sound/indicator-sound/src/.libs/libsoundmenu.so"); + IndicatorObject * sound_menu = indicator_object_new_from_file(BUILD_DIR "/.libs/libsoundmenu.so"); get_icon(sound_menu); determine_state_from_volume(40); -- cgit v1.2.3 From 4cb7db538df7b4e69e49ab047f401b8ba480f224 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 25 Feb 2010 14:43:34 +0000 Subject: path parsing fixed - tests are now portable --- tests/Makefile.am | 2 +- tests/test-indicator-sound.c | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index dadc1e4..4404333 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -15,7 +15,7 @@ test_indicator_sound_CFLAGS = \ $(APPLET_CFLAGS) \ -Wall -Werror \ -I$(srcdir) \ - -DBUILD_DIR="\"$(INDICATORDIR)"\" + -DTOP_BUILD_DIR="\"${abs_top_builddir}\"" test_indicator_sound_LDADD = \ $(APPLET_LIBS) \ diff --git a/tests/test-indicator-sound.c b/tests/test-indicator-sound.c index 0885bb5..0de09b7 100644 --- a/tests/test-indicator-sound.c +++ b/tests/test-indicator-sound.c @@ -23,14 +23,14 @@ with this program. If not, see . void test_libindicator_sound_init() { - IndicatorObject * sound_menu = indicator_object_new_from_file(BUILD_DIR "/.libs/libsoundmenu.so"); + IndicatorObject * sound_menu = indicator_object_new_from_file(TOP_BUILD_DIR "/src/.libs/libsoundmenu.so"); g_assert(sound_menu != NULL); g_object_unref(G_OBJECT(sound_menu)); } void test_libindicator_determine_state() { - IndicatorObject * sound_menu = indicator_object_new_from_file(BUILD_DIR "/.libs/libsoundmenu.so"); + IndicatorObject * sound_menu = indicator_object_new_from_file(TOP_BUILD_DIR "/src/.libs/libsoundmenu.so"); get_icon(sound_menu); determine_state_from_volume(40); -- cgit v1.2.3 From 6468402475d7bfced0ee905bdd56977cc2f4b7da Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 1 Mar 2010 21:54:03 +0000 Subject: new tests for dbus stuff --- configure.ac | 4 +- tests/Makefile.am | 81 +++++++++++++++++------ tests/test-defines.h | 24 +++++++ tests/test-indicator-sound-dbus-client.c | 109 +++++++++++++++++++++++++++++++ tests/test-indicator-sound-dbus-server.c | 61 +++++++++++++++++ 5 files changed, 256 insertions(+), 23 deletions(-) create mode 100644 tests/test-defines.h create mode 100644 tests/test-indicator-sound-dbus-client.c create mode 100644 tests/test-indicator-sound-dbus-server.c diff --git a/configure.ac b/configure.ac index c83df5c..4a2142e 100644 --- a/configure.ac +++ b/configure.ac @@ -1,10 +1,10 @@ -AC_INIT(src/indicator-sound.c) +AC_INIT(indicator-sound, 0.1.2, conor.curran@canonical.com) AC_PREREQ(2.53) AM_CONFIG_HEADER(config.h) -AM_INIT_AUTOMAKE(indicator-sound, 0.1.1) +AM_INIT_AUTOMAKE(indicator-sound, 0.1.2) AM_MAINTAINER_MODE diff --git a/tests/Makefile.am b/tests/Makefile.am index 4404333..7d061fb 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,8 @@ check_PROGRAMS = \ test-indicator-sound + test-indicator-sound-dbus-client \ + test-indicator-sound-dbus-server TESTS = DISTCLEANFILES = $(TESTS) @@ -21,35 +23,72 @@ test_indicator_sound_LDADD = \ $(APPLET_LIBS) \ $(INDICATORDIR)/libsoundmenu.la -#DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf +######################################### +## test-indicator-sound-dbus-client +######################################### + +test_indicator_sound_dbus_client_SOURCES = \ + test-defines.h \ + test-indicator-sound-dbus-client.c + +test_indicator_sound_dbus_client_CFLAGS = \ + $(SOUNDSERVICE_CFLAGS) \ + -Wall -Werror \ + -I$(srcdir) \ + -I$(SOUNDSERVICE_CFLAGS) + +test_indicator_sound_dbus_client_LDADD = \ + $(SOUNDSERVICE_LIBS) \ + $(INDICATORDIR)/libsoundmenu.la + +######################################### +## test-indicator-sound-dbus-server +######################################### +test_indicator_sound_dbus_server_SOURCES = \ + test-defines.h \ + test-indicator-sound-dbus-server.c + +test_indicator_sound_dbus_server_CFLAGS = \ + $(APPLET_CFLAGS) \ + -Wall -Werror \ + -I$(srcdir) + +test_libappindicator_dbus_server_LDADD = \ + $(SOUNDSERVICE_LIBS) \ + $(INDICATORDIR)/libsoundmenu.la + + +######################################### +## Actual tests +######################################### + +#XML_REPORT = indicator-sound-check-results.xml +#HTML_REPORT = indicator-sound-check-results.html + +#indicator-sound-tests: indicator-sound-tests-gtester Makefile.am +# @echo "#!/bin/sh" > $@ +# @echo $(DBUS_RUNNER) --task ./indicator-sound-tests-gtester >> $@ +# @chmod +x $@ -#test-indicator-sound-dbus: test-indicator-sound-dbus-client test-indicator-sound-dbus-server Makefile.am -# @echo "#!/bin/sh" > test-indicator-sound-dbus -# @echo $(DBUS_RUNNER) --task ./test-indicator-sound-dbus-client --task-name Client --task ./test-indicator-sound-dbus-server --task-name Server --ignore-return >> test-indicator-sound-dbus -# @chmod +x test-libappindicator-dbus +indicator-sound-tests-gtester: test-indicator-sound Makefile.am + @echo "#!/bin/sh" > $@ + @echo gtester -k --verbose -o=$(XML_REPORT) ./test-indicator-sound >> $@ + @chmod +x $@ -#TESTS += test-libappindicator-dbus +TESTS += indicator-sound-tests -XVFB_RUN=". $(srcdir)/run-xvfb.sh" +DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT) indicator-sound-tests-gtester -EXTRA_DIST = run-xvfb.sh +DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf +test-indicator-sound-dbus: test-indicator-sound-dbus-client test-indicator-sound-dbus-server Makefile.am + @echo "#!/bin/sh" > test-indicator-sound-dbus + @echo $(DBUS_RUNNER) --task ./test-indicator-sound-dbus-client --task-name Client --task ./test-indicator-sound-dbus-server --task-name Server --ignore-return >> test-indicator-sound-dbus + @chmod +x test-indicator-sound-dbus -############################# -# Test stuff -############################# +TESTS += test-indicator-sound-dbus -#XML_REPORT = loader-check-results.xml -#HTML_REPORT = loader-check-results.html -#loader-tester: test-loader libsoundmenu.la Makefile -# @echo "#!/bin/bash" > loader-tester -# @echo $(XVFB_RUN) >> $@ -# @echo gtester -k --verbose -o=$(XML_REPORT) ./test-loader >> loader-tester -# @chmod +x loader-tester -#TESTS += loader-tester -#DISTCLEANFILES += loader-tester -#DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT) diff --git a/tests/test-defines.h b/tests/test-defines.h new file mode 100644 index 0000000..68064fc --- /dev/null +++ b/tests/test-defines.h @@ -0,0 +1,24 @@ +/* +Testing defines to be shared between various tests. + +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + Ted Gould + +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 . +*/ + +#define TEST_MUTE FALSE + diff --git a/tests/test-indicator-sound-dbus-client.c b/tests/test-indicator-sound-dbus-client.c new file mode 100644 index 0000000..9d6f7ab --- /dev/null +++ b/tests/test-indicator-sound-dbus-client.c @@ -0,0 +1,109 @@ +/* +Tests for the libappindicator library that are over DBus. This is +the client side of those tests. + +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + Ted Gould + +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 . +*/ + + +#include +#include +#include "../src/dbus-shared-names.h" +/*#include "../src/indicator-sound.c"*/ +#include "test-defines.h" + +static GMainLoop * mainloop = NULL; +static gboolean passed = TRUE; + +static void +fetch_mute_cb (DBusGProxy * proxy, DBusGProxyCall * call, void * data) +{ + GError * error = NULL; + GValue value = {0}; + + if (!dbus_g_proxy_end_call(proxy, call, &error, G_TYPE_VALUE, &value, G_TYPE_INVALID)) { + g_warning("Getting mute failed: %s", error->message); + g_error_free(error); + passed = FALSE; + return; + } + + if (TEST_MUTE != g_value_get_boolean(&value))) { + g_debug("Mute vale Returned: FAILED"); + passed = FALSE; + } else { + g_debug("Property ID Returned: PASSED"); + } + return; +} + + +gboolean +kill_func (gpointer userdata) +{ + g_main_loop_quit(mainloop); + g_warning("Forced to Kill"); + passed = FALSE; + return FALSE; +} + +gint +main (gint argc, gchar * argv[]) +{ + g_type_init(); + + g_usleep(500000); + + GError * error = NULL; + DBusGConnection * session_bus = dbus_g_bus_get(DBUS_BUS_SESSION, &error); + if (error != NULL) { + g_error("Unable to get session bus: %s", error->message); + return 1; + } + + DBusGProxy * props = dbus_g_proxy_new_for_name_owner(session_bus, + INDICATOR_SOUND_DBUS_NAME, + INDICATOR_SOUND_SERVICE_DBUS_OBJECT, + INDICATOR_SOUND_SERVICE_DBUS_INTERFACE, + &error); + if (error != NULL) { + g_error("Unable to get property proxy: %s", error->message); + return 1; + } + + dbus_g_proxy_begin_call (props, + "GetSinkMute", + fetch_mute_cb, + NULL, NULL, + G_TYPE_INVALID); + + g_timeout_add_seconds(2, kill_func, NULL); + + mainloop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(mainloop); + + if (passed) { + g_debug("Quiting"); + return 0; + } else { + g_debug("Quiting as we're a failure"); + return 1; + } + return 0; +} diff --git a/tests/test-indicator-sound-dbus-server.c b/tests/test-indicator-sound-dbus-server.c new file mode 100644 index 0000000..c9ad61d --- /dev/null +++ b/tests/test-indicator-sound-dbus-server.c @@ -0,0 +1,61 @@ +/* +Tests for the libappindicator library that are over DBus. This is +the server side of those tests. + +Copyright 2009 Canonical Ltd. + +Authors: + Conor Curran + Ted Gould + +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 . +*/ + + +#include +#include +#include +#include "../src/sound-service-dbus.h" +#include "test-defines.h" + +static GMainLoop * mainloop = NULL; + +gboolean +kill_func (gpointer userdata) +{ + g_main_loop_quit(mainloop); + return FALSE; +} + +gint +main (gint argc, gchar * argv[]) +{ + g_type_init(); + g_debug("DBus ID: %s", dbus_connection_get_server_id(dbus_g_connection_get_connection(dbus_g_bus_get(DBUS_BUS_SESSION, NULL)))); + + dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL); + + // Set the mute value + sound_service_dbus_update_sink_mute(dbus_interface, TEST_MUTE); + g_timeout_add_seconds(2, kill_func, NULL); + + // Run the loop + mainloop = g_main_loop_new(NULL, FALSE); + g_main_loop_run(mainloop); + + g_debug("Quiting"); + + return 0; +} + + -- cgit v1.2.3 From c49359cb645a839fed19b8217635303dae4f825e Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 1 Mar 2010 16:06:30 -0600 Subject: Removing linking to the loadable library and fixing a missing '\' --- tests/Makefile.am | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/tests/Makefile.am b/tests/Makefile.am index 7d061fb..d4675df 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,6 +1,6 @@ check_PROGRAMS = \ - test-indicator-sound + test-indicator-sound \ test-indicator-sound-dbus-client \ test-indicator-sound-dbus-server @@ -20,8 +20,7 @@ test_indicator_sound_CFLAGS = \ -DTOP_BUILD_DIR="\"${abs_top_builddir}\"" test_indicator_sound_LDADD = \ - $(APPLET_LIBS) \ - $(INDICATORDIR)/libsoundmenu.la + $(APPLET_LIBS) ######################################### ## test-indicator-sound-dbus-client @@ -38,8 +37,7 @@ test_indicator_sound_dbus_client_CFLAGS = \ -I$(SOUNDSERVICE_CFLAGS) test_indicator_sound_dbus_client_LDADD = \ - $(SOUNDSERVICE_LIBS) \ - $(INDICATORDIR)/libsoundmenu.la + $(SOUNDSERVICE_LIBS) ######################################### ## test-indicator-sound-dbus-server @@ -53,9 +51,8 @@ test_indicator_sound_dbus_server_CFLAGS = \ -Wall -Werror \ -I$(srcdir) -test_libappindicator_dbus_server_LDADD = \ - $(SOUNDSERVICE_LIBS) \ - $(INDICATORDIR)/libsoundmenu.la +test_indicator_sound_dbus_server_LDADD = \ + $(SOUNDSERVICE_LIBS) ######################################### -- cgit v1.2.3 From 7a92d249547ff1783725850edb39a952e52ee8c9 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Mon, 1 Mar 2010 16:06:52 -0600 Subject: Removing including a C file and including some needed headers. --- tests/test-indicator-sound.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/test-indicator-sound.c b/tests/test-indicator-sound.c index 0de09b7..e103fa8 100644 --- a/tests/test-indicator-sound.c +++ b/tests/test-indicator-sound.c @@ -18,7 +18,8 @@ with this program. If not, see . */ #include -#include "../src/indicator-sound.c" +#include +#include void test_libindicator_sound_init() -- cgit v1.2.3 From be2b2e73044d5ba0c656431f0d19723af6b55946 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 2 Mar 2010 10:20:25 +0000 Subject: refactored the indicator tests so as no c file needs to be included --- src/indicator-sound.c | 11 +++++++++++ src/indicator-sound.h | 5 +++-- tests/Makefile.am | 41 +++++++++++++++++++++-------------------- tests/test-indicator-sound.c | 43 +++++++++++++++++++++---------------------- 4 files changed, 56 insertions(+), 44 deletions(-) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 546f404..3aca517 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -300,11 +300,22 @@ gint get_state() return current_state; } +gchar* get_state_image_name(gint state) +{ + return g_hash_table_lookup(volume_states, GINT_TO_POINTER(state)); +} + void prepare_for_tests(IndicatorObject *io) { + prepare_state_machine(); get_icon(io); } +void tidy_up_hash() +{ + g_hash_table_destroy(volume_states); +} + static void update_state(const gint state) { /* g_debug("update state beginning - previous_state = %i", previous_state);*/ diff --git a/src/indicator-sound.h b/src/indicator-sound.h index eaf8948..6d0c85c 100644 --- a/src/indicator-sound.h +++ b/src/indicator-sound.h @@ -21,9 +21,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - +// Essentially these are all exported to faciltiate testing void prepare_state_machine(); void determine_state_from_volume(gdouble volume_percent); gint get_state(); -// Not nice +gchar* get_state_image_name(gint state); void prepare_for_tests(IndicatorObject * io); +void tidy_up_hash(); diff --git a/tests/Makefile.am b/tests/Makefile.am index 285a26c..b20b070 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,8 +1,8 @@ check_PROGRAMS = \ test-indicator-sound \ - test-indicator-sound-dbus-client \ - test-indicator-sound-dbus-server + test-indicator-sound-dbus-client +# test-indicator-sound-dbus-server TESTS = DISTCLEANFILES = $(TESTS) @@ -44,20 +44,21 @@ test_indicator_sound_dbus_client_LDADD = \ ######################################### ## test-indicator-sound-dbus-server ######################################### -test_indicator_sound_dbus_server_SOURCES = \ - test-defines.h \ - test-indicator-sound-dbus-server.c - -test_indicator_sound_dbus_server_CFLAGS = \ - $(APPLET_CFLAGS) \ - -Wall -Werror \ - -I$(srcdir) \ - -I$(SOUNDSERVICE_CFLAGS) +#test_indicator_sound_dbus_server_SOURCES = \ +# test-defines.h -test_indicator_sound_dbus_server_LDADD = \ - $(SOUNDSERVICE_LIBS) \ - $(top_builddir)/src/libsoundmenu.la +#test_indicator_sound_dbus_server_CFLAGS = \ +# $(SOUNDSERVICE_CFLAGS) \ +# -Wall -Werror \ +# -I$(srcdir) \ +# -I$(SOUNDSERVICE_CFLAGS) +#test_indicator_sound_dbus_server_LDADD = \ +# $(SOUNDSERVICE_LIBS) \ +# $(top_builddir)/src/indicator_sound_service-sound-service.o \ +# $(top_builddir)/src/indicator_sound_service-pulse-manager.o \ +# $(top_builddir)/src/indicator_sound_service-slider-menu-item.o \ +# $(top_builddir)/src/indicator_sound_service-sound-service-dbus.o @@ -83,14 +84,14 @@ TESTS += indicator-sound-tests DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT) indicator-sound-tests-gtester -DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf +#DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf -test-indicator-sound-dbus: test-indicator-sound-dbus-client test-indicator-sound-dbus-server Makefile.am - @echo "#!/bin/sh" > test-indicator-sound-dbus - @echo $(DBUS_RUNNER) --task ./test-indicator-sound-dbus-client --task-name Client --task ./test-indicator-sound-dbus-server --task-name Server --ignore-return >> test-indicator-sound-dbus - @chmod +x test-indicator-sound-dbus +#test-indicator-sound-dbus: test-indicator-sound-dbus-client test-indicator-sound-dbus-server Makefile.am +# @echo "#!/bin/sh" > test-indicator-sound-dbus +# @echo $(DBUS_RUNNER) --task ./test-indicator-sound-dbus-client --task-name Client --task ./test-indicator-sound-dbus-server --task-name Server --ignore-return >> test-indicator-sound-dbus +# @chmod +x test-indicator-sound-dbus -TESTS += test-indicator-sound-dbus +#TESTS += test-indicator-sound-dbus diff --git a/tests/test-indicator-sound.c b/tests/test-indicator-sound.c index 5dad56c..eb68b17 100644 --- a/tests/test-indicator-sound.c +++ b/tests/test-indicator-sound.c @@ -57,34 +57,33 @@ void test_libindicator_determine_state() g_object_unref(G_OBJECT(sound_menu)); } -/*void test_libindicator_image_names()*/ -/*{*/ -/* prepare_state_machine();*/ - -/* gchar* muted_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED)); */ -/* g_assert(g_ascii_strncasecmp("audio-volume-muted-panel", muted_name, strlen("audio-volume-muted-panel")) == 0);*/ +void test_libindicator_image_names() +{ + prepare_state_machine(); -/* gchar* zero_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)); */ -/* g_assert(g_ascii_strncasecmp("audio-volume-low-zero-panel", zero_name, strlen("audio-volume-low-zero-panel")) == 0);*/ + gchar* muted_name = get_state_image_name(STATE_MUTED); + g_assert(g_ascii_strncasecmp("audio-volume-muted-panel", muted_name, strlen("audio-volume-muted-panel")) == 0); -/* gchar* low_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_LOW)); */ -/* g_assert(g_ascii_strncasecmp("audio-volume-low-panel", low_name, strlen("audio-volume-low-panel")) == 0);*/ + gchar* zero_name = get_state_image_name(STATE_ZERO); + g_assert(g_ascii_strncasecmp("audio-volume-low-zero-panel", zero_name, strlen("audio-volume-low-zero-panel")) == 0); -/* gchar* medium_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MEDIUM)); */ -/* g_assert(g_ascii_strncasecmp("audio-volume-medium-panel", medium_name, strlen("audio-volume-medium-panel")) == 0);*/ + gchar* low_name = get_state_image_name(STATE_LOW); + g_assert(g_ascii_strncasecmp("audio-volume-low-panel", low_name, strlen("audio-volume-low-panel")) == 0); -/* gchar* high_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)); */ -/* g_assert(g_ascii_strncasecmp("audio-volume-high-panel", high_name, strlen("audio-volume-high-panel")) == 0);*/ + gchar* medium_name = get_state_image_name(STATE_MEDIUM); + g_assert(g_ascii_strncasecmp("audio-volume-medium-panel", medium_name, strlen("audio-volume-medium-panel")) == 0); -/* gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); */ -/* g_assert(g_ascii_strncasecmp("audio-volume-muted-blocking-panel", blocked_name, strlen("audio-volume-muted-blocking-panel")) == 0);*/ + gchar* high_name = get_state_image_name(STATE_HIGH); + g_assert(g_ascii_strncasecmp("audio-volume-high-panel", high_name, strlen("audio-volume-high-panel")) == 0); -/* gchar* none_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE)); */ -/* g_assert(g_ascii_strncasecmp("audio-output-none-panel", none_name, strlen("audio-output-none-panel")) == 0);*/ + gchar* blocked_name = get_state_image_name(STATE_MUTED_WHILE_INPUT); + g_assert(g_ascii_strncasecmp("audio-volume-muted-blocking-panel", blocked_name, strlen("audio-volume-muted-blocking-panel")) == 0); -/* // tidy up*/ -/* g_hash_table_destroy(volume_states);*/ -/*}*/ + gchar* none_name = get_state_image_name(STATE_SINKS_NONE); + g_assert(g_ascii_strncasecmp("audio-output-none-panel", none_name, strlen("audio-output-none-panel")) == 0); + + tidy_up_hash(); +} @@ -95,7 +94,7 @@ gint main (gint argc, gchar * argv[]) g_test_add_func("/indicator-sound/indicator-sound/init", test_libindicator_sound_init); g_test_add_func("/indicator-sound/indicator-sound/state_machine", test_libindicator_determine_state); - //g_test_add_func("/indicator-sound/indicator-sound/image_names", test_libindicator_image_names); + g_test_add_func("/indicator-sound/indicator-sound/image_names", test_libindicator_image_names); return g_test_run (); } -- cgit v1.2.3 From 4bde209ef0f8ad381d70b2ade7eb3cf834eed074 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 2 Mar 2010 19:36:53 +0000 Subject: one big refactor --- src/Makefile.am | 2 + src/dbus-menu-manager.c | 230 ++++++++++++++++++++++++++++++++++++++++++++++++ src/dbus-menu-manager.h | 31 +++++++ src/indicator-sound.h | 5 ++ src/pulse-manager.c | 79 +++++++++++++---- src/pulse-manager.h | 4 +- src/sound-service.c | 134 +++------------------------- src/sound-service.h | 11 +-- tests/Makefile.am | 6 +- 9 files changed, 347 insertions(+), 155 deletions(-) create mode 100644 src/dbus-menu-manager.c create mode 100644 src/dbus-menu-manager.h diff --git a/src/Makefile.am b/src/Makefile.am index 5abacda..40a8fdd 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -48,6 +48,8 @@ indicator_sound_service_SOURCES = \ common-defs.h \ sound-service.h \ sound-service.c \ + dbus-menu-manager.c \ + dbus-menu-manager.h \ pulse-manager.h \ pulse-manager.c \ sound-service-dbus.h \ diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c new file mode 100644 index 0000000..652e6b2 --- /dev/null +++ b/src/dbus-menu-manager.c @@ -0,0 +1,230 @@ +/* +This service primarily controls PulseAudio and is driven by the sound indicator menu on the panel. +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +#include +#include + +#include +#include +#include + +#include "dbus-menu-manager.h" +#include "sound-service-dbus.h" +#include "pulse-manager.h" +#include "slider-menu-item.h" + +#include "dbus-shared-names.h" + +// DBUS items +static DbusmenuMenuitem *root_menuitem = NULL; +static DbusmenuMenuitem *mute_all_menuitem = NULL; +static SliderMenuItem *volume_slider_menuitem = NULL; +static SoundServiceDbus *dbus_interface = NULL; + +// PULSEAUDIO +static gboolean b_sink_available = FALSE; +static gboolean b_all_muted = FALSE; +static gboolean b_pulse_ready = FALSE; +static gboolean b_startup = TRUE; +static gdouble volume_percent = 0.0; + +static void set_global_mute_from_ui(); +static gboolean idle_routine (gpointer data); +static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service); +static void refresh_menu(); + +/*-------------------------------------------------------------------------*/ +// Public Methods +/*-------------------------------------------------------------------------*/ + +/** +setup: +**/ +void dbus_menu_manager_setup() +{ + root_menuitem = dbusmenu_menuitem_new(); + g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem)); + + g_idle_add(idle_routine, root_menuitem); + + dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL); + + DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT); + dbusmenu_server_set_root(server, root_menuitem); + establish_pulse_activities(dbus_interface); +} + +/** +teardown: +**/ +void dbus_menu_manager_teardown() +{ + //TODO tidy up dbus_interface and items! +} + +/** +update_pa_state: +**/ +void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble percent) +{ + b_sink_available = sink_available; + b_all_muted = sink_muted; + b_pulse_ready = pa_state; + volume_percent = percent; + g_debug("update pa state with state %i, availability of %i, mute value of %i and a volume percent is %f", pa_state, sink_available, sink_muted, volume_percent); + // Only rebuild the menu on start up... + if(b_startup == TRUE){ + rebuild_sound_menu(root_menuitem, dbus_interface); + b_startup = FALSE; + } + else{ + refresh_menu(); + } + // Emit the signals after the menus are setup/torn down + sound_service_dbus_update_sink_volume(dbus_interface, percent); + sound_service_dbus_update_sink_mute(dbus_interface, sink_muted); + dbus_menu_manager_update_mute_ui(b_all_muted); +} + +/** +update_mute_ui: +'public' method allowing the pa manager to update the mute menu item. +**/ +void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value) +{ + b_all_muted = incoming_mute_value; + dbusmenu_menuitem_property_set(mute_all_menuitem, + DBUSMENU_MENUITEM_PROP_LABEL, + (b_all_muted == FALSE ? "Mute All" : "Unmute")); + //dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? _("Mute All") : _("Unmute"))); +} + + +/*-------------------------------------------------------------------------*/ +// Private Methods +/*-------------------------------------------------------------------------*/ + +static void refresh_menu() +{ + g_debug("in the refresh menu method"); + if(b_sink_available == FALSE || b_pulse_ready == FALSE) + { + + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_ENABLED, + FALSE); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_VISIBLE, + FALSE); + dbusmenu_menuitem_property_set_bool(mute_all_menuitem, + DBUSMENU_MENUITEM_PROP_ENABLED, + FALSE); + + } + else if(b_sink_available == TRUE && b_pulse_ready == TRUE){ + + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_ENABLED, + TRUE); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_VISIBLE, + TRUE); + dbusmenu_menuitem_property_set_bool(mute_all_menuitem, + DBUSMENU_MENUITEM_PROP_ENABLED, + TRUE); + } +} + + + +/** + +**/ +static gboolean idle_routine (gpointer data) +{ + return FALSE; +} + + + +/** +show_sound_settings_dialog: +Bring up the gnome volume preferences dialog +**/ +static void show_sound_settings_dialog (DbusmenuMenuitem *mi, gpointer user_data) +{ + GError * error = NULL; + if (!g_spawn_command_line_async("gnome-volume-control", &error)) + { + g_warning("Unable to show dialog: %s", error->message); + g_error_free(error); + } +} + +/** +rebuild_sound_menu: +Build the DBus menu items, mute/unmute, slider, separator and sound preferences 'link' +**/ +static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service) +{ + // Mute button + mute_all_menuitem = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? "Mute All" : "Unmute")); + g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL); + dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available); + + // Slider + volume_slider_menuitem = slider_menu_item_new(b_sink_available, volume_percent); + dbusmenu_menuitem_child_append(root, mute_all_menuitem); + dbusmenu_menuitem_child_append(root, DBUSMENU_MENUITEM(volume_slider_menuitem)); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_ENABLED, + b_sink_available); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_VISIBLE, + b_sink_available); + // Separator + DbusmenuMenuitem *separator = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); + dbusmenu_menuitem_child_append(root, separator); + + // Sound preferences dialog + DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new(); + dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, + ("Sound Preferences...")); + dbusmenu_menuitem_child_append(root, settings_mi); + g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, + G_CALLBACK(show_sound_settings_dialog), NULL); +} + +/** +set_global_mute_from_ui: +Callback for the dbusmenuitem button +**/ +static void set_global_mute_from_ui() +{ + b_all_muted = !b_all_muted; + toggle_global_mute(b_all_muted); + dbusmenu_menuitem_property_set(mute_all_menuitem, + DBUSMENU_MENUITEM_PROP_LABEL, + (b_all_muted == FALSE ? "Mute All" : "Unmute")); +} + + diff --git a/src/dbus-menu-manager.h b/src/dbus-menu-manager.h new file mode 100644 index 0000000..5f49e5f --- /dev/null +++ b/src/dbus-menu-manager.h @@ -0,0 +1,31 @@ +#ifndef __INCLUDE_DBUS_MENU_MANAGER_H__ +#define __INCLUDE_DBUS_MENU_MANAGER_H__ + +/* +This handles the management of the dbusmeneu items. +Copyright 2010 Canonical Ltd. + +Authors: + Conor Curran + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see . +*/ + +void dbus_menu_manager_setup(); +void dbus_menu_manager_teardown(); +void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble current_vol); +// TODO update pa_state should incorporate the method below ! +void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value); + +#endif + diff --git a/src/indicator-sound.h b/src/indicator-sound.h index 6d0c85c..e508390 100644 --- a/src/indicator-sound.h +++ b/src/indicator-sound.h @@ -1,3 +1,6 @@ +#ifndef __INCLUDE_INDICATOR_SOUND_H__ +#define __INCLUDE_INDICATOR_SOUND_H__ + /* A small wrapper utility to load indicators and put them as menu items into the gnome-panel using it's applet interface. @@ -28,3 +31,5 @@ gint get_state(); gchar* get_state_image_name(gint state); void prepare_for_tests(IndicatorObject * io); void tidy_up_hash(); + +#endif diff --git a/src/pulse-manager.c b/src/pulse-manager.c index 9b9d7cd..4594d2f 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -26,12 +26,10 @@ with this program. If not, see . #include #include "pulse-manager.h" -#include "sound-service.h" - +#include "dbus-menu-manager.h" static GHashTable *sink_hash = NULL; static SoundServiceDbus *dbus_service = NULL; -// Until we find a satisfactory default sink this index should remain < 0 static gint DEFAULT_SINK_INDEX = -1; static gboolean pa_server_available = FALSE; // PA related @@ -46,6 +44,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v static void pulse_source_info_callback(pa_context *c, const pa_source_info *i, int eol, void *userdata); static void destroy_sink_info(void *value); static gboolean determine_sink_availability(); +static void reconnect_to_pulse(); /** @@ -65,14 +64,19 @@ void establish_pulse_activities(SoundServiceDbus *service) g_assert(pulse_context); sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info); + // Establish event callback registration pa_context_set_state_callback(pulse_context, context_state_callback, NULL); - pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOAUTOSPAWN, NULL); + // BUILD MENU ANYWHO - it will be updated + dbus_menu_manager_update_pa_state(FALSE, FALSE, FALSE, 0); + + pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL); } void close_pulse_activites() { - if (pulse_context){ + if (pulse_context != NULL){ + g_debug("freeing the pulse context"); pa_context_unref(pulse_context); pulse_context = NULL; } @@ -82,6 +86,30 @@ void close_pulse_activites() g_debug("I just closed communication with Pulse"); } +/** +reconnect_to_pulse() +In the event of Pulseaudio flapping in the wind handle gracefully without +memory leaks ! +*/ +static void reconnect_to_pulse() +{ + // reset + if (pulse_context != NULL){ + g_debug("freeing the pulse context"); + pa_context_unref(pulse_context); + pulse_context = NULL; + } + g_hash_table_destroy(sink_hash); + + // reconnect + pulse_context = pa_context_new(pa_glib_mainloop_get_api(pa_main_loop), "ayatana.indicator.sound"); + g_assert(pulse_context); + sink_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, destroy_sink_info); + // Establish event callback registration + pa_context_set_state_callback(pulse_context, context_state_callback, NULL); + dbus_menu_manager_update_pa_state(FALSE, FALSE, FALSE, 0); + pa_context_connect(pulse_context, NULL, PA_CONTEXT_NOFAIL, NULL); +} static void destroy_sink_info(void *value) { @@ -186,6 +214,8 @@ Use the base volume stored in the sink struct to calculate actual linear volumes */ void set_sink_volume(gdouble percent) { + if(pa_server_available == FALSE) + return; g_debug("in the pulse manager:set_sink_volume with percent %f", percent); if(DEFAULT_SINK_INDEX < 0) { @@ -245,12 +275,15 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in gboolean device_available = determine_sink_availability(); if(device_available == TRUE) { - update_pa_state(TRUE, device_available, default_sink_is_muted(), get_default_sink_volume()); + dbus_menu_manager_update_pa_state(TRUE, + device_available, + default_sink_is_muted(), + get_default_sink_volume()); } else{ //Update the indicator to show PA either is not ready or has no available sink g_warning("Cannot find a suitable default sink ..."); - update_pa_state(FALSE, device_available, TRUE, 0); + dbus_menu_manager_update_pa_state(FALSE, device_available, TRUE, 0); } } else{ @@ -291,7 +324,7 @@ static void pulse_default_sink_info_callback(pa_context *c, const pa_sink_info * } else { - update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume()); + dbus_menu_manager_update_pa_state(TRUE, determine_sink_availability(), default_sink_is_muted(), get_default_sink_volume()); } } } @@ -354,7 +387,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v { g_debug("Updating Mute from PA manager with mute = %i", s->mute); sound_service_dbus_update_sink_mute(dbus_service, s->mute); - update_mute_ui(s->mute); + dbus_menu_manager_update_mute_ui(s->mute); if(s->mute == FALSE){ pa_volume_t vol = pa_cvolume_avg(&s->volume); gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; @@ -366,12 +399,20 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v } else { - // TODO ADD new sink - part of big refactor - g_debug("attempting to add new sink with name %s", info->name); - //sink_info *s; - //s = g_new0(sink_info, 1); - //update the sinks hash with new sink. - } + sink_info *value; + value = g_new0(sink_info, 1); + value->index = value->device_index = info->index; + value->name = g_strdup(info->name); + value->description = g_strdup(info->description); + value->icon_name = g_strdup(pa_proplist_gets(info->proplist, PA_PROP_DEVICE_ICON_NAME)); + value->active_port = (info->active_port != NULL); + value->mute = !!info->mute; + value->volume = info->volume; + value->base_volume = info->base_volume; + value->channel_map = info->channel_map; + g_hash_table_insert(sink_hash, GINT_TO_POINTER(value->index), value); + g_debug("pulse-manager:update_sink_info -> After adding a new sink to our hash"); + } } @@ -382,7 +423,7 @@ static void pulse_server_info_callback(pa_context *c, const pa_server_info *info if (info == NULL) { g_warning("No server - get the hell out of here"); - update_pa_state(FALSE, FALSE, TRUE, 0); + dbus_menu_manager_update_pa_state(FALSE, FALSE, TRUE, 0); pa_server_available = FALSE; return; } @@ -474,7 +515,7 @@ static void context_state_callback(pa_context *c, void *userdata) { g_debug("unconnected"); break; case PA_CONTEXT_CONNECTING: - g_debug("connecting"); + g_debug("connecting - waiting for the server to become available"); break; case PA_CONTEXT_AUTHORIZING: g_debug("authorizing"); @@ -484,8 +525,8 @@ static void context_state_callback(pa_context *c, void *userdata) { break; case PA_CONTEXT_FAILED: g_warning("FAILED to retrieve context - Is PulseAudio Daemon running ?"); - //Update the indicator to show PA either is not ready or has no available sink - update_pa_state(FALSE, FALSE, TRUE, 0); + pa_server_available = FALSE; + reconnect_to_pulse(); break; case PA_CONTEXT_TERMINATED: g_debug("context terminated"); diff --git a/src/pulse-manager.h b/src/pulse-manager.h index 1be5e44..e1777fb 100644 --- a/src/pulse-manager.h +++ b/src/pulse-manager.h @@ -1,3 +1,5 @@ +#ifndef __INCLUDE_PULSE_MANAGER_H__ +#define __INCLUDE_PULSE_MANAGER_H__ /* A small wrapper utility to load indicators and put them as menu items into the gnome-panel using it's applet interface. @@ -21,7 +23,6 @@ with this program. If not, see . */ - #include #include #include "sound-service-dbus.h" @@ -47,4 +48,5 @@ void set_sink_volume(gdouble percent); void toggle_global_mute(gboolean mute_value); void close_pulse_activites(); +#endif diff --git a/src/sound-service.c b/src/sound-service.c index 61bf702..815fcdc 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -19,107 +19,22 @@ 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 . */ + #include "sound-service.h" -#include "sound-service-dbus.h" +#include "dbus-menu-manager.h" #include "pulse-manager.h" -#include "slider-menu-item.h" -#include "common-defs.h" - -// GTK + DBUS static GMainLoop *mainloop = NULL; -static DbusmenuMenuitem *root_menuitem = NULL; -static DbusmenuMenuitem *mute_all_menuitem = NULL; -static SliderMenuItem *volume_slider_menuitem = NULL; -static SoundServiceDbus *dbus_interface = NULL; - -// PULSEAUDIO -static gboolean b_sink_available = FALSE; -static gboolean b_all_muted = FALSE; -static gboolean b_pulse_ready = FALSE; -static gdouble volume_percent = 0.0; - -static void set_global_mute_from_ui(); -static gboolean idle_routine (gpointer data); -static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service); - /**********************************************************************************************************************/ -// Init functions (GTK and DBUS) +// Init and exit functions /**********************************************************************************************************************/ -/** -Pass to the g_idle_add method - returning False will ensure that this method is never called again as it is removed as an event source. -**/ -static gboolean idle_routine (gpointer data) -{ - return FALSE; -} - - -static void show_sound_settings_dialog (DbusmenuMenuitem *mi, gpointer user_data) -{ - GError * error = NULL; - if (!g_spawn_command_line_async("gnome-volume-control", &error)) - { - g_warning("Unable to show dialog: %s", error->message); - g_error_free(error); - } -} -/** -Build the DBus menu items. For now Mute all/Unmute is the only available option -**/ -static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service) -{ - // Mute button - mute_all_menuitem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _(b_all_muted == FALSE ? "Mute All" : "Unmute")); - g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL); - dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available); - - // Slider - volume_slider_menuitem = slider_menu_item_new(b_sink_available, volume_percent); - dbusmenu_menuitem_child_append(root, mute_all_menuitem); - dbusmenu_menuitem_child_append(root, DBUSMENU_MENUITEM(volume_slider_menuitem)); - - DbusmenuMenuitem *separator = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); - dbusmenu_menuitem_child_append(root, separator); - DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, - _("Sound Preferences...")); - dbusmenu_menuitem_child_append(root, settings_mi); - g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(show_sound_settings_dialog), NULL); -} /** -update_mute_ui: -'public' method allowing the server to update the mute UI +service_shutdown: +When the service interface starts to shutdown, we +should follow it. **/ -void update_mute_ui(gboolean incoming_mute_value) -{ - b_all_muted = incoming_mute_value; - dbusmenu_menuitem_property_set(mute_all_menuitem, - DBUSMENU_MENUITEM_PROP_LABEL, - _(b_all_muted == FALSE ? "Mute All" : "Unmute")); -} -/** -set_global_mute_from_ui: -Callback for the dbusmenuitem button -**/ -static void set_global_mute_from_ui() -{ - b_all_muted = !b_all_muted; - toggle_global_mute(b_all_muted); - dbusmenu_menuitem_property_set(mute_all_menuitem, - DBUSMENU_MENUITEM_PROP_LABEL, - _(b_all_muted == FALSE ? "Mute All" : "Unmute")); -} - - -/* When the service interface starts to shutdown, we - should follow it. - -*/ void service_shutdown (IndicatorService *service, gpointer user_data) { @@ -127,31 +42,15 @@ service_shutdown (IndicatorService *service, gpointer user_data) if (mainloop != NULL) { g_debug("Service shutdown !"); // TODO: uncomment for release !! - // TODO free the dbus interface !! - close_pulse_activites(); - g_main_loop_quit(mainloop); +/* close_pulse_activites();*/ +/* g_main_loop_quit(mainloop);*/ } return; } -void update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble percent) -{ - b_sink_available = sink_available; - b_all_muted = sink_muted; - b_pulse_ready = pa_state; - volume_percent = percent; - g_debug("update pa state with state %i, availability of %i, mute value of %i and a volume percent is %f", pa_state, sink_available, sink_muted, volume_percent); - sound_service_dbus_update_sink_volume(dbus_interface, percent); - sound_service_dbus_update_sink_mute(dbus_interface, sink_muted); - - // Only rebuild the menu on start up... - if(volume_slider_menuitem == NULL) - rebuild_sound_menu(root_menuitem, dbus_interface); -} - - -/* Main, is well, main. It brings everything up and throws - us into the mainloop of no return. Some refactoring needed.*/ +/** +main: +**/ int main (int argc, char ** argv) { @@ -167,16 +66,7 @@ main (int argc, char ** argv) INDICATOR_SERVICE_SIGNAL_SHUTDOWN, G_CALLBACK(service_shutdown), NULL); - root_menuitem = dbusmenu_menuitem_new(); - g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem)); - - g_idle_add(idle_routine, root_menuitem); - - dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL); - - DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT); - dbusmenu_server_set_root(server, root_menuitem); - establish_pulse_activities(dbus_interface); + dbus_menu_manager_setup(); // Run the loop mainloop = g_main_loop_new(NULL, FALSE); diff --git a/src/sound-service.h b/src/sound-service.h index d36ea41..cefbf45 100644 --- a/src/sound-service.h +++ b/src/sound-service.h @@ -27,13 +27,6 @@ with this program. If not, see . #include #include -#include -#include - -#include -#include -#include - #include #include "dbus-shared-names.h" @@ -41,7 +34,5 @@ with this program. If not, see . // ENTRY AND EXIT POINTS void service_shutdown(IndicatorService * service, gpointer user_data); int main (int argc, char ** argv); -void update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble current_vol); -void update_mute_ui(gboolean incoming_mute_value); -#endif +#endif diff --git a/tests/Makefile.am b/tests/Makefile.am index b20b070..ad985f4 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -11,7 +11,8 @@ DISTCLEANFILES = $(TESTS) ## test-indicator-sound ######################################### test_indicator_sound_SOURCES = \ - test-indicator-sound.c + test-indicator-sound.c \ + $(top_builddir)/src/indicator-sound.c test_indicator_sound_CFLAGS = \ $(APPLET_CFLAGS) \ @@ -20,8 +21,7 @@ test_indicator_sound_CFLAGS = \ -DTOP_BUILD_DIR="\"${abs_top_builddir}\"" test_indicator_sound_LDADD = \ - $(APPLET_LIBS) \ - $(top_builddir)/src/libsoundmenu_la-indicator-sound.o + $(APPLET_LIBS) ######################################### -- cgit v1.2.3 From 259f58ec21be89f22f478243f4c8acf9a44231f9 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 3 Mar 2010 15:05:08 +0000 Subject: tests compiling --- src/dbus-menu-manager.c | 1 - src/indicator-sound.c | 1 + src/sound-service-dbus.c | 10 ++--- tests/Makefile.am | 70 +++++++++++++++----------------- tests/test-indicator-sound-dbus-client.c | 9 ++-- 5 files changed, 43 insertions(+), 48 deletions(-) diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 652e6b2..3e33932 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -113,7 +113,6 @@ void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value) dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? "Mute All" : "Unmute")); - //dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? _("Mute All") : _("Unmute"))); } diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 3aca517..4bdfbb7 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -238,6 +238,7 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata) { + // TODO: This could be safer. if (connected) { if (sound_dbus_proxy == NULL) { GError * error = NULL; diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 99a9d34..952a2d3 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -29,8 +29,7 @@ #include "sound-service-marshal.h" #include "pulse-manager.h" -// DBUS methods - -// TODO - other should be static and moved from the header to here +// DBUS methods static gboolean sound_service_dbus_get_sink_volume(SoundServiceDbus* service, gdouble* volume_percent_input, GError** gerror); static gboolean sound_service_dbus_get_sink_mute(SoundServiceDbus* service, gboolean* mute_input, GError** gerror); static void sound_service_dbus_set_sink_volume(SoundServiceDbus* service, const guint volume_percent, GError** gerror); @@ -41,7 +40,6 @@ typedef struct _SoundServiceDbusPrivate SoundServiceDbusPrivate; struct _SoundServiceDbusPrivate { - DBusGConnection *system_bus; DBusGConnection *connection; gdouble volume_percent; gboolean mute; @@ -116,13 +114,10 @@ sound_service_dbus_init (SoundServiceDbus *self) GError *error = NULL; SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); - priv->system_bus = NULL; priv->connection = NULL; priv->volume_percent = 0; - /* Get the system bus */ - priv->system_bus = dbus_g_bus_get (DBUS_BUS_SYSTEM, &error); - /* Put the object on DBus */ + /* Fetch the session bus */ priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); if (error != NULL) { @@ -130,6 +125,7 @@ sound_service_dbus_init (SoundServiceDbus *self) g_error_free(error); return; } + /* register the service on it */ dbus_g_connection_register_g_object(priv->connection, "/org/ayatana/indicator/sound/service", G_OBJECT(self)); diff --git a/tests/Makefile.am b/tests/Makefile.am index ad985f4..a0b990b 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -1,8 +1,8 @@ check_PROGRAMS = \ test-indicator-sound \ - test-indicator-sound-dbus-client -# test-indicator-sound-dbus-server + test-indicator-sound-dbus-client \ + test-indicator-sound-dbus-server TESTS = DISTCLEANFILES = $(TESTS) @@ -27,53 +27,49 @@ test_indicator_sound_LDADD = \ ######################################### ## test-indicator-sound-dbus-client ######################################### - test_indicator_sound_dbus_client_SOURCES = \ test-defines.h \ - test-indicator-sound-dbus-client.c + test-indicator-sound-dbus-client.c test_indicator_sound_dbus_client_CFLAGS = \ $(SOUNDSERVICE_CFLAGS) \ -Wall -Werror \ - -I$(srcdir) \ - -I$(SOUNDSERVICE_CFLAGS) + -I$(srcdir) test_indicator_sound_dbus_client_LDADD = \ $(SOUNDSERVICE_LIBS) -######################################### -## test-indicator-sound-dbus-server -######################################### -#test_indicator_sound_dbus_server_SOURCES = \ -# test-defines.h - -#test_indicator_sound_dbus_server_CFLAGS = \ -# $(SOUNDSERVICE_CFLAGS) \ -# -Wall -Werror \ -# -I$(srcdir) \ -# -I$(SOUNDSERVICE_CFLAGS) - -#test_indicator_sound_dbus_server_LDADD = \ -# $(SOUNDSERVICE_LIBS) \ -# $(top_builddir)/src/indicator_sound_service-sound-service.o \ -# $(top_builddir)/src/indicator_sound_service-pulse-manager.o \ -# $(top_builddir)/src/indicator_sound_service-slider-menu-item.o \ -# $(top_builddir)/src/indicator_sound_service-sound-service-dbus.o - +######################################## +# test-indicator-sound-dbus-server +######################################## +test_indicator_sound_dbus_server_SOURCES = \ + test-defines.h \ + test-indicator-sound-dbus-server.c \ + $(top_builddir)/src/sound-service-dbus.c \ + $(top_builddir)/src/pulse-manager.c \ + $(top_builddir)/src/slider-menu-item.c \ + $(top_builddir)/src/dbus-menu-manager.c + +test_indicator_sound_dbus_server_CFLAGS = \ + $(SOUNDSERVICE_CFLAGS) \ + -Wall -Werror \ + -I$(srcdir) +test_indicator_sound_dbus_server_LDADD = \ + $(SOUNDSERVICE_LIBS) ######################################### ## Actual tests ######################################### -#XML_REPORT = indicator-sound-check-results.xml -#HTML_REPORT = indicator-sound-check-results.html +XML_REPORT = indicator-sound-check-results.xml +HTML_REPORT = indicator-sound-check-results.html -#indicator-sound-tests: indicator-sound-tests-gtester Makefile.am -# @echo "#!/bin/sh" > $@ -# @echo $(DBUS_RUNNER) --task ./indicator-sound-tests-gtester >> $@ -# @chmod +x $@ +indicator-sound-tests: indicator-sound-tests-gtester Makefile.am + @echo "#!/bin/sh" > $@ + @echo $(DBUS_RUNNER) --task ./indicator-sound-tests-gtester >> $@ + @chmod +x $@ indicator-sound-tests-gtester: test-indicator-sound Makefile.am @echo "#!/bin/sh" > $@ @@ -84,14 +80,14 @@ TESTS += indicator-sound-tests DISTCLEANFILES += $(XML_REPORT) $(HTML_REPORT) indicator-sound-tests-gtester -#DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf +DBUS_RUNNER=dbus-test-runner --dbus-config /usr/share/dbus-test-runner/session.conf -#test-indicator-sound-dbus: test-indicator-sound-dbus-client test-indicator-sound-dbus-server Makefile.am -# @echo "#!/bin/sh" > test-indicator-sound-dbus -# @echo $(DBUS_RUNNER) --task ./test-indicator-sound-dbus-client --task-name Client --task ./test-indicator-sound-dbus-server --task-name Server --ignore-return >> test-indicator-sound-dbus -# @chmod +x test-indicator-sound-dbus +test-indicator-sound-dbus: test-indicator-sound-dbus-client test-indicator-sound-dbus-server Makefile.am + @echo "#!/bin/sh" > test-indicator-sound-dbus + @echo $(DBUS_RUNNER) --task ./test-indicator-sound-dbus-client --task-name Client --task ./test-indicator-sound-dbus-server --task-name Server --ignore-return >> test-indicator-sound-dbus + @chmod +x test-indicator-sound-dbus -#TESTS += test-indicator-sound-dbus +TESTS += test-indicator-sound-dbus diff --git a/tests/test-indicator-sound-dbus-client.c b/tests/test-indicator-sound-dbus-client.c index dc36ae3..08ce93e 100644 --- a/tests/test-indicator-sound-dbus-client.c +++ b/tests/test-indicator-sound-dbus-client.c @@ -25,7 +25,6 @@ with this program. If not, see . #include #include #include "../src/dbus-shared-names.h" -/*#include "../src/indicator-sound.c"*/ #include "test-defines.h" static GMainLoop * mainloop = NULL; @@ -78,10 +77,14 @@ main (gint argc, gchar * argv[]) } DBusGProxy * props = dbus_g_proxy_new_for_name_owner(session_bus, - INDICATOR_SOUND_DBUS_NAME, + INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_SERVICE_DBUS_OBJECT, INDICATOR_SOUND_SERVICE_DBUS_INTERFACE, - &error); + &error); +/* ":1.0",*/ +/* "/need/a/path",*/ +/* DBUS_INTERFACE_PROPERTIES,*/ +/* &error);*/ if (error != NULL) { g_error("Unable to get property proxy: %s", error->message); return 1; -- cgit v1.2.3 From e2a152628f20271f5373702ad88fda483e0403ca Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 3 Mar 2010 21:57:43 +0000 Subject: debug trace was incorrect --- src/sound-service-dbus.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 952a2d3..72337fd 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -48,7 +48,7 @@ struct _SoundServiceDbusPrivate /* Signals */ enum { - SINK_INPUT_WHILE_MUTED, + SINK_INPUT_WHILE_MUTED, SINK_VOLUME_UPDATE, SINK_MUTE_UPDATE, LAST_SIGNAL @@ -121,7 +121,7 @@ sound_service_dbus_init (SoundServiceDbus *self) priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); if (error != NULL) { - g_error("Unable to connect to the session bus when creating application indicator: %s", error->message); + g_error("sound-service-dbus:Unable to connect to the session bus when creating indicator sound service : %s", error->message); g_error_free(error); return; } -- cgit v1.2.3 From 633b514efeaf1c4086e1b2e5fbef185b199517c8 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 4 Mar 2010 16:19:54 +0000 Subject: internationalisation reinstated whoops --- src/dbus-menu-manager.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 3e33932..17003df 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -18,6 +18,10 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ + +#include +#include + #include #include @@ -112,7 +116,7 @@ void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value) b_all_muted = incoming_mute_value; dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, - (b_all_muted == FALSE ? "Mute All" : "Unmute")); + _(b_all_muted == FALSE ? "Mute All" : "Unmute")); } @@ -185,7 +189,7 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service { // Mute button mute_all_menuitem = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? "Mute All" : "Unmute")); + dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, _(b_all_muted == FALSE ? "Mute All" : "Unmute")); g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL); dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available); @@ -207,7 +211,7 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service // Sound preferences dialog DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new(); dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, - ("Sound Preferences...")); + _("Sound Preferences...")); dbusmenu_menuitem_child_append(root, settings_mi); g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_sound_settings_dialog), NULL); @@ -223,7 +227,7 @@ static void set_global_mute_from_ui() toggle_global_mute(b_all_muted); dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, - (b_all_muted == FALSE ? "Mute All" : "Unmute")); + _(b_all_muted == FALSE ? "Mute All" : "Unmute")); } -- cgit v1.2.3 From 6b706a64c5bdcc4b33adfa94b5fa71dbda928399 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 4 Mar 2010 18:02:45 +0000 Subject: slider stretching in place --- src/dbus-menu-manager.c | 5 ++--- src/indicator-sound.c | 47 +++++++++++++++++++++-------------------------- src/slider-menu-item.c | 1 + src/sound-service.c | 4 ++-- 4 files changed, 26 insertions(+), 31 deletions(-) diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 17003df..d2102ef 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -18,7 +18,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ - #include #include @@ -210,8 +209,8 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service // Sound preferences dialog DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, - _("Sound Preferences...")); + dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL, _("Sound Preferences...")); +//_("Sound Preferences...")); dbusmenu_menuitem_child_append(root, settings_mi); g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(show_sound_settings_dialog), NULL); diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 3a6ae30..098b24f 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -78,14 +78,14 @@ G_DEFINE_TYPE (IndicatorSound, indicator_sound, INDICATOR_OBJECT_TYPE); static GtkLabel * get_label (IndicatorObject * io); static GtkImage * get_icon (IndicatorObject * io); static GtkMenu * get_menu (IndicatorObject * io); + //Slider related static GtkWidget *volume_slider = NULL; static gboolean new_slider_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget); -// Alternative callback mechanism, may use this again once ido is updated. -/*static gboolean user_change_value_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data);*/ static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data); static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data); +static void slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data); // DBUS communication static DBusGProxy *sound_dbus_proxy = NULL; @@ -96,6 +96,7 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value static void fetch_volume_percent_from_dbus(); static void fetch_mute_value_from_dbus(); + /****Volume States 'members' ***/ static void update_state(const gint state); @@ -201,6 +202,7 @@ get_menu (IndicatorObject * io) return GTK_MENU(menu); } + /** new_slider_item: Create a new dBusMenu Slider item. @@ -220,10 +222,9 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p // register slider changes listening on the range GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); + g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); - // alternative callback mechanism which i could use again at some point. -/* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */ - + g_signal_connect(slider, "size-allocate", G_CALLBACK(slider_size_allocate), NULL); // Set images on the ido primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); @@ -277,9 +278,6 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u return; } - - - /* Prepare states Array. */ @@ -451,6 +449,21 @@ static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data) return FALSE; } +/** +slider_size_allocate: +Callback on the size-allocate event on the slider item. +**/ +static void slider_size_allocate(GtkWidget *widget, + GtkAllocation *allocation, + gpointer user_data) +{ + g_print("size allocate on slider (%dx%d)\n", allocation->width, allocation->height); + if(allocation->width < 200) + { + gtk_widget_set_size_request(widget, 200, -1); + } +} + /** key_press_cb: **/ @@ -514,22 +527,4 @@ static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer dat return digested; } -/** -This callback should only be called when the user actually drags the slider. -Turned off for now in favour of the non descriminating value-changed call back. -Once the grabbing listener is implemented on the slider may revert to using this. -Its another tool for filtering unwanted volume change updates. -**/ -/*static gboolean user_change_value_event_cb(GtkRange *range, GtkScrollType scroll_type, gdouble input_value, gpointer user_data)*/ -/*{*/ -/* DbusmenuMenuitem *item = (DbusmenuMenuitem*)user_data;*/ -/* gdouble clamped_input = CLAMP(input_value, 0, 100);*/ -/* GValue value = {0};*/ -/* g_debug("User input on SLIDER - = %f", clamped_input);*/ -/* g_value_init(&value, G_TYPE_DOUBLE);*/ -/* g_value_set_double(&value, clamped_input);*/ -/* dbusmenu_menuitem_handle_event (item, "slider_change", &value, 0);*/ -/* return FALSE; */ -/*} */ - diff --git a/src/slider-menu-item.c b/src/slider-menu-item.c index ef3b1fa..a14f4f9 100644 --- a/src/slider-menu-item.c +++ b/src/slider-menu-item.c @@ -92,6 +92,7 @@ SliderMenuItem* slider_menu_item_new(gboolean sinks_available, gdouble start_vol SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL); dbusmenu_menuitem_property_set(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_SLIDER_MENUITEM_TYPE); dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_ENABLED, sinks_available); + dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_VISIBLE, sinks_available); return self; } diff --git a/src/sound-service.c b/src/sound-service.c index 403b2b0..9e967c2 100644 --- a/src/sound-service.c +++ b/src/sound-service.c @@ -44,8 +44,8 @@ service_shutdown (IndicatorService *service, gpointer user_data) if (mainloop != NULL) { g_debug("Service shutdown !"); // TODO: uncomment for release !! - close_pulse_activites(); - g_main_loop_quit(mainloop); +/* close_pulse_activites();*/ +/* g_main_loop_quit(mainloop);*/ } return; } -- cgit v1.2.3 From 378c3c3f79aae564090593af6c6ce6abdb3c541a Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 4 Mar 2010 18:34:15 +0000 Subject: correct size now being used for the icons - design_team_size --- src/indicator-sound.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 098b24f..28f85b8 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -116,6 +116,9 @@ static gint previous_state = 0; static gdouble initial_volume_percent = 0; static gboolean initial_mute = FALSE; +#define DESIGN_TEAM_SIZE design_team_size +static GtkIconSize design_team_size; + // Construction static void indicator_sound_class_init (IndicatorSoundClass *klass) @@ -129,6 +132,8 @@ indicator_sound_class_init (IndicatorSoundClass *klass) io_class->get_label = get_label; io_class->get_image = get_icon; io_class->get_menu = get_menu; + + design_team_size = gtk_icon_size_register("design-team-size", 22, 22); /* dbus_g_object_register_marshaller (_sound_service_marshal_VOID__INT_BOOLEAN,*/ /* G_TYPE_NONE,*/ @@ -181,7 +186,7 @@ get_icon (IndicatorObject * io) { gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); //g_debug("At start-up attempting to set the image to %s", current_name); - speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU)); + speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, DESIGN_TEAM_SIZE)); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; } @@ -227,9 +232,9 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p g_signal_connect(slider, "size-allocate", G_CALLBACK(slider_size_allocate), NULL); // Set images on the ido primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); + gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), DESIGN_TEAM_SIZE); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU); + gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), DESIGN_TEAM_SIZE); gtk_widget_show_all(volume_slider); @@ -325,7 +330,7 @@ static void update_state(const gint state) current_state = state; gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); + gtk_image_set_from_icon_name(speaker_image, image_name, DESIGN_TEAM_SIZE); } -- cgit v1.2.3 From 8d392c8f315f18c1ebc52850141b103897e2eea2 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 5 Mar 2010 10:38:57 +0000 Subject: blocking event now being registered, removed unneccessary marshaller --- src/Makefile.am | 18 ++---------------- src/dbus-menu-manager.c | 3 ++- src/indicator-sound.c | 17 ++++++----------- src/sound-service-dbus.h | 4 ---- 4 files changed, 10 insertions(+), 32 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 40a8fdd..73bb259 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -11,9 +11,7 @@ libsoundmenu_la_SOURCES = \ indicator-sound.h \ indicator-sound.c \ dbus-shared-names.h \ - sound-service-client.h \ - sound-service-marshal.c \ - sound-service-marshal.h + sound-service-client.h libsoundmenu_la_CFLAGS = $(APPLET_CFLAGS) -Wall -Werror libsoundmenu_la_LIBADD = $(APPLET_LIBS) @@ -30,16 +28,6 @@ sound-service-client.h: $(srcdir)/sound-service.xml --output=sound-service-client.h \ $(srcdir)/sound-service.xml -sound-service-marshal.h: $(srcdir)/sound-service.list - glib-genmarshal --header \ - --prefix=_sound_service_marshal $(srcdir)/sound-service.list \ - > sound-service-marshal.h - -sound-service-marshal.c: $(srcdir)/sound-service.list - glib-genmarshal --body \ - --prefix=_sound_service_marshal $(srcdir)/sound-service.list \ - > sound-service-marshal.c - ################# # Session Stuff @@ -74,9 +62,7 @@ sound-service-server.h: $(srcdir)/sound-service.xml ############### BUILT_SOURCES = \ sound-service-client.h \ - sound-service-server.h \ - sound-service-marshal.h \ - sound-service-marshal.c + sound-service-server.h EXTRA_DIST = \ sound-service.xml \ diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index d2102ef..243a3a7 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -157,7 +157,8 @@ static void refresh_menu() /** - +idle_routine: +Something for glip mainloop to do when idle **/ static gboolean idle_routine (gpointer data) { diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 28f85b8..1fb8090 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -90,7 +90,7 @@ static void slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation, // DBUS communication static DBusGProxy *sound_dbus_proxy = NULL; static void connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer userdata); -/*static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata);*/ +static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata); static void catch_signal_sink_volume_update(DBusGProxy * proxy, gdouble volume_percent, gpointer userdata); static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata); static void fetch_volume_percent_from_dbus(); @@ -135,11 +135,6 @@ indicator_sound_class_init (IndicatorSoundClass *klass) design_team_size = gtk_icon_size_register("design-team-size", 22, 22); -/* dbus_g_object_register_marshaller (_sound_service_marshal_VOID__INT_BOOLEAN,*/ -/* G_TYPE_NONE,*/ -/* G_TYPE_INT,*/ -/* G_TYPE_BOOLEAN,*/ -/* G_TYPE_INVALID);*/ return; } @@ -264,7 +259,7 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u g_debug("about to connect to the signals"); dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_TYPE_BOOLEAN, G_TYPE_INVALID); -/* dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL);*/ + dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_INPUT_WHILE_MUTED, G_CALLBACK(catch_signal_sink_input_while_muted), NULL, NULL); dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_VOLUME_UPDATE, G_TYPE_DOUBLE, G_TYPE_INVALID); dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_VOLUME_UPDATE, G_CALLBACK(catch_signal_sink_volume_update), NULL, NULL); dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); @@ -393,10 +388,10 @@ static void fetch_mute_value_from_dbus() g_debug("at the indicator start up and the MUTE returned from dbus method is %i", initial_mute); } -/*static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata)*/ -/*{*/ -/* g_debug("signal caught - sink input while muted with value %i", block_value);*/ -/*}*/ +static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) +{ + g_debug("signal caught - sink input while muted with value %i", block_value); +} static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) { diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h index ef0d7dd..1a06117 100644 --- a/src/sound-service-dbus.h +++ b/src/sound-service-dbus.h @@ -49,10 +49,6 @@ struct _SoundServiceDbus { struct _SoundServiceDbusClass { GObjectClass parent_class; - /* Signals -> outward messages to the DBUS and beyond*/ - // TODO - ARE THESE NECESSARY ? - //void (* sink_input_while_muted) (SoundServiceDbus *self, gboolean block_value, gpointer sound_data); - //void (* sink_volume_update) (SoundServiceDbus *self, gdouble sink_volume, gpointer sound_data); }; GType sound_service_dbus_get_type (void) G_GNUC_CONST; -- cgit v1.2.3 From c462eb03f66d00a39562d00238f5dce35f371df6 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Mon, 8 Mar 2010 19:12:18 +0000 Subject: no sink available dynamically being handled --- src/common-defs.h | 1 + src/dbus-menu-manager.c | 5 +++- src/indicator-sound.c | 75 ++++++++++++++++++++++++++++++++++++++++++++++-- src/pulse-manager.c | 15 ++++++---- src/sound-service-dbus.c | 37 ++++++++++++++++++++++-- src/sound-service-dbus.h | 1 + src/sound-service.xml | 10 +++++++ 7 files changed, 134 insertions(+), 10 deletions(-) diff --git a/src/common-defs.h b/src/common-defs.h index 942e269..9be1da5 100644 --- a/src/common-defs.h +++ b/src/common-defs.h @@ -22,6 +22,7 @@ with this program. If not, see . #define SIGNAL_SINK_INPUT_WHILE_MUTED "SinkInputWhileMuted" #define SIGNAL_SINK_VOLUME_UPDATE "SinkVolumeUpdate" #define SIGNAL_SINK_MUTE_UPDATE "SinkMuteUpdate" +#define SIGNAL_SINK_AVAILABLE_UPDATE "SinkAvailableUpdate" // DBUS items #define DBUSMENU_SLIDER_MENUITEM_TYPE "x-canonical-ido-slider-item" diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 243a3a7..38ed727 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -101,6 +101,8 @@ void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_availabl refresh_menu(); } // Emit the signals after the menus are setup/torn down + // preserve ordering ! + sound_service_dbus_update_sink_availability(dbus_interface, sink_available); sound_service_dbus_update_sink_volume(dbus_interface, percent); sound_service_dbus_update_sink_mute(dbus_interface, sink_muted); dbus_menu_manager_update_mute_ui(b_all_muted); @@ -199,7 +201,8 @@ static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service dbusmenu_menuitem_child_append(root, DBUSMENU_MENUITEM(volume_slider_menuitem)); dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), DBUSMENU_MENUITEM_PROP_ENABLED, - b_sink_available); + b_sink_available && !b_all_muted); + g_debug("!!!!!!**in the rebuild sound menu - slider active = %i", b_sink_available && !b_all_muted); dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), DBUSMENU_MENUITEM_PROP_VISIBLE, b_sink_available); diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 1fb8090..c10b549 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -93,8 +93,10 @@ static void connection_changed (IndicatorServiceManager * sm, gboolean connected static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean value, gpointer userdata); static void catch_signal_sink_volume_update(DBusGProxy * proxy, gdouble volume_percent, gpointer userdata); static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata); +static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean available_value, gpointer userdata); static void fetch_volume_percent_from_dbus(); static void fetch_mute_value_from_dbus(); +static void fetch_sink_availability_from_dbus(); /****Volume States 'members' ***/ @@ -110,11 +112,13 @@ static const gint STATE_SINKS_NONE = 6; static GHashTable *volume_states = NULL; static GtkImage *speaker_image = NULL; +static GtkImage *blocking_image = NULL; static GtkWidget* primary_image = NULL; static gint current_state = 0; static gint previous_state = 0; static gdouble initial_volume_percent = 0; static gboolean initial_mute = FALSE; +static gboolean device_available = TRUE; #define DESIGN_TEAM_SIZE design_team_size static GtkIconSize design_team_size; @@ -182,6 +186,8 @@ get_icon (IndicatorObject * io) gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); //g_debug("At start-up attempting to set the image to %s", current_name); speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, DESIGN_TEAM_SIZE)); + gchar* blocking_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + blocking_image = GTK_IMAGE(gtk_image_new_from_icon_name(blocking_name, DESIGN_TEAM_SIZE)); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; } @@ -264,11 +270,14 @@ connection_changed (IndicatorServiceManager * sm, gboolean connected, gpointer u dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_VOLUME_UPDATE, G_CALLBACK(catch_signal_sink_volume_update), NULL, NULL); dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_MUTE_UPDATE, G_CALLBACK(catch_signal_sink_mute_update), NULL, NULL); + dbus_g_proxy_add_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_TYPE_BOOLEAN, G_TYPE_INVALID); + dbus_g_proxy_connect_signal(sound_dbus_proxy, SIGNAL_SINK_AVAILABLE_UPDATE, G_CALLBACK(catch_signal_sink_availability_update), NULL, NULL); // Ensure we are in a coherent state with the service at start up. // Preserve ordering! fetch_volume_percent_from_dbus(); fetch_mute_value_from_dbus(); + fetch_sink_availability_from_dbus(); } } else { @@ -332,7 +341,8 @@ static void update_state(const gint state) void determine_state_from_volume(gdouble volume_percent) { /* g_debug("determine_state_from_volume - previous_state = %i", previous_state);*/ - + if (device_available == FALSE) + return; gint state = previous_state; if (volume_percent < 30.0 && volume_percent > 0){ state = STATE_LOW; @@ -350,6 +360,25 @@ void determine_state_from_volume(gdouble volume_percent) } +static void fetch_sink_availability_from_dbus() +{ + GError * error = NULL; + gboolean *available_input; + available_input = g_new0(gboolean, 1); + org_ayatana_indicator_sound_get_sink_availability(sound_dbus_proxy, available_input, &error); + if (error != NULL) { + g_warning("Unable to fetch AVAILABILITY at indicator start up: %s", error->message); + g_error_free(error); + g_free(available_input); + return; + } + device_available = *available_input; + if (device_available == FALSE) + update_state(STATE_SINKS_NONE); + g_free(available_input); + g_debug("IndicatorSound::fetch_sink_availability_from_dbus -> AVAILABILTY returned from dbus method is %i", device_available); + +} static void fetch_volume_percent_from_dbus() { @@ -391,6 +420,38 @@ static void fetch_mute_value_from_dbus() static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) { g_debug("signal caught - sink input while muted with value %i", block_value); + if (block_value == 1) { + GError* error= NULL; + // We can assume we are in the muted state ! + GtkIconTheme* theme = gtk_icon_theme_get_default(); + GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, + g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)), + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + &error); + if(error != NULL){ + g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); + g_error_free(error); + return; + } + gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + GdkPixbuf* blocked_buf = gtk_icon_theme_load_icon(theme, blocked_name, + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + &error); + if(error != NULL){ + g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); + g_error_free(error); + return; + } + g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf)); + gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, + gdk_pixbuf_get_width(blocked_buf), + gdk_pixbuf_get_height(blocked_buf), + 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128); + //gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE); + //gtk_image_set_from_pixbuf(speaker_image, blocked_buf); + } } static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) @@ -409,13 +470,23 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value { //We can be sure the service won't send a mute signal unless it has changed ! //UNMUTE's force a volume update therefore icon is updated appropriately => no need for unmute handling here. - if(mute_value == TRUE) + if(mute_value == TRUE && device_available != FALSE) { update_state(STATE_MUTED); } g_debug("signal caught - sink mute update with mute value: %i", mute_value); gtk_widget_set_sensitive(volume_slider, !mute_value); } + +static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean available_value, gpointer userdata) +{ + device_available = available_value; + if (device_available == FALSE){ + update_state(STATE_SINKS_NONE); + } + g_debug("signal caught - sink availability update with value: %i", available_value); +} + /** slider_prop_change_cb: Whenever we have a property change on a DbusmenuMenuitem this will be called. diff --git a/src/pulse-manager.c b/src/pulse-manager.c index 36e6351..40add4e 100644 --- a/src/pulse-manager.c +++ b/src/pulse-manager.c @@ -282,7 +282,7 @@ static void pulse_sink_info_callback(pa_context *c, const pa_sink_info *sink, in else{ //Update the indicator to show PA either is not ready or has no available sink g_warning("Cannot find a suitable default sink ..."); - dbus_menu_manager_update_pa_state(FALSE, device_available, TRUE, 0); + dbus_menu_manager_update_pa_state(FALSE, device_available, default_sink_is_muted(), get_default_sink_volume()); } } else{ @@ -398,6 +398,7 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v } else { + sink_info *value; value = g_new0(sink_info, 1); value->index = value->device_index = info->index; @@ -411,7 +412,8 @@ static void update_sink_info(pa_context *c, const pa_sink_info *info, int eol, v value->channel_map = info->channel_map; g_hash_table_insert(sink_hash, GINT_TO_POINTER(value->index), value); g_debug("pulse-manager:update_sink_info -> After adding a new sink to our hash"); - } + sound_service_dbus_update_sink_availability(dbus_service, TRUE); + } } @@ -460,8 +462,11 @@ static void subscribed_events_callback(pa_context *c, enum pa_subscription_event g_debug("PA_SUBSCRIPTION_EVENT_SINK event triggered"); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - //TODO handle the remove event => if its our default sink - update date pa state - } else + if(index == DEFAULT_SINK_INDEX) + g_debug("PA_SUBSCRIPTION_EVENT_SINK REMOVAL event triggered"); + sound_service_dbus_update_sink_availability(dbus_service, FALSE); + } + else { pa_operation_unref(pa_context_get_sink_info_by_index(c, index, update_sink_info, userdata)); } @@ -470,7 +475,7 @@ static void subscribed_events_callback(pa_context *c, enum pa_subscription_event g_debug("PA_SUBSCRIPTION_EVENT_SINK_INPUT event triggered!!"); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - //TODO handle the remove event + //handle the remove event - not relevant for current design } else { diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 72337fd..1cc5f0d 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -32,6 +32,7 @@ // DBUS methods static gboolean sound_service_dbus_get_sink_volume(SoundServiceDbus* service, gdouble* volume_percent_input, GError** gerror); static gboolean sound_service_dbus_get_sink_mute(SoundServiceDbus* service, gboolean* mute_input, GError** gerror); +static gboolean sound_service_dbus_get_sink_availability(SoundServiceDbus* service, gboolean* availability_input, GError** gerror); static void sound_service_dbus_set_sink_volume(SoundServiceDbus* service, const guint volume_percent, GError** gerror); #include "sound-service-server.h" @@ -43,6 +44,7 @@ struct _SoundServiceDbusPrivate DBusGConnection *connection; gdouble volume_percent; gboolean mute; + gboolean sink_availability; }; @@ -51,6 +53,7 @@ enum { SINK_INPUT_WHILE_MUTED, SINK_VOLUME_UPDATE, SINK_MUTE_UPDATE, + SINK_AVAILABLE_UPDATE, LAST_SIGNAL }; @@ -105,6 +108,15 @@ sound_service_dbus_class_init (SoundServiceDbusClass *klass) NULL, NULL, g_cclosure_marshal_VOID__BOOLEAN, G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + signals[SINK_AVAILABLE_UPDATE] = g_signal_new("sink-available-update", + G_TYPE_FROM_CLASS (klass), + G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, + g_cclosure_marshal_VOID__BOOLEAN, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); + + } @@ -116,6 +128,8 @@ sound_service_dbus_init (SoundServiceDbus *self) priv->connection = NULL; priv->volume_percent = 0; + priv->mute = FALSE; + priv->sink_availability = FALSE; /* Fetch the session bus */ priv->connection = dbus_g_bus_get(DBUS_BUS_SESSION, &error); @@ -129,8 +143,6 @@ sound_service_dbus_init (SoundServiceDbus *self) dbus_g_connection_register_g_object(priv->connection, "/org/ayatana/indicator/sound/service", G_OBJECT(self)); - - return; } @@ -174,6 +186,14 @@ static gboolean sound_service_dbus_get_sink_mute (SoundServiceDbus *self, gboole return TRUE; } +static gboolean sound_service_dbus_get_sink_availability (SoundServiceDbus *self, gboolean *availability_input, GError** gerror) +{ + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); + g_debug("Get sink availability - sound service dbus!, about to send over availability_value of %i", priv->sink_availability); + *availability_input = priv->sink_availability; + return TRUE; +} + /** SIGNALS Utility methods to emit signals from the service into the ether. @@ -212,5 +232,18 @@ void sound_service_dbus_update_sink_mute(SoundServiceDbus* obj, gboolean sink_mu priv->mute); } +void sound_service_dbus_update_sink_availability(SoundServiceDbus* obj, gboolean sink_availability) +{ + g_debug("Emitting signal: SINK_AVAILABILITY_UPDATE, with value %i", sink_availability); + + SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (obj); + priv->sink_availability = sink_availability; + + g_signal_emit(obj, + signals[SINK_AVAILABLE_UPDATE], + 0, + priv->sink_availability); +} + diff --git a/src/sound-service-dbus.h b/src/sound-service-dbus.h index 1a06117..ae4953e 100644 --- a/src/sound-service-dbus.h +++ b/src/sound-service-dbus.h @@ -56,6 +56,7 @@ GType sound_service_dbus_get_type (void) G_GNUC_CONST; void sound_service_dbus_sink_input_while_muted (SoundServiceDbus* obj, gboolean block_value); void sound_service_dbus_update_sink_volume(SoundServiceDbus* obj, gdouble sink_volume); void sound_service_dbus_update_sink_mute(SoundServiceDbus* obj, gboolean sink_mute); +void sound_service_dbus_update_sink_availability(SoundServiceDbus* obj, gboolean sink_availibity); G_END_DECLS diff --git a/src/sound-service.xml b/src/sound-service.xml index 580f0e1..12ed03e 100644 --- a/src/sound-service.xml +++ b/src/sound-service.xml @@ -5,6 +5,7 @@ + @@ -15,6 +16,11 @@ + + + + + @@ -30,6 +36,10 @@ Our respective UI element should listen to this and therefore will be updated wi + + + + -- cgit v1.2.3 From ea8064d34d73a1b242cc571fbfd9f0f39128178a Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Tue, 9 Mar 2010 18:10:09 +0000 Subject: smoother slider actions due ido grabbing update and pixbuf icon loading problems --- src/dbus-menu-manager.c | 5 ++ src/indicator-sound.c | 124 ++++++++++++++++++++++++++++++------------------ 2 files changed, 83 insertions(+), 46 deletions(-) diff --git a/src/dbus-menu-manager.c b/src/dbus-menu-manager.c index 38ed727..64f7108 100644 --- a/src/dbus-menu-manager.c +++ b/src/dbus-menu-manager.c @@ -154,6 +154,11 @@ static void refresh_menu() DBUSMENU_MENUITEM_PROP_ENABLED, TRUE); } +/* if(b_all_muted == TRUE){*/ +/* dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), */ +/* DBUSMENU_MENUITEM_PROP_ENABLED,*/ +/* FALSE); */ +/* }*/ } diff --git a/src/indicator-sound.c b/src/indicator-sound.c index c10b549..5fd68b2 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -5,7 +5,7 @@ into the gnome-panel using it's applet interface. Copyright 2010 Canonical Ltd. Authors: - Conor Curran + Conor Curran Ted Gould This program is free software: you can redistribute it and/or modify it @@ -82,10 +82,12 @@ static GtkMenu * get_menu (IndicatorObject * io); //Slider related static GtkWidget *volume_slider = NULL; static gboolean new_slider_item (DbusmenuMenuitem * newitem, DbusmenuMenuitem * parent, DbusmenuClient * client); -static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget); +/*static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget);*/ static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data); static gboolean key_press_cb(GtkWidget* widget, GdkEventKey* event, gpointer data); static void slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data); +static void slider_grabbed(GtkWidget *widget, gpointer user_data); +static void slider_released(GtkWidget *widget, gpointer user_data); // DBUS communication static DBusGProxy *sound_dbus_proxy = NULL; @@ -98,7 +100,6 @@ static void fetch_volume_percent_from_dbus(); static void fetch_mute_value_from_dbus(); static void fetch_sink_availability_from_dbus(); - /****Volume States 'members' ***/ static void update_state(const gint state); @@ -112,13 +113,13 @@ static const gint STATE_SINKS_NONE = 6; static GHashTable *volume_states = NULL; static GtkImage *speaker_image = NULL; -static GtkImage *blocking_image = NULL; -static GtkWidget* primary_image = NULL; static gint current_state = 0; static gint previous_state = 0; + static gdouble initial_volume_percent = 0; static gboolean initial_mute = FALSE; static gboolean device_available = TRUE; +static gboolean slider_in_direct_use = FALSE; #define DESIGN_TEAM_SIZE design_team_size static GtkIconSize design_team_size; @@ -184,10 +185,8 @@ static GtkImage * get_icon (IndicatorObject * io) { gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - //g_debug("At start-up attempting to set the image to %s", current_name); + g_debug("At start-up attempting to set the image to %s", current_name); speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, DESIGN_TEAM_SIZE)); - gchar* blocking_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); - blocking_image = GTK_IMAGE(gtk_image_new_from_icon_name(blocking_name, DESIGN_TEAM_SIZE)); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; } @@ -204,7 +203,6 @@ get_menu (IndicatorObject * io) // register Key-press listening on the menu widget as the slider does not allow this. g_signal_connect(menu, "key-press-event", G_CALLBACK(key_press_cb), NULL); - return GTK_MENU(menu); } @@ -224,15 +222,16 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent); - g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider); +/* g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);*/ // register slider changes listening on the range GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); - - g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); - g_signal_connect(slider, "size-allocate", G_CALLBACK(slider_size_allocate), NULL); + g_signal_connect(slider, "value-changed", G_CALLBACK(value_changed_event_cb), newitem); + g_signal_connect(volume_slider, "slider-grabbed", G_CALLBACK(slider_grabbed), NULL); + g_signal_connect(volume_slider, "slider-released", G_CALLBACK(slider_released), NULL); + g_signal_connect(slider, "size-allocate", G_CALLBACK(slider_size_allocate), NULL); // Set images on the ido - primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); + GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), DESIGN_TEAM_SIZE); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), DESIGN_TEAM_SIZE); @@ -413,6 +412,9 @@ static void fetch_mute_value_from_dbus() initial_mute = *mute_input; if (initial_mute == TRUE) update_state(STATE_MUTED); +// TODO bug down below - VIRTUALLY IMPOSSIBLE TO SETUP SLIDER WITH ANY ALTERNATIVE STARTUP STATE +/* GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);*/ +/* gtk_widget_set_sensitive(slider, !initial_mute);*/ g_free(mute_input); g_debug("at the indicator start up and the MUTE returned from dbus method is %i", initial_mute); } @@ -423,18 +425,25 @@ static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean blo if (block_value == 1) { GError* error= NULL; // We can assume we are in the muted state ! + gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); GtkIconTheme* theme = gtk_icon_theme_get_default(); - GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, - g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)), - 22, - GTK_ICON_LOOKUP_GENERIC_FALLBACK, - &error); + g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name)); +/* GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, */ +/* blocked_name,*/ +/* 22,*/ +/* GTK_ICON_LOOKUP_GENERIC_FALLBACK,*/ +/* &error);*/ if(error != NULL){ g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); g_error_free(error); return; } - gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + + GtkIconInfo* buffer_icon_info = gtk_icon_theme_lookup_icon(theme, blocked_name, + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK); + g_debug("The icon name of the buffer icon %s", gtk_icon_info_get_filename(buffer_icon_info)); + GdkPixbuf* blocked_buf = gtk_icon_theme_load_icon(theme, blocked_name, 22, GTK_ICON_LOOKUP_GENERIC_FALLBACK, @@ -445,25 +454,34 @@ static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean blo return; } g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf)); - gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, - gdk_pixbuf_get_width(blocked_buf), - gdk_pixbuf_get_height(blocked_buf), - 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128); +/* gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0,*/ +/* gdk_pixbuf_get_width(blocked_buf),*/ +/* gdk_pixbuf_get_height(blocked_buf), */ +/* 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128);*/ //gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE); - //gtk_image_set_from_pixbuf(speaker_image, blocked_buf); + + g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name)); + gchar ** theme_path; + gint nelements = 1; + + gtk_icon_theme_get_search_path(theme, &theme_path, &nelements); + g_debug("icon theme path is %s ", *theme_path); + gtk_image_set_from_pixbuf(speaker_image, blocked_buf); } } static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) { - GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); - GtkRange *range = (GtkRange*)slider; - - // DEBUG - gdouble current_value = gtk_range_get_value(range); - g_debug("SIGNAL- update sink volume - current_value : %f and new value : %f", current_value, volume_percent); - gtk_range_set_value(range, volume_percent); - determine_state_from_volume(volume_percent); + if (slider_in_direct_use != TRUE){ + GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); + GtkRange *range = (GtkRange*)slider; + + // DEBUG + gdouble current_value = gtk_range_get_value(range); + g_debug("SIGNAL- update sink volume - current_value : %f and new value : %f", current_value, volume_percent); + gtk_range_set_value(range, volume_percent); + determine_state_from_volume(volume_percent); + } } static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value, gpointer userdata) @@ -491,15 +509,15 @@ static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean av slider_prop_change_cb: Whenever we have a property change on a DbusmenuMenuitem this will be called. **/ -static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget) -{ - g_debug("slider_prop_change_cb - dodgy updater "); - g_debug("about to set the slider to %f", g_value_get_double(value)); - GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); - GtkRange* range = (GtkRange*)slider; - gtk_range_set_value(range, g_value_get_double(value)); - return; -} +/*static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget)*/ +/*{*/ +/* g_debug("slider_prop_change_cb - dodgy updater ");*/ +/* g_debug("about to set the slider to %f", g_value_get_double(value));*/ +/* GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);*/ +/* GtkRange* range = (GtkRange*)slider; */ +/* gtk_range_set_value(range, g_value_get_double(value)); */ +/* return;*/ +/*}*/ /** value_changed_event_cb: @@ -520,6 +538,20 @@ static gboolean value_changed_event_cb(GtkRange *range, gpointer user_data) return FALSE; } + +static void slider_grabbed (GtkWidget *widget, gpointer user_data) +{ + slider_in_direct_use = TRUE; + g_debug ("!!!!!! grabbed\n"); +} + +static void slider_released (GtkWidget *widget, gpointer user_data) +{ + slider_in_direct_use = FALSE; + g_debug ("!!!!!! released\n"); +} + + /** slider_size_allocate: Callback on the size-allocate event on the slider item. @@ -528,10 +560,10 @@ static void slider_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer user_data) { - g_print("size allocate on slider (%dx%d)\n", allocation->width, allocation->height); - if(allocation->width < 200) - { - gtk_widget_set_size_request(widget, 200, -1); + g_print("Size allocate on slider (%dx%d)\n", allocation->width, allocation->height); + if(allocation->width < 200){ + g_print("Attempting to resize the slider"); + gtk_widget_set_size_request(widget, 200, -1); } } -- cgit v1.2.3 From 16021586200c0e7746ce787e43a8721dfe23ae48 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 10 Mar 2010 10:53:23 +0000 Subject: fixed that annoying startup in mute state allowing slider to move - race conditions on start up are pretty hairy --- src/indicator-sound.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 5fd68b2..1876e69 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -235,6 +235,9 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), DESIGN_TEAM_SIZE); GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), DESIGN_TEAM_SIZE); + + // the race conditions at start up are like a west waterford greyhound dart. god knows who wins, who breaks a leg. + gtk_widget_set_sensitive(volume_slider, !initial_mute); gtk_widget_show_all(volume_slider); @@ -412,9 +415,6 @@ static void fetch_mute_value_from_dbus() initial_mute = *mute_input; if (initial_mute == TRUE) update_state(STATE_MUTED); -// TODO bug down below - VIRTUALLY IMPOSSIBLE TO SETUP SLIDER WITH ANY ALTERNATIVE STARTUP STATE -/* GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);*/ -/* gtk_widget_set_sensitive(slider, !initial_mute);*/ g_free(mute_input); g_debug("at the indicator start up and the MUTE returned from dbus method is %i", initial_mute); } -- cgit v1.2.3 From 59eb14451f0635c286d482e8b35cad622882aa35 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Wed, 10 Mar 2010 18:10:40 +0000 Subject: fade animation in place --- src/indicator-sound.c | 181 +++++++++++++++++++++++++++++++++++++------------- 1 file changed, 136 insertions(+), 45 deletions(-) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 1876e69..ebd4306 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -123,6 +123,13 @@ static gboolean slider_in_direct_use = FALSE; #define DESIGN_TEAM_SIZE design_team_size static GtkIconSize design_team_size; +static gint timeout_id; +static gint animation_id; +static GList * blocked_animation_list = NULL; +static GList * blocked_iter = NULL; +static void prepare_blocked_animation(); +static gboolean fade_back_to_mute_image(); +static gboolean commence_animation(); // Construction static void @@ -151,6 +158,9 @@ static void indicator_sound_init (IndicatorSound *self) self->service = indicator_service_manager_new_version(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_VERSION); g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self); prepare_state_machine(); + prepare_blocked_animation(); + timeout_id = 0; + animation_id = 0; return; } @@ -164,6 +174,8 @@ indicator_sound_dispose (GObject *object) self->service = NULL; } g_hash_table_destroy(volume_states); + // TODO delete all pointers in the list; + g_list_free(blocked_animation_list); G_OBJECT_CLASS (indicator_sound_parent_class)->dispose (object); return; } @@ -305,6 +317,51 @@ void prepare_state_machine() g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_SINKS_NONE), g_strdup("audio-output-none-panel")); } +/* +prepare_blocked_animation: +Prepares the array of images to be used in the blocked animation. +Only called at startup. +*/ +static void prepare_blocked_animation() +{ + GError* error= NULL; + int i; + + gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); + gchar* muted_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED)); + GtkIconTheme* theme = gtk_icon_theme_get_default(); + GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, + muted_name, + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + &error); + if(error != NULL){ + g_error("indicator-sound : prepare_blocked_animation - %s", error->message); + g_error_free(error); + return; + } + + GdkPixbuf* blocked_buf = gtk_icon_theme_load_icon(theme, blocked_name, + 22, + GTK_ICON_LOOKUP_GENERIC_FALLBACK, + &error); + if(error != NULL){ + g_error("indicator-sound : prepare_blocked_animation - %s", error->message); + g_error_free(error); + return; + } + + for(i = 0; i < 256; i++) + { + gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, + gdk_pixbuf_get_width(mute_buf), + gdk_pixbuf_get_height(mute_buf), + 0, 0, 1, 1, GDK_INTERP_BILINEAR, i); + g_debug("creating animation - alpha value = %i", i); + blocked_animation_list = g_list_append(blocked_animation_list, gdk_pixbuf_copy(blocked_buf)); + } +} + gint get_state() { return current_state; @@ -365,7 +422,7 @@ void determine_state_from_volume(gdouble volume_percent) static void fetch_sink_availability_from_dbus() { GError * error = NULL; - gboolean *available_input; + gboolean * available_input; available_input = g_new0(gboolean, 1); org_ayatana_indicator_sound_get_sink_availability(sound_dbus_proxy, available_input, &error); if (error != NULL) { @@ -422,53 +479,75 @@ static void fetch_mute_value_from_dbus() static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) { g_debug("signal caught - sink input while muted with value %i", block_value); - if (block_value == 1) { - GError* error= NULL; + if (block_value == 1 && timeout_id == 0 ) { // We can assume we are in the muted state ! - gchar* blocked_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)); - GtkIconTheme* theme = gtk_icon_theme_get_default(); - g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name)); -/* GdkPixbuf* mute_buf = gtk_icon_theme_load_icon(theme, */ -/* blocked_name,*/ -/* 22,*/ -/* GTK_ICON_LOOKUP_GENERIC_FALLBACK,*/ -/* &error);*/ - if(error != NULL){ - g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); - g_error_free(error); - return; - } - - GtkIconInfo* buffer_icon_info = gtk_icon_theme_lookup_icon(theme, blocked_name, - 22, - GTK_ICON_LOOKUP_GENERIC_FALLBACK); - g_debug("The icon name of the buffer icon %s", gtk_icon_info_get_filename(buffer_icon_info)); - - GdkPixbuf* blocked_buf = gtk_icon_theme_load_icon(theme, blocked_name, - 22, - GTK_ICON_LOOKUP_GENERIC_FALLBACK, - &error); - if(error != NULL){ - g_error("indicator-sound : catch_signal_sink_input_while_muted - %s", error->message); - g_error_free(error); - return; - } - g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf)); -/* gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0,*/ -/* gdk_pixbuf_get_width(blocked_buf),*/ -/* gdk_pixbuf_get_height(blocked_buf), */ -/* 0, 0, 1, 1, GDK_INTERP_BILINEAR, 128);*/ - //gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE); - - g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name)); - gchar ** theme_path; - gint nelements = 1; + gtk_image_set_from_icon_name(speaker_image, + g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)), + DESIGN_TEAM_SIZE); + blocked_iter = blocked_animation_list; + timeout_id = g_timeout_add_seconds(3, commence_animation, NULL); + } +} - gtk_icon_theme_get_search_path(theme, &theme_path, &nelements); - g_debug("icon theme path is %s ", *theme_path); - gtk_image_set_from_pixbuf(speaker_image, blocked_buf); - } +static gboolean commence_animation() +{ + animation_id = g_timeout_add_seconds(1, fade_back_to_mute_image, NULL); + timeout_id = 0; + g_debug("out of there\n"); + return FALSE; +} + +static gboolean fade_back_to_mute_image() +{ + g_debug("fade me entry\n"); + if(blocked_iter != NULL) + { + g_debug("in there\n"); + gtk_image_set_from_pixbuf(speaker_image, blocked_iter->data); + blocked_iter = blocked_iter->next; + return TRUE; + } + else{ + animation_id = 0; + g_debug("out of there\n"); + return FALSE; + } } +/* int i;*/ +/* GList * anim_iter;*/ +/* anim_iter = blocked_animation_list;*/ +/* for(i=0; i < 2560000; i++)*/ +/* { */ +/* if(i % 100000 == 0)*/ +/* {*/ +/* if (anim_iter != NULL)*/ +/* {*/ +/* gtk_image_set_from_pixbuf(speaker_image, anim_iter->data); */ +/* anim_iter = anim_iter->next; */ +/* g_debug("should now be setting each image");*/ +/* }*/ +/* }*/ +/* }*/ +/* gtk_image_set_from_icon_name(speaker_image,*/ +/* g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED)),*/ +/* DESIGN_TEAM_SIZE);*/ + //fade_id = g_timeout_add_seconds(0.2, fade_each_frame, NULL); + + + + +/* g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name));*/ +/* GtkIconInfo* buffer_icon_info = gtk_icon_theme_lookup_icon(theme, blocked_name,*/ +/* 22,*/ +/* GTK_ICON_LOOKUP_GENERIC_FALLBACK);*/ +/* g_debug("The icon name of the buffer icon %s", gtk_icon_info_get_filename(buffer_icon_info));*/ +/* g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf));*/ +/* g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name));*/ +/* gchar ** theme_path; */ +/* gint nelements = 1;*/ +/* gtk_icon_theme_get_search_path(theme, &theme_path, &nelements);*/ +/* gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE);*/ +/* g_debug("icon theme path is %s ", *theme_path);*/ static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) { @@ -492,6 +571,18 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value { update_state(STATE_MUTED); } + else{ + if(timeout_id != 0){ + g_debug("about to remove the timeout_id callback from the mainloop!!**"); + g_source_remove(timeout_id); + timeout_id = 0; + } + if(animation_id != 0){ + g_debug("about to remove the animation_id callback from the mainloop!!**"); + g_source_remove(animation_id); + animation_id = 0; + } + } g_debug("signal caught - sink mute update with mute value: %i", mute_value); gtk_widget_set_sensitive(volume_slider, !mute_value); } -- cgit v1.2.3 From c67c7ac2effb7ee425370ee33e6b5449e04b98c6 Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Thu, 11 Mar 2010 00:23:59 +0000 Subject: animation working much better now --- src/indicator-sound.c | 85 +++++---------------------------------------------- 1 file changed, 8 insertions(+), 77 deletions(-) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index ebd4306..d9c5aa6 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -123,13 +123,11 @@ static gboolean slider_in_direct_use = FALSE; #define DESIGN_TEAM_SIZE design_team_size static GtkIconSize design_team_size; -static gint timeout_id; static gint animation_id; static GList * blocked_animation_list = NULL; static GList * blocked_iter = NULL; static void prepare_blocked_animation(); static gboolean fade_back_to_mute_image(); -static gboolean commence_animation(); // Construction static void @@ -152,14 +150,11 @@ indicator_sound_class_init (IndicatorSoundClass *klass) static void indicator_sound_init (IndicatorSound *self) { - /* Set good defaults */ self->service = NULL; - /* Now let's fire these guys up. */ self->service = indicator_service_manager_new_version(INDICATOR_SOUND_DBUS_NAME, INDICATOR_SOUND_DBUS_VERSION); g_signal_connect(G_OBJECT(self->service), INDICATOR_SERVICE_MANAGER_SIGNAL_CONNECTION_CHANGE, G_CALLBACK(connection_changed), self); prepare_state_machine(); prepare_blocked_animation(); - timeout_id = 0; animation_id = 0; return; } @@ -234,7 +229,6 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p GtkMenuItem *menu_volume_slider = GTK_MENU_ITEM(volume_slider); dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), newitem, menu_volume_slider, parent); -/* g_signal_connect(G_OBJECT(newitem), DBUSMENU_MENUITEM_SIGNAL_PROPERTY_CHANGED, G_CALLBACK(slider_prop_change_cb), volume_slider);*/ // register slider changes listening on the range GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider); @@ -306,7 +300,6 @@ Prepare states Array. */ void prepare_state_machine() { - // TODO we need three more images volume_states = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, g_free); g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_MUTED), g_strdup("audio-volume-muted-panel")); g_hash_table_insert(volume_states, GINT_TO_POINTER(STATE_ZERO), g_strdup("audio-volume-low-zero-panel")); @@ -350,14 +343,14 @@ static void prepare_blocked_animation() g_error_free(error); return; } - - for(i = 0; i < 256; i++) + // sample 22 snapshots - range : 0-256 + for(i = 0; i < 23; i++) { gdk_pixbuf_composite(mute_buf, blocked_buf, 0, 0, gdk_pixbuf_get_width(mute_buf), gdk_pixbuf_get_height(mute_buf), - 0, 0, 1, 1, GDK_INTERP_BILINEAR, i); - g_debug("creating animation - alpha value = %i", i); + 0, 0, 1, 1, GDK_INTERP_BILINEAR, MIN(255, i * 11)); + g_debug("creating blocking animation - alpha value = %i", MIN(255, i * 11)); blocked_animation_list = g_list_append(blocked_animation_list, gdk_pixbuf_copy(blocked_buf)); } } @@ -479,75 +472,31 @@ static void fetch_mute_value_from_dbus() static void catch_signal_sink_input_while_muted(DBusGProxy * proxy, gboolean block_value, gpointer userdata) { g_debug("signal caught - sink input while muted with value %i", block_value); - if (block_value == 1 && timeout_id == 0 ) { + if (block_value == 1 && animation_id == 0 ) { // We can assume we are in the muted state ! gtk_image_set_from_icon_name(speaker_image, g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED_WHILE_INPUT)), DESIGN_TEAM_SIZE); blocked_iter = blocked_animation_list; - timeout_id = g_timeout_add_seconds(3, commence_animation, NULL); + animation_id = g_timeout_add_seconds(1, fade_back_to_mute_image, NULL); } } - -static gboolean commence_animation() -{ - animation_id = g_timeout_add_seconds(1, fade_back_to_mute_image, NULL); - timeout_id = 0; - g_debug("out of there\n"); - return FALSE; -} static gboolean fade_back_to_mute_image() { - g_debug("fade me entry\n"); if(blocked_iter != NULL) { - g_debug("in there\n"); + g_debug("in animation 'loop'\n"); gtk_image_set_from_pixbuf(speaker_image, blocked_iter->data); blocked_iter = blocked_iter->next; return TRUE; } else{ animation_id = 0; - g_debug("out of there\n"); + g_debug("exit from animation\n"); return FALSE; } } -/* int i;*/ -/* GList * anim_iter;*/ -/* anim_iter = blocked_animation_list;*/ -/* for(i=0; i < 2560000; i++)*/ -/* { */ -/* if(i % 100000 == 0)*/ -/* {*/ -/* if (anim_iter != NULL)*/ -/* {*/ -/* gtk_image_set_from_pixbuf(speaker_image, anim_iter->data); */ -/* anim_iter = anim_iter->next; */ -/* g_debug("should now be setting each image");*/ -/* }*/ -/* }*/ -/* }*/ -/* gtk_image_set_from_icon_name(speaker_image,*/ -/* g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_MUTED)),*/ -/* DESIGN_TEAM_SIZE);*/ - //fade_id = g_timeout_add_seconds(0.2, fade_each_frame, NULL); - - - - -/* g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name));*/ -/* GtkIconInfo* buffer_icon_info = gtk_icon_theme_lookup_icon(theme, blocked_name,*/ -/* 22,*/ -/* GTK_ICON_LOOKUP_GENERIC_FALLBACK);*/ -/* g_debug("The icon name of the buffer icon %s", gtk_icon_info_get_filename(buffer_icon_info));*/ -/* g_debug("gdk_pixbuf_get_width returns %i", gdk_pixbuf_get_width(blocked_buf));*/ -/* g_debug("DOES the ICON THEME Have the Blocked image = %i", gtk_icon_theme_has_icon(theme, blocked_name));*/ -/* gchar ** theme_path; */ -/* gint nelements = 1;*/ -/* gtk_icon_theme_get_search_path(theme, &theme_path, &nelements);*/ -/* gtk_image_set_from_icon_name(speaker_image, blocked_name, DESIGN_TEAM_SIZE);*/ -/* g_debug("icon theme path is %s ", *theme_path);*/ static void catch_signal_sink_volume_update(DBusGProxy *proxy, gdouble volume_percent, gpointer userdata) { @@ -572,11 +521,6 @@ static void catch_signal_sink_mute_update(DBusGProxy *proxy, gboolean mute_value update_state(STATE_MUTED); } else{ - if(timeout_id != 0){ - g_debug("about to remove the timeout_id callback from the mainloop!!**"); - g_source_remove(timeout_id); - timeout_id = 0; - } if(animation_id != 0){ g_debug("about to remove the animation_id callback from the mainloop!!**"); g_source_remove(animation_id); @@ -596,19 +540,6 @@ static void catch_signal_sink_availability_update(DBusGProxy *proxy, gboolean av g_debug("signal caught - sink availability update with value: %i", available_value); } -/** -slider_prop_change_cb: -Whenever we have a property change on a DbusmenuMenuitem this will be called. -**/ -/*static void slider_prop_change_cb (DbusmenuMenuitem * mi, gchar * prop, GValue * value, GtkWidget *widget)*/ -/*{*/ -/* g_debug("slider_prop_change_cb - dodgy updater ");*/ -/* g_debug("about to set the slider to %f", g_value_get_double(value));*/ -/* GtkWidget* slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)volume_slider);*/ -/* GtkRange* range = (GtkRange*)slider; */ -/* gtk_range_set_value(range, g_value_get_double(value)); */ -/* return;*/ -/*}*/ /** value_changed_event_cb: -- cgit v1.2.3 From 69c96d7e7fa903569073bd87069b2d9f6aeb3fa4 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 10 Mar 2010 22:59:35 -0600 Subject: Update to use new icon helper from libindicator --- src/indicator-sound.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 3a6ae30..0b92af8 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -34,6 +34,7 @@ with this program. If not, see . #include #include #include +#include #include "indicator-sound.h" #include "dbus-shared-names.h" @@ -180,7 +181,7 @@ get_icon (IndicatorObject * io) { gchar* current_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); //g_debug("At start-up attempting to set the image to %s", current_name); - speaker_image = GTK_IMAGE(gtk_image_new_from_icon_name(current_name, GTK_ICON_SIZE_MENU)); + speaker_image = indicator_image_helper(current_name); gtk_widget_show(GTK_WIDGET(speaker_image)); return speaker_image; } @@ -327,7 +328,9 @@ static void update_state(const gint state) current_state = state; gchar* image_name = g_hash_table_lookup(volume_states, GINT_TO_POINTER(current_state)); - gtk_image_set_from_icon_name(speaker_image, image_name, GTK_ICON_SIZE_MENU); + GtkImage * tempimage = indicator_image_helper(image_name); + gtk_image_set_from_pixbuf(speaker_image, gtk_image_get_pixbuf(tempimage)); + g_object_ref_sink(tempimage); } -- cgit v1.2.3 From 21d52b5ed3206791d5a0b4adc907be75a9e5f668 Mon Sep 17 00:00:00 2001 From: Ted Gould Date: Wed, 10 Mar 2010 23:07:22 -0600 Subject: Using GIcon for setting the icons on the IDO slider. --- src/indicator-sound.c | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/src/indicator-sound.c b/src/indicator-sound.c index 0b92af8..2dc6bf3 100644 --- a/src/indicator-sound.c +++ b/src/indicator-sound.c @@ -225,12 +225,23 @@ static gboolean new_slider_item(DbusmenuMenuitem * newitem, DbusmenuMenuitem * p // alternative callback mechanism which i could use again at some point. /* g_signal_connect(slider, "change-value", G_CALLBACK(user_change_value_event_cb), newitem); */ - // Set images on the ido + /* Get the primary Image */ primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(primary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO)), GTK_ICON_SIZE_MENU); + + /* Build a GIcon for the theme fallbacks */ + GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks(g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_ZERO))); + gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU); + g_object_unref(primary_gicon); + + /* Get the secondary image */ GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)volume_slider); - gtk_image_set_from_icon_name(GTK_IMAGE(secondary_image), g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH)), GTK_ICON_SIZE_MENU); + /* Build a GIcon for fallbacks */ + GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks(g_hash_table_lookup(volume_states, GINT_TO_POINTER(STATE_HIGH))); + gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); + g_object_unref(secondary_gicon); + + /* Make the widget visible to users */ gtk_widget_show_all(volume_slider); return TRUE; -- cgit v1.2.3