summaryrefslogtreecommitdiff
path: root/src/control/hcontrol.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/control/hcontrol.c')
-rw-r--r--src/control/hcontrol.c109
1 files changed, 54 insertions, 55 deletions
diff --git a/src/control/hcontrol.c b/src/control/hcontrol.c
index 713d1b9f..939169e6 100644
--- a/src/control/hcontrol.c
+++ b/src/control/hcontrol.c
@@ -89,42 +89,19 @@ int snd_hctl_poll_descriptors(snd_hctl_t *hctl, struct pollfd *pfds, unsigned in
return snd_ctl_poll_descriptors(hctl->ctl, pfds, space);
}
-static int _snd_hctl_find_elem(snd_hctl_t *hctl, const snd_ctl_elem_id_t *id, int *dir)
-{
- unsigned int l, u;
- int c = 0;
- int idx = -1;
- assert(hctl && id);
- assert(hctl->compare);
- l = 0;
- u = hctl->count;
- while (l < u) {
- idx = (l + u) / 2;
- c = hctl->compare((snd_hctl_elem_t *) id, hctl->pelems[idx]);
- if (c < 0)
- u = idx;
- else if (c > 0)
- l = idx + 1;
- else
- break;
- }
- *dir = c;
- return idx;
-}
-
-int snd_hctl_throw_event(snd_hctl_t *hctl, snd_ctl_event_type_t event,
+int snd_hctl_throw_event(snd_hctl_t *hctl, unsigned int mask,
snd_hctl_elem_t *elem)
{
if (hctl->callback)
- return hctl->callback(hctl, event, elem);
+ return hctl->callback(hctl, mask, elem);
return 0;
}
int snd_hctl_elem_throw_event(snd_hctl_elem_t *elem,
- snd_ctl_event_type_t event)
+ unsigned int mask)
{
if (elem->callback)
- return elem->callback(elem, event);
+ return elem->callback(elem, mask);
return 0;
}
@@ -207,6 +184,32 @@ static int get_compare_weight(const char *name)
return res + res1;
}
+static int _snd_hctl_find_elem(snd_hctl_t *hctl, const snd_ctl_elem_id_t *id, int *dir)
+{
+ unsigned int l, u;
+ snd_hctl_elem_t el;
+ int c = 0;
+ int idx = -1;
+ assert(hctl && id);
+ assert(hctl->compare);
+ el.id = *id;
+ el.compare_weight = get_compare_weight(id->name);
+ l = 0;
+ u = hctl->count;
+ while (l < u) {
+ idx = (l + u) / 2;
+ c = hctl->compare(&el, hctl->pelems[idx]);
+ if (c < 0)
+ u = idx;
+ else if (c > 0)
+ l = idx + 1;
+ else
+ break;
+ }
+ *dir = c;
+ return idx;
+}
+
static int snd_hctl_elem_add(snd_hctl_t *hctl, snd_hctl_elem_t *elem)
{
int dir;
@@ -241,14 +244,14 @@ static int snd_hctl_elem_add(snd_hctl_t *hctl, snd_hctl_elem_t *elem)
hctl->pelems[idx] = elem;
}
hctl->count++;
- return snd_hctl_throw_event(hctl, SND_CTL_EVENT_ADD, elem);
+ return snd_hctl_throw_event(hctl, SNDRV_CTL_EVENT_MASK_ADD, elem);
}
static void snd_hctl_elem_remove(snd_hctl_t *hctl, unsigned int idx)
{
snd_hctl_elem_t *elem = hctl->pelems[idx];
unsigned int m;
- snd_hctl_elem_throw_event(elem, SND_CTL_EVENT_REMOVE);
+ snd_hctl_elem_throw_event(elem, SNDRV_CTL_EVENT_MASK_REMOVE);
list_del(&elem->list);
free(elem);
hctl->count--;
@@ -408,11 +411,12 @@ int snd_hctl_load(snd_hctl_t *hctl)
hctl->compare = snd_hctl_compare_default;
snd_hctl_sort(hctl);
for (idx = 0; idx < hctl->count; idx++) {
- int res = snd_hctl_throw_event(hctl, SND_CTL_EVENT_ADD,
+ int res = snd_hctl_throw_event(hctl, SNDRV_CTL_EVENT_MASK_ADD,
hctl->pelems[idx]);
if (res < 0)
return res;
}
+ err = snd_ctl_subscribe_events(hctl->ctl, 1);
_end:
if (list.pids)
free(list.pids);
@@ -462,46 +466,41 @@ int snd_hctl_handle_event(snd_hctl_t *hctl, snd_ctl_event_t *event)
assert(hctl);
assert(hctl->ctl);
switch (event->type) {
- case SND_CTL_EVENT_REMOVE:
- {
+ case SND_CTL_EVENT_ELEM:
+ break;
+ default:
+ return 0;
+ }
+ if (event->data.elem.mask == SNDRV_CTL_EVENT_MASK_REMOVE) {
int dir;
- res = _snd_hctl_find_elem(hctl, &event->data.id, &dir);
+ res = _snd_hctl_find_elem(hctl, &event->data.elem.id, &dir);
assert(res >= 0 && dir == 0);
if (res < 0 || dir != 0)
return -ENOENT;
snd_hctl_elem_remove(hctl, res);
- break;
+ return 0;
}
- case SND_CTL_EVENT_VALUE:
- case SND_CTL_EVENT_INFO:
- elem = snd_hctl_find_elem(hctl, &event->data.id);
- assert(elem);
- if (!elem)
- return -ENOENT;
- return snd_hctl_elem_throw_event(elem, event->type);
- case SND_CTL_EVENT_ADD:
+ if (event->data.elem.mask & SNDRV_CTL_EVENT_MASK_ADD) {
elem = calloc(1, sizeof(snd_hctl_elem_t));
if (elem == NULL)
return -ENOMEM;
- elem->id = event->data.id;
+ elem->id = event->data.elem.id;
elem->hctl = hctl;
res = snd_hctl_elem_add(hctl, elem);
if (res < 0)
return res;
- break;
- case SND_CTL_EVENT_REBUILD:
- snd_hctl_free(hctl);
- res = snd_hctl_load(hctl);
+ }
+ if (event->data.elem.mask & (SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO)) {
+ elem = snd_hctl_find_elem(hctl, &event->data.elem.id);
+ assert(elem);
+ if (!elem)
+ return -ENOENT;
+ res = snd_hctl_elem_throw_event(elem, event->data.elem.mask &
+ (SNDRV_CTL_EVENT_MASK_VALUE |
+ SNDRV_CTL_EVENT_MASK_INFO));
if (res < 0)
return res;
-#if 0
- /* I don't think this have to be passed to higher level */
- return hctl_event(hctl, event->type, NULL);
-#endif
- break;
- default:
- assert(0);
- break;
}
return 0;
}