summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-10-31 13:55:07 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2016-10-31 19:53:34 +0900
commitd79232d605433374b898b7d1462608e595112170 (patch)
tree638974ab9f0bd8994347659c3dd7f277a4bf248e /src
parentfb6ffc6ac52f92de67c2602975df2418e3af0d62 (diff)
ecore audio - fix hang in wayland due to pulse audio connecting to x
pulse insists on connecting to the xserver on init/setup context if: 1. DISPLAY is set AND 2. DISPLAY is not empty so to do a pretty horrible worka-round, empty off the display if its set so pa doesnt go connect to x and do this if WAYLAND_DISPLAy is set assuming we'll use wayland then. this is far better than a solid rock-hard hang. :) @fix
Diffstat (limited to 'src')
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_out_pulse.c45
1 files changed, 44 insertions, 1 deletions
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c b/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
index 676d72d..73f9c72 100644
--- a/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
+++ b/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c
@@ -265,8 +265,9 @@ EOLIAN static Eo *
265_ecore_audio_out_pulse_efl_object_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_Data *_pd EINA_UNUSED) 265_ecore_audio_out_pulse_efl_object_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_Data *_pd EINA_UNUSED)
266{ 266{
267 int argc; 267 int argc;
268 char **argv; 268 char **argv, *disp = NULL;
269 Ecore_Audio_Output *out_obj = efl_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS); 269 Ecore_Audio_Output *out_obj = efl_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
270 static char *dispenv = NULL;
270 271
271 if (!EPA_LOAD()) return NULL; 272 if (!EPA_LOAD()) return NULL;
272 eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS)); 273 eo_obj = efl_constructor(efl_super(eo_obj, MY_CLASS));
@@ -274,6 +275,35 @@ _ecore_audio_out_pulse_efl_object_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_
274 out_obj->need_writer = EINA_FALSE; 275 out_obj->need_writer = EINA_FALSE;
275 276
276 if (!class_vars.context) { 277 if (!class_vars.context) {
278
279 // if we're in a wayland world rather than x11... but DISPLAY also set...
280 if (getenv("WAYLAND_DISPLAY")) disp = getenv("DISPLAY");
281 // make a tmp copy of display locally as we'll overwrite this
282 if (disp) disp = strdup(disp);
283 // if we had a previously allocated env var buffer for DISPLAY then
284 // free it only if DISPLAY env var changed
285 if (dispenv) {
286 if (!((disp) && (!strcmp(dispenv + 8/*"DISPLAY="*/, disp)))) {
287 free(dispenv);
288 dispenv = NULL;
289 }
290 }
291 // no previous display env but we have a display, then allocate a buffer
292 // that stays around until the next time here with the evn var string
293 // but have space for disp string too
294 if ((!dispenv) && (disp)) {
295 dispenv = malloc(8/*"DISPLAY="*/ + strlen(disp) + 1);
296 }
297 // ensure env var is empty and to a putenv as pulse wants to use DISPLAY
298 // and if its non-empty it'll try connect to the xserver and we do not
299 // want this to happen in a wayland universe
300 if (dispenv) {
301 strcpy(dispenv, "DISPLAY=");
302 putenv(dispenv);
303 }
304 // now hopefully getenv("DISPLAY") inside pulse will return NULL or it
305 // will return an empty string "" which pulse thinsk is the same as NULL
306
277 ecore_app_args_get(&argc, &argv); 307 ecore_app_args_get(&argc, &argv);
278 if (!argc) { 308 if (!argc) {
279 DBG("Could not get program name, pulse outputs will be named ecore_audio"); 309 DBG("Could not get program name, pulse outputs will be named ecore_audio");
@@ -281,6 +311,19 @@ _ecore_audio_out_pulse_efl_object_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_
281 } else { 311 } else {
282 class_vars.context = EPA_CALL(pa_context_new)(class_vars.api, basename(argv[0])); 312 class_vars.context = EPA_CALL(pa_context_new)(class_vars.api, basename(argv[0]));
283 } 313 }
314 // if we had a display value and a displayenv buffer then let's restore
315 // the previous value content of DISPLAY as we duplicated it above and
316 // add to the env of the dispenv buffer, then putenv that back. as the
317 // buffer is malloced this will be safe, but as the displayenv is local
318 // and static we wont go allocating these buffers forever. just this one
319 // here and then replace/re-use it.
320 if ((disp) && (dispenv)) {
321 strcat(dispenv, disp);
322 putenv(dispenv);
323 }
324 // free up our temporary local DISPLAY env sring copy if we have it
325 if (disp) free(disp);
326
284 EPA_CALL(pa_context_set_state_callback)(class_vars.context, _state_cb, NULL); 327 EPA_CALL(pa_context_set_state_callback)(class_vars.context, _state_cb, NULL);
285 EPA_CALL(pa_context_connect)(class_vars.context, NULL, PA_CONTEXT_NOFLAGS, NULL); 328 EPA_CALL(pa_context_connect)(class_vars.context, NULL, PA_CONTEXT_NOFLAGS, NULL);
286 } 329 }