|
Packit |
3ae693 |
/*-*- Mode: C; c-basic-offset: 8 -*-*/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
/***
|
|
Packit |
3ae693 |
This file is part of libcanberra.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
Copyright 2008 Lennart Poettering
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
libcanberra is free software; you can redistribute it and/or modify
|
|
Packit |
3ae693 |
it under the terms of the GNU Lesser General Public License as
|
|
Packit |
3ae693 |
published by the Free Software Foundation, either version 2.1 of the
|
|
Packit |
3ae693 |
License, or (at your option) any later version.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
libcanberra is distributed in the hope that it will be useful, but
|
|
Packit |
3ae693 |
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit |
3ae693 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
Packit |
3ae693 |
Lesser General Public License for more details.
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
You should have received a copy of the GNU Lesser General Public
|
|
Packit |
3ae693 |
License along with libcanberra. If not, see
|
|
Packit |
3ae693 |
<http://www.gnu.org/licenses/>.
|
|
Packit |
3ae693 |
***/
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#ifdef HAVE_CONFIG_H
|
|
Packit |
3ae693 |
#include <config.h>
|
|
Packit |
3ae693 |
#endif
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#include <ltdl.h>
|
|
Packit |
3ae693 |
#include <string.h>
|
|
Packit |
3ae693 |
#include <errno.h>
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#include "driver.h"
|
|
Packit |
3ae693 |
#include "common.h"
|
|
Packit |
3ae693 |
#include "malloc.h"
|
|
Packit |
3ae693 |
#include "driver-order.h"
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
struct private_dso {
|
|
Packit |
3ae693 |
lt_dlhandle module;
|
|
Packit |
3ae693 |
ca_bool_t ltdl_initialized;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int (*driver_open)(ca_context *c);
|
|
Packit |
3ae693 |
int (*driver_destroy)(ca_context *c);
|
|
Packit |
3ae693 |
int (*driver_change_device)(ca_context *c, const char *device);
|
|
Packit |
3ae693 |
int (*driver_change_props)(ca_context *c, ca_proplist *changed, ca_proplist *merged);
|
|
Packit |
3ae693 |
int (*driver_play)(ca_context *c, uint32_t id, ca_proplist *p, ca_finish_callback_t cb, void *userdata);
|
|
Packit |
3ae693 |
int (*driver_cancel)(ca_context *c, uint32_t id);
|
|
Packit |
3ae693 |
int (*driver_cache)(ca_context *c, ca_proplist *p);
|
|
Packit |
3ae693 |
int (*driver_playing)(ca_context *c, uint32_t id, int *playing);
|
|
Packit |
3ae693 |
};
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#define PRIVATE_DSO(c) ((struct private_dso *) ((c)->private_dso))
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static int ca_error_from_lt_error(int code) {
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static const int table[] = {
|
|
Packit |
3ae693 |
[LT_ERROR_UNKNOWN] = CA_ERROR_INTERNAL,
|
|
Packit |
3ae693 |
[LT_ERROR_DLOPEN_NOT_SUPPORTED] = CA_ERROR_NOTSUPPORTED,
|
|
Packit |
3ae693 |
[LT_ERROR_INVALID_LOADER] = CA_ERROR_INTERNAL,
|
|
Packit |
3ae693 |
[LT_ERROR_INIT_LOADER] = CA_ERROR_INTERNAL,
|
|
Packit |
3ae693 |
[LT_ERROR_REMOVE_LOADER] = CA_ERROR_INTERNAL,
|
|
Packit |
3ae693 |
[LT_ERROR_FILE_NOT_FOUND] = CA_ERROR_NOTFOUND,
|
|
Packit |
3ae693 |
[LT_ERROR_DEPLIB_NOT_FOUND] = CA_ERROR_NOTFOUND,
|
|
Packit |
3ae693 |
[LT_ERROR_NO_SYMBOLS] = CA_ERROR_NOTFOUND,
|
|
Packit |
3ae693 |
[LT_ERROR_CANNOT_OPEN] = CA_ERROR_ACCESS,
|
|
Packit |
3ae693 |
[LT_ERROR_CANNOT_CLOSE] = CA_ERROR_INTERNAL,
|
|
Packit |
3ae693 |
[LT_ERROR_SYMBOL_NOT_FOUND] = CA_ERROR_NOTFOUND,
|
|
Packit |
3ae693 |
[LT_ERROR_NO_MEMORY] = CA_ERROR_OOM,
|
|
Packit |
3ae693 |
[LT_ERROR_INVALID_HANDLE] = CA_ERROR_INVALID,
|
|
Packit |
3ae693 |
[LT_ERROR_BUFFER_OVERFLOW] = CA_ERROR_TOOBIG,
|
|
Packit |
3ae693 |
[LT_ERROR_INVALID_ERRORCODE] = CA_ERROR_INVALID,
|
|
Packit |
3ae693 |
[LT_ERROR_SHUTDOWN] = CA_ERROR_INTERNAL,
|
|
Packit |
3ae693 |
[LT_ERROR_CLOSE_RESIDENT_MODULE] = CA_ERROR_INTERNAL,
|
|
Packit |
3ae693 |
[LT_ERROR_INVALID_MUTEX_ARGS] = CA_ERROR_INTERNAL,
|
|
Packit |
3ae693 |
[LT_ERROR_INVALID_POSITION] = CA_ERROR_INTERNAL
|
|
Packit |
3ae693 |
#ifdef LT_ERROR_CONFLICTING_FLAGS
|
|
Packit |
3ae693 |
, [LT_ERROR_CONFLICTING_FLAGS] = CA_ERROR_INTERNAL
|
|
Packit |
3ae693 |
#endif
|
|
Packit |
3ae693 |
};
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (code < 0 || code >= (int) CA_ELEMENTSOF(table))
|
|
Packit |
3ae693 |
return CA_ERROR_INTERNAL;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return table[code];
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static int lt_error_from_string(const char *t) {
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
struct lt_error_code {
|
|
Packit |
3ae693 |
int code;
|
|
Packit |
3ae693 |
const char *text;
|
|
Packit |
3ae693 |
};
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static const struct lt_error_code lt_error_codes[] = {
|
|
Packit |
3ae693 |
/* This is so disgustingly ugly, it makes me vomit. But that's
|
|
Packit |
3ae693 |
* all ltdl's fault. */
|
|
Packit |
3ae693 |
#define LT_ERROR(u, s) { .code = LT_ERROR_ ## u, .text = s },
|
|
Packit |
3ae693 |
lt_dlerror_table
|
|
Packit |
3ae693 |
#undef LT_ERROR
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
{ .code = 0, .text = NULL }
|
|
Packit |
3ae693 |
};
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
const struct lt_error_code *c;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (c = lt_error_codes; c->text; c++)
|
|
Packit |
3ae693 |
if (ca_streq(t, c->text))
|
|
Packit |
3ae693 |
return c->code;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return -1;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static int ca_error_from_string(const char *t) {
|
|
Packit |
3ae693 |
int err;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((err = lt_error_from_string(t)) < 0)
|
|
Packit |
3ae693 |
return CA_ERROR_INTERNAL;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ca_error_from_lt_error(err);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static int try_open(ca_context *c, const char *t) {
|
|
Packit |
3ae693 |
char *mn;
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p = PRIVATE_DSO(c);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(mn = ca_sprintf_malloc(CA_PLUGIN_PATH "/libcanberra-%s", t)))
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
errno = 0;
|
|
Packit |
3ae693 |
p->module = lt_dlopenext(mn);
|
|
Packit |
3ae693 |
ca_free(mn);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!p->module) {
|
|
Packit |
3ae693 |
int ret;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (errno == ENOENT)
|
|
Packit |
3ae693 |
ret = CA_ERROR_NOTFOUND;
|
|
Packit |
3ae693 |
else
|
|
Packit |
3ae693 |
ret = ca_error_from_string(lt_dlerror());
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (ret == CA_ERROR_NOTFOUND)
|
|
Packit |
3ae693 |
ret = CA_ERROR_NODRIVER;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return CA_SUCCESS;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
static void* real_dlsym(lt_module m, const char *name, const char *symbol) {
|
|
Packit |
3ae693 |
char sn[256];
|
|
Packit |
3ae693 |
char *s;
|
|
Packit |
3ae693 |
void *r;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_null_if_fail(m);
|
|
Packit |
3ae693 |
ca_return_null_if_fail(name);
|
|
Packit |
3ae693 |
ca_return_null_if_fail(symbol);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
snprintf(sn, sizeof(sn), "%s_%s", name, symbol);
|
|
Packit |
3ae693 |
sn[sizeof(sn)-1] = 0;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (s = sn; *s; s++) {
|
|
Packit |
3ae693 |
if (*s >= 'a' && *s <= 'z')
|
|
Packit |
3ae693 |
continue;
|
|
Packit |
3ae693 |
if (*s >= 'A' && *s <= 'Z')
|
|
Packit |
3ae693 |
continue;
|
|
Packit |
3ae693 |
if (*s >= '0' && *s <= '9')
|
|
Packit |
3ae693 |
continue;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
*s = '_';
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((r = lt_dlsym(m, sn)))
|
|
Packit |
3ae693 |
return r;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return lt_dlsym(m, symbol);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
#define MAKE_FUNC_PTR(ret, args, x) ((ret (*) args ) (size_t) (x))
|
|
Packit |
3ae693 |
#define GET_FUNC_PTR(module, name, symbol, ret, args) MAKE_FUNC_PTR(ret, args, real_dlsym((module), (name), (symbol)))
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int driver_open(ca_context *c) {
|
|
Packit |
3ae693 |
int ret;
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
char *driver;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(!PRIVATE_DSO(c), CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(c->private_dso = p = ca_new0(struct private_dso, 1)))
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (lt_dlinit() != 0) {
|
|
Packit |
3ae693 |
ret = ca_error_from_string(lt_dlerror());
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p->ltdl_initialized = TRUE;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (c->driver) {
|
|
Packit |
3ae693 |
char *e;
|
|
Packit |
3ae693 |
size_t n;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(e = ca_strdup(c->driver))) {
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
n = strcspn(e, ",:");
|
|
Packit |
3ae693 |
e[n] = 0;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (n == 0) {
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
ca_free(e);
|
|
Packit |
3ae693 |
return CA_ERROR_INVALID;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = try_open(c, e)) < 0) {
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
ca_free(e);
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
driver = e;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
} else {
|
|
Packit |
3ae693 |
const char *const * e;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
for (e = ca_driver_order; *e; e++) {
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = try_open(c, *e)) == CA_SUCCESS)
|
|
Packit |
3ae693 |
break;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (ret != CA_ERROR_NODRIVER &&
|
|
Packit |
3ae693 |
ret != CA_ERROR_NOTAVAILABLE &&
|
|
Packit |
3ae693 |
ret != CA_ERROR_NOTFOUND) {
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!*e) {
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
return CA_ERROR_NODRIVER;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(driver = ca_strdup(*e))) {
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
return CA_ERROR_OOM;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_assert(p->module);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (!(p->driver_open = GET_FUNC_PTR(p->module, driver, "driver_open", int, (ca_context*))) ||
|
|
Packit |
3ae693 |
!(p->driver_destroy = GET_FUNC_PTR(p->module, driver, "driver_destroy", int, (ca_context*))) ||
|
|
Packit |
3ae693 |
!(p->driver_change_device = GET_FUNC_PTR(p->module, driver, "driver_change_device", int, (ca_context*, const char *))) ||
|
|
Packit |
3ae693 |
!(p->driver_change_props = GET_FUNC_PTR(p->module, driver, "driver_change_props", int, (ca_context *, ca_proplist *, ca_proplist *))) ||
|
|
Packit |
3ae693 |
!(p->driver_play = GET_FUNC_PTR(p->module, driver, "driver_play", int, (ca_context*, uint32_t, ca_proplist *, ca_finish_callback_t, void *))) ||
|
|
Packit |
3ae693 |
!(p->driver_cancel = GET_FUNC_PTR(p->module, driver, "driver_cancel", int, (ca_context*, uint32_t))) ||
|
|
Packit |
3ae693 |
!(p->driver_cache = GET_FUNC_PTR(p->module, driver, "driver_cache", int, (ca_context*, ca_proplist *))) ||
|
|
Packit |
3ae693 |
!(p->driver_playing = GET_FUNC_PTR(p->module, driver, "driver_playing", int, (ca_context*, uint32_t, int*)))) {
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_free(driver);
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
return CA_ERROR_CORRUPT;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_free(driver);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if ((ret = p->driver_open(c)) < 0) {
|
|
Packit |
3ae693 |
p->driver_destroy = NULL;
|
|
Packit |
3ae693 |
driver_destroy(c);
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return CA_SUCCESS;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int driver_destroy(ca_context *c) {
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
int ret = CA_SUCCESS;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p = PRIVATE_DSO(c);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (p->driver_destroy)
|
|
Packit |
3ae693 |
ret = p->driver_destroy(c);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (p->module)
|
|
Packit |
3ae693 |
lt_dlclose(p->module);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
if (p->ltdl_initialized) {
|
|
Packit |
3ae693 |
lt_dlexit();
|
|
Packit |
3ae693 |
p->ltdl_initialized = FALSE;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_free(p);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
c->private_dso = NULL;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return ret;
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int driver_change_device(ca_context *c, const char *device) {
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p = PRIVATE_DSO(c);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p->driver_change_device, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return p->driver_change_device(c, device);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int driver_change_props(ca_context *c, ca_proplist *changed, ca_proplist *merged) {
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p = PRIVATE_DSO(c);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p->driver_change_props, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return p->driver_change_props(c, changed, merged);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int driver_play(ca_context *c, uint32_t id, ca_proplist *pl, ca_finish_callback_t cb, void *userdata) {
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p = PRIVATE_DSO(c);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p->driver_play, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return p->driver_play(c, id, pl, cb, userdata);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int driver_cancel(ca_context *c, uint32_t id) {
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p = PRIVATE_DSO(c);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p->driver_cancel, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return p->driver_cancel(c, id);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int driver_cache(ca_context *c, ca_proplist *pl) {
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p = PRIVATE_DSO(c);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p->driver_cache, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return p->driver_cache(c, pl);
|
|
Packit |
3ae693 |
}
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
int driver_playing(ca_context *c, uint32_t id, int *playing) {
|
|
Packit |
3ae693 |
struct private_dso *p;
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(c->private_dso, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(playing, CA_ERROR_INVALID);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
p = PRIVATE_DSO(c);
|
|
Packit |
3ae693 |
ca_return_val_if_fail(p->driver_playing, CA_ERROR_STATE);
|
|
Packit |
3ae693 |
|
|
Packit |
3ae693 |
return p->driver_playing(c, id, playing);
|
|
Packit |
3ae693 |
}
|