Merge lp:~cjcurran/indicator-sound/voip-input-item into lp:~indicator-applet-developers/indicator-sound/trunk_3
- voip-input-item
- Merge into trunk_3
Proposed by
Conor Curran
Status: | Merged | ||||||||
---|---|---|---|---|---|---|---|---|---|
Merged at revision: | 202 | ||||||||
Proposed branch: | lp:~cjcurran/indicator-sound/voip-input-item | ||||||||
Merge into: | lp:~indicator-applet-developers/indicator-sound/trunk_3 | ||||||||
Diff against target: |
1537 lines (+1044/-44) 18 files modified
src/Makefile.am (+5/-1) src/active-sink.c (+61/-5) src/active-sink.h (+19/-6) src/common-defs.h (+5/-1) src/indicator-sound.c (+62/-4) src/music-player-bridge.vala (+5/-3) src/mute-menu-item.c (+1/-0) src/player-item.vala (+1/-2) src/pulseaudio-mgr.c (+190/-19) src/pulseaudio-mgr.h (+2/-0) src/settings-manager.vala (+2/-0) src/sound-service-dbus.c (+6/-2) src/sound-service-dbus.h (+2/-1) src/sound-service.c (+2/-0) src/voip-input-menu-item.c (+277/-0) src/voip-input-menu-item.h (+70/-0) src/voip-input-widget.c (+279/-0) src/voip-input-widget.h (+55/-0) |
||||||||
To merge this branch: | bzr merge lp:~cjcurran/indicator-sound/voip-input-item | ||||||||
Related bugs: |
|
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ted Gould (community) | Approve | ||
Review via email: mp+50364@code.launchpad.net |
Commit message
Description of the change
- big Voip input menu item feature added
- little keyboard shortcut feature removal
To post a comment you must log in.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'src/Makefile.am' | |||
2 | --- src/Makefile.am 2011-02-11 15:22:10 +0000 | |||
3 | +++ src/Makefile.am 2011-02-18 17:27:12 +0000 | |||
4 | @@ -20,6 +20,8 @@ | |||
5 | 20 | title-widget.h \ | 20 | title-widget.h \ |
6 | 21 | volume-widget.c \ | 21 | volume-widget.c \ |
7 | 22 | volume-widget.h \ | 22 | volume-widget.h \ |
8 | 23 | voip-input-widget.c \ | ||
9 | 24 | voip-input-widget.h \ | ||
10 | 23 | gen-sound-service.xml.h \ | 25 | gen-sound-service.xml.h \ |
11 | 24 | gen-sound-service.xml.c \ | 26 | gen-sound-service.xml.c \ |
12 | 25 | dbus-shared-names.h | 27 | dbus-shared-names.h |
13 | @@ -85,7 +87,7 @@ | |||
14 | 85 | # Sound Service C | 87 | # Sound Service C |
15 | 86 | ############################### | 88 | ############################### |
16 | 87 | indicator_sound_service_SOURCES = \ | 89 | indicator_sound_service_SOURCES = \ |
18 | 88 | common-defs.h \ | 90 | common-defs.h \ |
19 | 89 | sound-service.h \ | 91 | sound-service.h \ |
20 | 90 | sound-service.c \ | 92 | sound-service.c \ |
21 | 91 | pulseaudio-mgr.h \ | 93 | pulseaudio-mgr.h \ |
22 | @@ -96,6 +98,8 @@ | |||
23 | 96 | sound-service-dbus.c \ | 98 | sound-service-dbus.c \ |
24 | 97 | slider-menu-item.h \ | 99 | slider-menu-item.h \ |
25 | 98 | slider-menu-item.c \ | 100 | slider-menu-item.c \ |
26 | 101 | voip-input-menu-item.h \ | ||
27 | 102 | voip-input-menu-item.c \ | ||
28 | 99 | mute-menu-item.h \ | 103 | mute-menu-item.h \ |
29 | 100 | mute-menu-item.c \ | 104 | mute-menu-item.c \ |
30 | 101 | gen-sound-service.xml.h \ | 105 | gen-sound-service.xml.h \ |
31 | 102 | 106 | ||
32 | === modified file 'src/active-sink.c' | |||
33 | --- src/active-sink.c 2011-02-07 12:53:45 +0000 | |||
34 | +++ src/active-sink.c 2011-02-18 17:27:12 +0000 | |||
35 | @@ -21,7 +21,7 @@ | |||
36 | 21 | #include "active-sink.h" | 21 | #include "active-sink.h" |
37 | 22 | #include "slider-menu-item.h" | 22 | #include "slider-menu-item.h" |
38 | 23 | #include "mute-menu-item.h" | 23 | #include "mute-menu-item.h" |
40 | 24 | 24 | #include "voip-input-menu-item.h" | |
41 | 25 | #include "pulseaudio-mgr.h" | 25 | #include "pulseaudio-mgr.h" |
42 | 26 | 26 | ||
43 | 27 | typedef struct _ActiveSinkPrivate ActiveSinkPrivate; | 27 | typedef struct _ActiveSinkPrivate ActiveSinkPrivate; |
44 | @@ -30,7 +30,8 @@ | |||
45 | 30 | { | 30 | { |
46 | 31 | SliderMenuItem* volume_slider_menuitem; | 31 | SliderMenuItem* volume_slider_menuitem; |
47 | 32 | MuteMenuItem* mute_menuitem; | 32 | MuteMenuItem* mute_menuitem; |
49 | 33 | SoundState current_sound_state; | 33 | VoipInputMenuItem* voip_input_menu_item; |
50 | 34 | SoundState current_sound_state; | ||
51 | 34 | SoundServiceDbus* service; | 35 | SoundServiceDbus* service; |
52 | 35 | gint index; | 36 | gint index; |
53 | 36 | gchar* name; | 37 | gchar* name; |
54 | @@ -52,7 +53,6 @@ | |||
55 | 52 | static void active_sink_volume_update (ActiveSink* self, gdouble percent); | 53 | static void active_sink_volume_update (ActiveSink* self, gdouble percent); |
56 | 53 | static void active_sink_mute_update (ActiveSink* self, gboolean muted); | 54 | static void active_sink_mute_update (ActiveSink* self, gboolean muted); |
57 | 54 | 55 | ||
58 | 55 | |||
59 | 56 | G_DEFINE_TYPE (ActiveSink, active_sink, G_TYPE_OBJECT); | 56 | G_DEFINE_TYPE (ActiveSink, active_sink, G_TYPE_OBJECT); |
60 | 57 | 57 | ||
61 | 58 | static void | 58 | static void |
62 | @@ -72,6 +72,7 @@ | |||
63 | 72 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); | 72 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); |
64 | 73 | priv->mute_menuitem = NULL; | 73 | priv->mute_menuitem = NULL; |
65 | 74 | priv->volume_slider_menuitem = NULL; | 74 | priv->volume_slider_menuitem = NULL; |
66 | 75 | priv->voip_input_menu_item = NULL; | ||
67 | 75 | priv->current_sound_state = UNAVAILABLE; | 76 | priv->current_sound_state = UNAVAILABLE; |
68 | 76 | priv->index = -1; | 77 | priv->index = -1; |
69 | 77 | priv->name = NULL; | 78 | priv->name = NULL; |
70 | @@ -79,6 +80,7 @@ | |||
71 | 79 | 80 | ||
72 | 80 | // Init our menu items. | 81 | // Init our menu items. |
73 | 81 | priv->mute_menuitem = g_object_new (MUTE_MENU_ITEM_TYPE, NULL); | 82 | priv->mute_menuitem = g_object_new (MUTE_MENU_ITEM_TYPE, NULL); |
74 | 83 | priv->voip_input_menu_item = g_object_new (VOIP_INPUT_MENU_ITEM_TYPE, NULL);; | ||
75 | 82 | priv->volume_slider_menuitem = slider_menu_item_new (self); | 84 | priv->volume_slider_menuitem = slider_menu_item_new (self); |
76 | 83 | mute_menu_item_enable (priv->mute_menuitem, FALSE); | 85 | mute_menu_item_enable (priv->mute_menuitem, FALSE); |
77 | 84 | slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); | 86 | slider_menu_item_enable (priv->volume_slider_menuitem, FALSE); |
78 | @@ -121,6 +123,32 @@ | |||
79 | 121 | } | 123 | } |
80 | 122 | 124 | ||
81 | 123 | void | 125 | void |
82 | 126 | active_sink_activate_voip_item (ActiveSink* self, gint sink_input_index, gint client_index) | ||
83 | 127 | { | ||
84 | 128 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); | ||
85 | 129 | if (voip_input_menu_item_is_interested (priv->voip_input_menu_item, | ||
86 | 130 | sink_input_index, | ||
87 | 131 | client_index)){ | ||
88 | 132 | voip_input_menu_item_enable (priv->voip_input_menu_item, TRUE); | ||
89 | 133 | } | ||
90 | 134 | } | ||
91 | 135 | |||
92 | 136 | void | ||
93 | 137 | active_sink_deactivate_voip_source (ActiveSink* self, gboolean visible) | ||
94 | 138 | { | ||
95 | 139 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); | ||
96 | 140 | visible &= voip_input_menu_item_is_active (priv->voip_input_menu_item); | ||
97 | 141 | voip_input_menu_item_deactivate_source (priv->voip_input_menu_item, visible); | ||
98 | 142 | } | ||
99 | 143 | |||
100 | 144 | void | ||
101 | 145 | active_sink_deactivate_voip_client (ActiveSink* self) | ||
102 | 146 | { | ||
103 | 147 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); | ||
104 | 148 | voip_input_menu_item_deactivate_voip_client (priv->voip_input_menu_item); | ||
105 | 149 | } | ||
106 | 150 | |||
107 | 151 | void | ||
108 | 124 | active_sink_update (ActiveSink* sink, | 152 | active_sink_update (ActiveSink* sink, |
109 | 125 | const pa_sink_info* update) | 153 | const pa_sink_info* update) |
110 | 126 | { | 154 | { |
111 | @@ -168,6 +196,13 @@ | |||
112 | 168 | } | 196 | } |
113 | 169 | 197 | ||
114 | 170 | 198 | ||
115 | 199 | gint | ||
116 | 200 | active_sink_get_current_sink_input_index (ActiveSink* sink) | ||
117 | 201 | { | ||
118 | 202 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (sink); | ||
119 | 203 | return voip_input_menu_item_get_sink_input_index (priv->voip_input_menu_item); | ||
120 | 204 | } | ||
121 | 205 | |||
122 | 171 | static void | 206 | static void |
123 | 172 | active_sink_mute_update (ActiveSink* self, gboolean muted) | 207 | active_sink_mute_update (ActiveSink* self, gboolean muted) |
124 | 173 | { | 208 | { |
125 | @@ -219,7 +254,7 @@ | |||
126 | 219 | return state; | 254 | return state; |
127 | 220 | } | 255 | } |
128 | 221 | 256 | ||
130 | 222 | static pa_cvolume | 257 | pa_cvolume |
131 | 223 | active_sink_construct_mono_volume (const pa_cvolume* vol) | 258 | active_sink_construct_mono_volume (const pa_cvolume* vol) |
132 | 224 | { | 259 | { |
133 | 225 | pa_cvolume new_volume; | 260 | pa_cvolume new_volume; |
134 | @@ -279,6 +314,26 @@ | |||
135 | 279 | return priv->current_sound_state; | 314 | return priv->current_sound_state; |
136 | 280 | } | 315 | } |
137 | 281 | 316 | ||
138 | 317 | void | ||
139 | 318 | active_sink_update_voip_input_source (ActiveSink* self, const pa_source_info* update) | ||
140 | 319 | { | ||
141 | 320 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); | ||
142 | 321 | voip_input_menu_item_update (priv->voip_input_menu_item, update); | ||
143 | 322 | } | ||
144 | 323 | |||
145 | 324 | gboolean | ||
146 | 325 | active_sink_is_voip_source_populated (ActiveSink* self) | ||
147 | 326 | { | ||
148 | 327 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); | ||
149 | 328 | return voip_input_menu_item_is_populated (priv->voip_input_menu_item); | ||
150 | 329 | } | ||
151 | 330 | |||
152 | 331 | gint active_sink_get_source_index (ActiveSink* self) | ||
153 | 332 | { | ||
154 | 333 | ActiveSinkPrivate* priv = ACTIVE_SINK_GET_PRIVATE (self); | ||
155 | 334 | return voip_input_menu_item_get_index (priv->voip_input_menu_item); | ||
156 | 335 | } | ||
157 | 336 | |||
158 | 282 | ActiveSink* | 337 | ActiveSink* |
159 | 283 | active_sink_new (SoundServiceDbus* service) | 338 | active_sink_new (SoundServiceDbus* service) |
160 | 284 | { | 339 | { |
161 | @@ -287,7 +342,8 @@ | |||
162 | 287 | priv->service = service; | 342 | priv->service = service; |
163 | 288 | sound_service_dbus_build_sound_menu (service, | 343 | sound_service_dbus_build_sound_menu (service, |
164 | 289 | mute_menu_item_get_button (priv->mute_menuitem), | 344 | mute_menu_item_get_button (priv->mute_menuitem), |
166 | 290 | DBUSMENU_MENUITEM (priv->volume_slider_menuitem)); | 345 | DBUSMENU_MENUITEM (priv->volume_slider_menuitem), |
167 | 346 | DBUSMENU_MENUITEM (priv->voip_input_menu_item)); | ||
168 | 291 | pm_establish_pulse_connection (sink); | 347 | pm_establish_pulse_connection (sink); |
169 | 292 | return sink; | 348 | return sink; |
170 | 293 | } | 349 | } |
171 | 294 | 350 | ||
172 | === modified file 'src/active-sink.h' | |||
173 | --- src/active-sink.h 2011-02-07 11:45:06 +0000 | |||
174 | +++ src/active-sink.h 2011-02-18 17:27:12 +0000 | |||
175 | @@ -50,21 +50,34 @@ | |||
176 | 50 | 50 | ||
177 | 51 | GType active_sink_get_type (void) G_GNUC_CONST; | 51 | GType active_sink_get_type (void) G_GNUC_CONST; |
178 | 52 | 52 | ||
179 | 53 | /** | ||
180 | 54 | * TODO | ||
181 | 55 | * Refactor this to become a device manager obj basically acting as wrapper for | ||
182 | 56 | * the communication between pulseaudio-mgr and the individual items. | ||
183 | 57 | * First steps collapse slider/volume related stuff into slider-menu-item. | ||
184 | 58 | */ | ||
185 | 59 | |||
186 | 60 | // Sink related | ||
187 | 53 | void active_sink_populate (ActiveSink* sink, const pa_sink_info* update); | 61 | void active_sink_populate (ActiveSink* sink, const pa_sink_info* update); |
188 | 54 | void active_sink_update (ActiveSink* sink, const pa_sink_info* update); | 62 | void active_sink_update (ActiveSink* sink, const pa_sink_info* update); |
189 | 55 | |||
190 | 56 | gboolean active_sink_is_populated (ActiveSink* sink); | 63 | gboolean active_sink_is_populated (ActiveSink* sink); |
191 | 57 | void active_sink_determine_blocking_state (ActiveSink* self); | ||
192 | 58 | |||
193 | 59 | gint active_sink_get_index (ActiveSink* self); | 64 | gint active_sink_get_index (ActiveSink* self); |
194 | 60 | SoundState active_sink_get_state (ActiveSink* self); | ||
195 | 61 | |||
196 | 62 | void active_sink_deactivate (ActiveSink* self); | 65 | void active_sink_deactivate (ActiveSink* self); |
197 | 63 | |||
198 | 64 | void active_sink_update_mute (ActiveSink* self, gboolean mute_update); | 66 | void active_sink_update_mute (ActiveSink* self, gboolean mute_update); |
199 | 65 | void active_sink_update_volume (ActiveSink* self, gdouble percent); | 67 | void active_sink_update_volume (ActiveSink* self, gdouble percent); |
200 | 66 | void active_sink_ensure_sink_is_unmuted (ActiveSink* self); | 68 | void active_sink_ensure_sink_is_unmuted (ActiveSink* self); |
201 | 67 | 69 | ||
202 | 70 | // source and sinkinput/client related for VOIP functionality | ||
203 | 71 | void active_sink_update_voip_input_source (ActiveSink* sink, const pa_source_info* update); | ||
204 | 72 | void active_sink_activate_voip_item (ActiveSink* sink, gint sink_input_index, gint client_index); | ||
205 | 73 | gint active_sink_get_current_sink_input_index (ActiveSink* sink); | ||
206 | 74 | gboolean active_sink_is_voip_source_populated (ActiveSink* sink); | ||
207 | 75 | gint active_sink_get_source_index (ActiveSink* self); | ||
208 | 76 | void active_sink_determine_blocking_state (ActiveSink* self); | ||
209 | 77 | void active_sink_deactivate_voip_source (ActiveSink* self, gboolean visible); | ||
210 | 78 | void active_sink_deactivate_voip_client (ActiveSink* self); | ||
211 | 79 | SoundState active_sink_get_state (ActiveSink* self); | ||
212 | 80 | |||
213 | 68 | ActiveSink* active_sink_new (SoundServiceDbus* service); | 81 | ActiveSink* active_sink_new (SoundServiceDbus* service); |
214 | 69 | 82 | ||
215 | 70 | G_END_DECLS | 83 | G_END_DECLS |
216 | 71 | 84 | ||
217 | === modified file 'src/common-defs.h' | |||
218 | --- src/common-defs.h 2011-02-08 18:58:10 +0000 | |||
219 | +++ src/common-defs.h 2011-02-18 17:27:12 +0000 | |||
220 | @@ -31,13 +31,17 @@ | |||
221 | 31 | AVAILABLE | 31 | AVAILABLE |
222 | 32 | }SoundState; | 32 | }SoundState; |
223 | 33 | 33 | ||
225 | 34 | 34 | #define NOT_ACTIVE -1 | |
226 | 35 | #define DBUSMENU_PROPERTY_EMPTY -1 | 35 | #define DBUSMENU_PROPERTY_EMPTY -1 |
227 | 36 | 36 | ||
228 | 37 | /* DBUS Custom Items */ | 37 | /* DBUS Custom Items */ |
229 | 38 | #define DBUSMENU_VOLUME_MENUITEM_TYPE "x-canonical-ido-volume-type" | 38 | #define DBUSMENU_VOLUME_MENUITEM_TYPE "x-canonical-ido-volume-type" |
230 | 39 | #define DBUSMENU_VOLUME_MENUITEM_LEVEL "x-canonical-ido-volume-level" | 39 | #define DBUSMENU_VOLUME_MENUITEM_LEVEL "x-canonical-ido-volume-level" |
231 | 40 | 40 | ||
232 | 41 | #define DBUSMENU_VOIP_INPUT_MENUITEM_TYPE "x-canonical-ido-voip-input-type" | ||
233 | 42 | #define DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL "x-canonical-ido-voip-input-level" | ||
234 | 43 | #define DBUSMENU_VOIP_INPUT_MENUITEM_MUTE "x-canonical-ido-voip-input-mute" | ||
235 | 44 | |||
236 | 41 | #define DBUSMENU_MUTE_MENUITEM_TYPE "x-canonical-sound-menu-mute-type" | 45 | #define DBUSMENU_MUTE_MENUITEM_TYPE "x-canonical-sound-menu-mute-type" |
237 | 42 | #define DBUSMENU_MUTE_MENUITEM_VALUE "x-canonical-sound-menu-mute-value" | 46 | #define DBUSMENU_MUTE_MENUITEM_VALUE "x-canonical-sound-menu-mute-value" |
238 | 43 | 47 | ||
239 | 44 | 48 | ||
240 | === modified file 'src/indicator-sound.c' | |||
241 | --- src/indicator-sound.c 2011-02-16 11:20:21 +0000 | |||
242 | +++ src/indicator-sound.c 2011-02-18 17:27:12 +0000 | |||
243 | @@ -32,12 +32,12 @@ | |||
244 | 32 | #include "metadata-widget.h" | 32 | #include "metadata-widget.h" |
245 | 33 | #include "title-widget.h" | 33 | #include "title-widget.h" |
246 | 34 | #include "volume-widget.h" | 34 | #include "volume-widget.h" |
248 | 35 | 35 | #include "voip-input-widget.h" | |
249 | 36 | #include "dbus-shared-names.h" | 36 | #include "dbus-shared-names.h" |
250 | 37 | #include "sound-state-manager.h" | ||
251 | 37 | 38 | ||
252 | 38 | #include "gen-sound-service.xml.h" | 39 | #include "gen-sound-service.xml.h" |
253 | 39 | #include "common-defs.h" | 40 | #include "common-defs.h" |
254 | 40 | #include "sound-state-manager.h" | ||
255 | 41 | 41 | ||
256 | 42 | typedef struct _IndicatorSoundPrivate IndicatorSoundPrivate; | 42 | typedef struct _IndicatorSoundPrivate IndicatorSoundPrivate; |
257 | 43 | 43 | ||
258 | @@ -79,6 +79,10 @@ | |||
259 | 79 | DbusmenuMenuitem * parent, | 79 | DbusmenuMenuitem * parent, |
260 | 80 | DbusmenuClient * client, | 80 | DbusmenuClient * client, |
261 | 81 | gpointer user_data); | 81 | gpointer user_data); |
262 | 82 | static gboolean new_voip_slider_widget (DbusmenuMenuitem * newitem, | ||
263 | 83 | DbusmenuMenuitem * parent, | ||
264 | 84 | DbusmenuClient * client, | ||
265 | 85 | gpointer user_data); | ||
266 | 82 | static gboolean new_transport_widget (DbusmenuMenuitem * newitem, | 86 | static gboolean new_transport_widget (DbusmenuMenuitem * newitem, |
267 | 83 | DbusmenuMenuitem * parent, | 87 | DbusmenuMenuitem * parent, |
268 | 84 | DbusmenuClient * client, | 88 | DbusmenuClient * client, |
269 | @@ -191,6 +195,9 @@ | |||
270 | 191 | DBUSMENU_VOLUME_MENUITEM_TYPE, | 195 | DBUSMENU_VOLUME_MENUITEM_TYPE, |
271 | 192 | new_volume_slider_widget); | 196 | new_volume_slider_widget); |
272 | 193 | dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), | 197 | dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), |
273 | 198 | DBUSMENU_VOIP_INPUT_MENUITEM_TYPE, | ||
274 | 199 | new_voip_slider_widget); | ||
275 | 200 | dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), | ||
276 | 194 | DBUSMENU_TRANSPORT_MENUITEM_TYPE, | 201 | DBUSMENU_TRANSPORT_MENUITEM_TYPE, |
277 | 195 | new_transport_widget); | 202 | new_transport_widget); |
278 | 196 | dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), | 203 | dbusmenu_client_add_type_handler (DBUSMENU_CLIENT(client), |
279 | @@ -403,6 +410,53 @@ | |||
280 | 403 | parent); | 410 | parent); |
281 | 404 | return TRUE; | 411 | return TRUE; |
282 | 405 | } | 412 | } |
283 | 413 | /** | ||
284 | 414 | * new_voip_slider_widget | ||
285 | 415 | * Create the voip menu item widget, must of the time this widget will be hidden. | ||
286 | 416 | * @param newitem | ||
287 | 417 | * @param parent | ||
288 | 418 | * @param client | ||
289 | 419 | * @param user_data | ||
290 | 420 | * @return | ||
291 | 421 | */ | ||
292 | 422 | static gboolean | ||
293 | 423 | new_voip_slider_widget (DbusmenuMenuitem * newitem, | ||
294 | 424 | DbusmenuMenuitem * parent, | ||
295 | 425 | DbusmenuClient * client, | ||
296 | 426 | gpointer user_data) | ||
297 | 427 | { | ||
298 | 428 | g_debug("indicator-sound: new_voip_slider_widget"); | ||
299 | 429 | GtkWidget* voip_widget = NULL; | ||
300 | 430 | //IndicatorObject *io = NULL; | ||
301 | 431 | |||
302 | 432 | g_return_val_if_fail(DBUSMENU_IS_MENUITEM(newitem), FALSE); | ||
303 | 433 | g_return_val_if_fail(DBUSMENU_IS_GTKCLIENT(client), FALSE); | ||
304 | 434 | |||
305 | 435 | voip_widget = voip_input_widget_new (newitem); | ||
306 | 436 | /* | ||
307 | 437 | / io = g_object_get_data (G_OBJECT (client), "indicator"); | ||
308 | 438 | */ | ||
309 | 439 | //IndicatorSoundPrivate* priv = INDICATOR_SOUND_GET_PRIVATE(INDICATOR_SOUND (io)); | ||
310 | 440 | //priv->volume_widget = volume_widget; | ||
311 | 441 | |||
312 | 442 | GtkWidget* ido_slider_widget = voip_input_widget_get_ido_slider(VOIP_INPUT_WIDGET(voip_widget)); | ||
313 | 443 | |||
314 | 444 | gtk_widget_show_all(ido_slider_widget); | ||
315 | 445 | // register the style callback on this widget with state manager's style change | ||
316 | 446 | // handler (needs to remake the blocking animation for each style). | ||
317 | 447 | /* | ||
318 | 448 | g_signal_connect (ido_slider_widget, "style-set", | ||
319 | 449 | G_CALLBACK(sound_state_manager_style_changed_cb), | ||
320 | 450 | priv->state_manager); | ||
321 | 451 | */ | ||
322 | 452 | |||
323 | 453 | GtkMenuItem *menu_volume_item = GTK_MENU_ITEM(ido_slider_widget); | ||
324 | 454 | dbusmenu_gtkclient_newitem_base(DBUSMENU_GTKCLIENT(client), | ||
325 | 455 | newitem, | ||
326 | 456 | menu_volume_item, | ||
327 | 457 | parent); | ||
328 | 458 | return TRUE; | ||
329 | 459 | } | ||
330 | 406 | 460 | ||
331 | 407 | /*******************************************************************/ | 461 | /*******************************************************************/ |
332 | 408 | //UI callbacks | 462 | //UI callbacks |
333 | @@ -439,19 +493,23 @@ | |||
334 | 439 | switch (event->keyval) { | 493 | switch (event->keyval) { |
335 | 440 | case GDK_Right: | 494 | case GDK_Right: |
336 | 441 | digested = TRUE; | 495 | digested = TRUE; |
337 | 496 | /* | ||
338 | 442 | if (event->state & GDK_CONTROL_MASK) { | 497 | if (event->state & GDK_CONTROL_MASK) { |
339 | 443 | new_value = 100; | 498 | new_value = 100; |
340 | 444 | } else { | 499 | } else { |
341 | 500 | */ | ||
342 | 445 | new_value = current_value + five_percent; | 501 | new_value = current_value + five_percent; |
344 | 446 | } | 502 | //} |
345 | 447 | break; | 503 | break; |
346 | 448 | case GDK_Left: | 504 | case GDK_Left: |
347 | 449 | digested = TRUE; | 505 | digested = TRUE; |
348 | 506 | /* | ||
349 | 450 | if (event->state & GDK_CONTROL_MASK) { | 507 | if (event->state & GDK_CONTROL_MASK) { |
350 | 451 | new_value = 0; | 508 | new_value = 0; |
351 | 452 | } else { | 509 | } else { |
352 | 510 | */ | ||
353 | 453 | new_value = current_value - five_percent; | 511 | new_value = current_value - five_percent; |
355 | 454 | } | 512 | //} |
356 | 455 | break; | 513 | break; |
357 | 456 | case GDK_plus: | 514 | case GDK_plus: |
358 | 457 | digested = TRUE; | 515 | digested = TRUE; |
359 | 458 | 516 | ||
360 | === modified file 'src/music-player-bridge.vala' | |||
361 | --- src/music-player-bridge.vala 2011-01-31 19:14:47 +0000 | |||
362 | +++ src/music-player-bridge.vala 2011-02-18 17:27:12 +0000 | |||
363 | @@ -23,11 +23,13 @@ | |||
364 | 23 | 23 | ||
365 | 24 | public class MusicPlayerBridge : GLib.Object | 24 | public class MusicPlayerBridge : GLib.Object |
366 | 25 | { | 25 | { |
367 | 26 | const int DEVICE_ITEMS_COUNT = 3; | ||
368 | 27 | |||
369 | 26 | private SettingsManager settings_manager; | 28 | private SettingsManager settings_manager; |
370 | 27 | private Dbusmenu.Menuitem root_menu; | 29 | private Dbusmenu.Menuitem root_menu; |
371 | 28 | private HashMap<string, PlayerController> registered_clients; | 30 | private HashMap<string, PlayerController> registered_clients; |
372 | 29 | private Mpris2Watcher watcher; | 31 | private Mpris2Watcher watcher; |
374 | 30 | 32 | ||
375 | 31 | public MusicPlayerBridge() | 33 | public MusicPlayerBridge() |
376 | 32 | { | 34 | { |
377 | 33 | } | 35 | } |
378 | @@ -79,10 +81,10 @@ | |||
379 | 79 | private int calculate_menu_position() | 81 | private int calculate_menu_position() |
380 | 80 | { | 82 | { |
381 | 81 | if(this.registered_clients.size == 0){ | 83 | if(this.registered_clients.size == 0){ |
383 | 82 | return 2; | 84 | return DEVICE_ITEMS_COUNT; |
384 | 83 | } | 85 | } |
385 | 84 | else{ | 86 | else{ |
387 | 85 | return (2 + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY)); | 87 | return (DEVICE_ITEMS_COUNT + (this.registered_clients.size * PlayerController.WIDGET_QUANTITY)); |
388 | 86 | } | 88 | } |
389 | 87 | } | 89 | } |
390 | 88 | 90 | ||
391 | 89 | 91 | ||
392 | === modified file 'src/mute-menu-item.c' | |||
393 | --- src/mute-menu-item.c 2011-02-07 18:08:19 +0000 | |||
394 | +++ src/mute-menu-item.c 2011-02-18 17:27:12 +0000 | |||
395 | @@ -61,6 +61,7 @@ | |||
396 | 61 | { | 61 | { |
397 | 62 | g_debug("Building new Mute Menu Item"); | 62 | g_debug("Building new Mute Menu Item"); |
398 | 63 | MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE(self); | 63 | MuteMenuItemPrivate* priv = MUTE_MENU_ITEM_GET_PRIVATE(self); |
399 | 64 | priv->button = NULL; | ||
400 | 64 | priv->button = dbusmenu_menuitem_new(); | 65 | priv->button = dbusmenu_menuitem_new(); |
401 | 65 | dbusmenu_menuitem_property_set_bool (priv->button, | 66 | dbusmenu_menuitem_property_set_bool (priv->button, |
402 | 66 | DBUSMENU_MENUITEM_PROP_VISIBLE, | 67 | DBUSMENU_MENUITEM_PROP_VISIBLE, |
403 | 67 | 68 | ||
404 | === modified file 'src/player-item.vala' | |||
405 | --- src/player-item.vala 2011-02-09 10:56:49 +0000 | |||
406 | +++ src/player-item.vala 2011-02-18 17:27:12 +0000 | |||
407 | @@ -94,9 +94,8 @@ | |||
408 | 94 | { | 94 | { |
409 | 95 | foreach(string prop in attrs){ | 95 | foreach(string prop in attrs){ |
410 | 96 | //debug("populated ? - prop: %s", prop); | 96 | //debug("populated ? - prop: %s", prop); |
411 | 97 | int value_int = property_get_int(prop); | ||
412 | 98 | if(property_get_int(prop) != EMPTY){ | 97 | if(property_get_int(prop) != EMPTY){ |
414 | 99 | //debug("populated - prop %s and value %i", prop, value_int); | 98 | //debug("populated - prop %s and value %i", prop, property_get_int(prop)); |
415 | 100 | return true; | 99 | return true; |
416 | 101 | } | 100 | } |
417 | 102 | } | 101 | } |
418 | 103 | 102 | ||
419 | === modified file 'src/pulseaudio-mgr.c' | |||
420 | --- src/pulseaudio-mgr.c 2011-02-10 14:34:51 +0000 | |||
421 | +++ src/pulseaudio-mgr.c 2011-02-18 17:27:12 +0000 | |||
422 | @@ -19,9 +19,9 @@ | |||
423 | 19 | 19 | ||
424 | 20 | /**Notes | 20 | /**Notes |
425 | 21 | * | 21 | * |
429 | 22 | * Approach now is to set up the communication channels then query the server | 22 | * Approach now is to set up the communication channels, query the server |
430 | 23 | * fetch its default sink. If this fails then fetch the list of sinks and take | 23 | * fetch its default sink/source. If this fails then fetch the list of sinks/sources |
431 | 24 | * the first one which is not the auto-null sink. | 24 | * and take the first one which is not the auto-null sink. |
432 | 25 | * TODO: need to handle the situation where one chink in this linear chain breaks | 25 | * TODO: need to handle the situation where one chink in this linear chain breaks |
433 | 26 | * i.e. start off the process again and count the attempts (note different to | 26 | * i.e. start off the process again and count the attempts (note different to |
434 | 27 | reconnect attempts) | 27 | reconnect attempts) |
435 | @@ -47,10 +47,22 @@ | |||
436 | 47 | const pa_sink_info *info, | 47 | const pa_sink_info *info, |
437 | 48 | int eol, | 48 | int eol, |
438 | 49 | void *userdata); | 49 | void *userdata); |
439 | 50 | static void pm_default_source_info_callback (pa_context *c, | ||
440 | 51 | const pa_source_info *info, | ||
441 | 52 | int eol, | ||
442 | 53 | void *userdata); | ||
443 | 50 | static void pm_sink_info_callback (pa_context *c, | 54 | static void pm_sink_info_callback (pa_context *c, |
444 | 51 | const pa_sink_info *sink, | 55 | const pa_sink_info *sink, |
445 | 52 | int eol, | 56 | int eol, |
446 | 53 | void *userdata); | 57 | void *userdata); |
447 | 58 | static void pm_source_info_callback (pa_context *c, | ||
448 | 59 | const pa_source_info *info, | ||
449 | 60 | int eol, | ||
450 | 61 | void *userdata); | ||
451 | 62 | static void pm_update_source_info_callback (pa_context *c, | ||
452 | 63 | const pa_source_info *info, | ||
453 | 64 | int eol, | ||
454 | 65 | void *userdata); | ||
455 | 54 | static void pm_sink_input_info_callback (pa_context *c, | 66 | static void pm_sink_input_info_callback (pa_context *c, |
456 | 55 | const pa_sink_input_info *info, | 67 | const pa_sink_input_info *info, |
457 | 56 | int eol, | 68 | int eol, |
458 | @@ -64,6 +76,7 @@ | |||
459 | 64 | int eol, | 76 | int eol, |
460 | 65 | void* userdata); | 77 | void* userdata); |
461 | 66 | 78 | ||
462 | 79 | |||
463 | 67 | static gboolean reconnect_to_pulse (gpointer user_data); | 80 | static gboolean reconnect_to_pulse (gpointer user_data); |
464 | 68 | 81 | ||
465 | 69 | static gint connection_attempts = 0; | 82 | static gint connection_attempts = 0; |
466 | @@ -152,6 +165,25 @@ | |||
467 | 152 | GINT_TO_POINTER (update))); | 165 | GINT_TO_POINTER (update))); |
468 | 153 | } | 166 | } |
469 | 154 | 167 | ||
470 | 168 | void | ||
471 | 169 | pm_update_mic_gain (gint source_index, pa_cvolume new_gain) | ||
472 | 170 | { | ||
473 | 171 | pa_operation_unref (pa_context_set_source_volume_by_index (pulse_context, | ||
474 | 172 | source_index, | ||
475 | 173 | &new_gain, | ||
476 | 174 | NULL, | ||
477 | 175 | NULL) ); | ||
478 | 176 | } | ||
479 | 177 | |||
480 | 178 | void | ||
481 | 179 | pm_update_mic_mute (gint source_index, gint mute_update) | ||
482 | 180 | { | ||
483 | 181 | pa_operation_unref (pa_context_set_source_mute_by_index (pulse_context, | ||
484 | 182 | source_index, | ||
485 | 183 | mute_update, | ||
486 | 184 | NULL, | ||
487 | 185 | NULL)); | ||
488 | 186 | } | ||
489 | 155 | /**********************************************************************************************************************/ | 187 | /**********************************************************************************************************************/ |
490 | 156 | // Pulse-Audio asychronous call-backs | 188 | // Pulse-Audio asychronous call-backs |
491 | 157 | /**********************************************************************************************************************/ | 189 | /**********************************************************************************************************************/ |
492 | @@ -163,19 +195,21 @@ | |||
493 | 163 | uint32_t index, | 195 | uint32_t index, |
494 | 164 | void* userdata) | 196 | void* userdata) |
495 | 165 | { | 197 | { |
496 | 198 | if (IS_ACTIVE_SINK (userdata) == FALSE){ | ||
497 | 199 | g_critical ("subscribed events callback - our userdata is not what we think it should be"); | ||
498 | 200 | return; | ||
499 | 201 | } | ||
500 | 202 | ActiveSink* sink = ACTIVE_SINK (userdata); | ||
501 | 203 | |||
502 | 166 | switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { | 204 | switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) { |
503 | 167 | case PA_SUBSCRIPTION_EVENT_SINK: | 205 | case PA_SUBSCRIPTION_EVENT_SINK: |
509 | 168 | if (IS_ACTIVE_SINK (userdata) == FALSE){ | 206 | |
505 | 169 | g_warning ("subscribed events callback - our userdata is not what we think it should be"); | ||
506 | 170 | return; | ||
507 | 171 | } | ||
508 | 172 | ActiveSink* sink = ACTIVE_SINK (userdata); | ||
510 | 173 | // We don't care about any other sink other than the active one. | 207 | // We don't care about any other sink other than the active one. |
511 | 174 | if (index != active_sink_get_index (sink)) | 208 | if (index != active_sink_get_index (sink)) |
513 | 175 | return; | 209 | return; |
514 | 176 | 210 | ||
515 | 177 | if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { | 211 | if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { |
517 | 178 | active_sink_deactivate (ACTIVE_SINK (userdata)); | 212 | active_sink_deactivate (sink); |
518 | 179 | 213 | ||
519 | 180 | } | 214 | } |
520 | 181 | else{ | 215 | else{ |
521 | @@ -185,9 +219,36 @@ | |||
522 | 185 | userdata) ); | 219 | userdata) ); |
523 | 186 | } | 220 | } |
524 | 187 | break; | 221 | break; |
525 | 222 | case PA_SUBSCRIPTION_EVENT_SOURCE: | ||
526 | 223 | g_debug ("Looks like source event of some description"); | ||
527 | 224 | // We don't care about any other sink other than the active one. | ||
528 | 225 | if (index != active_sink_get_source_index (sink)) | ||
529 | 226 | return; | ||
530 | 227 | if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { | ||
531 | 228 | active_sink_deactivate_voip_source (sink, FALSE); | ||
532 | 229 | } | ||
533 | 230 | else{ | ||
534 | 231 | pa_operation_unref (pa_context_get_source_info_by_index (c, | ||
535 | 232 | index, | ||
536 | 233 | pm_update_source_info_callback, | ||
537 | 234 | userdata) ); | ||
538 | 235 | } | ||
539 | 236 | break; | ||
540 | 188 | case PA_SUBSCRIPTION_EVENT_SINK_INPUT: | 237 | case PA_SUBSCRIPTION_EVENT_SINK_INPUT: |
541 | 189 | // We don't care about sink input removals. | 238 | // We don't care about sink input removals. |
543 | 190 | if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) != PA_SUBSCRIPTION_EVENT_REMOVE) { | 239 | g_debug ("sink input event"); |
544 | 240 | if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_REMOVE) { | ||
545 | 241 | gint cached_index = active_sink_get_current_sink_input_index (sink); | ||
546 | 242 | |||
547 | 243 | g_debug ("Just saw a sink input removal event - index = %i and cached index = %i", index, cached_index); | ||
548 | 244 | |||
549 | 245 | if (index == cached_index){ | ||
550 | 246 | active_sink_deactivate_voip_client (sink); | ||
551 | 247 | } | ||
552 | 248 | } | ||
553 | 249 | else if ((t & PA_SUBSCRIPTION_EVENT_TYPE_MASK) == PA_SUBSCRIPTION_EVENT_NEW) { | ||
554 | 250 | g_debug ("some new sink input event ? - index = %i", index); | ||
555 | 251 | // Determine if its a VOIP app or a maybe blocking state. | ||
556 | 191 | pa_operation_unref (pa_context_get_sink_input_info (c, | 252 | pa_operation_unref (pa_context_get_sink_input_info (c, |
557 | 192 | index, | 253 | index, |
558 | 193 | pm_sink_input_info_callback, userdata)); | 254 | pm_sink_input_info_callback, userdata)); |
559 | @@ -206,6 +267,7 @@ | |||
560 | 206 | } | 267 | } |
561 | 207 | 268 | ||
562 | 208 | 269 | ||
563 | 270 | |||
564 | 209 | static void | 271 | static void |
565 | 210 | pm_context_state_callback (pa_context *c, void *userdata) | 272 | pm_context_state_callback (pa_context *c, void *userdata) |
566 | 211 | { | 273 | { |
567 | @@ -244,6 +306,7 @@ | |||
568 | 244 | 306 | ||
569 | 245 | if (!(o = pa_context_subscribe (c, (pa_subscription_mask_t) | 307 | if (!(o = pa_context_subscribe (c, (pa_subscription_mask_t) |
570 | 246 | (PA_SUBSCRIPTION_MASK_SINK| | 308 | (PA_SUBSCRIPTION_MASK_SINK| |
571 | 309 | PA_SUBSCRIPTION_MASK_SOURCE| | ||
572 | 247 | PA_SUBSCRIPTION_MASK_SINK_INPUT| | 310 | PA_SUBSCRIPTION_MASK_SINK_INPUT| |
573 | 248 | PA_SUBSCRIPTION_MASK_SERVER), NULL, NULL))) { | 311 | PA_SUBSCRIPTION_MASK_SERVER), NULL, NULL))) { |
574 | 249 | g_warning("pa_context_subscribe() failed"); | 312 | g_warning("pa_context_subscribe() failed"); |
575 | @@ -261,7 +324,8 @@ | |||
576 | 261 | 324 | ||
577 | 262 | /** | 325 | /** |
578 | 263 | After startup we go straight for the server info to see if it has details of | 326 | After startup we go straight for the server info to see if it has details of |
580 | 264 | the default sink. If so it makes things much easier. | 327 | the default sink and source. Normally these are valid, if there is none set |
581 | 328 | fetch the list of each and try to determine the sink. | ||
582 | 265 | **/ | 329 | **/ |
583 | 266 | static void | 330 | static void |
584 | 267 | pm_server_info_callback (pa_context *c, | 331 | pm_server_info_callback (pa_context *c, |
585 | @@ -276,24 +340,46 @@ | |||
586 | 276 | active_sink_deactivate (ACTIVE_SINK (userdata)); | 340 | active_sink_deactivate (ACTIVE_SINK (userdata)); |
587 | 277 | return; | 341 | return; |
588 | 278 | } | 342 | } |
589 | 343 | // Go for the default sink | ||
590 | 279 | if (info->default_sink_name != NULL) { | 344 | if (info->default_sink_name != NULL) { |
591 | 280 | g_debug ("default sink name from the server ain't null'"); | 345 | g_debug ("default sink name from the server ain't null'"); |
592 | 281 | if (!(operation = pa_context_get_sink_info_by_name (c, | 346 | if (!(operation = pa_context_get_sink_info_by_name (c, |
593 | 282 | info->default_sink_name, | 347 | info->default_sink_name, |
594 | 283 | pm_default_sink_info_callback, | 348 | pm_default_sink_info_callback, |
595 | 284 | userdata) )) { | 349 | userdata) )) { |
598 | 285 | } | 350 | g_warning("pa_context_get_sink_info_by_namet() failed"); |
599 | 286 | else{ | 351 | active_sink_deactivate (ACTIVE_SINK (userdata)); |
600 | 287 | pa_operation_unref(operation); | 352 | pa_operation_unref(operation); |
601 | 288 | return; | 353 | return; |
602 | 289 | } | 354 | } |
604 | 290 | } | 355 | } // If there is no default sink, try to determine a sink from the list of sinks |
605 | 291 | else if (!(operation = pa_context_get_sink_info_list(c, | 356 | else if (!(operation = pa_context_get_sink_info_list(c, |
606 | 292 | pm_sink_info_callback, | 357 | pm_sink_info_callback, |
608 | 293 | NULL))) { | 358 | userdata))) { |
609 | 294 | g_warning("pa_context_get_sink_info_list() failed"); | 359 | g_warning("pa_context_get_sink_info_list() failed"); |
610 | 360 | active_sink_deactivate (ACTIVE_SINK (userdata)); | ||
611 | 361 | pa_operation_unref(operation); | ||
612 | 295 | return; | 362 | return; |
613 | 296 | } | 363 | } |
614 | 364 | // And the source | ||
615 | 365 | if (info->default_source_name != NULL) { | ||
616 | 366 | g_debug ("default source name from the server is not null'"); | ||
617 | 367 | if (!(operation = pa_context_get_source_info_by_name (c, | ||
618 | 368 | info->default_source_name, | ||
619 | 369 | pm_default_source_info_callback, | ||
620 | 370 | userdata) )) { | ||
621 | 371 | g_warning("pa_context_get_default_source_info() failed"); | ||
622 | 372 | // TODO: call some input deactivate method on active sink | ||
623 | 373 | pa_operation_unref(operation); | ||
624 | 374 | return; | ||
625 | 375 | } | ||
626 | 376 | } | ||
627 | 377 | else if (!(operation = pa_context_get_source_info_list(c, | ||
628 | 378 | pm_source_info_callback, | ||
629 | 379 | userdata))) { | ||
630 | 380 | g_warning("pa_context_get_sink_info_list() failed"); | ||
631 | 381 | // TODO: call some input deactivate method for the source | ||
632 | 382 | } | ||
633 | 297 | pa_operation_unref(operation); | 383 | pa_operation_unref(operation); |
634 | 298 | } | 384 | } |
635 | 299 | 385 | ||
636 | @@ -335,8 +421,12 @@ | |||
637 | 335 | if (IS_ACTIVE_SINK (userdata) == FALSE){ | 421 | if (IS_ACTIVE_SINK (userdata) == FALSE){ |
638 | 336 | g_warning ("Default sink info callback - our user data is not what we think it should be"); | 422 | g_warning ("Default sink info callback - our user data is not what we think it should be"); |
639 | 337 | return; | 423 | return; |
642 | 338 | } | 424 | } |
643 | 339 | g_debug ("server has handed us a default sink"); | 425 | // Only repopulate if there is a change with regards the index |
644 | 426 | if (active_sink_get_index (ACTIVE_SINK (userdata)) == info->index) | ||
645 | 427 | return; | ||
646 | 428 | |||
647 | 429 | g_debug ("Pulse Server has handed us a new default sink"); | ||
648 | 340 | active_sink_populate (ACTIVE_SINK (userdata), info); | 430 | active_sink_populate (ACTIVE_SINK (userdata), info); |
649 | 341 | } | 431 | } |
650 | 342 | } | 432 | } |
651 | @@ -356,12 +446,30 @@ | |||
652 | 356 | g_warning("\n Sink input info callback : SINK INPUT INFO IS NULL BUT EOL was not POSITIVE!!!"); | 446 | g_warning("\n Sink input info callback : SINK INPUT INFO IS NULL BUT EOL was not POSITIVE!!!"); |
653 | 357 | return; | 447 | return; |
654 | 358 | } | 448 | } |
655 | 449 | |||
656 | 359 | if (IS_ACTIVE_SINK (userdata) == FALSE){ | 450 | if (IS_ACTIVE_SINK (userdata) == FALSE){ |
657 | 360 | g_warning ("sink input info callback - our user data is not what we think it should be"); | 451 | g_warning ("sink input info callback - our user data is not what we think it should be"); |
658 | 361 | return; | 452 | return; |
659 | 362 | } | 453 | } |
661 | 363 | 454 | // Check if this is Voip sink input | |
662 | 455 | gint result = pa_proplist_contains (info->proplist, PA_PROP_MEDIA_ROLE); | ||
663 | 364 | ActiveSink* a_sink = ACTIVE_SINK (userdata); | 456 | ActiveSink* a_sink = ACTIVE_SINK (userdata); |
664 | 457 | |||
665 | 458 | if (result == 1){ | ||
666 | 459 | g_debug ("Sink input info has media role property"); | ||
667 | 460 | const char* value = pa_proplist_gets (info->proplist, PA_PROP_MEDIA_ROLE); | ||
668 | 461 | g_debug ("prop role = %s", value); | ||
669 | 462 | if (g_strcmp0 (value, "phone") == 0) { | ||
670 | 463 | g_debug ("And yes its a VOIP app ... sink input index = %i", info->index); | ||
671 | 464 | active_sink_activate_voip_item (a_sink, (gint)info->index, (gint)info->client); | ||
672 | 465 | // TODO to start with we will assume our source is the same as what this 'client' | ||
673 | 466 | // is pointing at. This should probably be more intelligent : | ||
674 | 467 | // query for the list of source output info's and going on the name of the client | ||
675 | 468 | // from the sink input ensure our voip item is using the right source. | ||
676 | 469 | } | ||
677 | 470 | } | ||
678 | 471 | |||
679 | 472 | // And finally check for the mute blocking state | ||
680 | 365 | if (active_sink_get_index (a_sink) == info->sink){ | 473 | if (active_sink_get_index (a_sink) == info->sink){ |
681 | 366 | active_sink_determine_blocking_state (a_sink); | 474 | active_sink_determine_blocking_state (a_sink); |
682 | 367 | } | 475 | } |
683 | @@ -404,3 +512,66 @@ | |||
684 | 404 | } | 512 | } |
685 | 405 | } | 513 | } |
686 | 406 | 514 | ||
687 | 515 | // Source info related callbacks | ||
688 | 516 | static void | ||
689 | 517 | pm_default_source_info_callback (pa_context *c, | ||
690 | 518 | const pa_source_info *info, | ||
691 | 519 | int eol, | ||
692 | 520 | void *userdata) | ||
693 | 521 | { | ||
694 | 522 | if (eol > 0) { | ||
695 | 523 | return; | ||
696 | 524 | } | ||
697 | 525 | else { | ||
698 | 526 | if (IS_ACTIVE_SINK (userdata) == FALSE){ | ||
699 | 527 | g_warning ("Default sink info callback - our user data is not what we think it should be"); | ||
700 | 528 | return; | ||
701 | 529 | } | ||
702 | 530 | // If there is an index change we need to change our cached source | ||
703 | 531 | if (active_sink_get_source_index (ACTIVE_SINK (userdata)) == info->index) | ||
704 | 532 | return; | ||
705 | 533 | g_debug ("Pulse Server has handed us a new default source"); | ||
706 | 534 | active_sink_deactivate_voip_source (ACTIVE_SINK (userdata), TRUE); | ||
707 | 535 | active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info); | ||
708 | 536 | } | ||
709 | 537 | } | ||
710 | 538 | |||
711 | 539 | static void | ||
712 | 540 | pm_source_info_callback (pa_context *c, | ||
713 | 541 | const pa_source_info *info, | ||
714 | 542 | int eol, | ||
715 | 543 | void *userdata) | ||
716 | 544 | { | ||
717 | 545 | if (eol > 0) { | ||
718 | 546 | return; | ||
719 | 547 | } | ||
720 | 548 | else { | ||
721 | 549 | if (IS_ACTIVE_SINK (userdata) == FALSE){ | ||
722 | 550 | g_warning ("Default sink info callback - our user data is not what we think it should be"); | ||
723 | 551 | return; | ||
724 | 552 | } | ||
725 | 553 | // For now we will take the first available | ||
726 | 554 | if (active_sink_is_voip_source_populated (ACTIVE_SINK (userdata)) == FALSE){ | ||
727 | 555 | active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info); | ||
728 | 556 | } | ||
729 | 557 | } | ||
730 | 558 | } | ||
731 | 559 | |||
732 | 560 | static void | ||
733 | 561 | pm_update_source_info_callback (pa_context *c, | ||
734 | 562 | const pa_source_info *info, | ||
735 | 563 | int eol, | ||
736 | 564 | void *userdata) | ||
737 | 565 | { | ||
738 | 566 | if (eol > 0) { | ||
739 | 567 | return; | ||
740 | 568 | } | ||
741 | 569 | else { | ||
742 | 570 | if (IS_ACTIVE_SINK (userdata) == FALSE){ | ||
743 | 571 | g_warning ("Default sink info callback - our user data is not what we think it should be"); | ||
744 | 572 | return; | ||
745 | 573 | } | ||
746 | 574 | g_debug ("Got a source update for %s , index %i", info->name, info->index); | ||
747 | 575 | active_sink_update_voip_input_source (ACTIVE_SINK (userdata), info); | ||
748 | 576 | } | ||
749 | 577 | } | ||
750 | 407 | \ No newline at end of file | 578 | \ No newline at end of file |
751 | 408 | 579 | ||
752 | === modified file 'src/pulseaudio-mgr.h' | |||
753 | --- src/pulseaudio-mgr.h 2011-02-07 11:19:17 +0000 | |||
754 | +++ src/pulseaudio-mgr.h 2011-02-18 17:27:12 +0000 | |||
755 | @@ -22,6 +22,8 @@ | |||
756 | 22 | void pm_establish_pulse_connection (ActiveSink* active_sink); | 22 | void pm_establish_pulse_connection (ActiveSink* active_sink); |
757 | 23 | void close_pulse_activites(); | 23 | void close_pulse_activites(); |
758 | 24 | void pm_update_volume (gint sink_index, pa_cvolume new_volume); | 24 | void pm_update_volume (gint sink_index, pa_cvolume new_volume); |
759 | 25 | void pm_update_mic_gain (gint source_index, pa_cvolume new_gain); | ||
760 | 26 | void pm_update_mic_mute (gint source_index, int mute_update); | ||
761 | 25 | void pm_update_mute (gboolean update); | 27 | void pm_update_mute (gboolean update); |
762 | 26 | 28 | ||
763 | 27 | 29 | ||
764 | 28 | 30 | ||
765 | === modified file 'src/settings-manager.vala' | |||
766 | --- src/settings-manager.vala 2011-02-01 01:33:46 +0000 | |||
767 | +++ src/settings-manager.vala 2011-02-18 17:27:12 +0000 | |||
768 | @@ -71,6 +71,7 @@ | |||
769 | 71 | 71 | ||
770 | 72 | // Convenient debug method inorder to provide visability over | 72 | // Convenient debug method inorder to provide visability over |
771 | 73 | // the contents of both interested and blacklisted containers in its gsettings | 73 | // the contents of both interested and blacklisted containers in its gsettings |
772 | 74 | /** | ||
773 | 74 | private void reveal_contents() | 75 | private void reveal_contents() |
774 | 75 | { | 76 | { |
775 | 76 | var already_interested = this.settings.get_strv ("interested-media-players"); | 77 | var already_interested = this.settings.get_strv ("interested-media-players"); |
776 | @@ -87,4 +88,5 @@ | |||
777 | 87 | debug ("interested array size = %i", already_interested.length); | 88 | debug ("interested array size = %i", already_interested.length); |
778 | 88 | debug ("blacklisted array size = %i", blacklisted.length); | 89 | debug ("blacklisted array size = %i", blacklisted.length); |
779 | 89 | } | 90 | } |
780 | 91 | **/ | ||
781 | 90 | } | 92 | } |
782 | 91 | 93 | ||
783 | === modified file 'src/sound-service-dbus.c' | |||
784 | --- src/sound-service-dbus.c 2011-02-04 18:25:54 +0000 | |||
785 | +++ src/sound-service-dbus.c 2011-02-18 17:27:12 +0000 | |||
786 | @@ -157,14 +157,18 @@ | |||
787 | 157 | void | 157 | void |
788 | 158 | sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, | 158 | sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, |
789 | 159 | DbusmenuMenuitem* mute_item, | 159 | DbusmenuMenuitem* mute_item, |
791 | 160 | DbusmenuMenuitem* slider_item) | 160 | DbusmenuMenuitem* slider_item, |
792 | 161 | DbusmenuMenuitem* voip_input_menu_item) | ||
793 | 161 | { | 162 | { |
794 | 162 | SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); | 163 | SoundServiceDbusPrivate * priv = SOUND_SERVICE_DBUS_GET_PRIVATE(self); |
795 | 163 | 164 | ||
796 | 164 | // Mute button | 165 | // Mute button |
797 | 166 | // TODO this additions should be fixed position, i.e. add via position and not just append | ||
798 | 167 | // be explicit as it is fixed. | ||
799 | 165 | dbusmenu_menuitem_child_append (priv->root_menuitem, mute_item); | 168 | dbusmenu_menuitem_child_append (priv->root_menuitem, mute_item); |
800 | 169 | dbusmenu_menuitem_child_append (priv->root_menuitem, slider_item); | ||
801 | 166 | g_debug ("just about to add the slider %i", DBUSMENU_IS_MENUITEM(slider_item)); | 170 | g_debug ("just about to add the slider %i", DBUSMENU_IS_MENUITEM(slider_item)); |
803 | 167 | dbusmenu_menuitem_child_append (priv->root_menuitem, slider_item); | 171 | dbusmenu_menuitem_child_append (priv->root_menuitem, voip_input_menu_item); |
804 | 168 | 172 | ||
805 | 169 | // Separator | 173 | // Separator |
806 | 170 | DbusmenuMenuitem* separator = dbusmenu_menuitem_new(); | 174 | DbusmenuMenuitem* separator = dbusmenu_menuitem_new(); |
807 | 171 | 175 | ||
808 | === modified file 'src/sound-service-dbus.h' | |||
809 | --- src/sound-service-dbus.h 2011-02-04 16:17:31 +0000 | |||
810 | +++ src/sound-service-dbus.h 2011-02-18 17:27:12 +0000 | |||
811 | @@ -57,7 +57,8 @@ | |||
812 | 57 | void sound_service_dbus_update_sound_state (SoundServiceDbus* self, SoundState new_state); | 57 | void sound_service_dbus_update_sound_state (SoundServiceDbus* self, SoundState new_state); |
813 | 58 | void sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, | 58 | void sound_service_dbus_build_sound_menu ( SoundServiceDbus* self, |
814 | 59 | DbusmenuMenuitem* mute_item, | 59 | DbusmenuMenuitem* mute_item, |
816 | 60 | DbusmenuMenuitem* slider_item); | 60 | DbusmenuMenuitem* slider_item, |
817 | 61 | DbusmenuMenuitem* voip_input_menu_item); | ||
818 | 61 | 62 | ||
819 | 62 | 63 | ||
820 | 63 | G_END_DECLS | 64 | G_END_DECLS |
821 | 64 | 65 | ||
822 | === modified file 'src/sound-service.c' | |||
823 | --- src/sound-service.c 2011-02-09 10:57:13 +0000 | |||
824 | +++ src/sound-service.c 2011-02-18 17:27:12 +0000 | |||
825 | @@ -39,8 +39,10 @@ | |||
826 | 39 | { | 39 | { |
827 | 40 | if (mainloop != NULL) { | 40 | if (mainloop != NULL) { |
828 | 41 | g_debug("Service shutdown !"); | 41 | g_debug("Service shutdown !"); |
829 | 42 | |||
830 | 42 | close_pulse_activites(); | 43 | close_pulse_activites(); |
831 | 43 | g_main_loop_quit(mainloop); | 44 | g_main_loop_quit(mainloop); |
832 | 45 | |||
833 | 44 | } | 46 | } |
834 | 45 | return; | 47 | return; |
835 | 46 | } | 48 | } |
836 | 47 | 49 | ||
837 | === added file 'src/voip-input-menu-item.c' | |||
838 | --- src/voip-input-menu-item.c 1970-01-01 00:00:00 +0000 | |||
839 | +++ src/voip-input-menu-item.c 2011-02-18 17:27:12 +0000 | |||
840 | @@ -0,0 +1,277 @@ | |||
841 | 1 | /* | ||
842 | 2 | Copyright 2011 Canonical Ltd. | ||
843 | 3 | |||
844 | 4 | Authors: | ||
845 | 5 | Conor Curran <conor.curran@canonical.com> | ||
846 | 6 | |||
847 | 7 | This program is free software: you can redistribute it and/or modify it | ||
848 | 8 | under the terms of the GNU General Public License version 3, as published | ||
849 | 9 | by the Free Software Foundation. | ||
850 | 10 | |||
851 | 11 | This program is distributed in the hope that it will be useful, but | ||
852 | 12 | WITHOUT ANY WARRANTY; without even the implied warranties of | ||
853 | 13 | MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
854 | 14 | PURPOSE. See the GNU General Public License for more details. | ||
855 | 15 | |||
856 | 16 | You should have received a copy of the GNU General Public License along | ||
857 | 17 | with this program. If not, see <http://www.gnu.org/licenses/>. | ||
858 | 18 | */ | ||
859 | 19 | #ifdef HAVE_CONFIG_H | ||
860 | 20 | #include "config.h" | ||
861 | 21 | #endif | ||
862 | 22 | |||
863 | 23 | #include <glib/gi18n.h> | ||
864 | 24 | #include "voip-input-menu-item.h" | ||
865 | 25 | #include "common-defs.h" | ||
866 | 26 | #include "pulseaudio-mgr.h" | ||
867 | 27 | |||
868 | 28 | typedef struct _VoipInputMenuItemPrivate VoipInputMenuItemPrivate; | ||
869 | 29 | |||
870 | 30 | struct _VoipInputMenuItemPrivate { | ||
871 | 31 | ActiveSink* a_sink; | ||
872 | 32 | pa_cvolume volume; | ||
873 | 33 | gint mute; | ||
874 | 34 | guint32 volume_steps; | ||
875 | 35 | pa_channel_map channel_map; | ||
876 | 36 | pa_volume_t base_volume; | ||
877 | 37 | gint source_index; | ||
878 | 38 | gint sink_input_index; | ||
879 | 39 | gint client_index; | ||
880 | 40 | }; | ||
881 | 41 | |||
882 | 42 | #define VOIP_INPUT_MENU_ITEM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemPrivate)) | ||
883 | 43 | |||
884 | 44 | /* Prototypes */ | ||
885 | 45 | static void voip_input_menu_item_class_init (VoipInputMenuItemClass *klass); | ||
886 | 46 | static void voip_input_menu_item_init (VoipInputMenuItem *self); | ||
887 | 47 | static void voip_input_menu_item_dispose (GObject *object); | ||
888 | 48 | static void voip_input_menu_item_finalize (GObject *object); | ||
889 | 49 | static void handle_event (DbusmenuMenuitem * mi, const gchar * name, | ||
890 | 50 | GVariant * value, guint timestamp); | ||
891 | 51 | // TODO: | ||
892 | 52 | // This method should really be shared between this and the volume slider obj | ||
893 | 53 | // perfectly static - wait until the device mgr wrapper is properly sorted and | ||
894 | 54 | // then consolidate | ||
895 | 55 | static pa_cvolume voip_input_menu_item_construct_mono_volume (const pa_cvolume* vol); | ||
896 | 56 | |||
897 | 57 | G_DEFINE_TYPE (VoipInputMenuItem, voip_input_menu_item, DBUSMENU_TYPE_MENUITEM); | ||
898 | 58 | |||
899 | 59 | static void | ||
900 | 60 | voip_input_menu_item_class_init (VoipInputMenuItemClass *klass) | ||
901 | 61 | { | ||
902 | 62 | GObjectClass *object_class = G_OBJECT_CLASS (klass); | ||
903 | 63 | |||
904 | 64 | g_type_class_add_private (klass, sizeof (VoipInputMenuItemPrivate)); | ||
905 | 65 | |||
906 | 66 | object_class->dispose = voip_input_menu_item_dispose; | ||
907 | 67 | object_class->finalize = voip_input_menu_item_finalize; | ||
908 | 68 | |||
909 | 69 | DbusmenuMenuitemClass * mclass = DBUSMENU_MENUITEM_CLASS(klass); | ||
910 | 70 | mclass->handle_event = handle_event; | ||
911 | 71 | } | ||
912 | 72 | |||
913 | 73 | static void | ||
914 | 74 | voip_input_menu_item_init (VoipInputMenuItem *self) | ||
915 | 75 | { | ||
916 | 76 | g_debug("Building new Slider Menu Item"); | ||
917 | 77 | dbusmenu_menuitem_property_set( DBUSMENU_MENUITEM(self), | ||
918 | 78 | DBUSMENU_MENUITEM_PROP_TYPE, | ||
919 | 79 | DBUSMENU_VOIP_INPUT_MENUITEM_TYPE ); | ||
920 | 80 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (self); | ||
921 | 81 | dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(self), | ||
922 | 82 | DBUSMENU_MENUITEM_PROP_VISIBLE, | ||
923 | 83 | FALSE ); | ||
924 | 84 | |||
925 | 85 | priv->source_index = NOT_ACTIVE; | ||
926 | 86 | priv->sink_input_index = NOT_ACTIVE; | ||
927 | 87 | priv->client_index = NOT_ACTIVE; | ||
928 | 88 | priv->mute = NOT_ACTIVE; | ||
929 | 89 | } | ||
930 | 90 | |||
931 | 91 | static void | ||
932 | 92 | voip_input_menu_item_dispose (GObject *object) | ||
933 | 93 | { | ||
934 | 94 | G_OBJECT_CLASS (voip_input_menu_item_parent_class)->dispose (object); | ||
935 | 95 | return; | ||
936 | 96 | } | ||
937 | 97 | |||
938 | 98 | static void | ||
939 | 99 | voip_input_menu_item_finalize (GObject *object) | ||
940 | 100 | { | ||
941 | 101 | G_OBJECT_CLASS (voip_input_menu_item_parent_class)->finalize (object); | ||
942 | 102 | } | ||
943 | 103 | |||
944 | 104 | static void | ||
945 | 105 | handle_event (DbusmenuMenuitem * mi, | ||
946 | 106 | const gchar * name, | ||
947 | 107 | GVariant * value, | ||
948 | 108 | guint timestamp) | ||
949 | 109 | { | ||
950 | 110 | GVariant* input = NULL; | ||
951 | 111 | input = value; | ||
952 | 112 | if (g_variant_is_of_type(value, G_VARIANT_TYPE_VARIANT) == TRUE) { | ||
953 | 113 | input = g_variant_get_variant(value); | ||
954 | 114 | } | ||
955 | 115 | |||
956 | 116 | gdouble percent = g_variant_get_double(input); | ||
957 | 117 | if (value != NULL){ | ||
958 | 118 | if (IS_VOIP_INPUT_MENU_ITEM (mi)) { | ||
959 | 119 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (VOIP_INPUT_MENU_ITEM (mi)); | ||
960 | 120 | g_debug ("Handle event in the voip input level backend instance - %f", percent); | ||
961 | 121 | pa_cvolume new_volume; | ||
962 | 122 | pa_cvolume_init(&new_volume); | ||
963 | 123 | new_volume.channels = 1; | ||
964 | 124 | pa_volume_t new_volume_value = (pa_volume_t) ((percent * PA_VOLUME_NORM) / 100); | ||
965 | 125 | pa_cvolume_set(&new_volume, 1, new_volume_value); | ||
966 | 126 | |||
967 | 127 | pm_update_mic_gain (priv->source_index, new_volume); | ||
968 | 128 | // finally unmute if needed | ||
969 | 129 | if (priv->mute == 1) { | ||
970 | 130 | pm_update_mic_mute (priv->source_index, 0); | ||
971 | 131 | } | ||
972 | 132 | //active_sink_update_volume (priv->a_sink, volume_input); | ||
973 | 133 | //active_sink_ensure_sink_is_unmuted (priv->a_sink); | ||
974 | 134 | } | ||
975 | 135 | } | ||
976 | 136 | } | ||
977 | 137 | |||
978 | 138 | static pa_cvolume | ||
979 | 139 | voip_input_menu_item_construct_mono_volume (const pa_cvolume* vol) | ||
980 | 140 | { | ||
981 | 141 | pa_cvolume new_volume; | ||
982 | 142 | pa_cvolume_init(&new_volume); | ||
983 | 143 | new_volume.channels = 1; | ||
984 | 144 | pa_volume_t max_vol = pa_cvolume_max(vol); | ||
985 | 145 | pa_cvolume_set(&new_volume, 1, max_vol); | ||
986 | 146 | return new_volume; | ||
987 | 147 | } | ||
988 | 148 | |||
989 | 149 | void | ||
990 | 150 | voip_input_menu_item_update (VoipInputMenuItem* item, | ||
991 | 151 | const pa_source_info* source) | ||
992 | 152 | { | ||
993 | 153 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
994 | 154 | // only overwrite the constants of each source if the device has changed | ||
995 | 155 | if (priv->source_index == NOT_ACTIVE){ | ||
996 | 156 | priv->base_volume = source->base_volume; | ||
997 | 157 | priv->volume_steps = source->n_volume_steps; | ||
998 | 158 | priv->channel_map = source->channel_map; | ||
999 | 159 | priv->source_index = source->index; | ||
1000 | 160 | } | ||
1001 | 161 | priv->volume = voip_input_menu_item_construct_mono_volume (&source->volume); | ||
1002 | 162 | pa_volume_t vol = pa_cvolume_max (&source->volume); | ||
1003 | 163 | gdouble update = ((gdouble) vol * 100) / PA_VOLUME_NORM; | ||
1004 | 164 | |||
1005 | 165 | GVariant* new_volume = g_variant_new_double(update); | ||
1006 | 166 | dbusmenu_menuitem_property_set_variant(DBUSMENU_MENUITEM(item), | ||
1007 | 167 | DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, | ||
1008 | 168 | new_volume); | ||
1009 | 169 | // Only send over the mute updates if the state has changed. | ||
1010 | 170 | // in this order - volume first mute last!! | ||
1011 | 171 | if (priv->mute != source->mute){ | ||
1012 | 172 | g_debug ("voip menu item - update - mute = %i", priv->mute); | ||
1013 | 173 | GVariant* new_mute_update = g_variant_new_int32 (source->mute); | ||
1014 | 174 | dbusmenu_menuitem_property_set_variant (DBUSMENU_MENUITEM(item), | ||
1015 | 175 | DBUSMENU_VOIP_INPUT_MENUITEM_MUTE, | ||
1016 | 176 | new_mute_update); | ||
1017 | 177 | } | ||
1018 | 178 | |||
1019 | 179 | priv->mute = source->mute; | ||
1020 | 180 | |||
1021 | 181 | } | ||
1022 | 182 | |||
1023 | 183 | gboolean | ||
1024 | 184 | voip_input_menu_item_is_interested (VoipInputMenuItem* item, | ||
1025 | 185 | gint sink_input_index, | ||
1026 | 186 | gint client_index) | ||
1027 | 187 | { | ||
1028 | 188 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
1029 | 189 | // Check to make sure we are not handling another voip beforehand and that we | ||
1030 | 190 | // have an active sink (might need to match up at start up) | ||
1031 | 191 | if (priv->sink_input_index != NOT_ACTIVE && | ||
1032 | 192 | priv->source_index != NOT_ACTIVE){ | ||
1033 | 193 | return FALSE; | ||
1034 | 194 | } | ||
1035 | 195 | |||
1036 | 196 | priv->sink_input_index = sink_input_index; | ||
1037 | 197 | priv->client_index = client_index; | ||
1038 | 198 | |||
1039 | 199 | return TRUE; | ||
1040 | 200 | } | ||
1041 | 201 | |||
1042 | 202 | gboolean | ||
1043 | 203 | voip_input_menu_item_is_active (VoipInputMenuItem* item) | ||
1044 | 204 | { | ||
1045 | 205 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
1046 | 206 | return (priv->sink_input_index != NOT_ACTIVE && priv->client_index != NOT_ACTIVE); | ||
1047 | 207 | } | ||
1048 | 208 | |||
1049 | 209 | |||
1050 | 210 | gboolean | ||
1051 | 211 | voip_input_menu_item_is_populated (VoipInputMenuItem* item) | ||
1052 | 212 | { | ||
1053 | 213 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
1054 | 214 | return priv->source_index != NOT_ACTIVE; | ||
1055 | 215 | } | ||
1056 | 216 | |||
1057 | 217 | gint | ||
1058 | 218 | voip_input_menu_item_get_index (VoipInputMenuItem* item) | ||
1059 | 219 | { | ||
1060 | 220 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
1061 | 221 | return priv->source_index; | ||
1062 | 222 | } | ||
1063 | 223 | |||
1064 | 224 | gint | ||
1065 | 225 | voip_input_menu_item_get_sink_input_index (VoipInputMenuItem* item) | ||
1066 | 226 | { | ||
1067 | 227 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
1068 | 228 | |||
1069 | 229 | return priv->sink_input_index; | ||
1070 | 230 | } | ||
1071 | 231 | |||
1072 | 232 | /** | ||
1073 | 233 | * If the pulse server informs of a default source change | ||
1074 | 234 | * or the source in question is removed. | ||
1075 | 235 | * @param item | ||
1076 | 236 | */ | ||
1077 | 237 | void | ||
1078 | 238 | voip_input_menu_item_deactivate_source (VoipInputMenuItem* item, gboolean visible) | ||
1079 | 239 | { | ||
1080 | 240 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
1081 | 241 | priv->source_index = NOT_ACTIVE; | ||
1082 | 242 | dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item), | ||
1083 | 243 | DBUSMENU_MENUITEM_PROP_VISIBLE, | ||
1084 | 244 | visible ); | ||
1085 | 245 | } | ||
1086 | 246 | |||
1087 | 247 | void | ||
1088 | 248 | voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item) | ||
1089 | 249 | { | ||
1090 | 250 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
1091 | 251 | priv->client_index = NOT_ACTIVE; | ||
1092 | 252 | priv->sink_input_index = NOT_ACTIVE; | ||
1093 | 253 | voip_input_menu_item_enable (item, FALSE); | ||
1094 | 254 | } | ||
1095 | 255 | |||
1096 | 256 | void | ||
1097 | 257 | voip_input_menu_item_enable (VoipInputMenuItem* item, | ||
1098 | 258 | gboolean active) | ||
1099 | 259 | { | ||
1100 | 260 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (item); | ||
1101 | 261 | if (priv->source_index == NOT_ACTIVE && active == TRUE) { | ||
1102 | 262 | g_warning ("Tried to enable the VOIP menuitem but we don't have an active source ??"); | ||
1103 | 263 | active = FALSE; | ||
1104 | 264 | } | ||
1105 | 265 | dbusmenu_menuitem_property_set_bool( DBUSMENU_MENUITEM(item), | ||
1106 | 266 | DBUSMENU_MENUITEM_PROP_VISIBLE, | ||
1107 | 267 | active ); | ||
1108 | 268 | } | ||
1109 | 269 | |||
1110 | 270 | VoipInputMenuItem* | ||
1111 | 271 | voip_input_menu_item_new (ActiveSink* sink) | ||
1112 | 272 | { | ||
1113 | 273 | VoipInputMenuItem *self = g_object_new(VOIP_INPUT_MENU_ITEM_TYPE, NULL); | ||
1114 | 274 | VoipInputMenuItemPrivate* priv = VOIP_INPUT_MENU_ITEM_GET_PRIVATE (self); | ||
1115 | 275 | priv->a_sink = sink; | ||
1116 | 276 | return self; | ||
1117 | 277 | } | ||
1118 | 0 | \ No newline at end of file | 278 | \ No newline at end of file |
1119 | 1 | 279 | ||
1120 | === added file 'src/voip-input-menu-item.h' | |||
1121 | --- src/voip-input-menu-item.h 1970-01-01 00:00:00 +0000 | |||
1122 | +++ src/voip-input-menu-item.h 2011-02-18 17:27:12 +0000 | |||
1123 | @@ -0,0 +1,70 @@ | |||
1124 | 1 | /* | ||
1125 | 2 | Copyright 2011 Canonical Ltd. | ||
1126 | 3 | |||
1127 | 4 | Authors: | ||
1128 | 5 | Conor Curran <conor.curran@canonical.com> | ||
1129 | 6 | |||
1130 | 7 | This program is free software: you can redistribute it and/or modify it | ||
1131 | 8 | under the terms of the GNU General Public License version 3, as published | ||
1132 | 9 | by the Free Software Foundation. | ||
1133 | 10 | |||
1134 | 11 | This program is distributed in the hope that it will be useful, but | ||
1135 | 12 | WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1136 | 13 | MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1137 | 14 | PURPOSE. See the GNU General Public License for more details. | ||
1138 | 15 | |||
1139 | 16 | You should have received a copy of the GNU General Public License along | ||
1140 | 17 | with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1141 | 18 | */ | ||
1142 | 19 | #ifndef __VOIP_INPUT_MENU_ITEM_H__ | ||
1143 | 20 | #define __VOIP_INPUT_MENU_ITEM_H__ | ||
1144 | 21 | |||
1145 | 22 | #include <glib.h> | ||
1146 | 23 | #include <pulse/pulseaudio.h> | ||
1147 | 24 | #include <libdbusmenu-glib/menuitem.h> | ||
1148 | 25 | #include "active-sink.h" | ||
1149 | 26 | |||
1150 | 27 | G_BEGIN_DECLS | ||
1151 | 28 | |||
1152 | 29 | #define VOIP_INPUT_MENU_ITEM_TYPE (voip_input_menu_item_get_type ()) | ||
1153 | 30 | #define VOIP_INPUT_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItem)) | ||
1154 | 31 | #define VOIP_INPUT_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemClass)) | ||
1155 | 32 | #define IS_VOIP_INPUT_MENU_ITEM(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOIP_INPUT_MENU_ITEM_TYPE)) | ||
1156 | 33 | #define IS_VOIP_INPUT_MENU_ITEM_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOIP_INPUT_MENU_ITEM_TYPE)) | ||
1157 | 34 | #define VOIP_INPUT_MENU_ITEM_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOIP_INPUT_MENU_ITEM_TYPE, VoipInputMenuItemClass)) | ||
1158 | 35 | |||
1159 | 36 | typedef struct _VoipInputMenuItem VoipInputMenuItem; | ||
1160 | 37 | typedef struct _VoipInputMenuItemClass VoipInputMenuItemClass; | ||
1161 | 38 | |||
1162 | 39 | struct _VoipInputMenuItemClass { | ||
1163 | 40 | DbusmenuMenuitemClass parent_class; | ||
1164 | 41 | }; | ||
1165 | 42 | |||
1166 | 43 | struct _VoipInputMenuItem { | ||
1167 | 44 | DbusmenuMenuitem parent; | ||
1168 | 45 | }; | ||
1169 | 46 | |||
1170 | 47 | GType voip_input_menu_item_get_type (void); | ||
1171 | 48 | |||
1172 | 49 | void voip_input_menu_item_update (VoipInputMenuItem* item, | ||
1173 | 50 | const pa_source_info* source); | ||
1174 | 51 | void voip_input_menu_item_enable (VoipInputMenuItem* item, gboolean active); | ||
1175 | 52 | gboolean voip_input_menu_item_is_interested (VoipInputMenuItem* item, | ||
1176 | 53 | gint sink_input_index, | ||
1177 | 54 | gint client_index); | ||
1178 | 55 | gboolean voip_input_menu_item_is_active (VoipInputMenuItem* item); | ||
1179 | 56 | gboolean voip_input_menu_item_is_populated (VoipInputMenuItem* item); | ||
1180 | 57 | // TODO rename get source index | ||
1181 | 58 | gint voip_input_menu_item_get_index (VoipInputMenuItem* item); | ||
1182 | 59 | |||
1183 | 60 | gint voip_input_menu_item_get_sink_input_index (VoipInputMenuItem* item); | ||
1184 | 61 | |||
1185 | 62 | void voip_input_menu_item_deactivate_source (VoipInputMenuItem* item, gboolean visible); | ||
1186 | 63 | void voip_input_menu_item_deactivate_voip_client (VoipInputMenuItem* item); | ||
1187 | 64 | |||
1188 | 65 | VoipInputMenuItem* voip_input_menu_item_new (ActiveSink* sink); | ||
1189 | 66 | |||
1190 | 67 | G_END_DECLS | ||
1191 | 68 | |||
1192 | 69 | #endif | ||
1193 | 70 | |||
1194 | 0 | 71 | ||
1195 | === added file 'src/voip-input-widget.c' | |||
1196 | --- src/voip-input-widget.c 1970-01-01 00:00:00 +0000 | |||
1197 | +++ src/voip-input-widget.c 2011-02-18 17:27:12 +0000 | |||
1198 | @@ -0,0 +1,279 @@ | |||
1199 | 1 | |||
1200 | 2 | /* | ||
1201 | 3 | Copyright 2011 Canonical Ltd. | ||
1202 | 4 | |||
1203 | 5 | Authors: | ||
1204 | 6 | Conor Curran <conor.curran@canonical.com> | ||
1205 | 7 | |||
1206 | 8 | This program is free software: you can redistribute it and/or modify it | ||
1207 | 9 | under the terms of the GNU General Public License version 3, as published | ||
1208 | 10 | by the Free Software Foundation. | ||
1209 | 11 | |||
1210 | 12 | This program is distributed in the hope that it will be useful, but | ||
1211 | 13 | WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1212 | 14 | MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1213 | 15 | PURPOSE. See the GNU General Public License for more details. | ||
1214 | 16 | |||
1215 | 17 | You should have received a copy of the GNU General Public License along | ||
1216 | 18 | with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1217 | 19 | */ | ||
1218 | 20 | |||
1219 | 21 | #ifdef HAVE_CONFIG_H | ||
1220 | 22 | #include "config.h" | ||
1221 | 23 | #endif | ||
1222 | 24 | |||
1223 | 25 | #include <glib/gi18n.h> | ||
1224 | 26 | #include <math.h> | ||
1225 | 27 | #include <glib.h> | ||
1226 | 28 | #include "voip-input-widget.h" | ||
1227 | 29 | #include "common-defs.h" | ||
1228 | 30 | #include <libido/idoscalemenuitem.h> | ||
1229 | 31 | |||
1230 | 32 | typedef struct _VoipInputWidgetPrivate VoipInputWidgetPrivate; | ||
1231 | 33 | |||
1232 | 34 | struct _VoipInputWidgetPrivate | ||
1233 | 35 | { | ||
1234 | 36 | DbusmenuMenuitem* twin_item; | ||
1235 | 37 | GtkWidget* ido_voip_input_slider; | ||
1236 | 38 | gboolean grabbed; | ||
1237 | 39 | }; | ||
1238 | 40 | |||
1239 | 41 | #define VOIP_INPUT_WIDGET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetPrivate)) | ||
1240 | 42 | |||
1241 | 43 | /* Prototypes */ | ||
1242 | 44 | static void voip_input_widget_class_init (VoipInputWidgetClass *klass); | ||
1243 | 45 | static void voip_input_widget_init (VoipInputWidget *self); | ||
1244 | 46 | static void voip_input_widget_dispose (GObject *object); | ||
1245 | 47 | static void voip_input_widget_finalize (GObject *object); | ||
1246 | 48 | static void voip_input_widget_set_twin_item( VoipInputWidget* self, | ||
1247 | 49 | DbusmenuMenuitem* twin_item); | ||
1248 | 50 | static void voip_input_widget_property_update( DbusmenuMenuitem* item, gchar* property, | ||
1249 | 51 | GVariant* value, gpointer userdata ); | ||
1250 | 52 | |||
1251 | 53 | static gboolean voip_input_widget_change_value_cb (GtkRange *range, | ||
1252 | 54 | GtkScrollType scroll, | ||
1253 | 55 | gdouble value, | ||
1254 | 56 | gpointer user_data); | ||
1255 | 57 | static gboolean voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data); | ||
1256 | 58 | static void voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data); | ||
1257 | 59 | static void voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data); | ||
1258 | 60 | static void voip_input_widget_parent_changed (GtkWidget *widget, gpointer user_data); | ||
1259 | 61 | |||
1260 | 62 | G_DEFINE_TYPE (VoipInputWidget, voip_input_widget, G_TYPE_OBJECT); | ||
1261 | 63 | |||
1262 | 64 | |||
1263 | 65 | static void | ||
1264 | 66 | voip_input_widget_class_init (VoipInputWidgetClass *klass) | ||
1265 | 67 | { | ||
1266 | 68 | GObjectClass *gobject_class = G_OBJECT_CLASS (klass); | ||
1267 | 69 | |||
1268 | 70 | g_type_class_add_private (klass, sizeof (VoipInputWidgetPrivate)); | ||
1269 | 71 | |||
1270 | 72 | gobject_class->dispose = voip_input_widget_dispose; | ||
1271 | 73 | gobject_class->finalize = voip_input_widget_finalize; | ||
1272 | 74 | } | ||
1273 | 75 | |||
1274 | 76 | static void | ||
1275 | 77 | voip_input_widget_init (VoipInputWidget *self) | ||
1276 | 78 | { | ||
1277 | 79 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); | ||
1278 | 80 | |||
1279 | 81 | priv->ido_voip_input_slider = ido_scale_menu_item_new_with_range ("VOLUME", IDO_RANGE_STYLE_DEFAULT, 0, 0, 100, 1); | ||
1280 | 82 | g_object_ref (priv->ido_voip_input_slider); | ||
1281 | 83 | ido_scale_menu_item_set_style (IDO_SCALE_MENU_ITEM (priv->ido_voip_input_slider), IDO_SCALE_MENU_ITEM_STYLE_IMAGE); | ||
1282 | 84 | g_object_set(priv->ido_voip_input_slider, "reverse-scroll-events", TRUE, NULL); | ||
1283 | 85 | |||
1284 | 86 | g_signal_connect (priv->ido_voip_input_slider, | ||
1285 | 87 | "notify::parent", G_CALLBACK (voip_input_widget_parent_changed), | ||
1286 | 88 | NULL); | ||
1287 | 89 | |||
1288 | 90 | GtkWidget* voip_input_widget = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); | ||
1289 | 91 | |||
1290 | 92 | g_signal_connect(voip_input_widget, "change-value", G_CALLBACK(voip_input_widget_change_value_cb), self); | ||
1291 | 93 | g_signal_connect(voip_input_widget, "value-changed", G_CALLBACK(voip_input_widget_value_changed_cb), self); | ||
1292 | 94 | g_signal_connect(priv->ido_voip_input_slider, "slider-grabbed", G_CALLBACK(voip_input_widget_slider_grabbed), self); | ||
1293 | 95 | g_signal_connect(priv->ido_voip_input_slider, "slider-released", G_CALLBACK(voip_input_widget_slider_released), self); | ||
1294 | 96 | |||
1295 | 97 | GtkWidget* primary_image = ido_scale_menu_item_get_primary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); | ||
1296 | 98 | GIcon * primary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone"); | ||
1297 | 99 | gtk_image_set_from_gicon(GTK_IMAGE(primary_image), primary_gicon, GTK_ICON_SIZE_MENU); | ||
1298 | 100 | g_object_unref(primary_gicon); | ||
1299 | 101 | |||
1300 | 102 | GtkWidget* secondary_image = ido_scale_menu_item_get_secondary_image((IdoScaleMenuItem*)priv->ido_voip_input_slider); | ||
1301 | 103 | GIcon * secondary_gicon = g_themed_icon_new_with_default_fallbacks("audio-input-microphone-high"); | ||
1302 | 104 | gtk_image_set_from_gicon(GTK_IMAGE(secondary_image), secondary_gicon, GTK_ICON_SIZE_MENU); | ||
1303 | 105 | g_object_unref(secondary_gicon); | ||
1304 | 106 | |||
1305 | 107 | GtkAdjustment *adj = gtk_range_get_adjustment (GTK_RANGE (voip_input_widget)); | ||
1306 | 108 | gtk_adjustment_set_step_increment(adj, 4); | ||
1307 | 109 | } | ||
1308 | 110 | |||
1309 | 111 | static void | ||
1310 | 112 | voip_input_widget_dispose (GObject *object) | ||
1311 | 113 | { | ||
1312 | 114 | G_OBJECT_CLASS (voip_input_widget_parent_class)->dispose (object); | ||
1313 | 115 | } | ||
1314 | 116 | |||
1315 | 117 | static void | ||
1316 | 118 | voip_input_widget_finalize (GObject *object) | ||
1317 | 119 | { | ||
1318 | 120 | G_OBJECT_CLASS (voip_input_widget_parent_class)->finalize (object); | ||
1319 | 121 | } | ||
1320 | 122 | |||
1321 | 123 | static void | ||
1322 | 124 | voip_input_widget_property_update (DbusmenuMenuitem* item, gchar* property, | ||
1323 | 125 | GVariant* value, gpointer userdata) | ||
1324 | 126 | { | ||
1325 | 127 | g_return_if_fail (IS_VOIP_INPUT_WIDGET (userdata)); | ||
1326 | 128 | VoipInputWidget* mitem = VOIP_INPUT_WIDGET(userdata); | ||
1327 | 129 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); | ||
1328 | 130 | //g_debug("scrub-widget::property_update for prop %s", property); | ||
1329 | 131 | if(g_ascii_strcasecmp(DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL, property) == 0){ | ||
1330 | 132 | if(priv->grabbed == FALSE){ | ||
1331 | 133 | GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); | ||
1332 | 134 | GtkRange *range = (GtkRange*)slider; | ||
1333 | 135 | gdouble update = g_variant_get_double (value); | ||
1334 | 136 | //g_debug("volume-widget - update level with value %f", update); | ||
1335 | 137 | gtk_range_set_value(range, update); | ||
1336 | 138 | } | ||
1337 | 139 | } | ||
1338 | 140 | if(g_ascii_strcasecmp(DBUSMENU_VOIP_INPUT_MENUITEM_MUTE, property) == 0){ | ||
1339 | 141 | if(priv->grabbed == FALSE){ | ||
1340 | 142 | GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); | ||
1341 | 143 | GtkRange *range = (GtkRange*)slider; | ||
1342 | 144 | gint update = g_variant_get_int32 (value); | ||
1343 | 145 | gdouble level; | ||
1344 | 146 | if (update == 1){ | ||
1345 | 147 | level = 0; | ||
1346 | 148 | } | ||
1347 | 149 | else{ | ||
1348 | 150 | level = g_variant_get_double (dbusmenu_menuitem_property_get_variant (priv->twin_item, | ||
1349 | 151 | DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL)); | ||
1350 | 152 | } | ||
1351 | 153 | gtk_range_set_value(range, level); | ||
1352 | 154 | |||
1353 | 155 | g_debug ("voip-item-widget - update mute with value %i", update); | ||
1354 | 156 | } | ||
1355 | 157 | } | ||
1356 | 158 | } | ||
1357 | 159 | |||
1358 | 160 | static void | ||
1359 | 161 | voip_input_widget_set_twin_item (VoipInputWidget* self, | ||
1360 | 162 | DbusmenuMenuitem* twin_item) | ||
1361 | 163 | { | ||
1362 | 164 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); | ||
1363 | 165 | priv->twin_item = twin_item; | ||
1364 | 166 | g_object_ref(priv->twin_item); | ||
1365 | 167 | g_signal_connect(G_OBJECT(twin_item), "property-changed", | ||
1366 | 168 | G_CALLBACK(voip_input_widget_property_update), self); | ||
1367 | 169 | gdouble initial_level = g_variant_get_double (dbusmenu_menuitem_property_get_variant(twin_item, | ||
1368 | 170 | DBUSMENU_VOIP_INPUT_MENUITEM_LEVEL)); | ||
1369 | 171 | //g_debug("voip_input_widget_set_twin_item initial level = %f", initial_level); | ||
1370 | 172 | GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); | ||
1371 | 173 | GtkRange *range = (GtkRange*)slider; | ||
1372 | 174 | gtk_range_set_value(range, initial_level); | ||
1373 | 175 | |||
1374 | 176 | gint mute = g_variant_get_int32 (dbusmenu_menuitem_property_get_variant (priv->twin_item, | ||
1375 | 177 | DBUSMENU_VOIP_INPUT_MENUITEM_MUTE)); | ||
1376 | 178 | if (mute == 1){ | ||
1377 | 179 | gtk_range_set_value (range, 0.0); | ||
1378 | 180 | } | ||
1379 | 181 | } | ||
1380 | 182 | |||
1381 | 183 | static gboolean | ||
1382 | 184 | voip_input_widget_change_value_cb (GtkRange *range, | ||
1383 | 185 | GtkScrollType scroll, | ||
1384 | 186 | gdouble new_value, | ||
1385 | 187 | gpointer user_data) | ||
1386 | 188 | { | ||
1387 | 189 | g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); | ||
1388 | 190 | VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); | ||
1389 | 191 | voip_input_widget_update(mitem, new_value); | ||
1390 | 192 | return FALSE; | ||
1391 | 193 | } | ||
1392 | 194 | |||
1393 | 195 | |||
1394 | 196 | /** | ||
1395 | 197 | * We only want this callback to catch mouse icon press events which set the | ||
1396 | 198 | * slider to 0 or 100. Ignore all other events including the new Mute behaviour | ||
1397 | 199 | * (slider to go to 0 on mute without setting the level to 0 and return to | ||
1398 | 200 | * previous level on unmute) | ||
1399 | 201 | **/ | ||
1400 | 202 | static gboolean | ||
1401 | 203 | voip_input_widget_value_changed_cb(GtkRange *range, gpointer user_data) | ||
1402 | 204 | { | ||
1403 | 205 | g_return_val_if_fail (IS_VOIP_INPUT_WIDGET (user_data), FALSE); | ||
1404 | 206 | VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); | ||
1405 | 207 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); | ||
1406 | 208 | GtkWidget *slider = ido_scale_menu_item_get_scale((IdoScaleMenuItem*)priv->ido_voip_input_slider); | ||
1407 | 209 | gdouble current_value = CLAMP(gtk_range_get_value(GTK_RANGE(slider)), 0, 100); | ||
1408 | 210 | |||
1409 | 211 | gint mute = g_variant_get_int32 (dbusmenu_menuitem_property_get_variant (priv->twin_item, | ||
1410 | 212 | DBUSMENU_VOIP_INPUT_MENUITEM_MUTE)); | ||
1411 | 213 | if ((current_value == 0 && mute != 1) || current_value == 100 ){ | ||
1412 | 214 | voip_input_widget_update(mitem, current_value); | ||
1413 | 215 | } | ||
1414 | 216 | return FALSE; | ||
1415 | 217 | } | ||
1416 | 218 | |||
1417 | 219 | void | ||
1418 | 220 | voip_input_widget_update(VoipInputWidget* self, gdouble update) | ||
1419 | 221 | { | ||
1420 | 222 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); | ||
1421 | 223 | gdouble clamped = CLAMP(update, 0, 100); | ||
1422 | 224 | GVariant* new_volume = g_variant_new_double(clamped); | ||
1423 | 225 | dbusmenu_menuitem_handle_event (priv->twin_item, "update", new_volume, 0); | ||
1424 | 226 | } | ||
1425 | 227 | |||
1426 | 228 | GtkWidget* | ||
1427 | 229 | voip_input_widget_get_ido_slider(VoipInputWidget* self) | ||
1428 | 230 | { | ||
1429 | 231 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(self); | ||
1430 | 232 | return priv->ido_voip_input_slider; | ||
1431 | 233 | } | ||
1432 | 234 | |||
1433 | 235 | static void | ||
1434 | 236 | voip_input_widget_parent_changed (GtkWidget *widget, | ||
1435 | 237 | gpointer user_data) | ||
1436 | 238 | { | ||
1437 | 239 | gtk_widget_set_size_request (widget, 200, -1); | ||
1438 | 240 | //g_debug("voip_input_widget_parent_changed"); | ||
1439 | 241 | } | ||
1440 | 242 | |||
1441 | 243 | static void | ||
1442 | 244 | voip_input_widget_slider_grabbed(GtkWidget *widget, gpointer user_data) | ||
1443 | 245 | { | ||
1444 | 246 | VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); | ||
1445 | 247 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); | ||
1446 | 248 | priv->grabbed = TRUE; | ||
1447 | 249 | } | ||
1448 | 250 | |||
1449 | 251 | static void | ||
1450 | 252 | voip_input_widget_slider_released(GtkWidget *widget, gpointer user_data) | ||
1451 | 253 | { | ||
1452 | 254 | VoipInputWidget* mitem = VOIP_INPUT_WIDGET(user_data); | ||
1453 | 255 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); | ||
1454 | 256 | priv->grabbed = FALSE; | ||
1455 | 257 | } | ||
1456 | 258 | |||
1457 | 259 | void | ||
1458 | 260 | voip_input_widget_tidy_up (GtkWidget *widget) | ||
1459 | 261 | { | ||
1460 | 262 | VoipInputWidget* mitem = VOIP_INPUT_WIDGET(widget); | ||
1461 | 263 | VoipInputWidgetPrivate * priv = VOIP_INPUT_WIDGET_GET_PRIVATE(mitem); | ||
1462 | 264 | gtk_widget_destroy (priv->ido_voip_input_slider); | ||
1463 | 265 | } | ||
1464 | 266 | |||
1465 | 267 | /** | ||
1466 | 268 | * voip_input_widget_new: | ||
1467 | 269 | * @returns: a new #VoipInputWidget. | ||
1468 | 270 | **/ | ||
1469 | 271 | GtkWidget* | ||
1470 | 272 | voip_input_widget_new(DbusmenuMenuitem *item) | ||
1471 | 273 | { | ||
1472 | 274 | GtkWidget* widget = g_object_new(VOIP_INPUT_WIDGET_TYPE, NULL); | ||
1473 | 275 | voip_input_widget_set_twin_item((VoipInputWidget*)widget, item); | ||
1474 | 276 | return widget; | ||
1475 | 277 | } | ||
1476 | 278 | |||
1477 | 279 | |||
1478 | 0 | 280 | ||
1479 | === added file 'src/voip-input-widget.h' | |||
1480 | --- src/voip-input-widget.h 1970-01-01 00:00:00 +0000 | |||
1481 | +++ src/voip-input-widget.h 2011-02-18 17:27:12 +0000 | |||
1482 | @@ -0,0 +1,55 @@ | |||
1483 | 1 | /* | ||
1484 | 2 | Copyright 2011 Canonical Ltd. | ||
1485 | 3 | |||
1486 | 4 | Authors: | ||
1487 | 5 | Conor Curran <conor.curran@canonical.com> | ||
1488 | 6 | |||
1489 | 7 | This program is free software: you can redistribute it and/or modify it | ||
1490 | 8 | under the terms of the GNU General Public License version 3, as published | ||
1491 | 9 | by the Free Software Foundation. | ||
1492 | 10 | |||
1493 | 11 | This program is distributed in the hope that it will be useful, but | ||
1494 | 12 | WITHOUT ANY WARRANTY; without even the implied warranties of | ||
1495 | 13 | MERCHANTABILITY, SATISFACTORY QUALITY, or FITNESS FOR A PARTICULAR | ||
1496 | 14 | PURPOSE. See the GNU General Public License for more details. | ||
1497 | 15 | |||
1498 | 16 | You should have received a copy of the GNU General Public License along | ||
1499 | 17 | with this program. If not, see <http://www.gnu.org/licenses/>. | ||
1500 | 18 | */ | ||
1501 | 19 | #ifndef __VOIP_INPUT_WIDGET_H__ | ||
1502 | 20 | #define __VOIP_INPUT_WIDGET_H__ | ||
1503 | 21 | |||
1504 | 22 | #include <glib.h> | ||
1505 | 23 | #include <glib-object.h> | ||
1506 | 24 | #include <libdbusmenu-gtk/menuitem.h> | ||
1507 | 25 | |||
1508 | 26 | G_BEGIN_DECLS | ||
1509 | 27 | |||
1510 | 28 | #define VOIP_INPUT_WIDGET_TYPE (voip_input_widget_get_type ()) | ||
1511 | 29 | #define VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidget)) | ||
1512 | 30 | #define VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass)) | ||
1513 | 31 | #define IS_VOIP_INPUT_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VOIP_INPUT_WIDGET_TYPE)) | ||
1514 | 32 | #define IS_VOIP_INPUT_WIDGET_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VOIP_INPUT_WIDGET_TYPE)) | ||
1515 | 33 | #define VOIP_INPUT_WIDGET_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), VOIP_INPUT_WIDGET_TYPE, VoipInputWidgetClass)) | ||
1516 | 34 | |||
1517 | 35 | typedef struct _VoipInputWidget VoipInputWidget; | ||
1518 | 36 | typedef struct _VoipInputWidgetClass VoipInputWidgetClass; | ||
1519 | 37 | |||
1520 | 38 | struct _VoipInputWidgetClass { | ||
1521 | 39 | GObjectClass parent_class; | ||
1522 | 40 | }; | ||
1523 | 41 | |||
1524 | 42 | struct _VoipInputWidget { | ||
1525 | 43 | GObject parent; | ||
1526 | 44 | }; | ||
1527 | 45 | |||
1528 | 46 | GType voip_input_widget_get_type (void) G_GNUC_CONST; | ||
1529 | 47 | GtkWidget* voip_input_widget_new(DbusmenuMenuitem* twin_item); | ||
1530 | 48 | GtkWidget* voip_input_widget_get_ido_slider(VoipInputWidget* self); | ||
1531 | 49 | void voip_input_widget_update(VoipInputWidget* self, gdouble update); | ||
1532 | 50 | void voip_input_widget_tidy_up (GtkWidget *widget); | ||
1533 | 51 | |||
1534 | 52 | G_END_DECLS | ||
1535 | 53 | |||
1536 | 54 | #endif | ||
1537 | 55 |
Don't see anything odd. Looks good.