cf11f5a4deb00877acd49863ecb63c1e200a6a84
[profile/ivi/pulseaudio.git] / src / polypcore / namereg.c
1 /* $Id$ */
2
3 /***
4   This file is part of polypaudio.
5  
6   polypaudio 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   polypaudio 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 polypaudio; 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 <stdlib.h>
27 #include <string.h>
28 #include <assert.h>
29 #include <string.h>
30 #include <stdio.h>
31
32 #include <polyp/xmalloc.h>
33
34 #include <polypcore/autoload.h>
35 #include <polypcore/source.h>
36 #include <polypcore/sink.h>
37 #include <polypcore/core-subscribe.h>
38 #include <polypcore/util.h>
39
40 #include "namereg.h"
41
42 struct namereg_entry {
43     pa_namereg_type_t type;
44     char *name;
45     void *data;
46 };
47
48 void pa_namereg_free(pa_core *c) {
49     assert(c);
50     if (!c->namereg)
51         return;
52     assert(pa_hashmap_size(c->namereg) == 0);
53     pa_hashmap_free(c->namereg, NULL, NULL);
54 }
55
56 const char *pa_namereg_register(pa_core *c, const char *name, pa_namereg_type_t type, void *data, int fail) {
57     struct namereg_entry *e;
58     char *n = NULL;
59     int r;
60     
61     assert(c && name && data);
62
63     if (!c->namereg) {
64         c->namereg = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
65         assert(c->namereg);
66     }
67
68     if ((e = pa_hashmap_get(c->namereg, name)) && fail)
69         return NULL;
70
71     if (!e)
72         n = pa_xstrdup(name);
73     else {
74         unsigned i;
75         size_t l = strlen(name);
76         n = pa_xmalloc(l+3);
77         
78         for (i = 1; i <= 99; i++) {
79             snprintf(n, l+2, "%s%u", name, i);
80
81             if (!(e = pa_hashmap_get(c->namereg, n)))
82                 break;
83         }
84
85         if (e) {
86             pa_xfree(n);
87             return NULL;
88         }
89     }
90     
91     assert(n);
92     e = pa_xmalloc(sizeof(struct namereg_entry));
93     e->type = type;
94     e->name = n;
95     e->data = data;
96
97     r = pa_hashmap_put(c->namereg, e->name, e);
98     assert (r >= 0);
99
100     return e->name;
101     
102 }
103
104 void pa_namereg_unregister(pa_core *c, const char *name) {
105     struct namereg_entry *e;
106     assert(c && name);
107
108     e = pa_hashmap_remove(c->namereg, name);
109     assert(e);
110
111     pa_xfree(e->name);
112     pa_xfree(e);
113 }
114
115 void* pa_namereg_get(pa_core *c, const char *name, pa_namereg_type_t type, int autoload) {
116     struct namereg_entry *e;
117     uint32_t idx;
118     assert(c);
119     
120     if (!name) {
121         if (type == PA_NAMEREG_SOURCE)
122             name = pa_namereg_get_default_source_name(c);
123         else if (type == PA_NAMEREG_SINK)
124             name = pa_namereg_get_default_sink_name(c);
125     }
126
127     if (!name)
128         return NULL;
129     
130     if (c->namereg && (e = pa_hashmap_get(c->namereg, name)))
131         if (e->type == type)
132             return e->data;
133
134     if (pa_atou(name, &idx) < 0) {
135
136         if (autoload) {
137             pa_autoload_request(c, name, type);
138             
139             if (c->namereg && (e = pa_hashmap_get(c->namereg, name)))
140                 if (e->type == type)
141                     return e->data;
142         }
143         
144         return NULL;
145     }
146
147     if (type == PA_NAMEREG_SINK)
148         return pa_idxset_get_by_index(c->sinks, idx);
149     else if (type == PA_NAMEREG_SOURCE)
150         return pa_idxset_get_by_index(c->sources, idx);
151     else if (type == PA_NAMEREG_SAMPLE && c->scache)
152         return pa_idxset_get_by_index(c->scache, idx);
153
154     return NULL;
155 }
156
157 void pa_namereg_set_default(pa_core*c, const char *name, pa_namereg_type_t type) {
158     char **s;
159     assert(c && (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE));
160
161     s = type == PA_NAMEREG_SINK ? &c->default_sink_name : &c->default_source_name;
162     assert(s);
163
164     if (!name && !*s)
165         return;
166     
167     if (name && *s && !strcmp(name, *s))
168         return;
169     
170     pa_xfree(*s);
171     *s = pa_xstrdup(name);
172     pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_SERVER|PA_SUBSCRIPTION_EVENT_CHANGE, PA_INVALID_INDEX);
173 }
174
175 const char *pa_namereg_get_default_sink_name(pa_core *c) {
176     pa_sink *s;
177     assert(c);
178
179     if (c->default_sink_name)
180         return c->default_sink_name;
181     
182     if ((s = pa_idxset_first(c->sinks, NULL)))
183         pa_namereg_set_default(c, s->name, PA_NAMEREG_SINK);
184
185     if (c->default_sink_name)
186         return c->default_sink_name;
187
188     return NULL;
189 }
190
191 const char *pa_namereg_get_default_source_name(pa_core *c) {
192     pa_source *s;
193     uint32_t idx;
194     
195     assert(c);
196
197     if (c->default_source_name)
198         return c->default_source_name;
199
200     for (s = pa_idxset_first(c->sources, &idx); s; s = pa_idxset_next(c->sources, &idx))
201         if (!s->monitor_of) {
202             pa_namereg_set_default(c, s->name, PA_NAMEREG_SOURCE);
203             break;
204         }
205
206     if (!c->default_source_name)
207         if ((s = pa_idxset_first(c->sources, NULL)))
208             pa_namereg_set_default(c, s->name, PA_NAMEREG_SOURCE);
209
210     if (c->default_source_name)
211         return c->default_source_name;
212
213     return NULL;
214 }