Line
Link Here
|
0 |
-- a/configure.ac |
0 |
++ b/configure.ac |
Lines 260-265
Link Here
|
260 |
AC_SUBST(PULSE_CFLAGS) |
260 |
AC_SUBST(PULSE_CFLAGS) |
261 |
AC_SUBST(PULSE_LIBS) |
261 |
AC_SUBST(PULSE_LIBS) |
262 |
|
262 |
|
|
|
263 |
dnl ============================================== |
264 |
dnl GStreamer section |
265 |
dnl ============================================== |
266 |
GST_MAJORMINOR=auto |
267 |
|
268 |
AC_ARG_ENABLE(gstreamer, |
269 |
AC_HELP_STRING([--enable-gstreamer],[use gstreamer if available (and optionally specify a version)]), |
270 |
[case "${enableval}" in |
271 |
yes) ENABLE_GSTREAMER=yes ;; |
272 |
0.10) ENABLE_GSTREAMER=yes && GST_MAJORMINOR=0.10 ;; |
273 |
no) ENABLE_GSTREAMER=no ;; |
274 |
*) AC_MSG_ERROR([ |
275 |
*** Bad value ${enableval} for --enable-gstreamer |
276 |
*** Please use one of the following: |
277 |
*** --enable-gstreamer=0.10 |
278 |
]) ;; |
279 |
esac], |
280 |
[ENABLE_GSTREAMER=yes]) dnl Default value |
281 |
|
282 |
have_gstreamer=no |
283 |
if test "x$ENABLE_GSTREAMER" = "xyes"; then |
284 |
GST_REQS=0.10.1.2 |
285 |
PKGS="gstreamer-0.10 >= $GST_REQS gstreamer-plugins-base-0.10 >= $GST_REQS" |
286 |
|
287 |
PKG_CHECK_MODULES(GST, $PKGS, have_gstreamer=yes, |
288 |
AC_MSG_RESULT([no])) |
289 |
|
290 |
if test "x$have_pulse" = "xtrue"; then |
291 |
AC_MSG_ERROR([*** GStreamer & Pulseaudio both are selected ***]) |
292 |
fi |
293 |
|
294 |
if test "x$have_gstreamer" = "xyes"; then |
295 |
GST_LIBS="$GST_LIBS -lgstinterfaces-0.10 -lgstaudio-0.10" |
296 |
AC_DEFINE(HAVE_GSTREAMER,1,[enable gstreamer]) |
297 |
fi |
298 |
else |
299 |
AC_MSG_NOTICE([*** GStreamer support disabled ***]) |
300 |
fi |
301 |
AM_CONDITIONAL(HAVE_GSTREAMER, test "x$have_gstreamer" = "xyes") |
302 |
AC_SUBST(GST_LIBS) |
303 |
AC_SUBST(GST_CFLAGS) |
304 |
|
263 |
# --------------------------------------------------------------------------- |
305 |
# --------------------------------------------------------------------------- |
264 |
# Enable Profiling |
306 |
# Enable Profiling |
265 |
# --------------------------------------------------------------------------- |
307 |
# --------------------------------------------------------------------------- |
Lines 398-403
Link Here
|
398 |
dbus-1 system.d dir: ${DBUS_SYS_DIR} |
440 |
dbus-1 system.d dir: ${DBUS_SYS_DIR} |
399 |
|
441 |
|
400 |
Libnotify support: ${have_libnotify} |
442 |
Libnotify support: ${have_libnotify} |
|
|
443 |
GStreamer support: ${have_gstreamer} |
401 |
PulseAudio support: ${have_pulse} |
444 |
PulseAudio support: ${have_pulse} |
402 |
Profiling support: ${enable_profiling} |
445 |
Profiling support: ${enable_profiling} |
403 |
" |
446 |
" |
404 |
-- a/plugins/media-keys/Makefile.am |
447 |
++ b/plugins/media-keys/Makefile.am |
Lines 1-12
Link Here
|
1 |
NULL = |
1 |
NULL = |
2 |
|
2 |
|
3 |
SUBDIRS = |
3 |
SUBDIRS = cut-n-paste |
4 |
plugin_LTLIBRARIES = |
4 |
plugin_LTLIBRARIES = libmedia-keys.la |
5 |
|
|
|
6 |
if HAVE_PULSE |
7 |
SUBDIRS += cut-n-paste |
8 |
plugin_LTLIBRARIES += libmedia-keys.la |
9 |
endif |
10 |
|
5 |
|
11 |
BUILT_SOURCES = \ |
6 |
BUILT_SOURCES = \ |
12 |
gsd-media-keys-manager-glue.h \ |
7 |
gsd-media-keys-manager-glue.h \ |
Lines 54-69
Link Here
|
54 |
|
49 |
|
55 |
libmedia_keys_la_LIBADD = \ |
50 |
libmedia_keys_la_LIBADD = \ |
56 |
$(top_builddir)/plugins/common/libcommon.la \ |
51 |
$(top_builddir)/plugins/common/libcommon.la \ |
57 |
$(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la \ |
52 |
$(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la \ |
58 |
$(SETTINGS_PLUGIN_LIBS) \ |
53 |
$(SETTINGS_PLUGIN_LIBS) \ |
59 |
$(XF86MISC_LIBS) |
54 |
$(XF86MISC_LIBS) |
60 |
|
55 |
|
61 |
plugin_in_files = \ |
56 |
plugin_in_files = \ |
62 |
media-keys.gnome-settings-plugin.in |
57 |
media-keys.gnome-settings-plugin.in |
63 |
|
58 |
|
64 |
if HAVE_PULSE |
|
|
65 |
plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin) |
59 |
plugin_DATA = $(plugin_in_files:.gnome-settings-plugin.in=.gnome-settings-plugin) |
66 |
endif |
|
|
67 |
|
60 |
|
68 |
noinst_PROGRAMS = \ |
61 |
noinst_PROGRAMS = \ |
69 |
test-media-keys \ |
62 |
test-media-keys \ |
Lines 124-132
Link Here
|
124 |
$(XF86MISC_LIBS) \ |
117 |
$(XF86MISC_LIBS) \ |
125 |
$(GST_LIBS) |
118 |
$(GST_LIBS) |
126 |
|
119 |
|
127 |
if HAVE_PULSE |
|
|
128 |
test_media_keys_LDADD += $(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la |
120 |
test_media_keys_LDADD += $(top_builddir)/plugins/media-keys/cut-n-paste/libgvc.la |
129 |
endif |
|
|
130 |
|
121 |
|
131 |
gtkbuilderdir = $(pkgdatadir) |
122 |
gtkbuilderdir = $(pkgdatadir) |
132 |
gtkbuilder_DATA = \ |
123 |
gtkbuilder_DATA = \ |
133 |
-- a/plugins/media-keys/cut-n-paste/Makefile.am |
124 |
++ b/plugins/media-keys/cut-n-paste/Makefile.am |
Lines 4-19
Link Here
|
4 |
|
4 |
|
5 |
INCLUDES = \ |
5 |
INCLUDES = \ |
6 |
$(WARN_CFLAGS) \ |
6 |
$(WARN_CFLAGS) \ |
7 |
$(VOLUME_CONTROL_CFLAGS) \ |
|
|
8 |
$(PULSE_CFLAGS) \ |
9 |
$(NULL) |
7 |
$(NULL) |
10 |
|
8 |
|
11 |
libgvc_la_LIBADD = \ |
9 |
libgvc_la_LIBADD = \ |
12 |
$(VOLUME_CONTROL_LIBS) \ |
|
|
13 |
$(PULSE_LIBS) \ |
14 |
$(NULL) |
10 |
$(NULL) |
15 |
|
11 |
|
16 |
libgvc_la_SOURCES = \ |
12 |
libgvc_la_SOURCES = \ |
|
|
13 |
$(NULL) |
14 |
|
15 |
if HAVE_PULSE |
16 |
INCLUDES += \ |
17 |
$(VOLUME_CONTROL_CFLAGS) \ |
18 |
$(PULSE_CFLAGS) |
19 |
|
20 |
libgvc_la_LIBADD += \ |
21 |
$(VOLUME_CONTROL_LIBS) \ |
22 |
$(PULSE_LIBS) |
23 |
|
24 |
libgvc_la_SOURCES += \ |
17 |
gvc-mixer-stream.h \ |
25 |
gvc-mixer-stream.h \ |
18 |
gvc-mixer-stream.c \ |
26 |
gvc-mixer-stream.c \ |
19 |
gvc-channel-map.h \ |
27 |
gvc-channel-map.h \ |
Lines 31-38
Link Here
|
31 |
gvc-mixer-event-role.h \ |
39 |
gvc-mixer-event-role.h \ |
32 |
gvc-mixer-event-role.c \ |
40 |
gvc-mixer-event-role.c \ |
33 |
gvc-mixer-control.h \ |
41 |
gvc-mixer-control.h \ |
34 |
gvc-mixer-control.c \ |
42 |
gvc-mixer-control.c |
35 |
$(NULL) |
43 |
endif |
|
|
44 |
|
45 |
if HAVE_GSTREAMER |
46 |
INCLUDES += \ |
47 |
$(SETTINGS_PLUGIN_CFLAGS) \ |
48 |
$(AM_CFLAGS) \ |
49 |
$(GST_CFLAGS) |
50 |
|
51 |
libgvc_la_LIBADD += \ |
52 |
$(GST_LIBS) |
53 |
|
54 |
libgvc_la_SOURCES += \ |
55 |
gvc-gstreamer-acme-vol.c \ |
56 |
gvc-gstreamer-acme-vol.h |
57 |
endif |
36 |
|
58 |
|
37 |
MAINTAINERCLEANFILES = \ |
59 |
MAINTAINERCLEANFILES = \ |
38 |
*~ \ |
60 |
*~ \ |
39 |
-- /dev/null |
61 |
++ b/plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.c |
Line 0
Link Here
|
0 |
-- /dev/null |
1 |
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ |
|
|
2 |
|
3 |
/* acme-volume.c |
4 |
|
5 |
Copyright (C) 2002, 2003 Bastien Nocera |
6 |
Copyright (C) 2004 Novell, Inc. |
7 |
Copyright (C) 2009 PERIER Romain <mrpouet@tuxfamily.org> |
8 |
|
9 |
The Gnome Library is free software; you can redistribute it and/or |
10 |
modify it under the terms of the GNU Library General Public License as |
11 |
published by the Free Software Foundation; either version 2 of the |
12 |
License, or (at your option) any later version. |
13 |
|
14 |
The Gnome Library is distributed in the hope that it will be useful, |
15 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
17 |
Library General Public License for more details. |
18 |
|
19 |
You should have received a copy of the GNU Library General Public |
20 |
License along with the Gnome Library; see the file COPYING.LIB. If not, |
21 |
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
22 |
Boston, MA 02111-1307, USA. |
23 |
|
24 |
Author: Bastien Nocera <hadess@hadess.net> |
25 |
Jon Trowbridge <trow@ximian.com> |
26 |
*/ |
27 |
|
28 |
#include "config.h" |
29 |
#include "gvc-gstreamer-acme-vol.h" |
30 |
|
31 |
#include <gst/gst.h> |
32 |
#include <gst/audio/mixerutils.h> |
33 |
#include <gst/interfaces/mixer.h> |
34 |
#include <gst/interfaces/propertyprobe.h> |
35 |
|
36 |
#include <gconf/gconf-client.h> |
37 |
|
38 |
#include <string.h> |
39 |
|
40 |
#define TIMEOUT 4 |
41 |
|
42 |
#define DEFAULT_MIXER_DEVICE_KEY "/desktop/gnome/sound/default_mixer_device" |
43 |
#define DEFAULT_MIXER_TRACKS_KEY "/desktop/gnome/sound/default_mixer_tracks" |
44 |
|
45 |
#define ACME_VOLUME_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), ACME_TYPE_VOLUME, AcmeVolumePrivate)) |
46 |
|
47 |
struct AcmeVolumePrivate { |
48 |
GstMixer *mixer; |
49 |
GList *mixer_tracks; |
50 |
guint timer_id; |
51 |
gdouble volume; |
52 |
gboolean mute; |
53 |
GConfClient *gconf_client; |
54 |
}; |
55 |
|
56 |
G_DEFINE_TYPE (AcmeVolume, acme_volume, G_TYPE_OBJECT) |
57 |
|
58 |
static gboolean acme_volume_open (AcmeVolume *acme); |
59 |
static void acme_volume_close (AcmeVolume *acme); |
60 |
static gboolean acme_volume_close_real (AcmeVolume *self); |
61 |
|
62 |
static gpointer acme_volume_object = NULL; |
63 |
|
64 |
static void |
65 |
acme_volume_finalize (GObject *object) |
66 |
{ |
67 |
AcmeVolume *self; |
68 |
|
69 |
g_return_if_fail (object != NULL); |
70 |
g_return_if_fail (ACME_IS_VOLUME (object)); |
71 |
|
72 |
self = ACME_VOLUME (object); |
73 |
|
74 |
if (self->_priv->timer_id != 0) |
75 |
g_source_remove (self->_priv->timer_id); |
76 |
acme_volume_close_real (self); |
77 |
|
78 |
if (self->_priv->gconf_client != NULL) { |
79 |
g_object_unref (self->_priv->gconf_client); |
80 |
self->_priv->gconf_client = NULL; |
81 |
} |
82 |
|
83 |
G_OBJECT_CLASS (acme_volume_parent_class)->finalize (object); |
84 |
} |
85 |
|
86 |
void |
87 |
acme_volume_set_mute (AcmeVolume *self, gboolean val) |
88 |
{ |
89 |
GList *t; |
90 |
|
91 |
g_return_if_fail(ACME_IS_VOLUME(self)); |
92 |
g_return_if_fail(acme_volume_open(self)); |
93 |
|
94 |
for (t = self->_priv->mixer_tracks; t != NULL; t = t->next) { |
95 |
GstMixerTrack *track = GST_MIXER_TRACK (t->data); |
96 |
gst_mixer_set_mute (self->_priv->mixer, track, val); |
97 |
} |
98 |
self->_priv->mute = val; |
99 |
acme_volume_close (self); |
100 |
} |
101 |
|
102 |
static void |
103 |
update_state (AcmeVolume * self) |
104 |
{ |
105 |
gint *volumes, n; |
106 |
gdouble vol = 0; |
107 |
GstMixerTrack *track = GST_MIXER_TRACK (self->_priv->mixer_tracks->data); |
108 |
|
109 |
/* update mixer by getting volume */ |
110 |
volumes = g_new0 (gint, track->num_channels); |
111 |
gst_mixer_get_volume (self->_priv->mixer, track, volumes); |
112 |
for (n = 0; n < track->num_channels; n++) |
113 |
vol += volumes[n]; |
114 |
g_free (volumes); |
115 |
vol /= track->num_channels; |
116 |
vol = 100 * vol / (track->max_volume - track->min_volume); |
117 |
|
118 |
/* update mute flag, and volume if not muted */ |
119 |
if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MUTE)) |
120 |
self->_priv->mute = TRUE; |
121 |
self->_priv->volume = vol; |
122 |
} |
123 |
|
124 |
gboolean |
125 |
acme_volume_get_mute (AcmeVolume *self) |
126 |
{ |
127 |
g_return_val_if_fail(acme_volume_open(self), FALSE); |
128 |
|
129 |
update_state (self); |
130 |
acme_volume_close (self); |
131 |
|
132 |
return self->_priv->mute; |
133 |
} |
134 |
|
135 |
gint |
136 |
acme_volume_get_volume (AcmeVolume *self) |
137 |
{ |
138 |
|
139 |
g_return_val_if_fail(acme_volume_open(self), 0); |
140 |
|
141 |
update_state (self); |
142 |
|
143 |
acme_volume_close (self); |
144 |
|
145 |
return (gint) (self->_priv->volume + 0.5); |
146 |
} |
147 |
|
148 |
void |
149 |
acme_volume_set_volume (AcmeVolume *self, gint val) |
150 |
{ |
151 |
GList *t; |
152 |
|
153 |
g_return_if_fail(acme_volume_open(self)); |
154 |
|
155 |
val = CLAMP (val, 0, 100); |
156 |
|
157 |
for (t = self->_priv->mixer_tracks; t != NULL; t = t->next) { |
158 |
GstMixerTrack *track = GST_MIXER_TRACK (t->data); |
159 |
gint *volumes, n; |
160 |
gdouble scale = (track->max_volume - track->min_volume) / 100.0; |
161 |
gint vol = (gint) (val * scale + track->min_volume + 0.5); |
162 |
|
163 |
volumes = g_new (gint, track->num_channels); |
164 |
for (n = 0; n < track->num_channels; n++) |
165 |
volumes[n] = vol; |
166 |
gst_mixer_set_volume (self->_priv->mixer, track, volumes); |
167 |
g_free (volumes); |
168 |
} |
169 |
|
170 |
/* update state */ |
171 |
self->_priv->volume = val; |
172 |
|
173 |
acme_volume_close (self); |
174 |
} |
175 |
|
176 |
void |
177 |
acme_volume_mute_toggle (AcmeVolume *self) |
178 |
{ |
179 |
gboolean muted; |
180 |
|
181 |
g_return_if_fail (self != NULL); |
182 |
g_return_if_fail (ACME_IS_VOLUME(self)); |
183 |
|
184 |
muted = acme_volume_get_mute(self); |
185 |
acme_volume_set_mute(self, !muted); |
186 |
} |
187 |
|
188 |
gint |
189 |
acme_volume_get_threshold (AcmeVolume *self) |
190 |
{ |
191 |
GList *t; |
192 |
gint steps = 101; |
193 |
|
194 |
g_return_val_if_fail(acme_volume_open(self), 1); |
195 |
|
196 |
for (t = self->_priv->mixer_tracks; t != NULL; t = t->next) { |
197 |
GstMixerTrack *track = GST_MIXER_TRACK (t->data); |
198 |
gint track_steps = track->max_volume - track->min_volume; |
199 |
if (track_steps > 0 && track_steps < steps) |
200 |
steps = track_steps; |
201 |
} |
202 |
|
203 |
acme_volume_close (self); |
204 |
|
205 |
return 100 / steps + 1; |
206 |
} |
207 |
|
208 |
static gboolean |
209 |
acme_volume_close_real (AcmeVolume *self) |
210 |
{ |
211 |
if (self->_priv->mixer != NULL) |
212 |
{ |
213 |
gst_element_set_state (GST_ELEMENT (self->_priv->mixer), GST_STATE_NULL); |
214 |
gst_object_unref (GST_OBJECT (self->_priv->mixer)); |
215 |
g_list_foreach (self->_priv->mixer_tracks, (GFunc) g_object_unref, NULL); |
216 |
g_list_free (self->_priv->mixer_tracks); |
217 |
self->_priv->mixer = NULL; |
218 |
self->_priv->mixer_tracks = NULL; |
219 |
} |
220 |
|
221 |
self->_priv->timer_id = 0; |
222 |
return FALSE; |
223 |
} |
224 |
|
225 |
/* |
226 |
* _acme_set_mixer |
227 |
* @mixer A pointer to mixer element |
228 |
* @data A pointer to user data (AcmeVolume instance to be modified) |
229 |
* @return A gboolean indicating success if Master track was found, failed otherwises. |
230 |
*/ |
231 |
static gboolean |
232 |
_acme_set_mixer(GstMixer *mixer, gpointer user_data) |
233 |
{ |
234 |
const GList *tracks; |
235 |
|
236 |
for (tracks = gst_mixer_list_tracks (mixer); tracks != NULL; tracks = tracks->next) { |
237 |
GstMixerTrack *track = GST_MIXER_TRACK (tracks->data); |
238 |
|
239 |
if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MASTER)) { |
240 |
AcmeVolume *self; |
241 |
|
242 |
self = ACME_VOLUME (user_data); |
243 |
|
244 |
self->_priv->mixer = mixer; |
245 |
self->_priv->mixer_tracks = g_list_append (self->_priv->mixer_tracks, g_object_ref (track)); |
246 |
return TRUE; |
247 |
} |
248 |
|
249 |
continue; |
250 |
} |
251 |
|
252 |
return FALSE; |
253 |
} |
254 |
|
255 |
/* This is a modified version of code from gnome-media's gst-mixer */ |
256 |
static gboolean |
257 |
acme_volume_open (AcmeVolume *self) |
258 |
{ |
259 |
gchar *mixer_device, **factory_and_device = NULL; |
260 |
GList *mixer_list; |
261 |
|
262 |
if (self->_priv->timer_id != 0) { |
263 |
g_source_remove (self->_priv->timer_id); |
264 |
self->_priv->timer_id = 0; |
265 |
return TRUE; |
266 |
} |
267 |
|
268 |
mixer_device = gconf_client_get_string (self->_priv->gconf_client, DEFAULT_MIXER_DEVICE_KEY, NULL); |
269 |
if (mixer_device != NULL) |
270 |
factory_and_device = g_strsplit (mixer_device, ":", 2); |
271 |
|
272 |
if (factory_and_device != NULL && factory_and_device[0] != NULL) { |
273 |
GstElement *element; |
274 |
|
275 |
element = gst_element_factory_make (factory_and_device[0], NULL); |
276 |
|
277 |
if (element != NULL) { |
278 |
if (factory_and_device[1] != NULL && |
279 |
g_object_class_find_property (G_OBJECT_GET_CLASS (element), "device")) |
280 |
g_object_set (G_OBJECT (element), "device", factory_and_device[1], NULL); |
281 |
gst_element_set_state (element, GST_STATE_READY); |
282 |
|
283 |
if (GST_IS_MIXER (element)) |
284 |
self->_priv->mixer = GST_MIXER (element); |
285 |
else { |
286 |
gst_element_set_state (element, GST_STATE_NULL); |
287 |
gst_object_unref (element); |
288 |
} |
289 |
} |
290 |
} |
291 |
|
292 |
g_free (mixer_device); |
293 |
g_strfreev (factory_and_device); |
294 |
|
295 |
if (self->_priv->mixer != NULL) { |
296 |
const GList *m; |
297 |
GSList *tracks, *t; |
298 |
GError *error = NULL; |
299 |
|
300 |
/* Try to use tracks saved in GConf |
301 |
Note: errors need to be treated , for example if the user set a non type list for this key |
302 |
or if the elements type_list are not "matched" */ |
303 |
tracks = gconf_client_get_list (self->_priv->gconf_client, DEFAULT_MIXER_TRACKS_KEY, |
304 |
GCONF_VALUE_STRING, &error); |
305 |
|
306 |
if (error) { |
307 |
g_warning("ERROR: %s\n", error->message); |
308 |
g_error_free(error); |
309 |
} |
310 |
|
311 |
/* We use these tracks ONLY if they are supported on the system with the following mixer */ |
312 |
for (m = gst_mixer_list_tracks (self->_priv->mixer); m != NULL; m = m->next) { |
313 |
GstMixerTrack *track = GST_MIXER_TRACK (m->data); |
314 |
|
315 |
for (t = tracks; t != NULL; t = t->next) |
316 |
if (!strcmp (t->data, track->label)) |
317 |
self->_priv->mixer_tracks = g_list_append (self->_priv->mixer_tracks, g_object_ref (track)); |
318 |
|
319 |
} |
320 |
|
321 |
g_slist_foreach (tracks, (GFunc)g_free, NULL); |
322 |
g_slist_free (tracks); |
323 |
|
324 |
/* If no track stored in GConf is avaiable try to use Master track */ |
325 |
if (self->_priv->mixer_tracks == NULL) { |
326 |
for (m = gst_mixer_list_tracks (self->_priv->mixer); m != NULL; m = m->next) { |
327 |
GstMixerTrack *track = GST_MIXER_TRACK (m->data); |
328 |
|
329 |
if (GST_MIXER_TRACK_HAS_FLAG (track, GST_MIXER_TRACK_MASTER)) { |
330 |
self->_priv->mixer_tracks = g_list_append (self->_priv->mixer_tracks, g_object_ref (track)); |
331 |
break; |
332 |
} |
333 |
} |
334 |
} |
335 |
|
336 |
if (self->_priv->mixer_tracks != NULL) |
337 |
return TRUE; |
338 |
else { |
339 |
gst_element_set_state (GST_ELEMENT (self->_priv->mixer), GST_STATE_NULL); |
340 |
gst_object_unref (self->_priv->mixer); |
341 |
} |
342 |
} |
343 |
|
344 |
/* Go through all elements of a certain class and check whether |
345 |
* they implement a mixer. If so, walk through the tracks and look |
346 |
* for first one named "volume". |
347 |
* |
348 |
* We should probably do something intelligent if we don't find an |
349 |
* appropriate mixer/track. But now we do something stupid... |
350 |
* everything just becomes a no-op. |
351 |
*/ |
352 |
mixer_list = gst_audio_default_registry_mixer_filter (_acme_set_mixer, |
353 |
TRUE, |
354 |
self); |
355 |
|
356 |
if (mixer_list == NULL) |
357 |
return FALSE; |
358 |
|
359 |
/* do not unref the mixer as we keep the ref for self->priv->mixer */ |
360 |
g_list_free (mixer_list); |
361 |
|
362 |
return TRUE; |
363 |
} |
364 |
|
365 |
static void |
366 |
acme_volume_close (AcmeVolume *self) |
367 |
{ |
368 |
self->_priv->timer_id = g_timeout_add_seconds (TIMEOUT, |
369 |
(GSourceFunc) acme_volume_close_real, self); |
370 |
} |
371 |
|
372 |
static void |
373 |
acme_volume_init (AcmeVolume *self) |
374 |
{ |
375 |
self->_priv = ACME_VOLUME_GET_PRIVATE (self); |
376 |
self->_priv->gconf_client = gconf_client_get_default (); |
377 |
} |
378 |
|
379 |
static void |
380 |
acme_volume_class_init (AcmeVolumeClass *klass) |
381 |
{ |
382 |
G_OBJECT_CLASS (klass)->finalize = acme_volume_finalize; |
383 |
|
384 |
gst_init (NULL, NULL); |
385 |
|
386 |
g_type_class_add_private (klass, sizeof (AcmeVolumePrivate)); |
387 |
} |
388 |
|
389 |
/* acme_volume_new |
390 |
* @return A singleton instance of type AcmeVolume |
391 |
*/ |
392 |
AcmeVolume * |
393 |
acme_volume_new (void) |
394 |
{ |
395 |
if (acme_volume_object == NULL) { |
396 |
acme_volume_object = g_object_new (ACME_TYPE_VOLUME, NULL); |
397 |
return ACME_VOLUME(acme_volume_object); |
398 |
} |
399 |
g_object_ref(acme_volume_object); |
400 |
return ACME_VOLUME(acme_volume_object); |
401 |
} |
402 |
|
|
|
403 |
++ b/plugins/media-keys/cut-n-paste/gvc-gstreamer-acme-vol.h |
Line 0
Link Here
|
0 |
-- a/plugins/media-keys/gsd-media-keys-manager.c |
1 |
/* acme-volume.h |
|
|
2 |
|
3 |
Copyright (C) 2002, 2003 Bastien Nocera |
4 |
Copyright (C) 2004 Novell, Inc. |
5 |
Copyright (C) 2009 PERIER Romain <mrpouet@tuxfamily.org> |
6 |
|
7 |
The Gnome Library is free software; you can redistribute it and/or |
8 |
modify it under the terms of the GNU Library General Public License as |
9 |
published by the Free Software Foundation; either version 2 of the |
10 |
License, or (at your option) any later version. |
11 |
|
12 |
The Gnome Library is distributed in the hope that it will be useful, |
13 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
14 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
15 |
Library General Public License for more details. |
16 |
|
17 |
You should have received a copy of the GNU Library General Public |
18 |
License along with the Gnome Library; see the file COPYING.LIB. If not, |
19 |
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
20 |
Boston, MA 02111-1307, USA. |
21 |
|
22 |
Author: Bastien Nocera <hadess@hadess.net> |
23 |
Jon Trowbridge <trow@ximian.com> |
24 |
*/ |
25 |
|
26 |
#include <glib-object.h> |
27 |
|
28 |
#define ACME_TYPE_VOLUME (acme_volume_get_type ()) |
29 |
#define ACME_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), ACME_TYPE_VOLUME, AcmeVolume)) |
30 |
#define ACME_VOLUME_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), ACME_TYPE_VOLUME, AcmeVolumeClass)) |
31 |
#define ACME_IS_VOLUME(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), ACME_TYPE_VOLUME)) |
32 |
#define ACME_VOLUME_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), ACME_TYPE_VOLUME, AcmeVolumeClass)) |
33 |
|
34 |
typedef struct AcmeVolume AcmeVolume; |
35 |
typedef struct AcmeVolumeClass AcmeVolumeClass; |
36 |
typedef struct AcmeVolumePrivate AcmeVolumePrivate; |
37 |
|
38 |
struct AcmeVolume { |
39 |
GObject parent; |
40 |
AcmeVolumePrivate *_priv; |
41 |
}; |
42 |
|
43 |
struct AcmeVolumeClass { |
44 |
GObjectClass parent; |
45 |
}; |
46 |
|
47 |
GType acme_volume_get_type (void); |
48 |
AcmeVolume *acme_volume_new (void); |
49 |
void acme_volume_set_mute (AcmeVolume *self, gboolean val); |
50 |
void acme_volume_mute_toggle (AcmeVolume *self); |
51 |
gboolean acme_volume_get_mute (AcmeVolume *self); |
52 |
void acme_volume_set_volume (AcmeVolume *self, gint val); |
53 |
gint acme_volume_get_volume (AcmeVolume *self); |
54 |
gint acme_volume_get_threshold (AcmeVolume *self); |
55 |
|
56 |
|
|
|
57 |
++ b/plugins/media-keys/gsd-media-keys-manager.c |
Lines 53-58
Link Here
|
53 |
#ifdef HAVE_PULSE |
53 |
#ifdef HAVE_PULSE |
54 |
#include <canberra-gtk.h> |
54 |
#include <canberra-gtk.h> |
55 |
#include "gvc-mixer-control.h" |
55 |
#include "gvc-mixer-control.h" |
|
|
56 |
#elif defined(HAVE_GSTREAMER) |
57 |
#include "gvc-gstreamer-acme-vol.h" |
56 |
#endif /* HAVE_PULSE */ |
58 |
#endif /* HAVE_PULSE */ |
57 |
|
59 |
|
58 |
#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon" |
60 |
#define GSD_DBUS_PATH "/org/gnome/SettingsDaemon" |
Lines 88-93
Link Here
|
88 |
/* Volume bits */ |
90 |
/* Volume bits */ |
89 |
GvcMixerControl *volume; |
91 |
GvcMixerControl *volume; |
90 |
GvcMixerStream *stream; |
92 |
GvcMixerStream *stream; |
|
|
93 |
#elif defined(HAVE_GSTREAMER) |
94 |
AcmeVolume *volume; |
91 |
#endif /* HAVE_PULSE */ |
95 |
#endif /* HAVE_PULSE */ |
92 |
GtkWidget *dialog; |
96 |
GtkWidget *dialog; |
93 |
GConfClient *conf_client; |
97 |
GConfClient *conf_client; |
Lines 633-639
Link Here
|
633 |
CA_PROP_APPLICATION_ID, "org.gnome.VolumeControl", |
637 |
CA_PROP_APPLICATION_ID, "org.gnome.VolumeControl", |
634 |
NULL); |
638 |
NULL); |
635 |
} |
639 |
} |
|
|
640 |
#endif /* HAVE_PULSE */ |
636 |
|
641 |
|
|
|
642 |
#if defined(HAVE_PULSE) || defined(HAVE_GSTREAMER) |
637 |
static void |
643 |
static void |
638 |
do_sound_action (GsdMediaKeysManager *manager, |
644 |
do_sound_action (GsdMediaKeysManager *manager, |
639 |
int type) |
645 |
int type) |
Lines 642-649
Link Here
|
642 |
guint vol, norm_vol_step; |
648 |
guint vol, norm_vol_step; |
643 |
int vol_step; |
649 |
int vol_step; |
644 |
|
650 |
|
|
|
651 |
#ifdef HAVE_PULSE |
645 |
if (manager->priv->stream == NULL) |
652 |
if (manager->priv->stream == NULL) |
646 |
return; |
653 |
return; |
|
|
654 |
#elif defined(HAVE_GSTREAMER) |
655 |
if (manager->priv->volume == NULL) |
656 |
return; |
657 |
#endif |
647 |
|
658 |
|
648 |
vol_step = gconf_client_get_int (manager->priv->conf_client, |
659 |
vol_step = gconf_client_get_int (manager->priv->conf_client, |
649 |
GCONF_MISC_DIR "/volume_step", |
660 |
GCONF_MISC_DIR "/volume_step", |
Lines 652-669
Link Here
|
652 |
if (vol_step <= 0 || vol_step > 100) |
663 |
if (vol_step <= 0 || vol_step > 100) |
653 |
vol_step = VOLUME_STEP; |
664 |
vol_step = VOLUME_STEP; |
654 |
|
665 |
|
|
|
666 |
#ifdef HAVE_PULSE |
655 |
norm_vol_step = PA_VOLUME_NORM * vol_step / 100; |
667 |
norm_vol_step = PA_VOLUME_NORM * vol_step / 100; |
656 |
|
668 |
|
657 |
/* FIXME: this is racy */ |
669 |
/* FIXME: this is racy */ |
658 |
vol = gvc_mixer_stream_get_volume (manager->priv->stream); |
670 |
vol = gvc_mixer_stream_get_volume (manager->priv->stream); |
659 |
muted = gvc_mixer_stream_get_is_muted (manager->priv->stream); |
671 |
muted = gvc_mixer_stream_get_is_muted (manager->priv->stream); |
660 |
|
672 |
#else |
|
|
673 |
if (vol_step > 0) { |
674 |
gint threshold = acme_volume_get_threshold (manager->priv->volume); |
675 |
if (vol_step < threshold) |
676 |
vol_step = threshold; |
677 |
g_debug ("Using volume step of %d", vol_step); |
678 |
} |
679 |
vol = acme_volume_get_volume (manager->priv->volume); |
680 |
muted = acme_volume_get_mute (manager->priv->volume); |
681 |
#endif |
661 |
switch (type) { |
682 |
switch (type) { |
662 |
case MUTE_KEY: |
683 |
case MUTE_KEY: |
|
|
684 |
#ifdef HAVE_PULSE |
663 |
muted = !muted; |
685 |
muted = !muted; |
664 |
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); |
686 |
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); |
|
|
687 |
#else |
688 |
acme_volume_mute_toggle (manager->priv->volume); |
689 |
#endif |
665 |
break; |
690 |
break; |
666 |
case VOLUME_DOWN_KEY: |
691 |
case VOLUME_DOWN_KEY: |
|
|
692 |
#ifdef HAVE_PULSE |
667 |
if (!muted && (vol <= norm_vol_step)) { |
693 |
if (!muted && (vol <= norm_vol_step)) { |
668 |
muted = !muted; |
694 |
muted = !muted; |
669 |
vol = 0; |
695 |
vol = 0; |
Lines 675-685
Link Here
|
675 |
if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) |
701 |
if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) |
676 |
gvc_mixer_stream_push_volume (manager->priv->stream); |
702 |
gvc_mixer_stream_push_volume (manager->priv->stream); |
677 |
} |
703 |
} |
|
|
704 |
#else |
705 |
if (!muted && (vol <= vol_step)) |
706 |
acme_volume_mute_toggle (manager->priv->volume); |
707 |
acme_volume_set_volume (manager->priv->volume, vol - vol_step); |
708 |
#endif |
678 |
break; |
709 |
break; |
679 |
case VOLUME_UP_KEY: |
710 |
case VOLUME_UP_KEY: |
680 |
if (muted) { |
711 |
if (muted) { |
681 |
muted = !muted; |
712 |
muted = !muted; |
682 |
if (vol == 0) { |
713 |
if (vol == 0) { |
|
|
714 |
#ifdef HAVE_PULSE |
683 |
vol = vol + norm_vol_step; |
715 |
vol = vol + norm_vol_step; |
684 |
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); |
716 |
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); |
685 |
if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) |
717 |
if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) |
Lines 687-693
Link Here
|
687 |
} else { |
719 |
} else { |
688 |
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); |
720 |
gvc_mixer_stream_change_is_muted (manager->priv->stream, muted); |
689 |
} |
721 |
} |
|
|
722 |
#else |
723 |
/* We need to unmute otherwise vol is blocked (and muted) */ |
724 |
acme_volume_set_mute (manager->priv->volume, FALSE); |
725 |
} |
726 |
acme_volume_set_volume (manager->priv->volume, vol + vol_step); |
727 |
#endif |
690 |
} else { |
728 |
} else { |
|
|
729 |
#ifdef HAVE_PULSE |
691 |
if (vol < MAX_VOLUME) { |
730 |
if (vol < MAX_VOLUME) { |
692 |
gboolean set; |
731 |
gboolean set; |
693 |
if (vol + norm_vol_step >= MAX_VOLUME) { |
732 |
if (vol + norm_vol_step >= MAX_VOLUME) { |
Lines 698-710
Link Here
|
698 |
if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) |
737 |
if (gvc_mixer_stream_set_volume (manager->priv->stream, vol) != FALSE) |
699 |
gvc_mixer_stream_push_volume (manager->priv->stream); |
738 |
gvc_mixer_stream_push_volume (manager->priv->stream); |
700 |
} |
739 |
} |
|
|
740 |
#else |
741 |
acme_volume_set_volume (manager->priv->volume, vol + vol_step); |
742 |
#endif |
701 |
} |
743 |
} |
702 |
break; |
744 |
break; |
703 |
} |
745 |
} |
704 |
|
746 |
|
|
|
747 |
#ifdef HAVE_PULSE |
705 |
update_dialog (manager, vol, muted); |
748 |
update_dialog (manager, vol, muted); |
|
|
749 |
#else |
750 |
muted = acme_volume_get_mute (manager->priv->volume); |
751 |
vol = acme_volume_get_volume (manager->priv->volume); |
752 |
|
753 |
/* FIXME: AcmeVolume should probably emit signals |
754 |
instead of doing it like this */ |
755 |
dialog_init (manager); |
756 |
gsd_media_keys_window_set_volume_muted (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), |
757 |
muted); |
758 |
gsd_media_keys_window_set_volume_level (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), |
759 |
vol); |
760 |
gsd_media_keys_window_set_action (GSD_MEDIA_KEYS_WINDOW (manager->priv->dialog), |
761 |
GSD_MEDIA_KEYS_WINDOW_ACTION_VOLUME); |
762 |
dialog_show (manager); |
763 |
#endif /* HAVE_PULSE */ |
706 |
} |
764 |
} |
|
|
765 |
#endif /* defined(HAVE_PULSE) || defined(HAVE_GSTREAMER) */ |
707 |
|
766 |
|
|
|
767 |
#ifdef HAVE_PULSE |
708 |
static void |
768 |
static void |
709 |
update_default_sink (GsdMediaKeysManager *manager) |
769 |
update_default_sink (GsdMediaKeysManager *manager) |
710 |
{ |
770 |
{ |
Lines 863-871
Link Here
|
863 |
case MUTE_KEY: |
923 |
case MUTE_KEY: |
864 |
case VOLUME_DOWN_KEY: |
924 |
case VOLUME_DOWN_KEY: |
865 |
case VOLUME_UP_KEY: |
925 |
case VOLUME_UP_KEY: |
866 |
#ifdef HAVE_PULSE |
926 |
#if defined(HAVE_PULSE) || defined(HAVE_GSTREAMER) |
867 |
do_sound_action (manager, type); |
927 |
do_sound_action (manager, type); |
868 |
#endif /* HAVE_PULSE */ |
928 |
#endif /* HAVE_PULSE || HAVE_GSTREAMER */ |
869 |
break; |
929 |
break; |
870 |
case POWER_KEY: |
930 |
case POWER_KEY: |
871 |
do_exit_action (manager); |
931 |
do_exit_action (manager); |
Lines 1068-1073
Link Here
|
1068 |
gvc_mixer_control_open (manager->priv->volume); |
1128 |
gvc_mixer_control_open (manager->priv->volume); |
1069 |
|
1129 |
|
1070 |
gnome_settings_profile_end ("gvc_mixer_control_new"); |
1130 |
gnome_settings_profile_end ("gvc_mixer_control_new"); |
|
|
1131 |
#elif defined(HAVE_GSTREAMER) |
1132 |
gnome_settings_profile_start ("acme_volume_new"); |
1133 |
manager->priv->volume = acme_volume_new (); |
1134 |
gnome_settings_profile_end ("acme_volume_new"); |
1071 |
#endif /* HAVE_PULSE */ |
1135 |
#endif /* HAVE_PULSE */ |
1072 |
g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager); |
1136 |
g_idle_add ((GSourceFunc) start_media_keys_idle_cb, manager); |
1073 |
|
1137 |
|
Lines 1140-1151
Link Here
|
1140 |
g_object_unref (priv->stream); |
1204 |
g_object_unref (priv->stream); |
1141 |
priv->stream = NULL; |
1205 |
priv->stream = NULL; |
1142 |
} |
1206 |
} |
|
|
1207 |
#endif /* HAVE_PULSE */ |
1143 |
|
1208 |
|
|
|
1209 |
#if defined(HAVE_PULSE) || defined(HAVE_GSTREAMER) |
1144 |
if (priv->volume) { |
1210 |
if (priv->volume) { |
1145 |
g_object_unref (priv->volume); |
1211 |
g_object_unref (priv->volume); |
1146 |
priv->volume = NULL; |
1212 |
priv->volume = NULL; |
1147 |
} |
1213 |
} |
1148 |
#endif /* HAVE_PULSE */ |
1214 |
#endif /* defined(HAVE_PULSE) || defined(HAVE_GSTREAMER) */ |
1149 |
|
1215 |
|
1150 |
if (priv->dialog != NULL) { |
1216 |
if (priv->dialog != NULL) { |
1151 |
gtk_widget_destroy (priv->dialog); |
1217 |
gtk_widget_destroy (priv->dialog); |