153a5a1b3Sopenharmony_ci/*** 253a5a1b3Sopenharmony_ci This file is part of PulseAudio. 353a5a1b3Sopenharmony_ci 453a5a1b3Sopenharmony_ci Copyright 2004-2006 Lennart Poettering 553a5a1b3Sopenharmony_ci 653a5a1b3Sopenharmony_ci PulseAudio is free software; you can redistribute it and/or modify 753a5a1b3Sopenharmony_ci it under the terms of the GNU Lesser General Public License as published 853a5a1b3Sopenharmony_ci by the Free Software Foundation; either version 2.1 of the License, 953a5a1b3Sopenharmony_ci or (at your option) any later version. 1053a5a1b3Sopenharmony_ci 1153a5a1b3Sopenharmony_ci PulseAudio is distributed in the hope that it will be useful, but 1253a5a1b3Sopenharmony_ci WITHOUT ANY WARRANTY; without even the implied warranty of 1353a5a1b3Sopenharmony_ci MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 1453a5a1b3Sopenharmony_ci General Public License for more details. 1553a5a1b3Sopenharmony_ci 1653a5a1b3Sopenharmony_ci You should have received a copy of the GNU Lesser General Public License 1753a5a1b3Sopenharmony_ci along with PulseAudio; if not, see <http://www.gnu.org/licenses/>. 1853a5a1b3Sopenharmony_ci***/ 1953a5a1b3Sopenharmony_ci 2053a5a1b3Sopenharmony_ci#ifdef HAVE_CONFIG_H 2153a5a1b3Sopenharmony_ci#include <config.h> 2253a5a1b3Sopenharmony_ci#endif 2353a5a1b3Sopenharmony_ci 2453a5a1b3Sopenharmony_ci#include <string.h> 2553a5a1b3Sopenharmony_ci 2653a5a1b3Sopenharmony_ci#include <xcb/xcb.h> 2753a5a1b3Sopenharmony_ci 2853a5a1b3Sopenharmony_ci#include <pulse/xmalloc.h> 2953a5a1b3Sopenharmony_ci 3053a5a1b3Sopenharmony_ci#include <pulsecore/i18n.h> 3153a5a1b3Sopenharmony_ci#include <pulsecore/x11prop.h> 3253a5a1b3Sopenharmony_ci#include <pulsecore/log.h> 3353a5a1b3Sopenharmony_ci#include <pulsecore/core-util.h> 3453a5a1b3Sopenharmony_ci#include <pulsecore/macro.h> 3553a5a1b3Sopenharmony_ci 3653a5a1b3Sopenharmony_ci#include "client-conf-x11.h" 3753a5a1b3Sopenharmony_ci 3853a5a1b3Sopenharmony_ciint pa_client_conf_from_x11(pa_client_conf *c) { 3953a5a1b3Sopenharmony_ci const char *dname; 4053a5a1b3Sopenharmony_ci xcb_connection_t *xcb = NULL; 4153a5a1b3Sopenharmony_ci int ret = -1, screen = 0; 4253a5a1b3Sopenharmony_ci char t[1024]; 4353a5a1b3Sopenharmony_ci 4453a5a1b3Sopenharmony_ci pa_assert(c); 4553a5a1b3Sopenharmony_ci 4653a5a1b3Sopenharmony_ci /* Local connections will have configuration and X root window 4753a5a1b3Sopenharmony_ci * properties match 1:1, these paths are only strictly necessary 4853a5a1b3Sopenharmony_ci * for remote clients, so check for SSH_CONNECTION to make sure 4953a5a1b3Sopenharmony_ci * this is a remote session with X forwarding. 5053a5a1b3Sopenharmony_ci */ 5153a5a1b3Sopenharmony_ci if (!getenv("SSH_CONNECTION")) 5253a5a1b3Sopenharmony_ci goto finish; 5353a5a1b3Sopenharmony_ci 5453a5a1b3Sopenharmony_ci if (!(dname = getenv("DISPLAY"))) 5553a5a1b3Sopenharmony_ci goto finish; 5653a5a1b3Sopenharmony_ci 5753a5a1b3Sopenharmony_ci if (*dname == 0) 5853a5a1b3Sopenharmony_ci goto finish; 5953a5a1b3Sopenharmony_ci 6053a5a1b3Sopenharmony_ci if (!(xcb = xcb_connect(dname, NULL))) { 6153a5a1b3Sopenharmony_ci pa_log(_("xcb_connect() failed")); 6253a5a1b3Sopenharmony_ci goto finish; 6353a5a1b3Sopenharmony_ci } 6453a5a1b3Sopenharmony_ci 6553a5a1b3Sopenharmony_ci if (xcb_connection_has_error(xcb)) { 6653a5a1b3Sopenharmony_ci pa_log(_("xcb_connection_has_error() returned true")); 6753a5a1b3Sopenharmony_ci goto finish; 6853a5a1b3Sopenharmony_ci } 6953a5a1b3Sopenharmony_ci 7053a5a1b3Sopenharmony_ci if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t))) { 7153a5a1b3Sopenharmony_ci bool disable_autospawn = true; 7253a5a1b3Sopenharmony_ci 7353a5a1b3Sopenharmony_ci pa_xfree(c->default_server); 7453a5a1b3Sopenharmony_ci c->default_server = pa_xstrdup(t); 7553a5a1b3Sopenharmony_ci 7653a5a1b3Sopenharmony_ci if (pa_x11_get_prop(xcb, screen, "PULSE_SESSION_ID", t, sizeof(t))) { 7753a5a1b3Sopenharmony_ci char *id; 7853a5a1b3Sopenharmony_ci 7953a5a1b3Sopenharmony_ci if ((id = pa_session_id())) { 8053a5a1b3Sopenharmony_ci if (pa_streq(t, id)) 8153a5a1b3Sopenharmony_ci disable_autospawn = false; 8253a5a1b3Sopenharmony_ci pa_xfree(id); 8353a5a1b3Sopenharmony_ci } 8453a5a1b3Sopenharmony_ci } 8553a5a1b3Sopenharmony_ci 8653a5a1b3Sopenharmony_ci if (disable_autospawn) 8753a5a1b3Sopenharmony_ci c->autospawn = false; 8853a5a1b3Sopenharmony_ci } 8953a5a1b3Sopenharmony_ci 9053a5a1b3Sopenharmony_ci if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t))) { 9153a5a1b3Sopenharmony_ci pa_xfree(c->default_sink); 9253a5a1b3Sopenharmony_ci c->default_sink = pa_xstrdup(t); 9353a5a1b3Sopenharmony_ci } 9453a5a1b3Sopenharmony_ci 9553a5a1b3Sopenharmony_ci if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t))) { 9653a5a1b3Sopenharmony_ci pa_xfree(c->default_source); 9753a5a1b3Sopenharmony_ci c->default_source = pa_xstrdup(t); 9853a5a1b3Sopenharmony_ci } 9953a5a1b3Sopenharmony_ci 10053a5a1b3Sopenharmony_ci if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t))) { 10153a5a1b3Sopenharmony_ci if (pa_parsehex(t, c->cookie_from_x11, sizeof(c->cookie_from_x11)) != sizeof(c->cookie_from_x11)) { 10253a5a1b3Sopenharmony_ci pa_log(_("Failed to parse cookie data")); 10353a5a1b3Sopenharmony_ci goto finish; 10453a5a1b3Sopenharmony_ci } 10553a5a1b3Sopenharmony_ci 10653a5a1b3Sopenharmony_ci c->cookie_from_x11_valid = true; 10753a5a1b3Sopenharmony_ci } 10853a5a1b3Sopenharmony_ci 10953a5a1b3Sopenharmony_ci ret = 0; 11053a5a1b3Sopenharmony_ci 11153a5a1b3Sopenharmony_cifinish: 11253a5a1b3Sopenharmony_ci if (xcb) 11353a5a1b3Sopenharmony_ci xcb_disconnect(xcb); 11453a5a1b3Sopenharmony_ci 11553a5a1b3Sopenharmony_ci return ret; 11653a5a1b3Sopenharmony_ci 11753a5a1b3Sopenharmony_ci} 118