2
This service primarily controls PulseAudio and is driven by the sound indicator menu on the panel.
3
Copyright 2010 Canonical Ltd.
6
Conor Curran <conor.curran@canonical.com>
8
This program is free software: you can redistribute it and/or modify it
9
under the terms of the GNU General Public License version 3, as published
10
by the Free Software Foundation.
12
This program is distributed in the hope that it will be useful, but
13
WITHOUT ANY WARRANTY; without even the implied warranties of
14
MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR
15
PURPOSE. See the GNU General Public License for more details.
17
You should have received a copy of the GNU General Public License along
18
with this program. If not, see <http://www.gnu.org/licenses/>.
21
#include <dbus/dbus-glib.h>
22
#include <dbus/dbus-glib-bindings.h>
24
#include <libdbusmenu-glib/server.h>
25
#include <libdbusmenu-glib/menuitem.h>
26
#include <libdbusmenu-glib/client.h>
28
#include "dbus-menu-manager.h"
29
#include "sound-service-dbus.h"
30
#include "pulse-manager.h"
31
#include "slider-menu-item.h"
33
#include "dbus-shared-names.h"
36
static DbusmenuMenuitem *root_menuitem = NULL;
37
static DbusmenuMenuitem *mute_all_menuitem = NULL;
38
static SliderMenuItem *volume_slider_menuitem = NULL;
39
static SoundServiceDbus *dbus_interface = NULL;
42
static gboolean b_sink_available = FALSE;
43
static gboolean b_all_muted = FALSE;
44
static gboolean b_pulse_ready = FALSE;
45
static gboolean b_startup = TRUE;
46
static gdouble volume_percent = 0.0;
48
static void set_global_mute_from_ui();
49
static gboolean idle_routine (gpointer data);
50
static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service);
51
static void refresh_menu();
53
/*-------------------------------------------------------------------------*/
55
/*-------------------------------------------------------------------------*/
60
void dbus_menu_manager_setup()
62
root_menuitem = dbusmenu_menuitem_new();
63
g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem));
65
g_idle_add(idle_routine, root_menuitem);
67
dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL);
69
DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT);
70
dbusmenu_server_set_root(server, root_menuitem);
71
establish_pulse_activities(dbus_interface);
77
void dbus_menu_manager_teardown()
79
//TODO tidy up dbus_interface and items!
85
void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble percent)
87
b_sink_available = sink_available;
88
b_all_muted = sink_muted;
89
b_pulse_ready = pa_state;
90
volume_percent = percent;
91
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);
92
// Only rebuild the menu on start up...
93
if(b_startup == TRUE){
94
rebuild_sound_menu(root_menuitem, dbus_interface);
100
// Emit the signals after the menus are setup/torn down
101
sound_service_dbus_update_sink_volume(dbus_interface, percent);
102
sound_service_dbus_update_sink_mute(dbus_interface, sink_muted);
103
dbus_menu_manager_update_mute_ui(b_all_muted);
108
'public' method allowing the pa manager to update the mute menu item.
110
void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value)
112
b_all_muted = incoming_mute_value;
113
dbusmenu_menuitem_property_set(mute_all_menuitem,
114
DBUSMENU_MENUITEM_PROP_LABEL,
115
(b_all_muted == FALSE ? "Mute All" : "Unmute"));
119
/*-------------------------------------------------------------------------*/
121
/*-------------------------------------------------------------------------*/
123
static void refresh_menu()
125
g_debug("in the refresh menu method");
126
if(b_sink_available == FALSE || b_pulse_ready == FALSE)
129
dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
130
DBUSMENU_MENUITEM_PROP_ENABLED,
132
dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
133
DBUSMENU_MENUITEM_PROP_VISIBLE,
135
dbusmenu_menuitem_property_set_bool(mute_all_menuitem,
136
DBUSMENU_MENUITEM_PROP_ENABLED,
140
else if(b_sink_available == TRUE && b_pulse_ready == TRUE){
142
dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
143
DBUSMENU_MENUITEM_PROP_ENABLED,
145
dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
146
DBUSMENU_MENUITEM_PROP_VISIBLE,
148
dbusmenu_menuitem_property_set_bool(mute_all_menuitem,
149
DBUSMENU_MENUITEM_PROP_ENABLED,
159
static gboolean idle_routine (gpointer data)
167
show_sound_settings_dialog:
168
Bring up the gnome volume preferences dialog
170
static void show_sound_settings_dialog (DbusmenuMenuitem *mi, gpointer user_data)
172
GError * error = NULL;
173
if (!g_spawn_command_line_async("gnome-volume-control", &error))
175
g_warning("Unable to show dialog: %s", error->message);
182
Build the DBus menu items, mute/unmute, slider, separator and sound preferences 'link'
184
static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service)
187
mute_all_menuitem = dbusmenu_menuitem_new();
188
dbusmenu_menuitem_property_set(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_LABEL, (b_all_muted == FALSE ? "Mute All" : "Unmute"));
189
g_signal_connect(G_OBJECT(mute_all_menuitem), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED, G_CALLBACK(set_global_mute_from_ui), NULL);
190
dbusmenu_menuitem_property_set_bool(mute_all_menuitem, DBUSMENU_MENUITEM_PROP_ENABLED, b_sink_available);
193
volume_slider_menuitem = slider_menu_item_new(b_sink_available, volume_percent);
194
dbusmenu_menuitem_child_append(root, mute_all_menuitem);
195
dbusmenu_menuitem_child_append(root, DBUSMENU_MENUITEM(volume_slider_menuitem));
196
dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
197
DBUSMENU_MENUITEM_PROP_ENABLED,
199
dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
200
DBUSMENU_MENUITEM_PROP_VISIBLE,
203
DbusmenuMenuitem *separator = dbusmenu_menuitem_new();
204
dbusmenu_menuitem_property_set(separator, DBUSMENU_MENUITEM_PROP_TYPE, DBUSMENU_CLIENT_TYPES_SEPARATOR);
205
dbusmenu_menuitem_child_append(root, separator);
207
// Sound preferences dialog
208
DbusmenuMenuitem *settings_mi = dbusmenu_menuitem_new();
209
dbusmenu_menuitem_property_set(settings_mi, DBUSMENU_MENUITEM_PROP_LABEL,
210
("Sound Preferences..."));
211
dbusmenu_menuitem_child_append(root, settings_mi);
212
g_signal_connect(G_OBJECT(settings_mi), DBUSMENU_MENUITEM_SIGNAL_ITEM_ACTIVATED,
213
G_CALLBACK(show_sound_settings_dialog), NULL);
217
set_global_mute_from_ui:
218
Callback for the dbusmenuitem button
220
static void set_global_mute_from_ui()
222
b_all_muted = !b_all_muted;
223
toggle_global_mute(b_all_muted);
224
dbusmenu_menuitem_property_set(mute_all_menuitem,
225
DBUSMENU_MENUITEM_PROP_LABEL,
226
(b_all_muted == FALSE ? "Mute All" : "Unmute"));