]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Changed control to use events mask. Added subscribe ioctl
authorAbramo Bagnara <abramo@alsa-project.org>
Tue, 13 Feb 2001 21:29:30 +0000 (21:29 +0000)
committerAbramo Bagnara <abramo@alsa-project.org>
Tue, 13 Feb 2001 21:29:30 +0000 (21:29 +0000)
14 files changed:
aserver/aserver.c
include/aserver.h
include/control.h
include/control_m4.h
include/mixer.h
src/control/control.c
src/control/control_hw.c
src/control/control_local.h
src/control/control_m4.c
src/control/control_shm.c
src/control/hcontrol.c
src/mixer/mixer.c
src/mixer/mixer_local.h
src/mixer/simple.c

index dcf8d0a9237d63604a5d9a7b2885aa1a5619bbe2..c3f209fa89bb8bbbc62a554ac8d2f929fd1fc401 100644 (file)
@@ -572,8 +572,11 @@ int ctl_shm_cmd(client_t *client)
        case SND_CTL_IOCTL_ASYNC:
                ctrl->result = snd_ctl_async(ctl, ctrl->u.async.sig, ctrl->u.async.pid);
                break;
-       case SNDRV_CTL_IOCTL_INFO:
-               ctrl->result = snd_ctl_card_info(ctl, &ctrl->u.hw_info);
+       case SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS:
+               ctrl->result = snd_ctl_subscribe_events(ctl, ctrl->u.subscribe_events);
+               break;
+       case SNDRV_CTL_IOCTL_CARD_INFO:
+               ctrl->result = snd_ctl_card_info(ctl, &ctrl->u.card_info);
                break;
        case SNDRV_CTL_IOCTL_ELEM_LIST:
        {
index 69076a61a8d2a7e43b93cf31875c9f05cf5c26db..cc93d4b11fe108dd1b64275bd36db57da02a3bed 100644 (file)
@@ -95,7 +95,8 @@ typedef struct {
                        pid_t pid;
                } async;
                int device;
-               snd_ctl_card_info_t hw_info;
+               int subscribe_events;
+               snd_ctl_card_info_t card_info;
                snd_ctl_elem_list_t element_list;
                snd_ctl_elem_info_t element_info;
                snd_ctl_elem_value_t element_read;
index 586db0d1c39482ecf3db46e2e24086848ed5eb4f..45393f9a2d78b409e4499d5a3051b9fd0148a19e 100644 (file)
@@ -112,13 +112,14 @@ typedef enum sndrv_ctl_event_type snd_ctl_event_type_t;
 #define SND_CTL_ELEM_IFACE_SEQUENCER ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_SEQUENCER)
 #define SND_CTL_ELEM_IFACE_LAST ((snd_ctl_elem_iface_t) SNDRV_CTL_ELEM_IFACE_LAST)
 
-#define SND_CTL_EVENT_REBUILD ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_REBUILD)
-#define SND_CTL_EVENT_VALUE ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_VALUE)
-#define SND_CTL_EVENT_INFO ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_INFO)
-#define SND_CTL_EVENT_ADD ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_ADD)
-#define SND_CTL_EVENT_REMOVE ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_REMOVE)
+#define SND_CTL_EVENT_ELEM ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_ELEM)
 #define SND_CTL_EVENT_LAST ((snd_ctl_event_type_t) SNDRV_CTL_EVENT_LAST)
 
+#define SND_CTL_EVENT_MASK_ADD SNDRV_CTL_EVENT_MASK_ADD
+#define SND_CTL_EVENT_MASK_INFO SNDRV_CTL_EVENT_MASK_INFO
+#define SND_CTL_EVENT_MASK_VALUE SNDRV_CTL_EVENT_MASK_VALUE
+#define SND_CTL_EVENT_MASK_REMOVE SNDRV_CTL_EVENT_MASK_REMOVE
+
 enum _snd_ctl_type {
        SND_CTL_TYPE_HW,
        SND_CTL_TYPE_SHM,
@@ -160,6 +161,7 @@ int snd_ctl_close(snd_ctl_t *ctl);
 int snd_ctl_nonblock(snd_ctl_t *ctl, int nonblock);
 int snd_ctl_async(snd_ctl_t *ctl, int sig, pid_t pid);
 int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int space);
+int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe);
 int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info);
 int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t * list);
 int snd_ctl_elem_info(snd_ctl_t *ctl, snd_ctl_elem_info_t *info);
@@ -184,6 +186,15 @@ const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type);
 const char *snd_ctl_elem_iface_name(snd_ctl_elem_iface_t iface);
 const char *snd_ctl_event_type_name(snd_ctl_event_type_t type);
 
+unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj);
+unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj);
+void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr);
+snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj);
+unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj);
+unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj);
+const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj);
+unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj);
+
 int snd_ctl_elem_list_alloc_space(snd_ctl_elem_list_t *obj, unsigned int entries);
 void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj);
 
@@ -206,10 +217,10 @@ extern "C" {
 typedef int (*snd_hctl_compare_t)(const snd_hctl_elem_t *e1,
                                  const snd_hctl_elem_t *e2);
 typedef int (*snd_hctl_callback_t)(snd_hctl_t *hctl,
-                                  snd_ctl_event_type_t event,
+                                  unsigned int mask,
                                   snd_hctl_elem_t *elem);
 typedef int (*snd_hctl_elem_callback_t)(snd_hctl_elem_t *elem,
-                                       snd_ctl_event_type_t event);
+                                       unsigned int mask);
 
 int snd_hctl_open(snd_hctl_t **hctl, const char *name);
 int snd_hctl_close(snd_hctl_t *hctl);
index 0a911bf460ab25ca42e255fc0aad0c75e5260d78..11cf6eb3011624332354f09b71e40833f3f79cea 100644 (file)
@@ -62,20 +62,6 @@ void snd_ctl_event_copy(snd_ctl_event_t *dst, const snd_ctl_event_t *src);
 
 snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj);
 
-unsigned int snd_ctl_event_get_numid(const snd_ctl_event_t *obj);
-
-void snd_ctl_event_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr);
-
-snd_ctl_elem_iface_t snd_ctl_event_get_interface(const snd_ctl_event_t *obj);
-
-unsigned int snd_ctl_event_get_device(const snd_ctl_event_t *obj);
-
-unsigned int snd_ctl_event_get_subdevice(const snd_ctl_event_t *obj);
-
-const char *snd_ctl_event_get_name(const snd_ctl_event_t *obj);
-
-unsigned int snd_ctl_event_get_index(const snd_ctl_event_t *obj);
-
 size_t snd_ctl_elem_list_sizeof();
 #define snd_ctl_elem_list_alloca(ptr) ({ assert(ptr); *ptr = (snd_ctl_elem_list_t *) alloca(snd_ctl_elem_list_sizeof()); memset(*ptr, 0, snd_ctl_elem_list_sizeof()); 0; })
 int snd_ctl_elem_list_malloc(snd_ctl_elem_list_t **ptr);
index 0ce702d68b8d2dfc656aa138b8a15037897b5c71..b65ed54a8795b54b1334abd7dbaa0a0970e39b74 100644 (file)
@@ -10,10 +10,10 @@ typedef struct _snd_mixer_class snd_mixer_class_t;
 typedef struct _snd_mixer_info snd_mixer_info_t;
 typedef struct _snd_mixer_elem snd_mixer_elem_t;
 typedef int (*snd_mixer_callback_t)(snd_mixer_t *ctl,
-                                   snd_ctl_event_type_t event,
+                                   unsigned int mask,
                                    snd_mixer_elem_t *elem);
 typedef int (*snd_mixer_elem_callback_t)(snd_mixer_elem_t *elem,
-                                        snd_ctl_event_type_t event);
+                                        unsigned int mask);
 typedef int (*snd_mixer_compare_t)(const snd_mixer_elem_t *e1,
                                   const snd_mixer_elem_t *e2);
 
index fa62bb06dab20c79410079fbe4a5b31b0604e324..05e0fdfcda3a20e2cc1eec0595628e931c6a328c 100644 (file)
@@ -84,10 +84,16 @@ int snd_ctl_poll_descriptors(snd_ctl_t *ctl, struct pollfd *pfds, unsigned int s
        return 1;
 }
 
+int snd_ctl_subscribe_events(snd_ctl_t *ctl, int subscribe)
+{
+       assert(ctl);
+       return ctl->ops->subscribe_events(ctl, subscribe);
+}
+
 int snd_ctl_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
 {
        assert(ctl && info);
-       return ctl->ops->hw_info(ctl, info);
+       return ctl->ops->card_info(ctl, info);
 }
 
 int snd_ctl_elem_list(snd_ctl_t *ctl, snd_ctl_elem_list_t *list)
@@ -280,11 +286,7 @@ const char *snd_ctl_elem_iface_names[] = {
 };
 
 const char *snd_ctl_event_type_names[] = {
-       EVENT(REBUILD),
-       EVENT(VALUE),
-       EVENT(INFO),
-       EVENT(ADD),
-       EVENT(REMOVE),
+       EVENT(ELEM),
 };
 
 const char *snd_ctl_elem_type_name(snd_ctl_elem_type_t type)
@@ -323,3 +325,60 @@ void snd_ctl_elem_list_free_space(snd_ctl_elem_list_t *obj)
        free(obj->pids);
        obj->pids = NULL;
 }
+
+unsigned int snd_ctl_event_elem_get_mask(const snd_ctl_event_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_EVENT_ELEM);
+       return obj->data.elem.mask;
+}
+
+unsigned int snd_ctl_event_elem_get_numid(const snd_ctl_event_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_EVENT_ELEM);
+       return obj->data.elem.id.numid;
+}
+
+void snd_ctl_event_elem_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr)
+{
+       assert(obj && ptr);
+       assert(obj->type == SND_CTL_EVENT_ELEM);
+       *ptr = obj->data.elem.id;
+}
+
+snd_ctl_elem_iface_t snd_ctl_event_elem_get_interface(const snd_ctl_event_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_EVENT_ELEM);
+       return snd_int_to_enum(obj->data.elem.id.iface);
+}
+
+unsigned int snd_ctl_event_elem_get_device(const snd_ctl_event_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_EVENT_ELEM);
+       return obj->data.elem.id.device;
+}
+
+unsigned int snd_ctl_event_elem_get_subdevice(const snd_ctl_event_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_EVENT_ELEM);
+       return obj->data.elem.id.subdevice;
+}
+
+const char *snd_ctl_event_elem_get_name(const snd_ctl_event_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_EVENT_ELEM);
+       return obj->data.elem.id.name;
+}
+
+unsigned int snd_ctl_event_elem_get_index(const snd_ctl_event_t *obj)
+{
+       assert(obj);
+       assert(obj->type == SND_CTL_EVENT_ELEM);
+       return obj->data.elem.id.index;
+}
+
index 09a9cdd03a863c1ea1695c61bdea0eea4b3f09af..92b2ab6b1ce6f92dd1f1a572206b6601aad16e40 100644 (file)
@@ -111,10 +111,21 @@ static int snd_ctl_hw_poll_descriptor(snd_ctl_t *handle)
        return hw->fd;
 }
 
-static int snd_ctl_hw_hw_info(snd_ctl_t *handle, snd_ctl_card_info_t *info)
+static int snd_ctl_hw_subscribe_events(snd_ctl_t *handle, int subscribe)
 {
        snd_ctl_hw_t *hw = handle->private_data;
-       if (ioctl(hw->fd, SNDRV_CTL_IOCTL_INFO, info) < 0)
+       if (ioctl(hw->fd, SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS, &subscribe) < 0) {
+               SYSERR("SNDRV_CTL_IOCTL_SUBSCRIBE_EVENTS failed");
+               return -errno;
+       }
+       return subscribe;
+}
+
+static int snd_ctl_hw_card_info(snd_ctl_t *handle, snd_ctl_card_info_t *info)
+{
+       snd_ctl_hw_t *hw = handle->private_data;
+       if (ioctl(hw->fd, SNDRV_CTL_IOCTL_CARD_INFO, info) < 0)
+               SYSERR("SNDRV_CTL_IOCTL_CARD_INFO failed");
                return -errno;
        return 0;
 }
@@ -230,7 +241,8 @@ snd_ctl_ops_t snd_ctl_hw_ops = {
        nonblock: snd_ctl_hw_nonblock,
        async: snd_ctl_hw_async,
        poll_descriptor: snd_ctl_hw_poll_descriptor,
-       hw_info: snd_ctl_hw_hw_info,
+       subscribe_events: snd_ctl_hw_subscribe_events,
+       card_info: snd_ctl_hw_card_info,
        element_list: snd_ctl_hw_elem_list,
        element_info: snd_ctl_hw_elem_info,
        element_read: snd_ctl_hw_elem_read,
index 0c810324718571ecb73943870cf256bb7de2c9be..198dc7b64c71458e6cc1183ecc1eae38869f80f7 100644 (file)
@@ -27,7 +27,8 @@ typedef struct _snd_ctl_ops {
        int (*nonblock)(snd_ctl_t *handle, int nonblock);
        int (*async)(snd_ctl_t *handle, int sig, pid_t pid);
        int (*poll_descriptor)(snd_ctl_t *handle);
-       int (*hw_info)(snd_ctl_t *handle, snd_ctl_card_info_t *info);
+       int (*subscribe_events)(snd_ctl_t *handle, int subscribe);
+       int (*card_info)(snd_ctl_t *handle, snd_ctl_card_info_t *info);
        int (*element_list)(snd_ctl_t *handle, snd_ctl_elem_list_t *list);
        int (*element_info)(snd_ctl_t *handle, snd_ctl_elem_info_t *info);
        int (*element_read)(snd_ctl_t *handle, snd_ctl_elem_value_t *control);
index ad40e6ccefc7b48abfe35f68537c551d9148e03a..a0776a3763141728bb3fd9b627634858f67ff53e 100644 (file)
@@ -222,55 +222,6 @@ snd_ctl_event_type_t snd_ctl_event_get_type(const snd_ctl_event_t *obj)
        return snd_int_to_enum(obj->type);
 }
 
-unsigned int snd_ctl_event_get_numid(const snd_ctl_event_t *obj)
-{
-       assert(obj);
-       assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
-       return obj->data.id.numid;
-}
-
-void snd_ctl_event_get_id(const snd_ctl_event_t *obj, snd_ctl_elem_id_t *ptr)
-{
-       assert(obj && ptr);
-       assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
-       *ptr = obj->data.id;
-}
-
-snd_ctl_elem_iface_t snd_ctl_event_get_interface(const snd_ctl_event_t *obj)
-{
-       assert(obj);
-       assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
-       return snd_int_to_enum(obj->data.id.iface);
-}
-
-unsigned int snd_ctl_event_get_device(const snd_ctl_event_t *obj)
-{
-       assert(obj);
-       assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
-       return obj->data.id.device;
-}
-
-unsigned int snd_ctl_event_get_subdevice(const snd_ctl_event_t *obj)
-{
-       assert(obj);
-       assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
-       return obj->data.id.subdevice;
-}
-
-const char *snd_ctl_event_get_name(const snd_ctl_event_t *obj)
-{
-       assert(obj);
-       assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
-       return obj->data.id.name;
-}
-
-unsigned int snd_ctl_event_get_index(const snd_ctl_event_t *obj)
-{
-       assert(obj);
-       assert(obj->type != SNDRV_CTL_EVENT_REBUILD);
-       return obj->data.id.index;
-}
-
 size_t snd_ctl_elem_list_sizeof()
 {
        return sizeof(snd_ctl_elem_list_t);
index 96fc5c978e25b342bfadfd1c2ef2d19969102beb..79967d30380ea1c4483b1214abe48734ea5765df 100644 (file)
@@ -122,17 +122,26 @@ static int snd_ctl_shm_poll_descriptor(snd_ctl_t *ctl)
        return fd;
 }
 
-static int snd_ctl_shm_hw_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
+static int snd_ctl_shm_subscribe_events(snd_ctl_t *ctl, int subscribe)
+{
+       snd_ctl_shm_t *shm = ctl->private_data;
+       volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
+       ctrl->cmd = SND_CTL_IOCTL_POLL_DESCRIPTOR;
+       ctrl->u.subscribe_events = subscribe;
+       return snd_ctl_shm_action(ctl);
+}
+
+static int snd_ctl_shm_card_info(snd_ctl_t *ctl, snd_ctl_card_info_t *info)
 {
        snd_ctl_shm_t *shm = ctl->private_data;
        volatile snd_ctl_shm_ctrl_t *ctrl = shm->ctrl;
        int err;
-//     ctrl->u.hw_info = *info;
-       ctrl->cmd = SNDRV_CTL_IOCTL_INFO;
+//     ctrl->u.card_info = *info;
+       ctrl->cmd = SNDRV_CTL_IOCTL_CARD_INFO;
        err = snd_ctl_shm_action(ctl);
        if (err < 0)
                return err;
-       *info = ctrl->u.hw_info;
+       *info = ctrl->u.card_info;
        return err;
 }
 
@@ -334,7 +343,8 @@ snd_ctl_ops_t snd_ctl_shm_ops = {
        nonblock: snd_ctl_shm_nonblock,
        async: snd_ctl_shm_async,
        poll_descriptor: snd_ctl_shm_poll_descriptor,
-       hw_info: snd_ctl_shm_hw_info,
+       subscribe_events: snd_ctl_shm_subscribe_events,
+       card_info: snd_ctl_shm_card_info,
        element_list: snd_ctl_shm_elem_list,
        element_info: snd_ctl_shm_elem_info,
        element_read: snd_ctl_shm_elem_read,
index 713d1b9f0cf9a9910a24017ed29c2146f6050eeb..939169e6b1d1ae2e67619cbc63207ceef6e62817 100644 (file)
@@ -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;
 }
index 576d350cd3142f702e13a085f6545127d1fda8fd..65e8de0bd06305f9e420e60341854d585eb24f34 100644 (file)
@@ -87,56 +87,44 @@ int snd_mixer_elem_empty(snd_mixer_elem_t *melem)
 }
 
 static int hctl_elem_event_handler(snd_hctl_elem_t *helem,
-                                  snd_ctl_event_type_t event)
+                                  unsigned int mask)
 {
        bag_t *bag = snd_hctl_elem_get_callback_private(helem);
-       int res = 0;
-       switch (event) {
-       case SND_CTL_EVENT_VALUE:
-       case SND_CTL_EVENT_INFO:
-       {
-               int err = 0;
-               bag_iterator_t i;
-               bag_for_each(i, bag) {
-                       snd_mixer_elem_t *melem = bag_iterator_entry(i);
-                       snd_mixer_class_t *class = melem->class;
-                       err = class->event(class, event, helem, melem);
-                       if (err < 0)
-                               break;
-               }
-               break;
-       }
-       case SND_CTL_EVENT_REMOVE:
-       {
+       if (mask == SND_CTL_EVENT_MASK_REMOVE) {
+               int res = 0;
                int err;
                bag_iterator_t i, n;
                bag_for_each_safe(i, n, bag) {
                        snd_mixer_elem_t *melem = bag_iterator_entry(i);
                        snd_mixer_class_t *class = melem->class;
-                       err = class->event(class, event, helem, melem);
+                       err = class->event(class, mask, helem, melem);
                        if (err < 0)
                                res = err;
                }
                assert(bag_empty(bag));
                bag_free(bag);
-               break;
-
+               return res;
        }
-       default:
-               assert(0);
-               break;
+       if (mask & (SND_CTL_EVENT_MASK_VALUE | SND_CTL_EVENT_MASK_INFO)) {
+               int err = 0;
+               bag_iterator_t i;
+               bag_for_each(i, bag) {
+                       snd_mixer_elem_t *melem = bag_iterator_entry(i);
+                       snd_mixer_class_t *class = melem->class;
+                       err = class->event(class, mask, helem, melem);
+                       if (err < 0)
+                               return err;
+               }
        }
-       return res;
+       return 0;
 }
 
-static int hctl_event_handler(snd_hctl_t *hctl, snd_ctl_event_type_t event,
+static int hctl_event_handler(snd_hctl_t *hctl, unsigned int mask,
                              snd_hctl_elem_t *elem)
 {
        snd_mixer_t *mixer = snd_hctl_get_callback_private(hctl);
        int res = 0;
-       switch (event) {
-       case SND_CTL_EVENT_ADD:
-       {
+       if (mask & SND_CTL_EVENT_MASK_ADD) {
                struct list_head *pos;
                bag_t *bag;
                int err = bag_new(&bag);
@@ -147,15 +135,10 @@ static int hctl_event_handler(snd_hctl_t *hctl, snd_ctl_event_type_t event,
                list_for_each(pos, &mixer->classes) {
                        snd_mixer_class_t *c;
                        c = list_entry(pos, snd_mixer_class_t, list);
-                       err = c->event(c, event, elem, NULL);
+                       err = c->event(c, mask, elem, NULL);
                        if (err < 0)
                                res = err;
                }
-               break;
-       }
-       default:
-               assert(0);
-               break;
        }
        return res;
 }
@@ -203,21 +186,20 @@ int snd_mixer_detach(snd_mixer_t *mixer, const char *name)
        return -ENOENT;
 }
 
-int snd_mixer_throw_event(snd_mixer_t *mixer, snd_ctl_event_type_t event,
+int snd_mixer_throw_event(snd_mixer_t *mixer, unsigned int mask,
                          snd_mixer_elem_t *elem)
 {
        mixer->events++;
        if (mixer->callback)
-               return mixer->callback(mixer, event, elem);
+               return mixer->callback(mixer, mask, elem);
        return 0;
 }
 
-int snd_mixer_elem_throw_event(snd_mixer_elem_t *elem,
-                              snd_ctl_event_type_t event)
+int snd_mixer_elem_throw_event(snd_mixer_elem_t *elem, unsigned int mask)
 {
        elem->class->mixer->events++;
        if (elem->callback)
-               return elem->callback(elem, event);
+               return elem->callback(elem, mask);
        return 0;
 }
 
@@ -278,7 +260,7 @@ int snd_mixer_elem_add(snd_mixer_elem_t *elem, snd_mixer_class_t *class)
                mixer->pelems[idx] = elem;
        }
        mixer->count++;
-       return snd_mixer_throw_event(mixer, SND_CTL_EVENT_ADD, elem);
+       return snd_mixer_throw_event(mixer, SND_CTL_EVENT_MASK_ADD, elem);
 }
 
 int snd_mixer_elem_remove(snd_mixer_elem_t *elem)
@@ -296,7 +278,7 @@ int snd_mixer_elem_remove(snd_mixer_elem_t *elem)
                snd_hctl_elem_t *helem = bag_iterator_entry(i);
                snd_mixer_elem_detach(elem, helem);
        }
-       err = snd_mixer_elem_throw_event(elem, SND_CTL_EVENT_REMOVE);
+       err = snd_mixer_elem_throw_event(elem, SND_CTL_EVENT_MASK_REMOVE);
        list_del(&elem->list);
        if (elem->private_free)
                elem->private_free(elem);
@@ -312,7 +294,7 @@ int snd_mixer_elem_remove(snd_mixer_elem_t *elem)
 
 int snd_mixer_elem_change(snd_mixer_elem_t *elem)
 {
-       return snd_mixer_elem_throw_event(elem, SND_CTL_EVENT_INFO);
+       return snd_mixer_elem_throw_event(elem, SND_CTL_EVENT_MASK_INFO);
 }
 
 
@@ -330,7 +312,7 @@ int snd_mixer_class_register(snd_mixer_class_t *class, snd_mixer_t *mixer)
                slave = list_entry(pos, snd_mixer_slave_t, list);
                elem = snd_hctl_first_elem(slave->hctl);
                while (elem) {
-                       err = class->event(class, SND_CTL_EVENT_ADD, elem, NULL);
+                       err = class->event(class, SND_CTL_EVENT_MASK_ADD, elem, NULL);
                        if (err < 0)
                                return err;
                        elem = snd_hctl_elem_next(elem);
index 5910d0fa1ada2888bcd541e99e13f969e2891a7b..ca53592cd667ca569ffbecbd94a05518ea07e3a2 100644 (file)
@@ -49,7 +49,7 @@ typedef struct list_head *bag_iterator_t;
 struct _snd_mixer_class {
        struct list_head list;
        snd_mixer_t *mixer;
-       int (*event)(snd_mixer_class_t *class, snd_ctl_event_type_t event,
+       int (*event)(snd_mixer_class_t *class, unsigned int mask,
                     snd_hctl_elem_t *helem, snd_mixer_elem_t *melem);
        void *private_data;             
        void (*private_free)(snd_mixer_class_t *class);
@@ -111,8 +111,7 @@ struct _snd_mixer_selem_value {
 int snd_mixer_class_register(snd_mixer_class_t *class, snd_mixer_t *mixer);
 int snd_mixer_add_elem(snd_mixer_t *mixer, snd_mixer_elem_t *elem);
 int snd_mixer_remove_elem(snd_mixer_t *mixer, snd_mixer_elem_t *elem);
-int snd_mixer_elem_throw_event(snd_mixer_elem_t *elem,
-                              snd_ctl_event_type_t event);
+int snd_mixer_elem_throw_event(snd_mixer_elem_t *elem, unsigned int mask);
 int snd_mixer_elem_add(snd_mixer_elem_t *elem, snd_mixer_class_t *class);
 int snd_mixer_elem_remove(snd_mixer_elem_t *elem);
 int snd_mixer_elem_change(snd_mixer_elem_t *elem);
index ce906fa4613b50decd45e794d8e8bbfc674495c1..077369c82b31c1c3906e004e4539de6a468865f1 100644 (file)
@@ -787,21 +787,27 @@ int simple_event_info(snd_mixer_elem_t *melem)
        return snd_mixer_elem_change(melem);
 }
 
-int simple_event(snd_mixer_class_t *class, snd_ctl_event_type_t event,
+int simple_event(snd_mixer_class_t *class, unsigned int mask,
                 snd_hctl_elem_t *helem, snd_mixer_elem_t *melem)
 {
-       switch (event) {
-       case SND_CTL_EVENT_ADD:
-               return simple_event_add(class, helem);
-       case SND_CTL_EVENT_INFO:
-               return simple_event_info(melem);
-       case SND_CTL_EVENT_VALUE:
-               return snd_mixer_elem_throw_event(melem, event);
-       case SND_CTL_EVENT_REMOVE:
+       int err;
+       if (mask == SND_CTL_EVENT_MASK_REMOVE)
                return simple_event_remove(helem, melem);
-       default:
-               assert(0);
-               break;
+       if (mask & SND_CTL_EVENT_MASK_ADD) {
+               err = simple_event_add(class, helem);
+               if (err < 0)
+                       return err;
+       }
+       if (mask & SND_CTL_EVENT_MASK_INFO) {
+               err = simple_event_info(melem);
+               if (err < 0)
+                       return err;
+       }
+       if (mask & SND_CTL_EVENT_MASK_VALUE) {
+               /* FIXME */
+               err = snd_mixer_elem_throw_event(melem, mask);
+               if (err < 0)
+                       return err;
        }
        return 0;
 }