1/***
2  This file is part of PulseAudio.
3
4  Copyright 2004-2006 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 published
8  by the Free Software Foundation; either version 2.1 of the License,
9  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  General Public License for more details.
15
16  You should have received a copy of the GNU Lesser General Public License
17  along with PulseAudio; if not, see <http://www.gnu.org/licenses/>.
18***/
19
20#ifdef HAVE_CONFIG_H
21#include <config.h>
22#endif
23
24#include <string.h>
25
26#include <xcb/xcb.h>
27
28#include <pulse/xmalloc.h>
29
30#include <pulsecore/i18n.h>
31#include <pulsecore/x11prop.h>
32#include <pulsecore/log.h>
33#include <pulsecore/core-util.h>
34#include <pulsecore/macro.h>
35
36#include "client-conf-x11.h"
37
38int pa_client_conf_from_x11(pa_client_conf *c) {
39    const char *dname;
40    xcb_connection_t *xcb = NULL;
41    int ret = -1, screen = 0;
42    char t[1024];
43
44    pa_assert(c);
45
46    /* Local connections will have configuration and X root window
47     * properties match 1:1, these paths are only strictly necessary
48     * for remote clients, so check for SSH_CONNECTION to make sure
49     * this is a remote session with X forwarding.
50     */
51    if (!getenv("SSH_CONNECTION"))
52        goto finish;
53
54    if (!(dname = getenv("DISPLAY")))
55        goto finish;
56
57    if (*dname == 0)
58        goto finish;
59
60    if (!(xcb = xcb_connect(dname, NULL))) {
61        pa_log(_("xcb_connect() failed"));
62        goto finish;
63    }
64
65    if (xcb_connection_has_error(xcb)) {
66        pa_log(_("xcb_connection_has_error() returned true"));
67        goto finish;
68    }
69
70    if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t))) {
71        bool disable_autospawn = true;
72
73        pa_xfree(c->default_server);
74        c->default_server = pa_xstrdup(t);
75
76        if (pa_x11_get_prop(xcb, screen, "PULSE_SESSION_ID", t, sizeof(t))) {
77            char *id;
78
79            if ((id = pa_session_id())) {
80                if (pa_streq(t, id))
81                    disable_autospawn = false;
82                pa_xfree(id);
83            }
84        }
85
86        if (disable_autospawn)
87            c->autospawn = false;
88    }
89
90    if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t))) {
91        pa_xfree(c->default_sink);
92        c->default_sink = pa_xstrdup(t);
93    }
94
95    if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t))) {
96        pa_xfree(c->default_source);
97        c->default_source = pa_xstrdup(t);
98    }
99
100    if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t))) {
101        if (pa_parsehex(t, c->cookie_from_x11, sizeof(c->cookie_from_x11)) != sizeof(c->cookie_from_x11)) {
102            pa_log(_("Failed to parse cookie data"));
103            goto finish;
104        }
105
106        c->cookie_from_x11_valid = true;
107    }
108
109    ret = 0;
110
111finish:
112    if (xcb)
113        xcb_disconnect(xcb);
114
115    return ret;
116
117}
118