]> code.delx.au - pulseaudio/blob - polyp/subscribe.c
add missing copyright headers
[pulseaudio] / polyp / subscribe.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 <stdio.h>
27 #include <assert.h>
28
29 #include "queue.h"
30 #include "subscribe.h"
31 #include "xmalloc.h"
32
33 struct pa_subscription {
34 struct pa_core *core;
35 int dead;
36 void (*callback)(struct pa_core *c, enum pa_subscription_event_type t, uint32_t index, void *userdata);
37 void *userdata;
38 enum pa_subscription_mask mask;
39
40 struct pa_subscription *prev, *next;
41 };
42
43 struct pa_subscription_event {
44 enum pa_subscription_event_type type;
45 uint32_t index;
46 };
47
48 static void sched_event(struct pa_core *c);
49
50 struct pa_subscription* pa_subscription_new(struct pa_core *c, enum pa_subscription_mask m, void (*callback)(struct pa_core *c, enum pa_subscription_event_type t, uint32_t index, void *userdata), void *userdata) {
51 struct pa_subscription *s;
52 assert(c);
53
54 s = pa_xmalloc(sizeof(struct pa_subscription));
55 s->core = c;
56 s->dead = 0;
57 s->callback = callback;
58 s->userdata = userdata;
59 s->mask = m;
60
61 if ((s->next = c->subscriptions))
62 s->next->prev = s;
63 s->prev = NULL;
64 c->subscriptions = s;
65 return s;
66 }
67
68 void pa_subscription_free(struct pa_subscription*s) {
69 assert(s && !s->dead);
70 s->dead = 1;
71 sched_event(s->core);
72 }
73
74 static void free_item(struct pa_subscription *s) {
75 assert(s && s->core);
76
77 if (s->prev)
78 s->prev->next = s->next;
79 else
80 s->core->subscriptions = s->next;
81
82 if (s->next)
83 s->next->prev = s->prev;
84
85 pa_xfree(s);
86 }
87
88 void pa_subscription_free_all(struct pa_core *c) {
89 struct pa_subscription_event *e;
90 assert(c);
91
92 while (c->subscriptions)
93 free_item(c->subscriptions);
94
95 if (c->subscription_event_queue) {
96 while ((e = pa_queue_pop(c->subscription_event_queue)))
97 pa_xfree(e);
98
99 pa_queue_free(c->subscription_event_queue, NULL, NULL);
100 c->subscription_event_queue = NULL;
101 }
102
103 if (c->subscription_defer_event) {
104 c->mainloop->defer_free(c->subscription_defer_event);
105 c->subscription_defer_event = NULL;
106 }
107 }
108
109 /*static void dump_event(struct pa_subscription_event*e) {
110 switch (e->type & PA_SUBSCRIPTION_EVENT_FACILITY_MASK) {
111 case PA_SUBSCRIPTION_EVENT_SINK:
112 fprintf(stderr, "SINK_EVENT");
113 break;
114 case PA_SUBSCRIPTION_EVENT_SOURCE:
115 fprintf(stderr, "SOURCE_EVENT");
116 break;
117 case PA_SUBSCRIPTION_EVENT_SINK_INPUT:
118 fprintf(stderr, "SINK_INPUT_EVENT");
119 break;
120 case PA_SUBSCRIPTION_EVENT_SOURCE_OUTPUT:
121 fprintf(stderr, "SOURCE_OUTPUT_EVENT");
122 break;
123 case PA_SUBSCRIPTION_EVENT_MODULE:
124 fprintf(stderr, "MODULE_EVENT");
125 break;
126 case PA_SUBSCRIPTION_EVENT_CLIENT:
127 fprintf(stderr, "CLIENT_EVENT");
128 break;
129 default:
130 fprintf(stderr, "OTHER");
131 break;
132 }
133
134 switch (e->type & PA_SUBSCRIPTION_EVENT_TYPE_MASK) {
135 case PA_SUBSCRIPTION_EVENT_NEW:
136 fprintf(stderr, " NEW");
137 break;
138 case PA_SUBSCRIPTION_EVENT_CHANGE:
139 fprintf(stderr, " CHANGE");
140 break;
141 case PA_SUBSCRIPTION_EVENT_REMOVE:
142 fprintf(stderr, " REMOVE");
143 break;
144 default:
145 fprintf(stderr, " OTHER");
146 break;
147 }
148
149 fprintf(stderr, " %u\n", e->index);
150 }*/
151
152 static void defer_cb(struct pa_mainloop_api *m, struct pa_defer_event *e, void *userdata) {
153 struct pa_core *c = userdata;
154 struct pa_subscription *s;
155 assert(c && c->subscription_defer_event == e && c->mainloop == m);
156
157 c->mainloop->defer_enable(c->subscription_defer_event, 0);
158
159
160 /* Dispatch queued events */
161
162 if (c->subscription_event_queue) {
163 struct pa_subscription_event *e;
164
165 while ((e = pa_queue_pop(c->subscription_event_queue))) {
166 struct pa_subscription *s;
167
168 for (s = c->subscriptions; s; s = s->next) {
169
170 if (!s->dead && pa_subscription_match_flags(s->mask, e->type))
171 s->callback(c, e->type, e->index, s->userdata);
172 }
173
174 pa_xfree(e);
175 }
176 }
177
178 /* Remove dead subscriptions */
179
180 s = c->subscriptions;
181 while (s) {
182 struct pa_subscription *n = s->next;
183 if (s->dead)
184 free_item(s);
185 s = n;
186 }
187 }
188
189 static void sched_event(struct pa_core *c) {
190 assert(c);
191
192 if (!c->subscription_defer_event) {
193 c->subscription_defer_event = c->mainloop->defer_new(c->mainloop, defer_cb, c);
194 assert(c->subscription_defer_event);
195 }
196
197 c->mainloop->defer_enable(c->subscription_defer_event, 1);
198 }
199
200
201 void pa_subscription_post(struct pa_core *c, enum pa_subscription_event_type t, uint32_t index) {
202 struct pa_subscription_event *e;
203 assert(c);
204
205 e = pa_xmalloc(sizeof(struct pa_subscription_event));
206 e->type = t;
207 e->index = index;
208
209 if (!c->subscription_event_queue) {
210 c->subscription_event_queue = pa_queue_new();
211 assert(c->subscription_event_queue);
212 }
213
214 pa_queue_push(c->subscription_event_queue, e);
215 sched_event(c);
216 }
217
218