diff options
| author | Jaroslav Kysela <perex@perex.cz> | 2001-07-16 11:15:28 +0000 |
|---|---|---|
| committer | Jaroslav Kysela <perex@perex.cz> | 2001-07-16 11:15:28 +0000 |
| commit | bf858b73120b05d46ec932cb426ebf7b8b2a850b (patch) | |
| tree | 6ad6891916e47dd705f648b2ec925fc31ef95941 /src/timer/timer_query.c | |
| parent | 239182657d8e377f591b4ba79ddc3a647dd7e527 (diff) | |
| download | alsa-lib-bf858b73120b05d46ec932cb426ebf7b8b2a850b.tar.gz | |
Updated timer interface to follow new uniform configuration style.
Diffstat (limited to 'src/timer/timer_query.c')
| -rw-r--r-- | src/timer/timer_query.c | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/src/timer/timer_query.c b/src/timer/timer_query.c new file mode 100644 index 00000000..93d15260 --- /dev/null +++ b/src/timer/timer_query.c @@ -0,0 +1,193 @@ +/* + * \file timer/timer_query.c + * \author Jaroslav Kysela <perex@suse.cz> + * \date 2001 + * + * Timer Query Interface is designed to obtain identification of timers. + */ +/* + * Timer Query Interface - main file + * Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> + * + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Library General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <dlfcn.h> +#include <sys/ioctl.h> +#include "timer_local.h" + +static int snd_timer_query_open_conf(snd_timer_query_t **timer, + const char *name, snd_config_t *timer_root, + snd_config_t *timer_conf, int mode) +{ + const char *str; + char buf[256]; + int err; + snd_config_t *conf, *type_conf; + snd_config_iterator_t i, next; + const char *lib = NULL, *open_name = NULL; + int (*open_func)(snd_timer_query_t **, const char *, snd_config_t *, snd_config_t *, int) = NULL; + void *h; + if (snd_config_get_type(timer_conf) != SND_CONFIG_TYPE_COMPOUND) { + if (name) + SNDERR("Invalid type for TIMER %s definition", name); + else + SNDERR("Invalid type for TIMER definition"); + return -EINVAL; + } + err = snd_config_search(timer_conf, "type", &conf); + if (err < 0) { + SNDERR("type is not defined"); + return err; + } + err = snd_config_get_string(conf, &str); + if (err < 0) { + SNDERR("Invalid type for %s", snd_config_get_id(conf)); + return err; + } + err = snd_config_search_definition(timer_root, "timer_query_type", str, &type_conf); + if (err >= 0) { + if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) { + SNDERR("Invalid type for TIMER type %s definition", str); + goto _err; + } + snd_config_for_each(i, next, type_conf) { + snd_config_t *n = snd_config_iterator_entry(i); + const char *id = snd_config_get_id(n); + if (strcmp(id, "comment") == 0) + continue; + if (strcmp(id, "lib") == 0) { + err = snd_config_get_string(n, &lib); + if (err < 0) { + SNDERR("Invalid type for %s", id); + goto _err; + } + continue; + } + if (strcmp(id, "open") == 0) { + err = snd_config_get_string(n, &open_name); + if (err < 0) { + SNDERR("Invalid type for %s", id); + goto _err; + } + continue; + } + SNDERR("Unknown field %s", id); + err = -EINVAL; + goto _err; + } + } + if (!open_name) { + open_name = buf; + snprintf(buf, sizeof(buf), "_snd_timer_query_%s_open", str); + } + if (!lib) + lib = ALSA_LIB; + h = dlopen(lib, RTLD_NOW); + open_func = h ? dlsym(h, open_name) : NULL; + if (!h) { + SNDERR("Cannot open shared library %s", lib); + err = -ENOENT; + } else if (!open_func) { + SNDERR("symbol %s is not defined inside %s", open_name, lib); + dlclose(h); + err = -ENXIO; + } + _err: + if (type_conf) + snd_config_delete(type_conf); + if (err >= 0) + err = open_func(timer, name, timer_root, timer_conf, mode); + if (err < 0) + return err; + return 0; +} + +static int snd_timer_query_open_noupdate(snd_timer_query_t **timer, snd_config_t *root, const char *name, int mode) +{ + int err; + snd_config_t *timer_conf; + err = snd_config_search_definition(root, "timer", name, &timer_conf); + if (err < 0) { + SNDERR("Unknown timer %s", name); + return err; + } + err = snd_timer_query_open_conf(timer, name, root, timer_conf, mode); + snd_config_delete(timer_conf); + return err; +} + +/** + * \brief Opens a new connection to the timer query interface. + * \param timer Returned handle (NULL if not wanted) + * \param name ASCII identifier of the RawMidi handle + * \param mode Open mode + * \return 0 on success otherwise a negative error code + * + * Opens a new connection to the RawMidi interface specified with + * an ASCII identifier and mode. + */ +int snd_timer_query_open(snd_timer_query_t **timer, const char *name, int mode) +{ + int err; + assert(timer && name); + err = snd_config_update(); + if (err < 0) + return err; + return snd_timer_query_open_noupdate(timer, snd_config, name, mode); +} + +/** + * \brief close timer query handle + * \param timer timer handle + * \return 0 on success otherwise a negative error code + * + * Closes the specified timer handle and frees all associated + * resources. + */ +int snd_timer_query_close(snd_timer_query_t *timer) +{ + int err; + assert(timer); + if ((err = timer->ops->close(timer)) < 0) + return err; + if (timer->name) + free(timer->name); + free(timer); + return 0; +} + +/** + * \brief obtain the next timer identification + * \param timer timer handle + * \param tid timer identification + * \return 0 on success otherwise a negative error code + * + * if tid->dev_class is -1, then the first device is returned + * if result tid->dev_class is -1, no more devices are left + */ +int snd_timer_query_next_device(snd_timer_query_t *timer, snd_timer_id_t *tid) +{ + assert(timer); + assert(tid); + return timer->ops->next_device(timer, tid); +} |
