static int check_event(struct elem_set_trial *trial, unsigned int mask, unsigned int expected_count) { struct pollfd pfds; int count; unsigned short revents; snd_ctl_event_t *event; int err; snd_ctl_event_alloca(&event); if (snd_ctl_poll_descriptors_count(trial->handle) != 1) return -ENXIO; if (snd_ctl_poll_descriptors(trial->handle, &pfds, 1) != 1) return -ENXIO; while (expected_count > 0) { count = poll(&pfds, 1, 1000); if (count < 0) return errno; /* Some events are already supplied. */ if (count == 0) return -ETIMEDOUT; err = snd_ctl_poll_descriptors_revents(trial->handle, &pfds, count, &revents); if (err < 0) return err; if (revents & POLLERR) return -EIO; if (!(revents & POLLIN)) continue; err = snd_ctl_read(trial->handle, event); if (err < 0) return err; if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM) continue; /* * I expect each event is generated separately to the same * element. */ if (!(snd_ctl_event_elem_get_mask(event) & mask)) continue; --expected_count; } if (expected_count != 0) return -EIO; return 0; }
static int handle_event(int hwdep_fd, snd_ctl_t *ctl) { snd_ctl_event_t *event; unsigned int mask; int err; snd_ctl_event_alloca(&event); err = snd_ctl_read(ctl, event); if (err < 0) { fprintf(stderr, "Cannot read event from ctl %s\n", snd_ctl_name(ctl)); return err; } if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM) { return 0; } // Filter events mask = snd_ctl_event_elem_get_mask(event); if (mask & SND_CTL_EVENT_MASK_VALUE) { const char *event_name = snd_ctl_event_elem_get_name(event); if (!strcmp(event_name, HEADPHONE_SWITCH_NAME)) { // If headphones were plugged, mute LFE set_headphones_plugged(&headphones_plugged); if (headphones_plugged) { set_lfe_volume(hwdep_fd, 0); } } else if (!headphones_plugged && !strcmp(event_name, MASTER_VOLUME_NAME)) { // If headphones are unplugged and master volume changed, adjust LFE volume set_lfe_volume(hwdep_fd, get_master_volume()); } } return 0; }