• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <stdio.h>
25 #include <getopt.h>
26 #include <assert.h>
27 #include <locale.h>
28 
29 #include <xcb/xcb.h>
30 
31 #include <pulse/util.h>
32 #include <pulse/client-conf.h>
33 
34 #include <pulsecore/core-util.h>
35 #include <pulsecore/i18n.h>
36 #include <pulsecore/log.h>
37 #include <pulsecore/authkey.h>
38 #include <pulsecore/native-common.h>
39 #include <pulsecore/x11prop.h>
40 
main(int argc,char * argv[])41 int main(int argc, char *argv[]) {
42     const char *dname = NULL, *sink = NULL, *source = NULL, *server = NULL, *cookie_file = PA_NATIVE_COOKIE_FILE;
43     int c, ret = 1, screen = 0;
44     xcb_connection_t *xcb = NULL;
45     enum { DUMP, EXPORT, IMPORT, REMOVE } mode = DUMP;
46 
47     setlocale(LC_ALL, "");
48 #ifdef ENABLE_NLS
49     bindtextdomain(GETTEXT_PACKAGE, PULSE_LOCALEDIR);
50 #endif
51 
52     while ((c = getopt(argc, argv, "deiD:S:O:I:c:hr")) != -1) {
53         switch (c) {
54             case 'D' :
55                 dname = optarg;
56                 break;
57             case 'h':
58                 printf(_("%s [-D display] [-S server] [-O sink] [-I source] [-c file]  [-d|-e|-i|-r]\n\n"
59                        " -d    Show current PulseAudio data attached to X11 display (default)\n"
60                        " -e    Export local PulseAudio data to X11 display\n"
61                        " -i    Import PulseAudio data from X11 display to local environment variables and cookie file.\n"
62                        " -r    Remove PulseAudio data from X11 display\n"),
63                        pa_path_get_filename(argv[0]));
64                 ret = 0;
65                 goto finish;
66             case 'd':
67                 mode = DUMP;
68                 break;
69             case 'e':
70                 mode = EXPORT;
71                 break;
72             case 'i':
73                 mode = IMPORT;
74                 break;
75             case 'r':
76                 mode = REMOVE;
77                 break;
78             case 'c':
79                 cookie_file = optarg;
80                 break;
81             case 'I':
82                 source = optarg;
83                 break;
84             case 'O':
85                 sink = optarg;
86                 break;
87             case 'S':
88                 server = optarg;
89                 break;
90             default:
91                 fprintf(stderr, _("Failed to parse command line.\n"));
92                 goto finish;
93         }
94     }
95 
96     if (!(xcb = xcb_connect(dname, &screen))) {
97         pa_log(_("xcb_connect() failed"));
98         goto finish;
99     }
100 
101     if (xcb_connection_has_error(xcb)) {
102         pa_log(_("xcb_connection_has_error() returned true"));
103         goto finish;
104     }
105 
106     switch (mode) {
107         case DUMP: {
108             char t[1024];
109             if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t)))
110                 printf(_("Server: %s\n"), t);
111             if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t)))
112                 printf(_("Source: %s\n"), t);
113             if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t)))
114                 printf(_("Sink: %s\n"), t);
115             if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t)))
116                 printf(_("Cookie: %s\n"), t);
117 
118             break;
119         }
120 
121         case IMPORT: {
122             char t[1024];
123             if (pa_x11_get_prop(xcb, screen, "PULSE_SERVER", t, sizeof(t)))
124                 printf("PULSE_SERVER='%s'\nexport PULSE_SERVER\n", t);
125             if (pa_x11_get_prop(xcb, screen, "PULSE_SOURCE", t, sizeof(t)))
126                 printf("PULSE_SOURCE='%s'\nexport PULSE_SOURCE\n", t);
127             if (pa_x11_get_prop(xcb, screen, "PULSE_SINK", t, sizeof(t)))
128                 printf("PULSE_SINK='%s'\nexport PULSE_SINK\n", t);
129 
130             if (pa_x11_get_prop(xcb, screen, "PULSE_COOKIE", t, sizeof(t))) {
131                 uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
132                 size_t l;
133                 if ((l = pa_parsehex(t, cookie, sizeof(cookie))) != sizeof(cookie)) {
134                     fprintf(stderr, _("Failed to parse cookie data\n"));
135                     goto finish;
136                 }
137 
138                 if (pa_authkey_save(cookie_file, cookie, l) < 0) {
139                     fprintf(stderr, _("Failed to save cookie data\n"));
140                     goto finish;
141                 }
142             }
143 
144             break;
145         }
146 
147         case EXPORT: {
148             pa_client_conf *conf = pa_client_conf_new();
149             uint8_t cookie[PA_NATIVE_COOKIE_LENGTH];
150             char hx[PA_NATIVE_COOKIE_LENGTH*2+1];
151             assert(conf);
152 
153             pa_client_conf_load(conf, false, true);
154 
155             pa_x11_del_prop(xcb, screen, "PULSE_SERVER");
156             pa_x11_del_prop(xcb, screen, "PULSE_SINK");
157             pa_x11_del_prop(xcb, screen, "PULSE_SOURCE");
158             pa_x11_del_prop(xcb, screen, "PULSE_ID");
159             pa_x11_del_prop(xcb, screen, "PULSE_COOKIE");
160 
161             if (server)
162                 pa_x11_set_prop(xcb, screen, "PULSE_SERVER", server);
163             else if (conf->default_server)
164                 pa_x11_set_prop(xcb, screen, "PULSE_SERVER", conf->default_server);
165             else {
166                 char hn[256];
167                 if (!pa_get_fqdn(hn, sizeof(hn))) {
168                     fprintf(stderr, _("Failed to get FQDN.\n"));
169                     goto finish;
170                 }
171 
172                 pa_x11_set_prop(xcb, screen, "PULSE_SERVER", hn);
173             }
174 
175             if (sink)
176                 pa_x11_set_prop(xcb, screen, "PULSE_SINK", sink);
177             else if (conf->default_sink)
178                 pa_x11_set_prop(xcb, screen, "PULSE_SINK", conf->default_sink);
179 
180             if (source)
181                 pa_x11_set_prop(xcb, screen, "PULSE_SOURCE", source);
182             if (conf->default_source)
183                 pa_x11_set_prop(xcb, screen, "PULSE_SOURCE", conf->default_source);
184 
185             pa_client_conf_free(conf);
186 
187             if (pa_authkey_load(cookie_file, true, cookie, sizeof(cookie)) < 0) {
188                 fprintf(stderr, _("Failed to load cookie data\n"));
189                 goto finish;
190             }
191 
192             pa_x11_set_prop(xcb, screen, "PULSE_COOKIE", pa_hexstr(cookie, sizeof(cookie), hx, sizeof(hx)));
193             break;
194         }
195 
196         case REMOVE:
197             pa_x11_del_prop(xcb, screen, "PULSE_SERVER");
198             pa_x11_del_prop(xcb, screen, "PULSE_SINK");
199             pa_x11_del_prop(xcb, screen, "PULSE_SOURCE");
200             pa_x11_del_prop(xcb, screen, "PULSE_ID");
201             pa_x11_del_prop(xcb, screen, "PULSE_COOKIE");
202             pa_x11_del_prop(xcb, screen, "PULSE_SESSION_ID");
203             break;
204 
205         default:
206             fprintf(stderr, _("Not yet implemented.\n"));
207             goto finish;
208     }
209 
210     ret = 0;
211 
212 finish:
213 
214     if (xcb) {
215         xcb_flush(xcb);
216         xcb_disconnect(xcb);
217     }
218 
219     return ret;
220 }
221