From 7ba3797b9006f0a7e048787ee6de91fd05e60d2b Mon Sep 17 00:00:00 2001 From: Conor Curran Date: Fri, 4 Feb 2011 14:08:09 +0000 Subject: on the last hurdle --- src/active-sink.c | 101 ++++++++++++++++++++++++++++--- src/active-sink.h | 1 + src/pulseaudio-mgr.c | 8 +-- src/sound-service-dbus.c | 150 ++++++----------------------------------------- 4 files changed, 116 insertions(+), 144 deletions(-) (limited to 'src') diff --git a/src/active-sink.c b/src/active-sink.c index e85aab8..b41d6d3 100644 --- a/src/active-sink.c +++ b/src/active-sink.c @@ -17,15 +17,24 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . */ -#include -#include +#include + #include "active-sink.h" +#include "slider-menu-item.h" +#include "mute-menu-item.h" + + typedef struct _ActiveSinkPrivate ActiveSinkPrivate; struct _ActiveSinkPrivate { - sink_details* details; + gboolean is_active; + SliderMenuItem* volume_slider_menuitem; + MuteMenuItem* mute_menuitem; + SoundState current_sound_state; + gint index; + SoundServiceDbus* service; }; #define ACTIVE_SINK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ACTIVE_SINK_TYPE, ActiveSinkPrivate)) @@ -36,6 +45,8 @@ static void active_sink_init (ActiveSink *self); static void active_sink_dispose (GObject *object); static void active_sink_finalize (GObject *object); +static SoundState active_sink_get_state_from_volume (ActiveSink* self); + G_DEFINE_TYPE (ActiveSink, active_sink, G_TYPE_OBJECT); static void @@ -54,6 +65,15 @@ active_sink_init(ActiveSink *self) { ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); priv->details = NULL; + priv->mute_menuitem = NULL; + priv->volume_slider_menuitem = NULL; + priv->current_sound_state = UNAVAILABLE; + priv->is_active = TRUE; + priv->index = -1; + + // Init our menu items. + priv->mute_menuitem = g_object_new (MUTE_MENU_ITEM_TYPE, NULL); + priv->volume_slider_menuitem = g_object_new (SLIDER_MENU_ITEM_TYPE, NULL); } static void @@ -76,38 +96,103 @@ active_sink_finalize (GObject *object) G_OBJECT_CLASS (active_sink_parent_class)->finalize (object); } +// This needs to populate the appropriate values on the menu items void -active_sink_update_details (ActiveSink* sink, sink_details* details) +active_sink_populate (ActiveSink* sink, + gdouble volume, + gboolean mute, + gint device_index) { ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE(sink); - priv->details = details; + active_sink_update_volume (sink, volume); + active_sink_update_mute (sink, mute); + priv->index = device_index; + priv->is_active = TRUE; } gboolean active_sink_is_populated (ActiveSink* sink) { ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (sink); - return (priv->details != NULL); + return priv->is_active; } gboolean active_sink_is_muted (ActiveSink* self) { - return FALSE; + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + return mute_menu_item_is_muted (priv->mute_menuitem); } gint active_sink_get_index (ActiveSink* self) { - return 0; + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + return priv->index; } void active_sink_update_volume (ActiveSink* self, gdouble percent) { + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + slider_menu_item_update (priv->volume_slider_menuitem, percent); + sound_service_dbus_update_sound_state (priv->service, + active_sink_get_state_from_volume (self)); } void active_sink_update_mute (ActiveSink* self, gboolean muted) { + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + mute_menu_item_update (priv->mute_menuitem, muted); + SoundState state = active_sink_get_state_from_volume (self); + + if (muted == TRUE){ + state = MUTED; + } + sound_service_dbus_update_sound_state (priv->service, state); +} + +SoundState +active_sink_get_state (ActiveSink* self) +{ + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + return priv->current_sound_state; +} + + +static SoundState +active_sink_get_state_from_volume (ActiveSink* self) +{ + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); + GVariant* v = dbusmenu_menuitem_property_get_variant (DBUSMENU_MENUITEM(priv->volume_slider_menuitem), + DBUSMENU_VOLUME_MENUITEM_LEVEL); + gdouble volume_percent = g_variant_get_double (v); + + SoundState state = LOW_LEVEL; + + if (volume_percent < 30.0 && volume_percent > 0) { + state = LOW_LEVEL; + } + else if (volume_percent < 70.0 && volume_percent >= 30.0) { + state = MEDIUM_LEVEL; + } + else if (volume_percent >= 70.0) { + state = HIGH_LEVEL; + } + else if (volume_percent == 0.0) { + state = ZERO_LEVEL; + } + return state; +} + +ActiveSink* active_sink_new (SoundServiceDbus* service) +{ + ActiveSink* sink = g_object_new (ACTIVE_SINK_TYPE, NULL); + ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (sink); + priv->service = service; + sound_service_dbus_build_sound_menu (service, + priv->mute_menuitem, + priv->voluem_slider_menuitem); + return sink; } diff --git a/src/active-sink.h b/src/active-sink.h index 251d0a7..827b8a7 100644 --- a/src/active-sink.h +++ b/src/active-sink.h @@ -61,6 +61,7 @@ void active_sink_update_details (ActiveSink* sink, sink_details* details); gboolean active_sink_is_populated (ActiveSink* sink); gboolean active_sink_is_muted (ActiveSink* self); gint active_sink_get_index (ActiveSink* self); +SoundState active_sink_get_state (ActiveSink* self); void active_sink_update_volume (ActiveSink* self, gdouble vol_percent); void active_sink_update_mute (ActiveSink* self, gboolean muted); diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index 5089e23..28340b7 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -62,7 +62,7 @@ static void pm_update_active_sink (pa_context *c, void *userdata); -static void populate_active_sink (const pa_sink_info *info, ActiveSink* sink); +static void pm_populate_active_sink (const pa_sink_info *info, ActiveSink* sink); static gboolean reconnect_to_pulse (gpointer user_data); static pa_cvolume construct_mono_volume(const pa_cvolume* vol); @@ -143,10 +143,8 @@ reconnect_to_pulse (gpointer user_data) } static void -populate_active_sink (const pa_sink_info *info, ActiveSink* sink) +pm_populate_active_sink (const pa_sink_info *info, ActiveSink* sink) { - sink_details *details; - details = g_new0 (sink_details, 1); details->index = info->index; details->name = g_strdup (info->name); details->mute = !!info->mute; @@ -351,7 +349,7 @@ pm_default_sink_info_callback (pa_context *c, } g_debug ("server has handed us a default sink"); - populate_active_sink (info, ACTIVE_SINK (userdata)); + pm_populate_active_sink (info, ACTIVE_SINK (userdata)); } } diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 637bee4..9009869 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -32,10 +32,6 @@ #include "gen-sound-service.xml.h" #include "dbus-shared-names.h" -#include "pulse-manager.h" -#include "slider-menu-item.h" -#include "mute-menu-item.h" -#include "pulse-manager.h" // DBUS methods static void bus_method_call (GDBusConnection * connection, @@ -57,16 +53,15 @@ static GDBusInterfaceVTable interface_table = { typedef struct _SoundServiceDbusPrivate SoundServiceDbusPrivate; struct _SoundServiceDbusPrivate { - GDBusConnection* connection; - DbusmenuMenuitem* root_menuitem; - SliderMenuItem* volume_slider_menuitem; - MuteMenuItem* mute_menuitem; - SoundState current_sound_state; + GDBusConnection* connection; + DbusmenuMenuitem* root_menuitem; + ActiveSink* active_sink; }; static GDBusNodeInfo * node_info = NULL; static GDBusInterfaceInfo * interface_info = NULL; static gboolean b_startup = TRUE; + #define SOUND_SERVICE_DBUS_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUND_SERVICE_DBUS_TYPE, SoundServiceDbusPrivate)) static void sound_service_dbus_class_init (SoundServiceDbusClass *klass); @@ -133,8 +128,6 @@ sound_service_dbus_init (SoundServiceDbus *self) priv->connection = NULL; - priv->current_sound_state = UNAVAILABLE; - /* Fetch the session bus */ priv->connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error); @@ -167,32 +160,26 @@ sound_service_dbus_create_root_item (SoundServiceDbus* self) DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_MENU_DBUS_OBJECT_PATH); dbusmenu_server_set_root (server, priv->root_menuitem); g_object_unref (priv->root_menuitem); - establish_pulse_activities (self); + priv->active_sink = active_sink_new (self); + //establish_pulse_activities (self); return priv->root_menuitem; } -static void +void sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, - gboolean mute_update, - gboolean availability, - gdouble volume ) + DbusmenuMenuitem* mute_item, + DbusmenuMenuitem* slider_item) { SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); // Mute button - priv->mute_menuitem = mute_menu_item_new ( mute_update, availability); - dbusmenu_menuitem_child_append (priv->root_menuitem, - mute_menu_item_get_button (priv->mute_menuitem)); - - // Slider - priv->volume_slider_menuitem = slider_menu_item_new ( availability, volume ); - dbusmenu_menuitem_child_append (priv->root_menuitem, DBUSMENU_MENUITEM ( priv->volume_slider_menuitem )); + dbusmenu_menuitem_child_append (priv->root_menuitem, mute_item)); + dbusmenu_menuitem_child_append (priv->root_menuitem, slider_item )); // Separator - DbusmenuMenuitem* separator = dbusmenu_menuitem_new(); - dbusmenu_menuitem_property_set( separator, + dbusmenu_menuitem_property_set (separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR); dbusmenu_menuitem_child_append(priv->root_menuitem, separator); @@ -207,9 +194,7 @@ sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, dbusmenu_menuitem_child_append(priv->root_menuitem, settings_mi); g_object_unref (settings_mi); g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, - G_CALLBACK(show_sound_settings_dialog), NULL); - - sound_service_dbus_determine_state (self, availability, mute_update, volume); + G_CALLBACK(show_sound_settings_dialog), NULL); } /** @@ -229,41 +214,11 @@ show_sound_settings_dialog (DbusmenuMenuitem *mi, } } -void -sound_service_dbus_update_pa_state ( SoundServiceDbus* self, - gboolean availability, - gboolean mute_update, - gdouble volume ) -{ - g_debug("update pa state with availability of %i, mute value of %i and a volume percent is %f", availability, mute_update, volume); - SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); - - if (b_startup == TRUE) { - sound_service_dbus_build_sound_menu ( self, - mute_update, - availability, - volume ); - b_startup = FALSE; - return; - } - - mute_menu_item_update ( priv->mute_menuitem, - mute_update ); - slider_menu_item_update ( priv->volume_slider_menuitem, - volume ); - - mute_menu_item_enable ( priv->mute_menuitem, availability); - slider_menu_item_enable ( priv->volume_slider_menuitem, - availability ); - sound_service_dbus_determine_state (self, availability, mute_update, volume); - -} - - static void sound_service_dbus_dispose (GObject *object) { G_OBJECT_CLASS (sound_service_dbus_parent_class)->dispose (object); + //TODO dispose of the active sink instance ! return; } @@ -274,76 +229,6 @@ sound_service_dbus_finalize (GObject *object) return; } -// UNTIL PA-MANAGER IS REFACTORED AND THE ACTIVESINK CLASS IS CREATED LEAVE -// THE UI ELEMENTS SEPARATELY HANDLED LIKE THIS. -void -sound_service_dbus_update_volume (SoundServiceDbus* self, - gdouble volume) -{ - SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); - slider_menu_item_update (priv->volume_slider_menuitem, volume); - sound_service_dbus_update_sound_state (self, - sound_service_dbus_get_state_from_volume (self)); -} - -void -sound_service_dbus_update_sink_mute (SoundServiceDbus* self, - gboolean mute_update) -{ - SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); - mute_menu_item_update (priv->mute_menuitem, mute_update); - SoundState state = sound_service_dbus_get_state_from_volume (self); - if (mute_update == TRUE){ - state = MUTED; - } - sound_service_dbus_update_sound_state (self, state); -} - -/*------- State calculators ------------------*/ -static SoundState -sound_service_dbus_get_state_from_volume (SoundServiceDbus* self) -{ - SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (self); - GVariant* v = dbusmenu_menuitem_property_get_variant (DBUSMENU_MENUITEM(priv->volume_slider_menuitem), - DBUSMENU_VOLUME_MENUITEM_LEVEL); - gdouble volume_percent = g_variant_get_double (v); - - SoundState state = LOW_LEVEL; - - if (volume_percent < 30.0 && volume_percent > 0) { - state = LOW_LEVEL; - } - else if (volume_percent < 70.0 && volume_percent >= 30.0) { - state = MEDIUM_LEVEL; - } - else if (volume_percent >= 70.0) { - state = HIGH_LEVEL; - } - else if (volume_percent == 0.0) { - state = ZERO_LEVEL; - } - return state; -} - -static void -sound_service_dbus_determine_state (SoundServiceDbus* self, - gboolean availability, - gboolean mute, - gdouble volume) -{ - SoundState update; - if (availability == FALSE) { - update = UNAVAILABLE; - } - else if (mute == TRUE) { - update = MUTED; - } - else{ - update = sound_service_dbus_get_state_from_volume (self); - } - sound_service_dbus_update_sound_state (self, update); -} - // EMIT STATE SIGNAL @@ -401,8 +286,8 @@ bus_method_call (GDBusConnection * connection, SoundServiceDbusPrivate *priv = SOUND_SERVICE_DBUS_GET_PRIVATE (service); if (g_strcmp0(method, "GetSoundState") == 0) { - g_debug("Get state - %i", priv->current_sound_state ); - retval = g_variant_new ( "(i)", priv->current_sound_state); + g_debug("Get state - %i", active_sink_get_state (priv->active_sink); + retval = g_variant_new ( "(i)", active_sink_get_state (priv->active_sink)); } else if (g_strcmp0(method, "BlacklistMediaPlayer") == 0) { gboolean blacklist; @@ -422,6 +307,9 @@ bus_method_call (GDBusConnection * connection, g_dbus_method_invocation_return_value (invocation, retval); } +/** + TODO - Works nicely but refactor into at least two different methods +**/ static gboolean sound_service_dbus_blacklist_player (SoundServiceDbus* self, gchar* player_name, gboolean blacklist) -- cgit v1.2.3