]> code.delx.au - pulseaudio/blob - polyp/autoload.c
12cd1f91e1bd218792f5d85e562662d8e05b03b5
[pulseaudio] / polyp / autoload.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 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 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 <assert.h>
27 #include <stdlib.h>
28 #include <string.h>
29
30 #include "autoload.h"
31 #include "module.h"
32 #include "xmalloc.h"
33 #include "memchunk.h"
34 #include "sound-file.h"
35 #include "log.h"
36 #include "scache.h"
37 #include "subscribe.h"
38
39 static void entry_free(struct pa_autoload_entry *e) {
40 assert(e);
41 pa_subscription_post(e->core, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_REMOVE, PA_INVALID_INDEX);
42 pa_xfree(e->name);
43 pa_xfree(e->module);
44 pa_xfree(e->argument);
45 pa_xfree(e);
46 }
47
48 static struct pa_autoload_entry* entry_new(struct pa_core *c, const char *name) {
49 struct pa_autoload_entry *e = NULL;
50 assert(c && name);
51
52 if (c->autoload_hashmap && (e = pa_hashmap_get(c->autoload_hashmap, name)))
53 return NULL;
54
55 e = pa_xmalloc(sizeof(struct pa_autoload_entry));
56 e->core = c;
57 e->name = pa_xstrdup(name);
58 e->module = e->argument = NULL;
59 e->in_action = 0;
60
61 if (!c->autoload_hashmap)
62 c->autoload_hashmap = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
63 assert(c->autoload_hashmap);
64
65 pa_hashmap_put(c->autoload_hashmap, e->name, e);
66
67 pa_subscription_post(c, PA_SUBSCRIPTION_EVENT_AUTOLOAD|PA_SUBSCRIPTION_EVENT_NEW, PA_INVALID_INDEX);
68
69 return e;
70 }
71
72 int pa_autoload_add(struct pa_core *c, const char*name, enum pa_namereg_type type, const char*module, const char *argument) {
73 struct pa_autoload_entry *e = NULL;
74 assert(c && name && module && (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE));
75
76 if (!(e = entry_new(c, name)))
77 return -1;
78
79 e->module = pa_xstrdup(module);
80 e->argument = pa_xstrdup(argument);
81 e->type = type;
82 return 0;
83 }
84
85 int pa_autoload_remove(struct pa_core *c, const char*name, enum pa_namereg_type type) {
86 struct pa_autoload_entry *e;
87 assert(c && name && type);
88
89 if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)))
90 return -1;
91
92 pa_hashmap_remove(c->autoload_hashmap, e->name);
93 entry_free(e);
94 return 0;
95 }
96
97 void pa_autoload_request(struct pa_core *c, const char *name, enum pa_namereg_type type) {
98 struct pa_autoload_entry *e;
99 struct pa_module *m;
100 assert(c && name);
101
102 if (!c->autoload_hashmap || !(e = pa_hashmap_get(c->autoload_hashmap, name)) || (e->type != type))
103 return;
104
105 if (e->in_action)
106 return;
107
108 e->in_action = 1;
109
110 if (type == PA_NAMEREG_SINK || type == PA_NAMEREG_SOURCE) {
111 if ((m = pa_module_load(c, e->module, e->argument)))
112 m->auto_unload = 1;
113 }
114
115 e->in_action = 0;
116 }
117
118 static void free_func(void *p, void *userdata) {
119 struct pa_autoload_entry *e = p;
120 entry_free(e);
121 }
122
123 void pa_autoload_free(struct pa_core *c) {
124 if (!c->autoload_hashmap)
125 return;
126
127 pa_hashmap_free(c->autoload_hashmap, free_func, NULL);
128 }