summaryrefslogtreecommitdiff
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
parentfb6ffc6ac52f92de67c2602975df2418e3af0d62 (diff)
downloadefl-d79232d605433374b898b7d1462608e595112170.tar.gz
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
-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 676d72dc60..73f9c72058 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 *
_ecore_audio_out_pulse_efl_object_constructor(Eo *eo_obj, Ecore_Audio_Out_Pulse_Data *_pd EINA_UNUSED)
{
int argc;
- char **argv;
+ char **argv, *disp = NULL;
Ecore_Audio_Output *out_obj = efl_data_scope_get(eo_obj, ECORE_AUDIO_OUT_CLASS);
+ static char *dispenv = NULL;
if (!EPA_LOAD()) return NULL;
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_
out_obj->need_writer = EINA_FALSE;
if (!class_vars.context) {
+
+ // if we're in a wayland world rather than x11... but DISPLAY also set...
+ if (getenv("WAYLAND_DISPLAY")) disp = getenv("DISPLAY");
+ // make a tmp copy of display locally as we'll overwrite this
+ if (disp) disp = strdup(disp);
+ // if we had a previously allocated env var buffer for DISPLAY then
+ // free it only if DISPLAY env var changed
+ if (dispenv) {
+ if (!((disp) && (!strcmp(dispenv + 8/*"DISPLAY="*/, disp)))) {
+ free(dispenv);
+ dispenv = NULL;
+ }
+ }
+ // no previous display env but we have a display, then allocate a buffer
+ // that stays around until the next time here with the evn var string
+ // but have space for disp string too
+ if ((!dispenv) && (disp)) {
+ dispenv = malloc(8/*"DISPLAY="*/ + strlen(disp) + 1);
+ }
+ // ensure env var is empty and to a putenv as pulse wants to use DISPLAY
+ // and if its non-empty it'll try connect to the xserver and we do not
+ // want this to happen in a wayland universe
+ if (dispenv) {
+ strcpy(dispenv, "DISPLAY=");
+ putenv(dispenv);
+ }
+ // now hopefully getenv("DISPLAY") inside pulse will return NULL or it
+ // will return an empty string "" which pulse thinsk is the same as NULL
+
ecore_app_args_get(&argc, &argv);
if (!argc) {
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_
} else {
class_vars.context = EPA_CALL(pa_context_new)(class_vars.api, basename(argv[0]));
}
+ // if we had a display value and a displayenv buffer then let's restore
+ // the previous value content of DISPLAY as we duplicated it above and
+ // add to the env of the dispenv buffer, then putenv that back. as the
+ // buffer is malloced this will be safe, but as the displayenv is local
+ // and static we wont go allocating these buffers forever. just this one
+ // here and then replace/re-use it.
+ if ((disp) && (dispenv)) {
+ strcat(dispenv, disp);
+ putenv(dispenv);
+ }
+ // free up our temporary local DISPLAY env sring copy if we have it
+ if (disp) free(disp);
+
EPA_CALL(pa_context_set_state_callback)(class_vars.context, _state_cb, NULL);
EPA_CALL(pa_context_connect)(class_vars.context, NULL, PA_CONTEXT_NOFLAGS, NULL);
}