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