]> code.delx.au - pulseaudio/blob - src/pulsecore/cli-text.c
big s/polyp/pulse/g
[pulseaudio] / src / pulsecore / cli-text.c
1 /* $Id$ */
2
3 /***
4 This file is part of PulseAudio.
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 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, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19 USA.
20 ***/
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <assert.h>
27 #include <string.h>
28
29 #include <pulse/volume.h>
30 #include <pulse/xmalloc.h>
31
32 #include <pulsecore/module.h>
33 #include <pulsecore/client.h>
34 #include <pulsecore/sink.h>
35 #include <pulsecore/source.h>
36 #include <pulsecore/sink-input.h>
37 #include <pulsecore/source-output.h>
38 #include <pulsecore/strbuf.h>
39 #include <pulsecore/sample-util.h>
40 #include <pulsecore/core-scache.h>
41 #include <pulsecore/autoload.h>
42
43 #include "cli-text.h"
44
45 char *pa_module_list_to_string(pa_core *c) {
46 pa_strbuf *s;
47 pa_module *m;
48 uint32_t idx = PA_IDXSET_INVALID;
49 assert(c);
50
51 s = pa_strbuf_new();
52 assert(s);
53
54 pa_strbuf_printf(s, "%u module(s) loaded.\n", pa_idxset_size(c->modules));
55
56 for (m = pa_idxset_first(c->modules, &idx); m; m = pa_idxset_next(c->modules, &idx))
57 pa_strbuf_printf(s, " index: %u\n\tname: <%s>\n\targument: <%s>\n\tused: %i\n\tauto unload: %s\n", m->index, m->name, m->argument, m->n_used, m->auto_unload ? "yes" : "no");
58
59 return pa_strbuf_tostring_free(s);
60 }
61
62 char *pa_client_list_to_string(pa_core *c) {
63 pa_strbuf *s;
64 pa_client *client;
65 uint32_t idx = PA_IDXSET_INVALID;
66 assert(c);
67
68 s = pa_strbuf_new();
69 assert(s);
70
71 pa_strbuf_printf(s, "%u client(s) logged in.\n", pa_idxset_size(c->clients));
72
73 for (client = pa_idxset_first(c->clients, &idx); client; client = pa_idxset_next(c->clients, &idx)) {
74 pa_strbuf_printf(s, " index: %u\n\tname: <%s>\n\tdriver: <%s>\n", client->index, client->name, client->driver);
75
76 if (client->owner)
77 pa_strbuf_printf(s, "\towner module: <%u>\n", client->owner->index);
78 }
79
80 return pa_strbuf_tostring_free(s);
81 }
82
83 char *pa_sink_list_to_string(pa_core *c) {
84 pa_strbuf *s;
85 pa_sink *sink;
86 uint32_t idx = PA_IDXSET_INVALID;
87 assert(c);
88
89 s = pa_strbuf_new();
90 assert(s);
91
92 pa_strbuf_printf(s, "%u sink(s) available.\n", pa_idxset_size(c->sinks));
93
94 for (sink = pa_idxset_first(c->sinks, &idx); sink; sink = pa_idxset_next(c->sinks, &idx)) {
95 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
96
97 pa_strbuf_printf(
98 s,
99 " %c index: %u\n"
100 "\tname: <%s>\n"
101 "\tdriver: <%s>\n"
102 "\tvolume: <%s>\n"
103 "\tlatency: <%0.0f usec>\n"
104 "\tmonitor_source: <%u>\n"
105 "\tsample spec: <%s>\n"
106 "\tchannel map: <%s>\n",
107 c->default_sink_name && !strcmp(sink->name, c->default_sink_name) ? '*' : ' ',
108 sink->index, sink->name,
109 sink->driver,
110 pa_cvolume_snprint(cv, sizeof(cv), pa_sink_get_volume(sink, PA_MIXER_HARDWARE)),
111 (double) pa_sink_get_latency(sink),
112 sink->monitor_source->index,
113 pa_sample_spec_snprint(ss, sizeof(ss), &sink->sample_spec),
114 pa_channel_map_snprint(cm, sizeof(cm), &sink->channel_map));
115
116 if (sink->owner)
117 pa_strbuf_printf(s, "\towner module: <%u>\n", sink->owner->index);
118 if (sink->description)
119 pa_strbuf_printf(s, "\tdescription: <%s>\n", sink->description);
120 }
121
122 return pa_strbuf_tostring_free(s);
123 }
124
125 char *pa_source_list_to_string(pa_core *c) {
126 pa_strbuf *s;
127 pa_source *source;
128 uint32_t idx = PA_IDXSET_INVALID;
129 assert(c);
130
131 s = pa_strbuf_new();
132 assert(s);
133
134 pa_strbuf_printf(s, "%u source(s) available.\n", pa_idxset_size(c->sources));
135
136 for (source = pa_idxset_first(c->sources, &idx); source; source = pa_idxset_next(c->sources, &idx)) {
137 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
138
139
140 pa_strbuf_printf(
141 s,
142 " %c index: %u\n"
143 "\tname: <%s>\n"
144 "\tdriver: <%s>\n"
145 "\tlatency: <%0.0f usec>\n"
146 "\tsample spec: <%s>\n"
147 "\tchannel map: <%s>\n",
148 c->default_source_name && !strcmp(source->name, c->default_source_name) ? '*' : ' ',
149 source->index,
150 source->name,
151 source->driver,
152 (double) pa_source_get_latency(source),
153 pa_sample_spec_snprint(ss, sizeof(ss), &source->sample_spec),
154 pa_channel_map_snprint(cm, sizeof(cm), &source->channel_map));
155
156 if (source->monitor_of)
157 pa_strbuf_printf(s, "\tmonitor_of: <%u>\n", source->monitor_of->index);
158 if (source->owner)
159 pa_strbuf_printf(s, "\towner module: <%u>\n", source->owner->index);
160 if (source->description)
161 pa_strbuf_printf(s, "\tdescription: <%s>\n", source->description);
162 }
163
164 return pa_strbuf_tostring_free(s);
165 }
166
167
168 char *pa_source_output_list_to_string(pa_core *c) {
169 pa_strbuf *s;
170 pa_source_output *o;
171 uint32_t idx = PA_IDXSET_INVALID;
172 static const char* const state_table[] = {
173 "RUNNING",
174 "CORKED",
175 "DISCONNECTED"
176 };
177 assert(c);
178
179 s = pa_strbuf_new();
180 assert(s);
181
182 pa_strbuf_printf(s, "%u source outputs(s) available.\n", pa_idxset_size(c->source_outputs));
183
184 for (o = pa_idxset_first(c->source_outputs, &idx); o; o = pa_idxset_next(c->source_outputs, &idx)) {
185 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
186
187 assert(o->source);
188
189 pa_strbuf_printf(
190 s,
191 " index: %u\n"
192 "\tname: '%s'\n"
193 "\tdriver: <%s>\n"
194 "\tstate: %s\n"
195 "\tsource: <%u> '%s'\n"
196 "\tsample spec: <%s>\n"
197 "\tchannel map: <%s>\n"
198 "\tresample method: %s\n",
199 o->index,
200 o->name,
201 o->driver,
202 state_table[o->state],
203 o->source->index, o->source->name,
204 pa_sample_spec_snprint(ss, sizeof(ss), &o->sample_spec),
205 pa_channel_map_snprint(cm, sizeof(cm), &o->channel_map),
206 pa_resample_method_to_string(pa_source_output_get_resample_method(o)));
207 if (o->owner)
208 pa_strbuf_printf(s, "\towner module: <%u>\n", o->owner->index);
209 if (o->client)
210 pa_strbuf_printf(s, "\tclient: <%u> '%s'\n", o->client->index, o->client->name);
211 }
212
213 return pa_strbuf_tostring_free(s);
214 }
215
216 char *pa_sink_input_list_to_string(pa_core *c) {
217 pa_strbuf *s;
218 pa_sink_input *i;
219 uint32_t idx = PA_IDXSET_INVALID;
220 static const char* const state_table[] = {
221 "RUNNING",
222 "CORKED",
223 "DISCONNECTED"
224 };
225
226 assert(c);
227 s = pa_strbuf_new();
228 assert(s);
229
230 pa_strbuf_printf(s, "%u sink input(s) available.\n", pa_idxset_size(c->sink_inputs));
231
232 for (i = pa_idxset_first(c->sink_inputs, &idx); i; i = pa_idxset_next(c->sink_inputs, &idx)) {
233 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX], cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX];
234
235 assert(i->sink);
236
237 pa_strbuf_printf(
238 s,
239 " index: %u\n"
240 "\tname: <%s>\n"
241 "\tdriver: <%s>\n"
242 "\tstate: %s\n"
243 "\tsink: <%u> '%s'\n"
244 "\tvolume: <%s>\n"
245 "\tlatency: <%0.0f usec>\n"
246 "\tsample spec: <%s>\n"
247 "\tchannel map: <%s>\n"
248 "\tresample method: %s\n",
249 i->index,
250 i->name,
251 i->driver,
252 state_table[i->state],
253 i->sink->index, i->sink->name,
254 pa_cvolume_snprint(cv, sizeof(cv), pa_sink_input_get_volume(i)),
255 (double) pa_sink_input_get_latency(i),
256 pa_sample_spec_snprint(ss, sizeof(ss), &i->sample_spec),
257 pa_channel_map_snprint(cm, sizeof(cm), &i->channel_map),
258 pa_resample_method_to_string(pa_sink_input_get_resample_method(i)));
259
260 if (i->owner)
261 pa_strbuf_printf(s, "\towner module: <%u>\n", i->owner->index);
262 if (i->client)
263 pa_strbuf_printf(s, "\tclient: <%u> '%s'\n", i->client->index, i->client->name);
264 }
265
266 return pa_strbuf_tostring_free(s);
267 }
268
269 char *pa_scache_list_to_string(pa_core *c) {
270 pa_strbuf *s;
271 assert(c);
272
273 s = pa_strbuf_new();
274 assert(s);
275
276 pa_strbuf_printf(s, "%u cache entries available.\n", c->scache ? pa_idxset_size(c->scache) : 0);
277
278 if (c->scache) {
279 pa_scache_entry *e;
280 uint32_t idx = PA_IDXSET_INVALID;
281
282 for (e = pa_idxset_first(c->scache, &idx); e; e = pa_idxset_next(c->scache, &idx)) {
283 double l = 0;
284 char ss[PA_SAMPLE_SPEC_SNPRINT_MAX] = "n/a", cv[PA_CVOLUME_SNPRINT_MAX], cm[PA_CHANNEL_MAP_SNPRINT_MAX] = "n/a";
285
286 if (e->memchunk.memblock) {
287 pa_sample_spec_snprint(ss, sizeof(ss), &e->sample_spec);
288 pa_channel_map_snprint(cm, sizeof(cm), &e->channel_map);
289 l = (double) e->memchunk.length / pa_bytes_per_second(&e->sample_spec);
290 }
291
292 pa_strbuf_printf(
293 s,
294 " name: <%s>\n"
295 "\tindex: <%u>\n"
296 "\tsample spec: <%s>\n"
297 "\tchannel map: <%s>\n"
298 "\tlength: <%lu>\n"
299 "\tduration: <%0.1fs>\n"
300 "\tvolume: <%s>\n"
301 "\tlazy: %s\n"
302 "\tfilename: %s\n",
303 e->name,
304 e->index,
305 ss,
306 cm,
307 (long unsigned)(e->memchunk.memblock ? e->memchunk.length : 0),
308 l,
309 pa_cvolume_snprint(cv, sizeof(cv), &e->volume),
310 e->lazy ? "yes" : "no",
311 e->filename ? e->filename : "n/a");
312 }
313 }
314
315 return pa_strbuf_tostring_free(s);
316 }
317
318 char *pa_autoload_list_to_string(pa_core *c) {
319 pa_strbuf *s;
320 assert(c);
321
322 s = pa_strbuf_new();
323 assert(s);
324
325 pa_strbuf_printf(s, "%u autoload entries available.\n", c->autoload_hashmap ? pa_hashmap_size(c->autoload_hashmap) : 0);
326
327 if (c->autoload_hashmap) {
328 pa_autoload_entry *e;
329 void *state = NULL;
330
331 while ((e = pa_hashmap_iterate(c->autoload_hashmap, &state, NULL))) {
332 pa_strbuf_printf(
333 s, " name: <%s>\n\ttype: <%s>\n\tindex: <%u>\n\tmodule_name: <%s>\n\targuments: <%s>\n",
334 e->name,
335 e->type == PA_NAMEREG_SOURCE ? "source" : "sink",
336 e->index,
337 e->module,
338 e->argument);
339
340 }
341 }
342
343 return pa_strbuf_tostring_free(s);
344 }
345
346 char *pa_full_status_string(pa_core *c) {
347 pa_strbuf *s;
348 int i;
349
350 s = pa_strbuf_new();
351
352 for (i = 0; i < 8; i++) {
353 char *t = NULL;
354
355 switch (i) {
356 case 0:
357 t = pa_sink_list_to_string(c);
358 break;
359 case 1:
360 t = pa_source_list_to_string(c);
361 break;
362 case 2:
363 t = pa_sink_input_list_to_string(c);
364 break;
365 case 3:
366 t = pa_source_output_list_to_string(c);
367 break;
368 case 4:
369 t = pa_client_list_to_string(c);
370 break;
371 case 5:
372 t = pa_module_list_to_string(c);
373 break;
374 case 6:
375 t = pa_scache_list_to_string(c);
376 break;
377 case 7:
378 t = pa_autoload_list_to_string(c);
379 break;
380 }
381
382 pa_strbuf_puts(s, t);
383 pa_xfree(t);
384 }
385
386 return pa_strbuf_tostring_free(s);
387 }