Branch data Line data Source code
1 : : /***
2 : : This file is part of PulseAudio.
3 : :
4 : : Copyright 2008 Lennart Poettering
5 : :
6 : : PulseAudio is free software; you can redistribute it and/or modify
7 : : it under the terms of the GNU Lesser General Public License as
8 : : published by the Free Software Foundation; either version 2.1 of the
9 : : License, or (at your option) any later version.
10 : :
11 : : PulseAudio is distributed in the hope that it will be useful, but
12 : : WITHOUT ANY WARRANTY; without even the implied warranty of
13 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 : : Lesser General Public License for more details.
15 : :
16 : : You should have received a copy of the GNU Lesser General Public
17 : : License along with PulseAudio; if not, write to the Free Software
18 : : Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 : : USA.
20 : : ***/
21 : :
22 : : #ifdef HAVE_CONFIG_H
23 : : #include <config.h>
24 : : #endif
25 : :
26 : : #include <string.h>
27 : : #include <locale.h>
28 : :
29 : : #ifdef ENABLE_NLS
30 : : #include <libintl.h>
31 : : #endif
32 : :
33 : : #ifdef __APPLE__
34 : : #include <crt_externs.h>
35 : : #define environ (*_NSGetEnviron())
36 : : #elif !HAVE_DECL_ENVIRON
37 : : extern char **environ;
38 : : #endif
39 : :
40 : : #include <pulse/gccmacro.h>
41 : : #include <pulse/proplist.h>
42 : : #include <pulse/utf8.h>
43 : : #include <pulse/xmalloc.h>
44 : : #include <pulse/util.h>
45 : :
46 : : #include <pulsecore/core-util.h>
47 : :
48 : : #if defined(HAVE_GLIB) && defined(PA_GCC_WEAKREF)
49 : : #include <glib.h>
50 : : static G_CONST_RETURN gchar* _g_get_application_name(void) PA_GCC_WEAKREF(g_get_application_name);
51 : : #endif
52 : :
53 : : #if defined(HAVE_GTK) && defined(PA_GCC_WEAKREF)
54 : : #pragma GCC diagnostic ignored "-Wstrict-prototypes"
55 : : #include <gtk/gtk.h>
56 : : #include <gdk/gdkx.h>
57 : : static G_CONST_RETURN gchar* _gtk_window_get_default_icon_name(void) PA_GCC_WEAKREF(gtk_window_get_default_icon_name);
58 : : static Display *_gdk_display PA_GCC_WEAKREF(gdk_display);
59 : : #endif
60 : :
61 : : #include "proplist-util.h"
62 : :
63 : : static void add_glib_properties(pa_proplist *p) {
64 : :
65 : : #if defined(HAVE_GLIB) && defined(PA_GCC_WEAKREF)
66 : :
67 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_NAME))
68 [ # # ]: 0 : if (_g_get_application_name) {
69 : : const gchar *t;
70 : :
71 : : /* We ignore the tiny race condition here. */
72 : :
73 [ # # ]: 0 : if ((t = _g_get_application_name()))
74 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, t);
75 : : }
76 : :
77 : : #endif
78 : : }
79 : :
80 : 0 : static void add_gtk_properties(pa_proplist *p) {
81 : :
82 : : #if defined(HAVE_GTK) && defined(PA_GCC_WEAKREF)
83 : :
84 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_ICON_NAME))
85 [ # # ]: 0 : if (_gtk_window_get_default_icon_name) {
86 : : const gchar *t;
87 : :
88 : : /* We ignore the tiny race condition here. */
89 : :
90 [ # # ]: 0 : if ((t = _gtk_window_get_default_icon_name()))
91 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_ICON_NAME, t);
92 : : }
93 : :
94 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_WINDOW_X11_DISPLAY))
95 [ # # ][ # # ]: 0 : if (&_gdk_display && _gdk_display) {
96 : : const char *t;
97 : :
98 : : /* We ignore the tiny race condition here. */
99 : :
100 [ # # ]: 0 : if ((t = DisplayString(_gdk_display)))
101 : 0 : pa_proplist_sets(p, PA_PROP_WINDOW_X11_DISPLAY, t);
102 : : }
103 : :
104 : : #endif
105 : 0 : }
106 : :
107 : 0 : void pa_init_proplist(pa_proplist *p) {
108 : : char **e;
109 : : const char *pp;
110 : :
111 [ # # ]: 0 : pa_assert(p);
112 : :
113 [ # # ]: 0 : if (environ) {
114 : :
115 : : /* Some applications seem to reset environ to NULL for various
116 : : * reasons, hence we need to check for this explicitly. See
117 : : * rhbz #473080 */
118 : :
119 [ # # ]: 0 : for (e = environ; *e; e++) {
120 : :
121 [ # # ]: 0 : if (pa_startswith(*e, "PULSE_PROP_")) {
122 : : size_t kl, skip;
123 : : char *k;
124 : : pa_bool_t override;
125 : :
126 [ # # ]: 0 : if (pa_startswith(*e, "PULSE_PROP_OVERRIDE_")) {
127 : : skip = 20;
128 : : override = TRUE;
129 : : } else {
130 : 0 : skip = 11;
131 : 0 : override = FALSE;
132 : : }
133 : :
134 [ # # ][ # # ]: 0 : kl = strcspn(*e+skip, "=");
[ # # ][ # # ]
135 : :
136 [ # # ]: 0 : if ((*e)[skip+kl] != '=')
137 : 0 : continue;
138 : :
139 : 0 : k = pa_xstrndup(*e+skip, kl);
140 : :
141 [ # # ]: 0 : if (!pa_streq(k, "OVERRIDE"))
142 [ # # ][ # # ]: 0 : if (override || !pa_proplist_contains(p, k))
143 : 0 : pa_proplist_sets(p, k, *e+skip+kl+1);
144 : 0 : pa_xfree(k);
145 : : }
146 : : }
147 : : }
148 : :
149 [ # # ]: 0 : if ((pp = getenv("PULSE_PROP"))) {
150 : : pa_proplist *t;
151 : :
152 [ # # ]: 0 : if ((t = pa_proplist_from_string(pp))) {
153 : 0 : pa_proplist_update(p, PA_UPDATE_MERGE, t);
154 : 0 : pa_proplist_free(t);
155 : : }
156 : : }
157 : :
158 [ # # ]: 0 : if ((pp = getenv("PULSE_PROP_OVERRIDE"))) {
159 : : pa_proplist *t;
160 : :
161 [ # # ]: 0 : if ((t = pa_proplist_from_string(pp))) {
162 : 0 : pa_proplist_update(p, PA_UPDATE_REPLACE, t);
163 : 0 : pa_proplist_free(t);
164 : : }
165 : : }
166 : :
167 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_ID)) {
168 : : char t[32];
169 : 0 : pa_snprintf(t, sizeof(t), "%lu", (unsigned long) getpid());
170 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_ID, t);
171 : : }
172 : :
173 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_USER)) {
174 : : char *u;
175 : :
176 [ # # ]: 0 : if ((u = pa_get_user_name_malloc())) {
177 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_USER, u);
178 : 0 : pa_xfree(u);
179 : : }
180 : : }
181 : :
182 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_HOST)) {
183 : : char *h;
184 : :
185 [ # # ]: 0 : if ((h = pa_get_host_name_malloc())) {
186 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_HOST, h);
187 : 0 : pa_xfree(h);
188 : : }
189 : : }
190 : :
191 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_BINARY)) {
192 : : char *t;
193 : :
194 [ # # ]: 0 : if ((t = pa_get_binary_name_malloc())) {
195 : 0 : char *c = pa_utf8_filter(t);
196 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_BINARY, c);
197 : 0 : pa_xfree(t);
198 : 0 : pa_xfree(c);
199 : : }
200 : : }
201 : :
202 : : add_glib_properties(p);
203 : 0 : add_gtk_properties(p);
204 : :
205 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_NAME)) {
206 : : const char *t;
207 : :
208 [ # # ]: 0 : if ((t = pa_proplist_gets(p, PA_PROP_APPLICATION_PROCESS_BINARY)))
209 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_NAME, t);
210 : : }
211 : :
212 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_LANGUAGE)) {
213 : : const char *l;
214 : :
215 [ # # ]: 0 : if ((l = setlocale(LC_MESSAGES, NULL)))
216 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_LANGUAGE, l);
217 : : }
218 : :
219 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_WINDOW_X11_DISPLAY)) {
220 : : const char *t;
221 : :
222 [ # # ]: 0 : if ((t = getenv("DISPLAY"))) {
223 : 0 : char *c = pa_utf8_filter(t);
224 : 0 : pa_proplist_sets(p, PA_PROP_WINDOW_X11_DISPLAY, c);
225 : 0 : pa_xfree(c);
226 : : }
227 : : }
228 : :
229 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_MACHINE_ID)) {
230 : : char *m;
231 : :
232 [ # # ]: 0 : if ((m = pa_machine_id())) {
233 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_MACHINE_ID, m);
234 : 0 : pa_xfree(m);
235 : : }
236 : : }
237 : :
238 [ # # ]: 0 : if (!pa_proplist_contains(p, PA_PROP_APPLICATION_PROCESS_SESSION_ID)) {
239 : : char *s;
240 : :
241 [ # # ]: 0 : if ((s = pa_session_id())) {
242 : 0 : pa_proplist_sets(p, PA_PROP_APPLICATION_PROCESS_SESSION_ID, s);
243 : 0 : pa_xfree(s);
244 : : }
245 : : }
246 : 0 : }
247 : :
248 : 0 : char *pa_proplist_get_stream_group(pa_proplist *p, const char *prefix, const char *cache) {
249 : : const char *r;
250 : : char *t;
251 : :
252 [ # # ]: 0 : if (!p)
253 : : return NULL;
254 : :
255 [ # # ][ # # ]: 0 : if (cache && (r = pa_proplist_gets(p, cache)))
256 : 0 : return pa_xstrdup(r);
257 : :
258 [ # # ]: 0 : if (!prefix)
259 : 0 : prefix = "stream";
260 : :
261 [ # # ]: 0 : if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_ROLE)))
262 : 0 : t = pa_sprintf_malloc("%s-by-media-role:%s", prefix, r);
263 [ # # ]: 0 : else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_ID)))
264 : 0 : t = pa_sprintf_malloc("%s-by-application-id:%s", prefix, r);
265 [ # # ]: 0 : else if ((r = pa_proplist_gets(p, PA_PROP_APPLICATION_NAME)))
266 : 0 : t = pa_sprintf_malloc("%s-by-application-name:%s", prefix, r);
267 [ # # ]: 0 : else if ((r = pa_proplist_gets(p, PA_PROP_MEDIA_NAME)))
268 : 0 : t = pa_sprintf_malloc("%s-by-media-name:%s", prefix, r);
269 : : else
270 : 0 : t = pa_sprintf_malloc("%s-fallback:%s", prefix, r);
271 : :
272 [ # # ]: 0 : if (cache)
273 : 0 : pa_proplist_sets(p, cache, t);
274 : :
275 : : return t;
276 : : }
|