2 * module-murphy-ivi -- PulseAudio module for providing audio routing support
3 * Copyright (c) 2012, Intel Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU Lesser General Public License,
7 * version 2.1, as published by the Free Software Foundation.
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.
12 * See the GNU Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this program; if not, write to the
16 * Free Software Foundation, Inc., 51 Franklin St - Fifth Floor, Boston,
25 #include <pulsecore/pulsecore-config.h>
27 #include <pulse/proplist.h>
28 #include <pulsecore/core-util.h>
29 #include <pulsecore/module.h>
31 #include "constrain.h"
36 static mir_constr_def *cstrdef_create(struct userdata *, const char *,
37 mir_constrain_func_t, const char *);
38 static void cstrdef_destroy(struct userdata *, mir_constr_def *);
40 static mir_constr_link *cstrlink_create(struct userdata *, mir_constr_def *,
42 static void cstrlink_destroy(struct userdata *, mir_constr_link *);
45 static void pa_hashmap_constrdef_free(void *cd, void *u)
47 cstrdef_destroy(u, cd);
51 pa_constrain *pa_constrain_init(struct userdata *u)
53 pa_constrain *constrain = pa_xnew0(pa_constrain, 1);
55 constrain->defs = pa_hashmap_new(pa_idxset_string_hash_func,
56 pa_idxset_string_compare_func);
60 void pa_constrain_done(struct userdata *u)
62 pa_constrain *constrain;
66 if (u && (constrain = u->constrain)) {
67 PA_HASHMAP_FOREACH(cd, constrain->defs, state) {
68 cstrdef_destroy(u, cd);
71 pa_hashmap_free(constrain->defs);
80 mir_constr_def *mir_constrain_create(struct userdata *u, const char *name,
81 mir_constrain_func_t func,
84 pa_constrain *constrain;
91 pa_assert_se((constrain = u->constrain));
93 if ((cd = mir_constrain_find(u, key))) {
94 if (pa_streq(name, cd->name) && func == cd->func)
97 pa_log_debug("attempt to redefine constrain %s/%s => %s/%s",
98 cd->name,cd->key, name,key);
103 cd = cstrdef_create(u, name, func, key);
105 if (pa_hashmap_put(constrain->defs, cd->key, cd) < 0) {
112 pa_log_debug("constrain %s/%s created", cd->name, cd->key);
117 void mir_constrain_destroy(struct userdata *u, const char *key)
119 pa_constrain *constrain;
124 pa_assert_se((constrain = u->constrain));
126 if ((cd = pa_hashmap_remove(constrain->defs, key))) {
127 pa_log_debug("destroying constrain %s/%s", cd->name, cd->key);
128 cstrdef_destroy(u, cd);
132 mir_constr_def *mir_constrain_find(struct userdata *u, const char *key)
134 pa_constrain *constrain;
139 pa_assert_se((constrain = u->constrain));
141 cd = pa_hashmap_get(constrain->defs, key);
147 void mir_constrain_add_node(struct userdata *u,
157 cl = cstrlink_create(u, cd, node);
159 MIR_DLIST_APPEND(mir_constr_link, link, cl, &cd->nodes);
160 MIR_DLIST_APPEND(mir_constr_link, nodchain, cl, &node->constrains);
162 pa_log_debug("node '%s' added to constrain %s/%s",
163 node->amname, cd->name, cd->key);
167 void mir_constrain_remove_node(struct userdata *u, mir_node *node)
170 mir_constr_link *cl, *n;
175 MIR_DLIST_FOR_EACH_SAFE(mir_constr_link,nodchain, cl,n, &node->constrains){
176 pa_assert_se((cd = cl->def));
178 pa_log_debug("node '%s' removed from constrain %s/%s",
179 node->amname, cd->name, cd->key);
181 cstrlink_destroy(u, cl);
186 void mir_constrain_apply(struct userdata *u, mir_node *node, uint32_t stamp)
199 MIR_DLIST_FOR_EACH(mir_constr_link, nodchain, cl, &node->constrains) {
200 pa_assert(node == cl->node);
201 pa_assert_se((cd = cl->def));
203 pa_log_debug("applying constrain %s/%s", cd->name, cd->key);
205 MIR_DLIST_FOR_EACH(mir_constr_link, link, c, &cd->nodes) {
207 blocked = cd->func(u, cd, node, n);
209 MIR_DLIST_FOR_EACH(mir_rtentry, nodchain, rte, &n->rtentries) {
210 pa_assert_se((rtg = rte->group));
212 rte->blocked = blocked;
215 pa_log_debug(" %sblocking '%s' in table '%s'",
216 blocked ? "":"un", n->amname, rtg->name);
222 int mir_constrain_print(mir_node *node, char *buf, int len)
237 MIR_DLIST_FOR_EACH(mir_constr_link, nodchain, cl, &node->constrains) {
243 p += snprintf(p, e-p, "%s'%s'", s, cd->name);
250 bool mir_constrain_port(struct userdata *u,
264 pa_assert_se((active_port = active->paport));
265 pa_assert_se((node_port = node->paport));
267 block = !pa_streq(active_port, node_port);
272 bool mir_constrain_profile(struct userdata *u,
277 char *active_profile;
286 pa_assert_se((active_profile = active->pacard.profile));
287 pa_assert_se((node_profile = node->pacard.profile));
289 block = !pa_streq(active_profile, node_profile);
294 static mir_constr_def *cstrdef_create(struct userdata *u,
296 mir_constrain_func_t func,
306 cd = pa_xnew0(mir_constr_def, 1);
307 cd->key = pa_xstrdup(key);
308 cd->name = pa_xstrdup(name);
310 MIR_DLIST_INIT(cd->nodes);
315 static void cstrdef_destroy(struct userdata *u, mir_constr_def *cd)
317 mir_constr_link *cl, *n;
322 MIR_DLIST_FOR_EACH_SAFE(mir_constr_link, link, cl,n, &cd->nodes) {
323 cstrlink_destroy(u, cl);
331 static mir_constr_link *cstrlink_create(struct userdata *u,
341 cl = pa_xnew0(mir_constr_link, 1);
344 MIR_DLIST_INIT(cl->link);
345 MIR_DLIST_INIT(cl->nodchain);
350 static void cstrlink_destroy(struct userdata *u, mir_constr_link *cl)
355 MIR_DLIST_UNLINK(mir_constr_link, link, cl);
356 MIR_DLIST_UNLINK(mir_constr_link, nodchain, cl);
365 * indent-tabs-mode: nil