~ted/indicator-sound/revert-notifications

« back to all changes in this revision

Viewing changes to src/dbus-menu-manager.c

  • Committer: Conor Curran
  • Date: 2010-03-04 15:52:59 UTC
  • mfrom: (36.2.9 indicator-sound)
  • Revision ID: conor.curran@canonical.com-20100304155259-mozczr2wfohxrn7p
merge with the test branch - service side refactored and tests introduced

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
This service primarily controls PulseAudio and is driven by the sound indicator menu on the panel.
 
3
Copyright 2010 Canonical Ltd.
 
4
 
 
5
Authors:
 
6
    Conor Curran <conor.curran@canonical.com>
 
7
 
 
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.
 
11
 
 
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.
 
16
 
 
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/>.
 
19
*/
 
20
 
 
21
#include <dbus/dbus-glib.h>
 
22
#include <dbus/dbus-glib-bindings.h>
 
23
 
 
24
#include <libdbusmenu-glib/server.h>
 
25
#include <libdbusmenu-glib/menuitem.h>
 
26
#include <libdbusmenu-glib/client.h>
 
27
 
 
28
#include "dbus-menu-manager.h" 
 
29
#include "sound-service-dbus.h" 
 
30
#include "pulse-manager.h"
 
31
#include "slider-menu-item.h"
 
32
 
 
33
#include "dbus-shared-names.h"
 
34
 
 
35
// DBUS items
 
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;
 
40
 
 
41
// PULSEAUDIO
 
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;
 
47
 
 
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();
 
52
 
 
53
/*-------------------------------------------------------------------------*/
 
54
//                          Public Methods 
 
55
/*-------------------------------------------------------------------------*/
 
56
 
 
57
/**
 
58
setup:
 
59
**/
 
60
void dbus_menu_manager_setup()
 
61
{
 
62
    root_menuitem = dbusmenu_menuitem_new();
 
63
    g_debug("Root ID: %d", dbusmenu_menuitem_get_id(root_menuitem));
 
64
        
 
65
    g_idle_add(idle_routine, root_menuitem);
 
66
 
 
67
    dbus_interface = g_object_new(SOUND_SERVICE_DBUS_TYPE, NULL);
 
68
 
 
69
    DbusmenuServer *server = dbusmenu_server_new(INDICATOR_SOUND_DBUS_OBJECT);
 
70
    dbusmenu_server_set_root(server, root_menuitem);
 
71
    establish_pulse_activities(dbus_interface);
 
72
}
 
73
 
 
74
/**
 
75
teardown:
 
76
**/
 
77
void dbus_menu_manager_teardown()
 
78
{
 
79
    //TODO tidy up dbus_interface and items!
 
80
}
 
81
 
 
82
/**
 
83
update_pa_state:
 
84
**/
 
85
void dbus_menu_manager_update_pa_state(gboolean pa_state, gboolean sink_available, gboolean sink_muted, gdouble percent)
 
86
{
 
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);
 
95
        b_startup = FALSE;
 
96
    }
 
97
    else{
 
98
        refresh_menu();
 
99
    }
 
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);
 
104
}
 
105
 
 
106
/**
 
107
update_mute_ui:
 
108
'public' method allowing the pa manager to update the mute menu item.
 
109
**/
 
110
void dbus_menu_manager_update_mute_ui(gboolean incoming_mute_value)
 
111
{
 
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"));
 
116
}
 
117
 
 
118
 
 
119
/*-------------------------------------------------------------------------*/
 
120
//                          Private Methods 
 
121
/*-------------------------------------------------------------------------*/
 
122
 
 
123
static void refresh_menu()
 
124
{
 
125
    g_debug("in the refresh menu method");
 
126
    if(b_sink_available == FALSE || b_pulse_ready == FALSE)
 
127
    {
 
128
 
 
129
        dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), 
 
130
                                            DBUSMENU_MENUITEM_PROP_ENABLED,
 
131
                                            FALSE);   
 
132
        dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), 
 
133
                                            DBUSMENU_MENUITEM_PROP_VISIBLE,
 
134
                                            FALSE);   
 
135
        dbusmenu_menuitem_property_set_bool(mute_all_menuitem, 
 
136
                                            DBUSMENU_MENUITEM_PROP_ENABLED,
 
137
                                            FALSE);
 
138
 
 
139
    }
 
140
    else if(b_sink_available == TRUE  && b_pulse_ready == TRUE){
 
141
 
 
142
        dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), 
 
143
                                            DBUSMENU_MENUITEM_PROP_ENABLED,
 
144
                                            TRUE);   
 
145
        dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem), 
 
146
                                            DBUSMENU_MENUITEM_PROP_VISIBLE,
 
147
                                            TRUE);   
 
148
        dbusmenu_menuitem_property_set_bool(mute_all_menuitem, 
 
149
                                            DBUSMENU_MENUITEM_PROP_ENABLED,
 
150
                                            TRUE);        
 
151
    }
 
152
}
 
153
 
 
154
 
 
155
 
 
156
/**
 
157
 
 
158
**/
 
159
static gboolean idle_routine (gpointer data)
 
160
{
 
161
    return FALSE;
 
162
}
 
163
 
 
164
 
 
165
 
 
166
/**
 
167
show_sound_settings_dialog:
 
168
Bring up the gnome volume preferences dialog
 
169
**/
 
170
static void show_sound_settings_dialog (DbusmenuMenuitem *mi, gpointer user_data) 
 
171
{
 
172
    GError * error = NULL;
 
173
    if (!g_spawn_command_line_async("gnome-volume-control", &error)) 
 
174
    {
 
175
        g_warning("Unable to show dialog: %s", error->message);
 
176
        g_error_free(error);
 
177
    }
 
178
}
 
179
 
 
180
/**
 
181
rebuild_sound_menu:
 
182
Build the DBus menu items, mute/unmute, slider, separator and sound preferences 'link'
 
183
**/
 
184
static void rebuild_sound_menu(DbusmenuMenuitem *root, SoundServiceDbus *service)
 
185
{
 
186
    // Mute button
 
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);
 
191
 
 
192
    // Slider
 
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,
 
198
                                        b_sink_available);       
 
199
    dbusmenu_menuitem_property_set_bool(DBUSMENU_MENUITEM(volume_slider_menuitem),
 
200
                                        DBUSMENU_MENUITEM_PROP_VISIBLE,
 
201
                                        b_sink_available);   
 
202
    // Separator
 
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);
 
206
 
 
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);
 
214
}
 
215
 
 
216
/**
 
217
set_global_mute_from_ui:
 
218
Callback for the dbusmenuitem button
 
219
**/
 
220
static void set_global_mute_from_ui()
 
221
{
 
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"));
 
227
}
 
228
 
 
229