source: roaraudio/libroarlight/slfi.c @ 5982:c38f275b38ae

Last change on this file since 5982:c38f275b38ae was 5982:c38f275b38ae, checked in by phi, 10 years ago

Added support to load light control filters into roard.

File size: 6.1 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
242//ll
Note: See TracBrowser for help on using the repository browser.