diff options
author | Conor Curran <conor.curran@canonical.com> | 2011-03-15 09:35:59 +0000 |
---|---|---|
committer | Conor Curran <conor.curran@canonical.com> | 2011-03-15 09:35:59 +0000 |
commit | 661b34c4f8175efbd51a4471c01e96a370806228 (patch) | |
tree | f141fb88b4e85f1d78f2767c1e6bc976b7606521 | |
parent | 014ef9d63fdf4d7213f1a9481d0566a63daa7543 (diff) | |
parent | baddd57857b450ec4f80312811d5f50b78c46781 (diff) | |
download | ayatana-indicator-sound-661b34c4f8175efbd51a4471c01e96a370806228.tar.gz ayatana-indicator-sound-661b34c4f8175efbd51a4471c01e96a370806228.tar.bz2 ayatana-indicator-sound-661b34c4f8175efbd51a4471c01e96a370806228.zip |
step one in sorting the volume slider mute behaviour
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/active-sink.c | 349 | ||||
-rw-r--r-- | src/active-sink.h | 85 | ||||
-rw-r--r-- | src/device.c | 290 | ||||
-rw-r--r-- | src/device.h | 84 | ||||
-rw-r--r-- | src/pulseaudio-mgr.c | 86 | ||||
-rw-r--r-- | src/pulseaudio-mgr.h | 4 | ||||
-rw-r--r-- | src/slider-menu-item.c | 119 | ||||
-rw-r--r-- | src/slider-menu-item.h | 12 | ||||
-rw-r--r-- | src/sound-service-dbus.c | 10 | ||||
-rw-r--r-- | src/voip-input-menu-item.c | 6 | ||||
-rw-r--r-- | src/voip-input-menu-item.h | 4 |
12 files changed, 543 insertions, 510 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 7525d71..f7dc2ef 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -92,8 +92,8 @@ indicator_sound_service_SOURCES = \ sound-service.c \ pulseaudio-mgr.h \ pulseaudio-mgr.c \ - active-sink.c \ - active-sink.h \ + device.c \ + device.h \ sound-service-dbus.h \ sound-service-dbus.c \ slider-menu-item.h \ diff --git a/src/active-sink.c b/src/active-sink.c deleted file mode 100644 index a78d33e..0000000 --- a/src/active-sink.c +++ /dev/null @@ -1,349 +0,0 @@ -/* -Copyright 2011 Canonical Ltd. - -Authors: - Conor Curran <conor.curran@canonical.com> - -This program is free software: you can redistribute it and/or modify it -under the terms of the GNU General Public License version 3, as published -by the Free Software Foundation. - -This program is distributed in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranties of -MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR -PURPOSE. See the GNU General Public License for more details. - -You should have received a copy of the GNU General Public License along -with this program. If not, see <http://www.gnu.org/licenses/>. -*/ -#include <libdbusmenu-glib/menuitem.h> - -#include "active-sink.h" -#include "slider-menu-item.h" -#include "mute-menu-item.h" -#include "voip-input-menu-item.h" -#include "pulseaudio-mgr.h" - -typedef struct _ActiveSinkPrivate ActiveSinkPrivate; - -struct _ActiveSinkPrivate -{ - SliderMenuItem* volume_slider_menuitem; - MuteMenuItem* mute_menuitem; - VoipInputMenuItem* voip_input_menu_item; - SoundState current_sound_state; - SoundServiceDbus* service; - gint index; - gchar* name; - pa_cvolume volume; - pa_channel_map channel_map; - pa_volume_t base_volume; -}; - -#define ACTIVE_SINK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ACTIVE_SINK_TYPE, ActiveSinkPrivate)) - -/* Prototypes */ -static void active_sink_class_init (ActiveSinkClass *klass); -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); -static pa_cvolume active_sink_construct_mono_volume (const pa_cvolume* vol); -static void active_sink_volume_update (ActiveSink* self, gdouble percent); -static void active_sink_mute_update (ActiveSink* self, gboolean muted); - -G_DEFINE_TYPE (ActiveSink, active_sink, G_TYPE_OBJECT); - -static void -active_sink_class_init (ActiveSinkClass *klass) -{ - GObjectClass *gobject_class = G_OBJECT_CLASS (klass); - - g_type_class_add_private (klass, sizeof (ActiveSinkPrivate)); - - gobject_class->dispose = active_sink_dispose; - gobject_class->finalize = active_sink_finalize; -} - -static void -active_sink_init (ActiveSink *self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - priv->mute_menuitem = NULL; - priv->volume_slider_menuitem = NULL; - priv->voip_input_menu_item = NULL; - priv->current_sound_state = UNAVAILABLE; - priv->index = -1; - priv->name = NULL; - priv->service = NULL; - - // Init our menu items. - priv->mute_menuitem = g_object_new (MUTE_MENU_ITEM_TYPE, NULL); - priv->voip_input_menu_item = g_object_new (VOIP_INPUT_MENU_ITEM_TYPE, NULL);; - priv->volume_slider_menuitem = slider_menu_item_new (self); - mute_menu_item_enable (priv->mute_menuitem, FALSE); - slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); -} - -static void -active_sink_dispose (GObject *object) -{ - G_OBJECT_CLASS (active_sink_parent_class)->dispose (object); -} - -static void -active_sink_finalize (GObject *object) -{ - G_OBJECT_CLASS (active_sink_parent_class)->finalize (object); -} - -void -active_sink_populate (ActiveSink* sink, - const pa_sink_info* update) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE(sink); - - priv->name = g_strdup (update->name); - priv->index = update->index; - active_sink_mute_update (sink, update->mute); - priv->volume = active_sink_construct_mono_volume (&update->volume); - priv->base_volume = update->base_volume; - priv->channel_map = update->channel_map; - - pa_volume_t vol = pa_cvolume_max (&update->volume); - gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; - - active_sink_volume_update (sink, volume_percent); - active_sink_mute_update (sink, update->mute); - mute_menu_item_enable (priv->mute_menuitem, TRUE); - slider_menu_item_enable (priv->volume_slider_menuitem, TRUE); - - g_debug ("Active sink has been populated - volume %f", volume_percent); -} - -void -active_sink_activate_voip_item (ActiveSink* self, gint sink_input_index, gint client_index) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - if (voip_input_menu_item_is_interested (priv->voip_input_menu_item, - sink_input_index, - client_index)){ - voip_input_menu_item_enable (priv->voip_input_menu_item, TRUE); - } -} - -void -active_sink_deactivate_voip_source (ActiveSink* self, gboolean visible) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - visible &= voip_input_menu_item_is_active (priv->voip_input_menu_item); - voip_input_menu_item_deactivate_source (priv->voip_input_menu_item, visible); -} - -void -active_sink_deactivate_voip_client (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - voip_input_menu_item_deactivate_voip_client (priv->voip_input_menu_item); -} - -void -active_sink_update (ActiveSink* sink, - const pa_sink_info* update) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (sink); - active_sink_mute_update (sink, update->mute); - priv->volume = active_sink_construct_mono_volume (&update->volume); - priv->base_volume = update->base_volume; - priv->channel_map = update->channel_map; - - pa_volume_t vol = pa_cvolume_max (&update->volume); - gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; - - active_sink_volume_update (sink, volume_percent); - active_sink_mute_update (sink, update->mute); -} - -// To the UI -static void -active_sink_volume_update (ActiveSink* self, gdouble percent) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - slider_menu_item_update (priv->volume_slider_menuitem, percent); - SoundState state = active_sink_get_state_from_volume (self); - if (priv->current_sound_state != state){ - priv->current_sound_state = state; - sound_service_dbus_update_sound_state (priv->service, - priv->current_sound_state); - } -} - -// From the UI -void -active_sink_update_volume (ActiveSink* self, gdouble percent) -{ - pa_cvolume new_volume; - pa_cvolume_init(&new_volume); - new_volume.channels = 1; - pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100); - pa_cvolume_set(&new_volume, 1, new_volume_value); - - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - - pa_cvolume_set(&priv->volume, priv->channel_map.channels, new_volume_value); - pm_update_volume (priv->index, new_volume); -} - - -gint -active_sink_get_current_sink_input_index (ActiveSink* sink) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (sink); - return voip_input_menu_item_get_sink_input_index (priv->voip_input_menu_item); -} - -static void -active_sink_mute_update (ActiveSink* self, gboolean muted) -{ - 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; - } - if (priv->current_sound_state != state){ - priv->current_sound_state = state; - sound_service_dbus_update_sound_state (priv->service, state); - } -} - -void -active_sink_ensure_sink_is_unmuted (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - if (mute_menu_item_is_muted (priv->mute_menuitem)){ - pm_update_mute (FALSE); - } -} - - -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; -} - -pa_cvolume -active_sink_construct_mono_volume (const pa_cvolume* vol) -{ - pa_cvolume new_volume; - pa_cvolume_init(&new_volume); - new_volume.channels = 1; - pa_volume_t max_vol = pa_cvolume_max(vol); - pa_cvolume_set(&new_volume, 1, max_vol); - return new_volume; -} - -void -active_sink_determine_blocking_state (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - if (mute_menu_item_is_muted (priv->mute_menuitem)){ - /** - We don't want to set the current state to blocking - as this is a fire and forget event. - */ - sound_service_dbus_update_sound_state (priv->service, - BLOCKED); - } -} - -gint -active_sink_get_index (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - return priv->index; -} - -gboolean -active_sink_is_populated (ActiveSink* sink) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (sink); - return (priv->index != -1); -} - -void -active_sink_deactivate (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - priv->current_sound_state = UNAVAILABLE; - sound_service_dbus_update_sound_state (priv->service, - priv->current_sound_state); - mute_menu_item_enable (priv->mute_menuitem, FALSE); - slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); - priv->index = -1; - g_free(priv->name); - priv->name = NULL; -} - -SoundState -active_sink_get_state (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - return priv->current_sound_state; -} - -void -active_sink_update_voip_input_source (ActiveSink* self, const pa_source_info* update) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - voip_input_menu_item_update (priv->voip_input_menu_item, update); -} - -gboolean -active_sink_is_voip_source_populated (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - return voip_input_menu_item_is_populated (priv->voip_input_menu_item); -} - -gint active_sink_get_source_index (ActiveSink* self) -{ - ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); - return voip_input_menu_item_get_index (priv->voip_input_menu_item); -} - -ActiveSink* -active_sink_new (SoundServiceDbus* service) -{ - 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, - mute_menu_item_get_button (priv->mute_menuitem), - DBUSMENU_MENUITEM (priv->volume_slider_menuitem), - DBUSMENU_MENUITEM (priv->voip_input_menu_item)); - pm_establish_pulse_connection (sink); - return sink; -} diff --git a/src/active-sink.h b/src/active-sink.h deleted file mode 100644 index 57b3079..0000000 --- a/src/active-sink.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2010 Canonical Ltd. - * - * Authors: - * Conor Curran <conor.curran@canonical.com> - * - * This program is free software: you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 3, as published - * by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranties of - * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR - * PURPOSE. See the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see <http://www.gnu.org/licenses/>. - */ - -#ifndef __ACTIVE_SINK_H__ -#define __ACTIVE_SINK_H__ - -#include <glib.h> -#include <glib-object.h> - -#include "common-defs.h" -#include "sound-service-dbus.h" - -#include <pulse/pulseaudio.h> - -G_BEGIN_DECLS - -#define ACTIVE_SINK_TYPE (active_sink_get_type ()) -#define ACTIVE_SINK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), ACTIVE_SINK_TYPE, ActiveSink)) -#define ACTIVE_SINK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), ACTIVE_SINK_TYPE, ActiveSinkClass)) -#define IS_ACTIVE_SINK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), ACTIVE_SINK_TYPE)) -#define IS_ACTIVE_SINK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), ACTIVE_SINK_TYPE)) -#define ACTIVE_SINK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), ACTIVE_SINK_TYPE, ActiveSinkClass)) - -typedef struct _ActiveSink ActiveSink; -typedef struct _ActiveSinkClass ActiveSinkClass; - -struct _ActiveSink { - GObject parent; -}; - -struct _ActiveSinkClass { - GObjectClass parent_class; -}; - -GType active_sink_get_type (void) G_GNUC_CONST; - -/** - * TODO - * Refactor this to become a device manager obj basically acting as wrapper for - * the communication between pulseaudio-mgr and the individual items. - * First steps collapse slider/volume related stuff into slider-menu-item. - */ - -// Sink related -void active_sink_populate (ActiveSink* sink, const pa_sink_info* update); -void active_sink_update (ActiveSink* sink, const pa_sink_info* update); -gboolean active_sink_is_populated (ActiveSink* sink); -gint active_sink_get_index (ActiveSink* self); -void active_sink_deactivate (ActiveSink* self); -void active_sink_update_mute (ActiveSink* self, gboolean mute_update); -void active_sink_update_volume (ActiveSink* self, gdouble percent); -void active_sink_ensure_sink_is_unmuted (ActiveSink* self); - -// source and sinkinput/client related for VOIP functionality -void active_sink_update_voip_input_source (ActiveSink* sink, const pa_source_info* update); -void active_sink_activate_voip_item (ActiveSink* sink, gint sink_input_index, gint client_index); -gint active_sink_get_current_sink_input_index (ActiveSink* sink); -gboolean active_sink_is_voip_source_populated (ActiveSink* sink); -gint active_sink_get_source_index (ActiveSink* self); -void active_sink_determine_blocking_state (ActiveSink* self); -void active_sink_deactivate_voip_source (ActiveSink* self, gboolean visible); -void active_sink_deactivate_voip_client (ActiveSink* self); -SoundState active_sink_get_state (ActiveSink* self); - -ActiveSink* active_sink_new (SoundServiceDbus* service); - -G_END_DECLS - -#endif diff --git a/src/device.c b/src/device.c new file mode 100644 index 0000000..2f38beb --- /dev/null +++ b/src/device.c @@ -0,0 +1,290 @@ +/* +Copyright 2011 Canonical Ltd. + +Authors: + Conor Curran <conor.curran@canonical.com> + +This program is free software: you can redistribute it and/or modify it +under the terms of the GNU General Public License version 3, as published +by the Free Software Foundation. + +This program is distributed in the hope that it will be useful, but +WITHOUT ANY WARRANTY; without even the implied warranties of +MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR +PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along +with this program. If not, see <http://www.gnu.org/licenses/>. +*/ +#include <libdbusmenu-glib/menuitem.h> + +#include "device.h" +#include "slider-menu-item.h" +#include "mute-menu-item.h" +#include "voip-input-menu-item.h" +#include "pulseaudio-mgr.h" + +typedef struct _DevicePrivate DevicePrivate; + +struct _DevicePrivate +{ + SliderMenuItem* volume_slider_menuitem; + MuteMenuItem* mute_menuitem; + VoipInputMenuItem* voip_input_menu_item; + SoundState current_sound_state; + SoundServiceDbus* service; +}; + +#define DEVICE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), DEVICE_TYPE, DevicePrivate)) + +/* Prototypes */ +static void device_class_init (DeviceClass *klass); +static void device_init (Device *self); +static void device_dispose (GObject *object); +static void device_finalize (GObject *object); + +static SoundState device_get_state_from_volume (Device* self); +static void device_mute_update (Device* self, gboolean muted); + +G_DEFINE_TYPE (Device, device, G_TYPE_OBJECT); + +static void +device_class_init (DeviceClass *klass) +{ + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + g_type_class_add_private (klass, sizeof (DevicePrivate)); + + gobject_class->dispose = device_dispose; + gobject_class->finalize = device_finalize; +} + +static void +device_init (Device *self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + priv->mute_menuitem = NULL; + priv->volume_slider_menuitem = NULL; + priv->voip_input_menu_item = NULL; + priv->current_sound_state = UNAVAILABLE; + priv->service = NULL; + + // Init our menu items. + priv->mute_menuitem = g_object_new (MUTE_MENU_ITEM_TYPE, NULL); + priv->voip_input_menu_item = g_object_new (VOIP_INPUT_MENU_ITEM_TYPE, NULL);; + priv->volume_slider_menuitem = slider_menu_item_new (self); + mute_menu_item_enable (priv->mute_menuitem, FALSE); + slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); +} + +static void +device_dispose (GObject *object) +{ + G_OBJECT_CLASS (device_parent_class)->dispose (object); +} + +static void +device_finalize (GObject *object) +{ + G_OBJECT_CLASS (device_parent_class)->finalize (object); +} + +void +device_populate (Device* self, + const pa_sink_info* update) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE(self); + device_mute_update (self, update->mute); + mute_menu_item_enable (priv->mute_menuitem, TRUE); + slider_menu_item_populate (priv->volume_slider_menuitem, update); + SoundState state = device_get_state_from_volume (self); + if (priv->current_sound_state != state){ + priv->current_sound_state = state; + sound_service_dbus_update_sound_state (priv->service, + priv->current_sound_state); + } + +} + +void +device_activate_voip_item (Device* self, gint sink_input_index, gint client_index) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + if (voip_input_menu_item_is_interested (priv->voip_input_menu_item, + sink_input_index, + client_index)){ + voip_input_menu_item_enable (priv->voip_input_menu_item, TRUE); + } +} + +void +device_deactivate_voip_source (Device* self, gboolean visible) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + visible &= voip_input_menu_item_is_active (priv->voip_input_menu_item); + voip_input_menu_item_deactivate_source (priv->voip_input_menu_item, visible); +} + +void +device_deactivate_voip_client (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + voip_input_menu_item_deactivate_voip_client (priv->voip_input_menu_item); +} + +void +device_update (Device* self, + const pa_sink_info* update) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + slider_menu_item_update (priv->volume_slider_menuitem, update); + + SoundState state = device_get_state_from_volume (self); + if (priv->current_sound_state != state){ + priv->current_sound_state = state; + sound_service_dbus_update_sound_state (priv->service, + priv->current_sound_state); + } + + device_mute_update (self, update->mute); +} + +gint +device_get_current_sink_input_index (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + return voip_input_menu_item_get_sink_input_index (priv->voip_input_menu_item); +} + +static void +device_mute_update (Device* self, gboolean muted) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + mute_menu_item_update (priv->mute_menuitem, muted); + SoundState state = device_get_state_from_volume (self); + + if (muted == TRUE){ + state = MUTED; + } + // Only send signals if something has changed + if (priv->current_sound_state != state){ + priv->current_sound_state = state; + sound_service_dbus_update_sound_state (priv->service, state); + } +} + +void +device_ensure_sink_is_unmuted (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + if (mute_menu_item_is_muted (priv->mute_menuitem)){ + pm_update_mute (FALSE); + } +} + + +static SoundState +device_get_state_from_volume (Device* self) +{ + DevicePrivate* priv = DEVICE_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; +} + +void +device_determine_blocking_state (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + if (mute_menu_item_is_muted (priv->mute_menuitem)){ + /** + We don't want to set the current state to blocking + as this is a fire and forget event. + */ + sound_service_dbus_update_sound_state (priv->service, + BLOCKED); + } +} + +gint +device_get_index (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + return slider_menu_item_get_sink_index (priv->volume_slider_menuitem); +} + +gboolean +device_is_populated (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + return dbusmenu_menuitem_property_get_bool (DBUSMENU_MENUITEM (priv->volume_slider_menuitem), + DBUSMENU_MENUITEM_PROP_ENABLED); +} + +void +device_deactivate (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + priv->current_sound_state = UNAVAILABLE; + sound_service_dbus_update_sound_state (priv->service, + priv->current_sound_state); + mute_menu_item_enable (priv->mute_menuitem, FALSE); + slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); +} + +SoundState +device_get_state (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + return priv->current_sound_state; +} + +void +device_update_voip_input_source (Device* self, const pa_source_info* update) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + voip_input_menu_item_update (priv->voip_input_menu_item, update); +} + +gboolean +device_is_voip_source_populated (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + return voip_input_menu_item_is_populated (priv->voip_input_menu_item); +} + +gint device_get_source_index (Device* self) +{ + DevicePrivate* priv = DEVICE_GET_PRIVATE (self); + return voip_input_menu_item_get_index (priv->voip_input_menu_item); +} + +Device* +device_new (SoundServiceDbus* service) +{ + Device* sink = g_object_new (DEVICE_TYPE, NULL); + DevicePrivate* priv = DEVICE_GET_PRIVATE (sink); + priv->service = service; + sound_service_dbus_build_sound_menu (service, + mute_menu_item_get_button (priv->mute_menuitem), + DBUSMENU_MENUITEM (priv->volume_slider_menuitem), + DBUSMENU_MENUITEM (priv->voip_input_menu_item)); + pm_establish_pulse_connection (sink); + return sink; +} diff --git a/src/device.h b/src/device.h new file mode 100644 index 0000000..42d8189 --- /dev/null +++ b/src/device.h @@ -0,0 +1,84 @@ +/* + * Copyright 2010 Canonical Ltd. + * + * Authors: + * Conor Curran <conor.curran@canonical.com> + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 3, as published + * by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranties of + * MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR + * PURPOSE. See the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef __DEVICE_H__ +#define __DEVICE_H__ + +#include <glib.h> +#include <glib-object.h> + +#include "common-defs.h" +#include "sound-service-dbus.h" + +#include <pulse/pulseaudio.h> + +G_BEGIN_DECLS + +#define DEVICE_TYPE (device_get_type ()) +#define DEVICE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), DEVICE_TYPE, Device)) +#define DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), DEVICE_TYPE, DeviceClass)) +#define IS_DEVICE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), DEVICE_TYPE)) +#define IS_DEVICE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), DEVICE_TYPE)) +#define DEVICE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), DEVICE_TYPE, DeviceClass)) + +typedef struct _Device Device; +typedef struct _DeviceClass DeviceClass; + +struct _Device { + GObject parent; +}; + +struct _DeviceClass { + GObjectClass parent_class; +}; + +GType device_get_type (void) G_GNUC_CONST; + +/** + * TODO + * Refactor this to become a device manager obj basically acting as wrapper for + * the communication between pulseaudio-mgr and the individual items. + * First steps collapse slider/volume related stuff into slider-menu-item. + */ + +// Sink related +void device_populate (Device* sink, const pa_sink_info* update); +void device_update (Device* sink, const pa_sink_info* update); +gboolean device_is_populated (Device* sink); +gint device_get_index (Device* self); +void device_deactivate (Device* self); +void device_update_mute (Device* self, gboolean mute_update); +void device_ensure_sink_is_unmuted (Device* self); + +// source and sinkinput/client related for VOIP functionality +void device_update_voip_input_source (Device* sink, const pa_source_info* update); +void device_activate_voip_item (Device* sink, gint sink_input_index, gint client_index); +gint device_get_current_sink_input_index (Device* sink); +gboolean device_is_voip_source_populated (Device* sink); +gint device_get_source_index (Device* self); +void device_determine_blocking_state (Device* self); +void device_deactivate_voip_source (Device* self, gboolean visible); +void device_deactivate_voip_client (Device* self); +SoundState device_get_state (Device* self); + +Device* device_new (SoundServiceDbus* service); + +G_END_DECLS + +#endif diff --git a/src/pulseaudio-mgr.c b/src/pulseaudio-mgr.c index 6d11221..036b46b 100644 --- a/src/pulseaudio-mgr.c +++ b/src/pulseaudio-mgr.c @@ -68,7 +68,7 @@ static void pm_sink_input_info_callback (pa_context *c, const pa_sink_input_info *info, int eol, void *userdata); -static void pm_update_active_sink (pa_context *c, +static void pm_update_device (pa_context *c, const pa_sink_info *info, int eol, void *userdata); @@ -89,11 +89,11 @@ static pa_glib_mainloop *pa_main_loop = NULL; Entry Point **/ void -pm_establish_pulse_connection (ActiveSink* active_sink) +pm_establish_pulse_connection (Device* device) { pa_main_loop = pa_glib_mainloop_new (g_main_context_default ()); g_assert (pa_main_loop); - reconnect_to_pulse ((gpointer)active_sink); + reconnect_to_pulse ((gpointer)device); } /** @@ -119,7 +119,7 @@ reconnect_to_pulse (gpointer user_data) { g_debug("Attempt a pulse connection"); // reset - g_return_val_if_fail (IS_ACTIVE_SINK (user_data), FALSE); + g_return_val_if_fail (IS_DEVICE (user_data), FALSE); connection_attempts += 1; if (pulse_context != NULL) { @@ -216,38 +216,38 @@ pm_subscribed_events_callback (pa_context *c, uint32_t index, void* userdata) { - if (IS_ACTIVE_SINK (userdata) == FALSE){ + if (IS_DEVICE (userdata) == FALSE){ g_critical ("subscribed events callback - our userdata is not what we think it should be"); return; } - ActiveSink* sink = ACTIVE_SINK (userdata); + Device* sink = DEVICE (userdata); switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { case PA_SUBSCRIPTION_EVENT_SINK: // We don't care about any other sink other than the active one. - if (index != active_sink_get_index (sink)) + if (index != device_get_index (sink)) return; if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - active_sink_deactivate (sink); + device_deactivate (sink); } else{ pa_operation_unref (pa_context_get_sink_info_by_index (c, index, - pm_update_active_sink, + pm_update_device, userdata) ); } break; case PA_SUBSCRIPTION_EVENT_SOURCE: g_debug ("Looks like source event of some description - index = %i", index); // We don't care about any other sink other than the active one. - if (index != active_sink_get_source_index (sink)) + if (index != device_get_source_index (sink)) return; if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { g_debug ("Source removal event - index = %i", index); - active_sink_deactivate_voip_source (sink, FALSE); + device_deactivate_voip_source (sink, FALSE); } else{ pa_operation_unref (pa_context_get_source_info_by_index (c, @@ -260,12 +260,12 @@ pm_subscribed_events_callback (pa_context *c, // We don't care about sink input removals. g_debug ("sink input event"); if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { - gint cached_index = active_sink_get_current_sink_input_index (sink); + gint cached_index = device_get_current_sink_input_index (sink); g_debug ("Just saw a sink input removal event - index = %i and cached index = %i", index, cached_index); if (index == cached_index){ - active_sink_deactivate_voip_client (sink); + device_deactivate_voip_client (sink); } } else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { @@ -308,7 +308,7 @@ pm_context_state_callback (pa_context *c, void *userdata) break; case PA_CONTEXT_FAILED: g_warning("PA_CONTEXT_FAILED - Is PulseAudio Daemon running ?"); - active_sink_deactivate (ACTIVE_SINK (userdata)); + device_deactivate (DEVICE (userdata)); if (reconnect_idle_id == 0){ reconnect_idle_id = g_timeout_add_seconds (RECONNECT_DELAY, reconnect_to_pulse, @@ -362,7 +362,7 @@ pm_server_info_callback (pa_context *c, if (info == NULL) { g_warning("No PA server - get the hell out of here"); - active_sink_deactivate (ACTIVE_SINK (userdata)); + device_deactivate (DEVICE (userdata)); return; } // Go for the default sink @@ -373,7 +373,7 @@ pm_server_info_callback (pa_context *c, pm_default_sink_info_callback, userdata) )) { g_warning("pa_context_get_sink_info_by_namet() failed"); - active_sink_deactivate (ACTIVE_SINK (userdata)); + device_deactivate (DEVICE (userdata)); pa_operation_unref(operation); return; } @@ -382,7 +382,7 @@ pm_server_info_callback (pa_context *c, pm_sink_info_callback, userdata))) { g_warning("pa_context_get_sink_info_list() failed"); - active_sink_deactivate (ACTIVE_SINK (userdata)); + device_deactivate (DEVICE (userdata)); pa_operation_unref(operation); return; } @@ -421,14 +421,14 @@ pm_sink_info_callback (pa_context *c, return; } else { - if (IS_ACTIVE_SINK (userdata) == FALSE || sink == NULL){ + if (IS_DEVICE (userdata) == FALSE || sink == NULL){ g_warning ("sink info callback - our user data is not what we think it should be or the sink parameter is null"); return; } - ActiveSink* a_sink = ACTIVE_SINK (userdata); - if (active_sink_is_populated (a_sink) == FALSE && + Device* a_sink = DEVICE (userdata); + if (device_is_populated (a_sink) == FALSE && g_ascii_strncasecmp("auto_null", sink->name, 9) != 0){ - active_sink_populate (a_sink, sink); + device_populate (a_sink, sink); } } } @@ -443,16 +443,16 @@ pm_default_sink_info_callback (pa_context *c, return; } else { - if (IS_ACTIVE_SINK (userdata) == FALSE || info == NULL){ + if (IS_DEVICE (userdata) == FALSE || info == NULL){ g_warning ("Default sink info callback - our user data is not what we think it should be or the info parameter is null"); return; } // Only repopulate if there is a change with regards the index - if (active_sink_get_index (ACTIVE_SINK (userdata)) == info->index) + if (device_get_index (DEVICE (userdata)) == info->index) return; g_debug ("Pulse Server has handed us a new default sink"); - active_sink_populate (ACTIVE_SINK (userdata), info); + device_populate (DEVICE (userdata), info); } } @@ -466,18 +466,18 @@ pm_sink_input_info_callback (pa_context *c, return; } else { - if (info == NULL || IS_ACTIVE_SINK (userdata) == FALSE) { + if (info == NULL || IS_DEVICE (userdata) == FALSE) { g_warning("Sink input info callback : SINK INPUT INFO IS NULL or our user_data is not what we think it should be"); return; } - if (IS_ACTIVE_SINK (userdata) == FALSE){ + if (IS_DEVICE (userdata) == FALSE){ g_warning ("sink input info callback - our user data is not what we think it should be"); return; } // Check if this is Voip sink input gint result = pa_proplist_contains (info->proplist, PA_PROP_MEDIA_ROLE); - ActiveSink* a_sink = ACTIVE_SINK (userdata); + Device* a_sink = DEVICE (userdata); if (result == 1){ g_debug ("Sink input info has media role property"); @@ -485,7 +485,7 @@ pm_sink_input_info_callback (pa_context *c, g_debug ("prop role = %s", value); if (g_strcmp0 (value, "phone") == 0) { g_debug ("And yes its a VOIP app ... sink input index = %i", info->index); - active_sink_activate_voip_item (a_sink, (gint)info->index, (gint)info->client); + device_activate_voip_item (a_sink, (gint)info->index, (gint)info->client); // TODO to start with we will assume our source is the same as what this 'client' // is pointing at. This should probably be more intelligent : // query for the list of source output info's and going on the name of the client @@ -494,14 +494,14 @@ pm_sink_input_info_callback (pa_context *c, } // And finally check for the mute blocking state - if (active_sink_get_index (a_sink) == info->sink){ - active_sink_determine_blocking_state (a_sink); + if (device_get_index (a_sink) == info->sink){ + device_determine_blocking_state (a_sink); } } } static void -pm_update_active_sink (pa_context *c, +pm_update_device (pa_context *c, const pa_sink_info *info, int eol, void *userdata) @@ -510,11 +510,11 @@ pm_update_active_sink (pa_context *c, return; } else{ - if (IS_ACTIVE_SINK (userdata) == FALSE || info == NULL){ - g_warning ("update_active_sink - our user data is not what we think it should be or the info parameter is null"); + if (IS_DEVICE (userdata) == FALSE || info == NULL){ + g_warning ("update_device - our user data is not what we think it should be or the info parameter is null"); return; } - active_sink_update (ACTIVE_SINK(userdata), info); + device_update (DEVICE(userdata), info); } } @@ -551,16 +551,16 @@ pm_default_source_info_callback (pa_context *c, return; } else { - if (IS_ACTIVE_SINK (userdata) == FALSE || info == NULL){ + if (IS_DEVICE (userdata) == FALSE || info == NULL){ g_warning ("Default source info callback - our user data is not what we think it should be or the source info parameter is null"); return; } // If there is an index change we need to change our cached source - if (active_sink_get_source_index (ACTIVE_SINK (userdata)) == info->index) + if (device_get_source_index (DEVICE (userdata)) == info->index) return; g_debug ("Pulse Server has handed us a new default source"); - active_sink_deactivate_voip_source (ACTIVE_SINK (userdata), TRUE); - active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info); + device_deactivate_voip_source (DEVICE (userdata), TRUE); + device_update_voip_input_source (DEVICE (userdata), info); } } @@ -574,13 +574,13 @@ pm_source_info_callback (pa_context *c, return; } else { - if (IS_ACTIVE_SINK (userdata) == FALSE || info == NULL){ + if (IS_DEVICE (userdata) == FALSE || info == NULL){ g_warning ("source info callback - our user data is not what we think it should be or the source info parameter is null"); return; } // For now we will take the first available - if (active_sink_is_voip_source_populated (ACTIVE_SINK (userdata)) == FALSE){ - active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info); + if (device_is_voip_source_populated (DEVICE (userdata)) == FALSE){ + device_update_voip_input_source (DEVICE (userdata), info); } } } @@ -595,11 +595,11 @@ pm_update_source_info_callback (pa_context *c, return; } else { - if (IS_ACTIVE_SINK (userdata) == FALSE || info == NULL ){ + if (IS_DEVICE (userdata) == FALSE || info == NULL ){ g_warning ("source info update callback - our user data is not what we think it should be or the source info paramter is null"); return; } g_debug ("Got a source update for %s , index %i", info->name, info->index); - active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info); + device_update_voip_input_source (DEVICE (userdata), info); } } diff --git a/src/pulseaudio-mgr.h b/src/pulseaudio-mgr.h index d61117d..ace47f3 100644 --- a/src/pulseaudio-mgr.h +++ b/src/pulseaudio-mgr.h @@ -17,9 +17,9 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "active-sink.h" +#include "device.h" -void pm_establish_pulse_connection (ActiveSink* active_sink); +void pm_establish_pulse_connection (Device* device); void close_pulse_activites(); void pm_update_volume (gint sink_index, pa_cvolume new_volume); void pm_update_mic_gain (gint source_index, pa_cvolume new_gain); diff --git a/src/slider-menu-item.c b/src/slider-menu-item.c index 1c88f01..fb66563 100644 --- a/src/slider-menu-item.c +++ b/src/slider-menu-item.c @@ -23,11 +23,17 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib/gi18n.h> #include "slider-menu-item.h" #include "common-defs.h" +#include "pulseaudio-mgr.h" typedef struct _SliderMenuItemPrivate SliderMenuItemPrivate; struct _SliderMenuItemPrivate { - ActiveSink* a_sink; + Device* a_sink; + gint index; + gchar* name; + pa_cvolume volume; + pa_channel_map channel_map; + pa_volume_t base_volume; }; #define SLIDER_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SLIDER_MENU_ITEM_TYPE, SliderMenuItemPrivate)) @@ -39,6 +45,8 @@ static void slider_menu_item_dispose (GObject *object); static void slider_menu_item_finalize (GObject *object); static void handle_event (DbusmenuMenuitem * mi, const gchar * name, GVariant * value, guint timestamp); +static pa_cvolume slider_menu_item_construct_mono_volume (const pa_cvolume* vol); +static void slider_menu_item_update_volume (SliderMenuItem* self, gdouble percent); G_DEFINE_TYPE (SliderMenuItem, slider_menu_item, DBUSMENU_TYPE_MENUITEM); @@ -63,7 +71,13 @@ slider_menu_item_init (SliderMenuItem *self) g_debug("Building new Slider Menu Item"); dbusmenu_menuitem_property_set( DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_TYPE, - DBUSMENU_VOLUME_MENUITEM_TYPE ); + DBUSMENU_VOLUME_MENUITEM_TYPE ); + + SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); + + priv->index = -1; + priv->name = NULL; + return; } @@ -97,33 +111,108 @@ handle_event (DbusmenuMenuitem * mi, SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (SLIDER_MENU_ITEM (mi)); gdouble volume_input = g_variant_get_double(input); //g_debug ("slider menu item about to update volume %f", volume_input); - active_sink_update_volume (priv->a_sink, volume_input); - active_sink_ensure_sink_is_unmuted (priv->a_sink); + slider_menu_item_update_volume (SLIDER_MENU_ITEM (mi), volume_input); + device_ensure_sink_is_unmuted (priv->a_sink); } } } + +void +slider_menu_item_populate (SliderMenuItem* self, const pa_sink_info* update) +{ + SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); + priv->name = g_strdup (update->name); + priv->index = update->index; + priv->volume = slider_menu_item_construct_mono_volume (&update->volume); + priv->base_volume = update->base_volume; + priv->channel_map = update->channel_map; + + pa_volume_t vol = pa_cvolume_max (&update->volume); + gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; + GVariant* new_volume = g_variant_new_double (volume_percent); + dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self), + DBUSMENU_VOLUME_MENUITEM_LEVEL, + new_volume); + slider_menu_item_enable (self, TRUE); +} + +// From the UI +static void +slider_menu_item_update_volume (SliderMenuItem* self, gdouble percent) +{ + pa_cvolume new_volume; + pa_cvolume_init(&new_volume); + new_volume.channels = 1; + pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100); + pa_cvolume_set(&new_volume, 1, new_volume_value); + + SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); + + pa_cvolume_set(&priv->volume, priv->channel_map.channels, new_volume_value); + pm_update_volume (priv->index, new_volume); +} + +// To the UI void -slider_menu_item_update (SliderMenuItem* item, - gdouble update) +slider_menu_item_update (SliderMenuItem* self, const pa_sink_info* update) { - GVariant* new_volume = g_variant_new_double(update); - dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(item), - DBUSMENU_VOLUME_MENUITEM_LEVEL, - new_volume); + SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); + + priv->volume = slider_menu_item_construct_mono_volume (&update->volume); + priv->base_volume = update->base_volume; + priv->channel_map = update->channel_map; + + pa_volume_t vol = pa_cvolume_max (&update->volume); + gdouble volume_percent = ((gdouble) vol * 100) / PA_VOLUME_NORM; + + GVariant* new_volume = g_variant_new_double (volume_percent); + dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(self), + DBUSMENU_VOLUME_MENUITEM_LEVEL, + new_volume); } +/* + * Enable/Disabled can be considered the equivalent of whether we have an active + * sink or not, let the widget have inherent state. + */ void -slider_menu_item_enable (SliderMenuItem* item, - gboolean active) +slider_menu_item_enable (SliderMenuItem* self, gboolean active) { - dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item), + SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); + + dbusmenu_menuitem_property_set_bool (DBUSMENU_MENUITEM(self), DBUSMENU_MENUITEM_PROP_ENABLED, - active ); + active); + if(active == FALSE){ + priv->index = -1; + if(priv->name != NULL){ + g_free(priv->name); + priv->name = NULL; + } + } +} + +gint +slider_menu_item_get_sink_index (SliderMenuItem* self) +{ + SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); + return priv->index; +} + +static pa_cvolume +slider_menu_item_construct_mono_volume (const pa_cvolume* vol) +{ + pa_cvolume new_volume; + pa_cvolume_init(&new_volume); + new_volume.channels = 1; + pa_volume_t max_vol = pa_cvolume_max(vol); + pa_cvolume_set(&new_volume, 1, max_vol); + return new_volume; } SliderMenuItem* -slider_menu_item_new (ActiveSink* sink) +slider_menu_item_new (Device* sink) { SliderMenuItem *self = g_object_new(SLIDER_MENU_ITEM_TYPE, NULL); SliderMenuItemPrivate* priv = SLIDER_MENU_ITEM_GET_PRIVATE (self); diff --git a/src/slider-menu-item.h b/src/slider-menu-item.h index f094c71..4375971 100644 --- a/src/slider-menu-item.h +++ b/src/slider-menu-item.h @@ -23,7 +23,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib-object.h> #include <libdbusmenu-glib/menuitem.h> -#include "active-sink.h" +#include "device.h" G_BEGIN_DECLS @@ -47,10 +47,16 @@ struct _SliderMenuItem { GType slider_menu_item_get_type (void); -void slider_menu_item_update(SliderMenuItem* item, gdouble update); +void slider_menu_item_update(SliderMenuItem* item, const pa_sink_info* update); void slider_menu_item_enable(SliderMenuItem* item, gboolean active); +void slider_menu_item_populate (SliderMenuItem* self, const pa_sink_info* update); +//void +//active_sink_update (ActiveSink* sink, +// const pa_sink_info* update) -SliderMenuItem* slider_menu_item_new (ActiveSink* sink); +gint slider_menu_item_get_sink_index (SliderMenuItem* self); + +SliderMenuItem* slider_menu_item_new (Device* sink); G_END_DECLS diff --git a/src/sound-service-dbus.c b/src/sound-service-dbus.c index 8d0cc0b..7c817af 100644 --- a/src/sound-service-dbus.c +++ b/src/sound-service-dbus.c @@ -29,7 +29,7 @@ #include <libdbusmenu-glib/client.h> #include "sound-service-dbus.h" -#include "active-sink.h" +#include "device.h" #include "gen-sound-service.xml.h" #include "dbus-shared-names.h" @@ -55,7 +55,7 @@ typedef struct _SoundServiceDbusPrivate SoundServiceDbusPrivate; struct _SoundServiceDbusPrivate { GDBusConnection* connection; DbusmenuMenuitem* root_menuitem; - ActiveSink* active_sink; + Device* device; }; static GDBusNodeInfo * node_info = NULL; @@ -155,7 +155,7 @@ sound_service_dbus_create_root_item (SoundServiceDbus* self) paths); dbusmenu_server_set_root (server, priv->root_menuitem); g_object_unref (priv->root_menuitem); - priv->active_sink = active_sink_new (self); + priv->device = device_new (self); return priv->root_menuitem; } @@ -272,8 +272,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", active_sink_get_state (priv->active_sink)); - retval = g_variant_new ( "(i)", active_sink_get_state (priv->active_sink)); + g_debug("Get state - %i", device_get_state (priv->device)); + retval = g_variant_new ( "(i)", device_get_state (priv->device)); } else if (g_strcmp0(method, "BlacklistMediaPlayer") == 0) { gboolean blacklist; diff --git a/src/voip-input-menu-item.c b/src/voip-input-menu-item.c index a742654..a92f91c 100644 --- a/src/voip-input-menu-item.c +++ b/src/voip-input-menu-item.c @@ -28,7 +28,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. typedef struct _VoipInputMenuItemPrivate VoipInputMenuItemPrivate; struct _VoipInputMenuItemPrivate { - ActiveSink* a_sink; + Device* a_sink; pa_cvolume volume; gint mute; guint32 volume_steps; @@ -129,8 +129,6 @@ handle_event (DbusmenuMenuitem * mi, if (priv->mute == 1) { pm_update_mic_mute (priv->source_index, 0); } - //active_sink_update_volume (priv->a_sink, volume_input); - //active_sink_ensure_sink_is_unmuted (priv->a_sink); } } } @@ -268,7 +266,7 @@ voip_input_menu_item_enable (VoipInputMenuItem* item, } VoipInputMenuItem* -voip_input_menu_item_new (ActiveSink* sink) +voip_input_menu_item_new (Device* sink) { VoipInputMenuItem *self = g_object_new(VOIP_INPUT_MENU_ITEM_TYPE, NULL); VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (self); diff --git a/src/voip-input-menu-item.h b/src/voip-input-menu-item.h index 6f4ed85..30ada5a 100644 --- a/src/voip-input-menu-item.h +++ b/src/voip-input-menu-item.h @@ -22,7 +22,7 @@ with this program. If not, see <http://www.gnu.org/licenses/>. #include <glib.h> #include <pulse/pulseaudio.h> #include <libdbusmenu-glib/menuitem.h> -#include "active-sink.h" +#include "device.h" G_BEGIN_DECLS @@ -62,7 +62,7 @@ gint voip_input_menu_item_get_sink_input_index (VoipInputMenuItem* item); void voip_input_menu_item_deactivate_source (VoipInputMenuItem* item, gboolean visible); void voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item); -VoipInputMenuItem* voip_input_menu_item_new (ActiveSink* sink); +VoipInputMenuItem* voip_input_menu_item_new (Device* sink); G_END_DECLS |