source: roaraudio/libroarlight/slfi.c @ 6016:ea4c2d2eb39a

Last change on this file since 6016:ea4c2d2eb39a was 5983:377909b17ccb, checked in by phi, 10 years ago

added support to *add* RoarDMX events in SLFI filters

File size: 6.7 KB
Line 
1//slfi.h:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2009-2014
5 *
6 *  This file is part of libroardsp a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  libroardsp is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include "libroarlight.h"
27
28static const struct roar_slfi_filter * __find_impl_registered(const char * name, struct roar_dl_lhandle ** lhandle) {
29 const void * impl;
30 size_t impl_size;
31 int options;
32 ssize_t i;
33
34 for (i = 0; ; i++) {
35  if ( roar_dl_query_fn(lhandle, ROAR_DL_FN_FILTER, ROAR_DL_FILTER_SUBTYPE_SLFI, &impl, &impl_size, ROAR_DL_FILTER_VERSION_SLFI, &options, i) == -1 ) {
36   return NULL;
37  }
38
39  if ( impl_size != ROAR_DL_FILTER_SIZE_SLFI ) {
40   ROAR_WARN("__find_impl_registered(*): Object %p has wrong size of %u. Strange.", impl, (unsigned int)impl_size);
41   continue;
42  }
43
44  if ( ((const struct roar_slfi_filter *)impl)->name == NULL ) {
45   ROAR_WARN("__find_impl_registered(*): Object %p has no name. Strange.", impl);
46   continue;
47  }
48
49  if ( !!strcmp(((const struct roar_slfi_filter *)impl)->name, name) )
50   continue;
51
52  return impl;
53 }
54}
55
56static struct roar_dl_lhandle * __find_impl_autoload(const char * name) {
57 struct roar_dl_lhandle * lhandle = NULL;
58 struct roar_dl_librarypara * para = NULL;
59 char buf[80];
60 int err;
61
62 para = roar_dl_para_new(NULL, NULL, LIBROAR_DL_APPNAME, LIBROAR_DL_ABIVERSION);
63 if ( para == NULL )
64  return NULL;
65
66 snprintf(buf, sizeof(buf), "filter-slfi-%s", name);
67 lhandle = roar_dl_open(buf, ROAR_DL_FLAG_PLUGIN, 1, para);
68
69 err = roar_error;
70 roar_dl_para_unref(para);
71 roar_error = err;
72
73 return lhandle;
74}
75
76static const struct roar_slfi_filter * __find_impl(const char * name, int autoload, struct roar_dl_lhandle ** lhandle) {
77 const struct roar_slfi_filter * impl;
78 struct roar_dl_lhandle * loaded_lhandle = NULL;
79 int err;
80
81 impl = __find_impl_registered(name, lhandle);
82 if ( impl != NULL ) {
83  roar_dl_ref(*lhandle);
84  return impl;
85 }
86
87 if ( autoload ) {
88  loaded_lhandle = __find_impl_autoload(name);
89  if ( loaded_lhandle == NULL )
90   return NULL;
91
92  impl = __find_impl_registered(name, lhandle);
93  if ( impl == NULL ) {
94   err = roar_error;
95   roar_dl_unref(loaded_lhandle);
96   roar_err_set(err);
97   return NULL;
98  } else if ( *lhandle != loaded_lhandle ) {
99   ROAR_WARN("__find_impl(name='%s', autoload=%i, lhandle=%p): Loaded handle and found handle do not match. Strange.", name, autoload, lhandle);
100   roar_dl_unref(loaded_lhandle);
101   roar_err_set(ROAR_ERROR_BADFH);
102   return NULL;
103  } else {
104   *lhandle = loaded_lhandle;
105   return impl;
106  }
107 }
108
109 roar_err_set(ROAR_ERROR_NOENT);
110 return NULL;
111}
112
113struct roar_slfi_inst * roar_slfi_new(const char * name, int autoload, const struct roar_keyval * para, ssize_t paralen) {
114 const struct roar_slfi_filter * impl;
115 struct roar_dl_lhandle  * lhandle = NULL;
116 struct roar_slfi_inst   * inst;
117 int err;
118
119 impl = __find_impl(name, autoload, &lhandle);
120 if ( impl == NULL )
121  return NULL;
122
123 inst = roar_mm_malloc(sizeof(*inst));
124 if ( inst == NULL )
125  return NULL;
126
127 memset(inst, 0, sizeof(*inst));
128
129 inst->refc = 1;
130 inst->impl = impl;
131 inst->flags = impl->flags;
132 inst->userdata = NULL;
133 inst->lhandle = lhandle;
134
135 if ( inst->impl->init != NULL ) {
136  if ( lhandle != NULL )
137   roar_dl_context_restore(lhandle);
138  if ( inst->impl->init(inst, para, paralen) != 0 ) {
139   err = roar_error;
140   if ( lhandle != NULL )
141    roar_dl_context_store(lhandle);
142   if ( inst->userdata != NULL )
143    roar_mm_free(inst->userdata);
144   roar_mm_free(inst);
145   if ( lhandle != NULL )
146    roar_dl_unref(lhandle);
147   roar_err_set(err);
148   return NULL;
149  }
150  if ( lhandle != NULL )
151   roar_dl_context_store(lhandle);
152 }
153
154 return inst;
155}
156
157int roar_slfi_ref(struct roar_slfi_inst * inst) {
158  if ( inst == NULL || inst->impl == NULL ) {
159  roar_err_set(ROAR_ERROR_FAULT);
160  return -1;
161 }
162
163 inst->refc++;
164
165 return 0;
166}
167
168int roar_slfi_unref(struct roar_slfi_inst * inst) {
169  if ( inst == NULL || inst->impl == NULL ) {
170  roar_err_set(ROAR_ERROR_FAULT);
171  return -1;
172 }
173
174 inst->refc--;
175
176 if ( inst->refc )
177  return 0;
178
179 if ( inst->impl->uninit != NULL ) {
180  if ( inst->lhandle != NULL )
181   roar_dl_context_restore(inst->lhandle);
182  inst->impl->uninit(inst);
183  if ( inst->lhandle != NULL )
184   roar_dl_context_store(inst->lhandle);
185 }
186
187 if ( inst->userdata != NULL )
188  roar_mm_free(inst->userdata);
189
190 if ( inst->lhandle != NULL )
191  roar_dl_unref(inst->lhandle);
192
193 roar_mm_free(inst);
194
195 return 0;
196}
197
198int roar_slfi_update(struct roar_slfi_inst * inst, uint8_t * universe, ssize_t size_of_universe, int32_t usecspassed, const uint8_t * event, size_t eventlen) {
199 int ret;
200
201 if ( inst == NULL || inst->impl == NULL ) {
202  roar_err_set(ROAR_ERROR_FAULT);
203  return -1;
204 }
205
206 if ( inst->impl->update == NULL ) {
207  roar_err_set(ROAR_ERROR_NOSYS);
208  return -1;
209 }
210
211 if ( inst->lhandle != NULL )
212  roar_dl_context_restore(inst->lhandle);
213 ret = inst->impl->update(inst, universe, size_of_universe, usecspassed, event, eventlen);
214 if ( inst->lhandle != NULL )
215  roar_dl_context_store(inst->lhandle);
216
217 return ret;
218}
219
220int roar_slfi_ctl(struct roar_slfi_inst * inst, enum roar_slfi_command command, void * argp) {
221 int ret;
222
223 if ( inst == NULL || inst->impl == NULL ) {
224  roar_err_set(ROAR_ERROR_FAULT);
225  return -1;
226 }
227
228 if ( inst->impl->ctl == NULL ) {
229  roar_err_set(ROAR_ERROR_NOSYS);
230  return -1;
231 }
232
233 if ( inst->lhandle != NULL )
234  roar_dl_context_restore(inst->lhandle);
235 ret = inst->impl->ctl(inst, command, argp);
236 if ( inst->lhandle != NULL )
237  roar_dl_context_store(inst->lhandle);
238
239 return ret;
240}
241
242int roar_slfi_event_add(struct roar_slfi_inst * inst, uint8_t event) {
243 if ( inst == NULL ) {
244  roar_err_set(ROAR_ERROR_FAULT);
245  return -1;
246 }
247
248 if ( inst->cb_event_add == NULL ) {
249  roar_err_set(ROAR_ERROR_NOSYS);
250  return -1;
251 }
252
253 return inst->cb_event_add(inst, inst->cb_event_add_userdata, event);
254}
255
256int roar_slfi_cb_set_event_add(struct roar_slfi_inst * inst, int (*cb)(struct roar_slfi_inst * inst, void * userdata, uint8_t event), void * userdata) {
257 if ( inst == NULL ) {
258  roar_err_set(ROAR_ERROR_FAULT);
259  return -1;
260 }
261
262 inst->cb_event_add = cb;
263 inst->cb_event_add_userdata = userdata;
264 return 0;
265}
266
267//ll
Note: See TracBrowser for help on using the repository browser.