aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTaylor Holberton <tay10r@protonmail.com>2020-06-03 09:43:06 -0400
committerGitHub <noreply@github.com>2020-06-03 09:43:06 -0400
commit1a53e3a9daa9ea7226c2884c6ad45c31a146c9fe (patch)
tree582e20875d0bb1803b8ce15b7cba81c293772349 /src
parent102f06d85c60e0ac52d755fbdd8d3f8531f5e3d5 (diff)
parentdf855e804886f2846d0bdb6d8b1aad506452f051 (diff)
Merge pull request #159 from rohkkumar/plugin_update
Mixer event plugin update
Diffstat (limited to 'src')
-rw-r--r--src/mixer.c72
-rw-r--r--src/mixer_hw.c9
-rw-r--r--src/mixer_plugin.c2
3 files changed, 72 insertions, 11 deletions
diff --git a/src/mixer.c b/src/mixer.c
index 1c9e63b..c8480d7 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -475,7 +475,7 @@ int mixer_wait_event(struct mixer *mixer, int timeout)
{
struct pollfd *pfd;
struct mixer_ctl_group *grp;
- int count = 0, num_fds = 0, i;
+ int count = 0, num_fds = 0, i, ret = 0;
if (mixer->fd >= 0)
num_fds++;
@@ -485,7 +485,7 @@ int mixer_wait_event(struct mixer *mixer, int timeout)
num_fds++;
#endif
- pfd = (struct pollfd *)calloc(sizeof(struct pollfd), num_fds);
+ pfd = (struct pollfd *)calloc(num_fds, sizeof(struct pollfd));
if (!pfd)
return -ENOMEM;
@@ -506,33 +506,85 @@ int mixer_wait_event(struct mixer *mixer, int timeout)
#endif
if (!count)
- return 0;
+ goto exit;
for (;;) {
int err;
err = poll(pfd, count, timeout);
- if (err < 0)
- return -errno;
+ if (err < 0) {
+ ret = -errno;
+ goto exit;
+ }
if (!err)
- return 0;
+ goto exit;
+
for (i = 0; i < count; i++) {
- if (pfd[i].revents & (POLLERR | POLLNVAL))
- return -EIO;
+ if (pfd[i].revents & (POLLERR | POLLNVAL)) {
+ ret = -EIO;
+ goto exit;
+ }
if (pfd[i].revents & (POLLIN | POLLOUT)) {
if ((i == 0) && mixer->fd >= 0) {
grp = mixer->h_grp;
grp->event_cnt++;
}
#ifdef TINYALSA_USES_PLUGINS
- else {
+ else {
grp = mixer->v_grp;
grp->event_cnt++;
}
#endif
- return 1;
+ ret = 1;
+ goto exit;
}
}
}
+exit:
+ free(pfd);
+ return ret;
+}
+
+/** Consume a mixer event.
+ * If mixer_subscribe_events has been called,
+ * mixer_wait_event will identify when a control value has changed.
+ * This function will clear a single event from the mixer so that
+ * further events can be alerted.
+ *
+ * @param mixer A mixer handle.
+ * @returns 0 on success. -errno on failure.
+ * @ingroup libtinyalsa-mixer
+ */
+int mixer_consume_event(struct mixer *mixer)
+{
+ struct snd_ctl_event ev;
+
+ return mixer_read_event(mixer, &ev);
+}
+
+int mixer_read_event(struct mixer *mixer, struct snd_ctl_event *ev)
+{
+ struct mixer_ctl_group *grp;
+ ssize_t count = 0;
+
+ if (mixer->h_grp) {
+ grp = mixer->h_grp;
+ if (grp->event_cnt) {
+ grp->event_cnt--;
+ count = grp->ops->read_event(grp->data, ev, sizeof(*ev));
+ return (count >= 0) ? 0 : -errno;
+ }
+ }
+#ifdef TINYALSA_USES_PLUGINS
+ if (mixer->v_grp) {
+ grp = mixer->v_grp;
+ if (grp->event_cnt) {
+ grp->event_cnt--;
+ count = grp->ops->read_event(grp->data, ev, sizeof(*ev));
+ return (count >= 0) ? 0 : -errno;
+ }
+ }
+#endif
+ return 0;
}
static unsigned int mixer_grp_get_count(struct mixer_ctl_group *grp)
diff --git a/src/mixer_hw.c b/src/mixer_hw.c
index 2e86dfa..da5a390 100644
--- a/src/mixer_hw.c
+++ b/src/mixer_hw.c
@@ -82,9 +82,18 @@ static int mixer_hw_ioctl(void *data, unsigned int cmd, ...)
return ioctl(hw_data->fd, cmd, arg);
}
+static ssize_t mixer_hw_read_event(void *data, struct snd_ctl_event *ev,
+ size_t size)
+{
+ struct mixer_hw_data *hw_data = data;
+
+ return read(hw_data->fd, ev, size);
+}
+
static const struct mixer_ops mixer_hw_ops = {
.close = mixer_hw_close,
.ioctl = mixer_hw_ioctl,
+ .read_event = mixer_hw_read_event,
};
int mixer_hw_open(unsigned int card, void **data,
diff --git a/src/mixer_plugin.c b/src/mixer_plugin.c
index 389003e..9f22b7e 100644
--- a/src/mixer_plugin.c
+++ b/src/mixer_plugin.c
@@ -137,8 +137,8 @@ static int mixer_plug_info_integer(struct snd_control *ctl,
void mixer_plug_notifier_cb(struct mixer_plugin *plugin)
{
- eventfd_write(plugin->eventfd, 1);
plugin->event_cnt++;
+ eventfd_write(plugin->eventfd, 1);
}
/* In consume_event/read, do not call eventfd_read until all events are read from list.