mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	Changed control to use events mask. Added subscribe ioctl
This commit is contained in:
		
							parent
							
								
									fa51799255
								
							
						
					
					
						commit
						3e97ef3ea0
					
				
					 14 changed files with 225 additions and 205 deletions
				
			
		| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue