1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * based on indicator-messages.c written by :
6 * Ted Gould <ted@canonical.com>
7 * Cody Russell <cody.russell@canonical.com>
8 * E-mail : see the 'copyright' file.
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 3
13 * of the License, or (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23 #include <stdlib.h>
24
25 #if (SOUND_SERVICE_VERSION < 1)
26 #include "dbus-shared-names-old.h"
27 #else
28 #include "dbus-shared-names.h"
29 #endif
30
31 #include "applet-struct.h"
32 #include "common-defs.h"
33 #include "volume-widget.h"
34 #include "mute-widget.h"
35 #include "applet-menu.h"
36 #include "applet-backend-alsamixer.h" // cd_mixer_init_alsa (fallback alsa backend)
37 #include "applet-generic.h"
38 #include "applet-draw.h"
39 #include "applet-backend-sound-menu-old.h"
40
41 /*
42 // we can use icons designed for Unity, or more common icons that we are likely to find in icons themes.
43 static const gchar *_get_icon_from_state_unity (gint iState)
44 {
45 switch (iState)
46 {
47 case MUTED: return "audio-volume-muted-panel";
48 case ZERO_LEVEL: return "audio-volume-low-zero-panel";
49 case LOW_LEVEL: return "audio-volume-low-panel";
50 case MEDIUM_LEVEL: return "audio-volume-medium-panel";
51 case HIGH_LEVEL: return "audio-volume-high-panel";
52 case BLOCKED: return "audio-volume-muted-blocking-panel";
53 default: return "audio-output-none-panel";
54 }
55 }
56 static const gchar *_get_icon_from_state (gint iState)
57 {
58 switch (iState)
59 {
60 case ZERO_LEVEL: return "audio-volume-off";
61 case LOW_LEVEL: return "audio-volume-low";
62 case MEDIUM_LEVEL: return "audio-volume-medium";
63 case HIGH_LEVEL: return "audio-volume-high";
64 default: return "audio-volume-muted";
65 }
66 }*/
67
68 ///////////
69 // PROXY //
70 ///////////
71
72 static void
on_sound_state_updated(DBusGProxy * proxy,gint iNewState,GldiModuleInstance * myApplet)73 on_sound_state_updated (DBusGProxy * proxy, gint iNewState, GldiModuleInstance *myApplet)
74 {
75 cd_debug ("%s (iNewState : %d)", __func__, iNewState);
76 CD_APPLET_ENTER;
77 if (iNewState != myData.iCurrentState)
78 {
79 myData.iCurrentState = iNewState;
80 gboolean bIsMute = (iNewState == MUTED
81 || iNewState == UNAVAILABLE
82 || iNewState == BLOCKED);
83 if (myData.bIsMute != bIsMute)
84 {
85 myData.bIsMute = bIsMute;
86 cd_update_icon ();
87 }
88 }
89 CD_APPLET_LEAVE();
90 }
91
_get_volume(void)92 static int _get_volume (void)
93 {
94 if (myData.volume_widget)
95 return (int)volume_widget_get_current_volume (myData.volume_widget);
96 else
97 return 0;
98 }
99
_set_volume(int iVolume)100 static void _set_volume (int iVolume)
101 {
102 if (myData.volume_widget)
103 volume_widget_update (VOLUME_WIDGET(myData.volume_widget), (gdouble)iVolume, "scroll updates");
104 }
105
_toggle_mute(void)106 static void _toggle_mute (void)
107 {
108 if (myData.mute_widget)
109 mute_widget_toggle (MUTE_WIDGET (myData.mute_widget));
110 }
111
_show_menu(void)112 static void _show_menu (void)
113 {
114 cd_indicator_show_menu (myData.pIndicator);
115 }
116
_stop(void)117 static void _stop (void)
118 {
119 cd_indicator_destroy (myData.pIndicator);
120
121 g_list_free (myData.transport_widgets_list);
122 }
123
cd_sound_on_connect(GldiModuleInstance * myApplet)124 static void cd_sound_on_connect (GldiModuleInstance *myApplet)
125 {
126 cd_debug ("%s ()", __func__);
127 // the sound service is up and running, stop the alsa mixer if ever we initialized it before.
128 cd_stop ();
129
130 // and set the interface
131 myData.ctl.get_volume = _get_volume;
132 myData.ctl.set_volume = _set_volume;
133 myData.ctl.toggle_mute = _toggle_mute;
134 myData.ctl.show_hide = _show_menu;
135 myData.ctl.stop = _stop;
136 myData.ctl.reload = cd_update_icon;
137
138 // connect to the service signals.
139 dbus_g_proxy_add_signal(myData.pIndicator->pServiceProxy, INDICATOR_SOUND_SIGNAL_STATE_UPDATE, G_TYPE_INT, G_TYPE_INVALID);
140 dbus_g_proxy_connect_signal(myData.pIndicator->pServiceProxy,
141 INDICATOR_SOUND_SIGNAL_STATE_UPDATE,
142 G_CALLBACK(on_sound_state_updated),
143 myApplet,
144 NULL);
145 }
146
cd_sound_on_disconnect(GldiModuleInstance * myApplet)147 static void cd_sound_on_disconnect (GldiModuleInstance *myApplet)
148 {
149 CD_APPLET_ENTER;
150 cd_debug ("%s", __func__);
151
152 if (myData.ctl.get_volume == _get_volume) // the backend was set, unset it
153 {
154 memset (&myData.ctl, 0, sizeof (CDSoundCtl));
155
156 cd_debug ("clean");
157 myData.volume_widget = NULL;
158 myData.transport_widgets_list = NULL;
159 myData.voip_widget = NULL;
160 myData.mute_widget = NULL;
161 }
162
163 // no (more) sound service, now rely on alsa.
164 cd_mixer_init_alsa ();
165
166 CD_APPLET_LEAVE();
167 }
168
_on_got_sound_state(DBusGProxy * proxy,DBusGProxyCall * call_id,GldiModuleInstance * myApplet)169 static void _on_got_sound_state (DBusGProxy *proxy, DBusGProxyCall *call_id, GldiModuleInstance *myApplet)
170 {
171 CD_APPLET_ENTER;
172 int iCurrentState = 0;
173 gboolean bSuccess = dbus_g_proxy_end_call (proxy,
174 call_id,
175 NULL,
176 G_TYPE_INT,
177 &iCurrentState,
178 G_TYPE_INVALID);
179 cd_debug ("got sound state: %d", iCurrentState);
180
181 // update the icon.
182 if (bSuccess)
183 {
184 myData.iCurrentState = iCurrentState;
185 myData.bIsMute = (iCurrentState == MUTED
186 || iCurrentState == UNAVAILABLE
187 || iCurrentState == BLOCKED);
188 myData.iCurrentVolume = _get_volume ();
189
190 cd_update_icon ();
191 }
192 CD_APPLET_LEAVE();
193 }
cd_sound_get_initial_values(GldiModuleInstance * myApplet)194 static void cd_sound_get_initial_values (GldiModuleInstance *myApplet)
195 {
196 // query the service to display initial values.
197 dbus_g_proxy_begin_call (myData.pIndicator->pServiceProxy, "GetSoundState",
198 (DBusGProxyCallNotify)_on_got_sound_state,
199 myApplet,
200 (GDestroyNotify) NULL,
201 G_TYPE_INVALID);
202 }
203
204
205
update_accessible_desc(double new_value)206 void update_accessible_desc (double new_value)
207 {
208 cd_debug ("%s (%p)", __func__, myData.volume_widget);
209 if (!myData.volume_widget)
210 return;
211
212 myData.iCurrentVolume = (new_value < 0 ? _get_volume() : new_value);
213 cd_update_icon ();
214 }
215
cd_mixer_connect_to_sound_service(void)216 void cd_mixer_connect_to_sound_service (void)
217 {
218 myData.pIndicator = cd_indicator_new (myApplet,
219 INDICATOR_SOUND_DBUS_NAME,
220 INDICATOR_SOUND_SERVICE_DBUS_OBJECT_PATH,
221 INDICATOR_SOUND_DBUS_INTERFACE,
222 INDICATOR_SOUND_MENU_DBUS_OBJECT_PATH,
223 0);
224 myData.pIndicator->on_connect = cd_sound_on_connect;
225 myData.pIndicator->on_disconnect = cd_sound_on_disconnect;
226 myData.pIndicator->get_initial_values = cd_sound_get_initial_values;
227 myData.pIndicator->add_menu_handler = cd_sound_add_menu_handler;
228 }
229