1
2use crate::alsa;
3use super::pcm::Info;
4use core::ffi::CStr;
5use ::alloc::ffi::CString;
6use super::Direction;
7use super::error::*;
8use super::mixer::MilliBel;
9use super::Round;
10use core::{ptr, mem, fmt, cmp};
11use crate::{Card, poll};
12use core::cell::UnsafeCell;
13use libc::{c_uint, c_void, size_t, c_long, c_int, pollfd, c_short};
14
15const ELEM_ID_SIZE: usize = 64;
20#[derive(Debug)]
26pub struct DeviceIter<'a>(&'a Ctl, c_int);
27
28impl<'a> DeviceIter<'a>{
29 pub fn new(ctl: &'a Ctl) -> DeviceIter<'a> {
30 DeviceIter(ctl, -1)
31 }
32}
33
34impl<'a> Iterator for DeviceIter<'a> {
35 type Item = c_int;
36
37 fn next(&mut self) -> Option<c_int> {
38 match acheck!(snd_ctl_pcm_next_device(self.0.0, &mut self.1)) {
39 Ok(_) if self.1 == -1 => None,
40 Ok(_) => Some(self.1),
41 Err(_) => None,
42 }
43 }
44}
45
46#[derive(Debug)]
48pub struct Ctl(*mut alsa::snd_ctl_t);
49
50unsafe impl Send for Ctl {}
51
52impl Ctl {
53 pub fn new(c: &str, nonblock: bool) -> Result<Self> {
55 Self::open(&CString::new(c).unwrap(), nonblock)
56 }
57
58 pub fn open(c: &CStr, nonblock: bool) -> Result<Ctl> {
60 let mut r = ptr::null_mut();
61 let flags = if nonblock { 1 } else { 0 }; acheck!(snd_ctl_open(&mut r, c.as_ptr(), flags)).map(|_| Ctl(r))
63 }
64
65 pub fn from_card(c: &Card, nonblock: bool) -> Result<Ctl> {
66 let s = ::alloc::format!("hw:{}", c.get_index());
67 Ctl::open(&CString::new(s).unwrap(), nonblock)
68 }
69
70 pub fn card_info(&self) -> Result<CardInfo> { CardInfo::new().and_then(|c|
71 acheck!(snd_ctl_card_info(self.0, c.0)).map(|_| c)) }
72
73 pub fn wait(&self, timeout_ms: Option<u32>) -> Result<bool> {
74 acheck!(snd_ctl_wait(self.0, timeout_ms.map(|x| x as c_int).unwrap_or(-1))).map(|i| i == 1) }
75
76 pub fn get_db_range(&self, id: &ElemId) -> Result<(MilliBel, MilliBel)> {
77 let mut min: c_long = 0;
78 let mut max: c_long = 0;
79 acheck!(snd_ctl_get_dB_range(self.0, elem_id_ptr(id), &mut min, &mut max))
80 .map(|_| (MilliBel(min as i64), MilliBel(max as i64)))
81 }
82
83 pub fn convert_to_db(&self, id: &ElemId, volume: i64) -> Result<MilliBel> {
84 let mut m: c_long = 0;
85 acheck!(snd_ctl_convert_to_dB(self.0, elem_id_ptr(id), volume as c_long, &mut m))
86 .map(|_| MilliBel(m as i64))
87 }
88
89 pub fn convert_from_db(&self, id: &ElemId, mb: MilliBel, dir: Round) -> Result<i64> {
90 let mut m: c_long = 0;
91 acheck!(snd_ctl_convert_from_dB(self.0, elem_id_ptr(id), mb.0 as c_long, &mut m, dir as c_int))
92 .map(|_| m as i64)
93 }
94
95 pub fn elem_read(&self, val: &mut ElemValue) -> Result<()> {
96 acheck!(snd_ctl_elem_read(self.0, elem_value_ptr(val))).map(|_| ())
97 }
98
99 pub fn elem_write(&self, val: &ElemValue) -> Result<()> {
100 acheck!(snd_ctl_elem_write(self.0, elem_value_ptr(val))).map(|_| ())
101 }
102
103 pub fn elem_lock(&self, id: &ElemId) -> Result<i32> {
104 acheck!(snd_ctl_elem_lock(self.0, elem_id_ptr(id)))
105 }
106
107 pub fn elem_unlock(&self, id: &ElemId) -> Result<i32> {
108 acheck!(snd_ctl_elem_unlock(self.0, elem_id_ptr(id)))
109 }
110
111 pub fn elem_list(&self) -> Result<ElemList> {
112 let list = elem_list_new(|list| {
114 acheck!(snd_ctl_elem_list(self.0, list.0))?;
115 Ok(list.get_count())
116 })?;
117 acheck!(snd_ctl_elem_list(self.0, list.0))?;
118 Ok(list)
119 }
120
121 pub fn subscribe_events(&self, subscribe: bool) -> Result<()> {
125 acheck!(snd_ctl_subscribe_events(self.0, if subscribe { 1 } else { 0 })).map(|_| ())
126 }
127
128 pub fn read(&self) -> Result<Option<Event>> {
129 let e = event_new()?;
130 acheck!(snd_ctl_read(self.0, e.0)).map(|r| if r == 1 { Some(e) } else { None })
131 }
132
133 pub fn pcm_info(&self, device: u32, subdevice: u32, direction: Direction) -> Result<Info> {
134 Info::new().and_then(|mut info| {
135 info.set_device(device);
136 info.set_subdevice(subdevice);
137 info.set_stream(direction);
138 acheck!(snd_ctl_pcm_info(self.0, info.0)).map(|_| info )
139 })
140 }
141}
142
143impl Drop for Ctl {
144 fn drop(&mut self) { unsafe { alsa::snd_ctl_close(self.0) }; }
145}
146
147impl poll::Descriptors for Ctl {
148 fn count(&self) -> usize {
149 unsafe { alsa::snd_ctl_poll_descriptors_count(self.0) as usize }
150 }
151 fn fill(&self, p: &mut [pollfd]) -> Result<usize> {
152 let z = unsafe { alsa::snd_ctl_poll_descriptors(self.0, p.as_mut_ptr(), p.len() as c_uint) };
153 from_code("snd_ctl_poll_descriptors", z).map(|_| z as usize)
154 }
155 fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {
156 let mut r = 0;
157 let z = unsafe { alsa::snd_ctl_poll_descriptors_revents(self.0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };
158 from_code("snd_ctl_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))
159 }
160}
161
162
163pub fn ctl_ptr(a: &Ctl) -> *mut alsa::snd_ctl_t { a.0 }
164
165#[derive(Debug)]
167pub struct CardInfo(*mut alsa::snd_ctl_card_info_t);
168
169impl Drop for CardInfo {
170 fn drop(&mut self) { unsafe { alsa::snd_ctl_card_info_free(self.0) }}
171}
172
173impl CardInfo {
174 fn new() -> Result<CardInfo> {
175 let mut p = ptr::null_mut();
176 acheck!(snd_ctl_card_info_malloc(&mut p)).map(|_| CardInfo(p))
177 }
178
179 pub fn get_id(&self) -> Result<&str> {
180 from_const("snd_ctl_card_info_get_id", unsafe { alsa::snd_ctl_card_info_get_id(self.0) })}
181 pub fn get_driver(&self) -> Result<&str> {
182 from_const("snd_ctl_card_info_get_driver", unsafe { alsa::snd_ctl_card_info_get_driver(self.0) })}
183 pub fn get_components(&self) -> Result<&str> {
184 from_const("snd_ctl_card_info_get_components", unsafe { alsa::snd_ctl_card_info_get_components(self.0) })}
185 pub fn get_longname(&self) -> Result<&str> {
186 from_const("snd_ctl_card_info_get_longname", unsafe { alsa::snd_ctl_card_info_get_longname(self.0) })}
187 pub fn get_name(&self) -> Result<&str> {
188 from_const("snd_ctl_card_info_get_name", unsafe { alsa::snd_ctl_card_info_get_name(self.0) })}
189 pub fn get_mixername(&self) -> Result<&str> {
190 from_const("snd_ctl_card_info_get_mixername", unsafe { alsa::snd_ctl_card_info_get_mixername(self.0) })}
191 pub fn get_card(&self) -> Card { Card::new(unsafe { alsa::snd_ctl_card_info_get_card(self.0) })}
192}
193
194alsa_enum!(
195 ElemIface, ALL_ELEMIFACE[7],
197
198 Card = SND_CTL_ELEM_IFACE_CARD,
199 Hwdep = SND_CTL_ELEM_IFACE_HWDEP,
200 Mixer = SND_CTL_ELEM_IFACE_MIXER,
201 PCM = SND_CTL_ELEM_IFACE_PCM,
202 Rawmidi = SND_CTL_ELEM_IFACE_RAWMIDI,
203 Timer = SND_CTL_ELEM_IFACE_TIMER,
204 Sequencer = SND_CTL_ELEM_IFACE_SEQUENCER,
205);
206
207alsa_enum!(
208 ElemType, ALL_ELEMTYPE[7],
210
211 None = SND_CTL_ELEM_TYPE_NONE,
212 Boolean = SND_CTL_ELEM_TYPE_BOOLEAN,
213 Integer = SND_CTL_ELEM_TYPE_INTEGER,
214 Enumerated = SND_CTL_ELEM_TYPE_ENUMERATED,
215 Bytes = SND_CTL_ELEM_TYPE_BYTES,
216 IEC958 = SND_CTL_ELEM_TYPE_IEC958,
217 Integer64 = SND_CTL_ELEM_TYPE_INTEGER64,
218);
219
220pub struct ElemValue {
222 ptr: *mut alsa::snd_ctl_elem_value_t,
223 etype: ElemType,
224 count: u32,
225}
226
227impl Drop for ElemValue {
228 fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_value_free(self.ptr) }; }
229}
230
231pub fn elem_value_ptr(a: &ElemValue) -> *mut alsa::snd_ctl_elem_value_t { a.ptr }
232
233pub fn elem_value_new(t: ElemType, count: u32) -> Result<ElemValue> {
234 let mut p = ptr::null_mut();
235 acheck!(snd_ctl_elem_value_malloc(&mut p))
236 .map(|_| ElemValue { ptr: p, etype: t, count })
237}
238
239impl ElemValue {
240
241 pub fn set_id(&mut self, id: &ElemId) {
242 unsafe { alsa::snd_ctl_elem_value_set_id(self.ptr, elem_id_ptr(id)) }
243 }
244
245 pub fn get_boolean(&self, idx: u32) -> Option<bool> {
250 if self.etype != ElemType::Boolean || idx >= self.count { None }
251 else { Some( unsafe { alsa::snd_ctl_elem_value_get_boolean(self.ptr, idx as c_uint) } != 0) }
252 }
253
254 pub fn set_boolean(&mut self, idx: u32, val: bool) -> Option<()> {
255 if self.etype != ElemType::Boolean || idx >= self.count { None }
256 else { unsafe { alsa::snd_ctl_elem_value_set_boolean(self.ptr, idx as c_uint, if val {1} else {0}) }; Some(()) }
257 }
258
259 pub fn get_integer(&self, idx: u32) -> Option<i32> {
260 if self.etype != ElemType::Integer || idx >= self.count { None }
261 else { Some( unsafe { alsa::snd_ctl_elem_value_get_integer(self.ptr, idx as c_uint) } as i32) }
262 }
263
264 pub fn set_integer(&mut self, idx: u32, val: i32) -> Option<()> {
265 if self.etype != ElemType::Integer || idx >= self.count { None }
266 else { unsafe { alsa::snd_ctl_elem_value_set_integer(self.ptr, idx as c_uint, val as c_long) }; Some(()) }
267 }
268
269 pub fn get_integer64(&self, idx: u32) -> Option<i64> {
270 if self.etype != ElemType::Integer64 || idx >= self.count { None }
271 else { Some( unsafe { alsa::snd_ctl_elem_value_get_integer64(self.ptr, idx as c_uint) } as i64) }
272 }
273
274 pub fn set_integer64(&mut self, idx: u32, val: i64) -> Option<()> {
275 if self.etype != ElemType::Integer || idx >= self.count { None }
276 else { unsafe { alsa::snd_ctl_elem_value_set_integer64(self.ptr, idx as c_uint, val) }; Some(()) }
277 }
278
279 pub fn get_enumerated(&self, idx: u32) -> Option<u32> {
280 if self.etype != ElemType::Enumerated || idx >= self.count { None }
281 else { Some( unsafe { alsa::snd_ctl_elem_value_get_enumerated(self.ptr, idx as c_uint) } as u32) }
282 }
283
284 pub fn set_enumerated(&mut self, idx: u32, val: u32) -> Option<()> {
285 if self.etype != ElemType::Enumerated || idx >= self.count { None }
286 else { unsafe { alsa::snd_ctl_elem_value_set_enumerated(self.ptr, idx as c_uint, val as c_uint) }; Some(()) }
287 }
288
289 pub fn get_byte(&self, idx: u32) -> Option<u8> {
290 if self.etype != ElemType::Bytes || idx >= self.count { None }
291 else { Some( unsafe { alsa::snd_ctl_elem_value_get_byte(self.ptr, idx as c_uint) } as u8) }
292 }
293
294 pub fn set_byte(&mut self, idx: u32, val: u8) -> Option<()> {
295 if self.etype != ElemType::Bytes || idx >= self.count { None }
296 else { unsafe { alsa::snd_ctl_elem_value_set_byte(self.ptr, idx as c_uint, val) }; Some(()) }
297 }
298
299 pub fn get_bytes(&self) -> Option<&[u8]> {
300 if self.etype != ElemType::Bytes { None }
301 else { Some( unsafe { ::core::slice::from_raw_parts(
302 alsa::snd_ctl_elem_value_get_bytes(self.ptr) as *const u8, self.count as usize) } ) }
303 }
304
305 pub fn set_bytes(&mut self, val: &[u8]) -> Option<()> {
306 if self.etype != ElemType::Bytes || val.len() != self.count as usize { None }
307
308 else { unsafe { alsa::snd_ctl_elem_set_bytes(self.ptr, val.as_ptr() as *mut c_void, val.len() as size_t) }; Some(()) }
311 }
312
313 pub fn new(t: ElemType) -> Result<ElemValue> {
315 let count = match t {
317 ElemType::None => 1,
318 ElemType::Boolean => 128,
319 ElemType::Integer => 128,
320 ElemType::Enumerated => 128,
321 ElemType::Bytes => 512,
322 ElemType::IEC958 => 1,
323 ElemType::Integer64 => 64,
324 };
325 let ev = elem_value_new(t, count)?;
327 unsafe { alsa::snd_ctl_elem_value_clear(elem_value_ptr(&ev)) };
328 Ok(ev)
329 }
330
331}
332
333impl fmt::Debug for ElemValue {
334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
335 use self::ElemType::*;
336 write!(f, "ElemValue({:?}", self.etype)?;
337 for a in 0..self.count { match self.etype {
338 Boolean => write!(f, ",{:?}", self.get_boolean(a).unwrap()),
339 Integer => write!(f, ",{:?}", self.get_integer(a).unwrap()),
340 Integer64 => write!(f, ",{:?}", self.get_integer64(a).unwrap()),
341 Enumerated => write!(f, ",{:?}", self.get_enumerated(a).unwrap()),
342 Bytes => write!(f, ",{:?}", self.get_byte(a).unwrap()),
343 _ => Ok(()),
344 }?};
345 write!(f, ")")
346 }
347}
348
349#[derive(Debug)]
351pub struct ElemInfo(*mut alsa::snd_ctl_elem_info_t);
352
353pub fn elem_info_ptr(a: &ElemInfo) -> *mut alsa::snd_ctl_elem_info_t { a.0 }
354
355impl Drop for ElemInfo {
356 fn drop(&mut self) { unsafe { alsa::snd_ctl_elem_info_free(self.0) }; }
357}
358
359pub fn elem_info_new() -> Result<ElemInfo> {
360 let mut p = ptr::null_mut();
361 acheck!(snd_ctl_elem_info_malloc(&mut p)).map(|_| ElemInfo(p))
362}
363
364impl ElemInfo {
365 pub fn get_type(&self) -> ElemType { ElemType::from_c_int(
366 unsafe { alsa::snd_ctl_elem_info_get_type(self.0) } as c_int, "snd_ctl_elem_info_get_type").unwrap() }
367 pub fn get_count(&self) -> u32 { unsafe { alsa::snd_ctl_elem_info_get_count(self.0) as u32 } }
368}
369
370pub struct ElemId(UnsafeCell<[u8; ELEM_ID_SIZE]>);
376
377pub fn elem_id_new() -> Result<ElemId> {
378 assert!(unsafe { alsa::snd_ctl_elem_id_sizeof() } as usize <= ELEM_ID_SIZE);
379 Ok(ElemId(UnsafeCell::new(unsafe { mem::zeroed() })))
380}
381
382#[inline]
383pub fn elem_id_ptr(a: &ElemId) -> *mut alsa::snd_ctl_elem_id_t { a.0.get() as *mut _ as *mut alsa::snd_ctl_elem_id_t }
384
385unsafe impl Send for ElemId {}
386
387impl Clone for ElemId {
388 fn clone(&self) -> Self {
389 ElemId(UnsafeCell::new(unsafe { *self.0.get() }))
390 }
391}
392
393impl ElemId {
416 pub fn get_name(&self) -> Result<&str> {
417 from_const("snd_hctl_elem_id_get_name", unsafe { alsa::snd_ctl_elem_id_get_name(elem_id_ptr(self)) })}
418 pub fn get_device(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_device(elem_id_ptr(self)) as u32 }}
419 pub fn get_subdevice(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_subdevice(elem_id_ptr(self)) as u32 }}
420 pub fn get_numid(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_numid(elem_id_ptr(self)) as u32 }}
421 pub fn get_index(&self) -> u32 { unsafe { alsa::snd_ctl_elem_id_get_index(elem_id_ptr(self)) as u32 }}
422 pub fn get_interface(&self) -> ElemIface { ElemIface::from_c_int(
423 unsafe { alsa::snd_ctl_elem_id_get_interface(elem_id_ptr(self)) } as c_int, "snd_ctl_elem_id_get_interface").unwrap() }
424
425 pub fn set_device(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_device(elem_id_ptr(self), v) }}
426 pub fn set_subdevice(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_subdevice(elem_id_ptr(self), v) }}
427 pub fn set_numid(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_numid(elem_id_ptr(self), v) }}
428 pub fn set_index(&mut self, v: u32) { unsafe { alsa::snd_ctl_elem_id_set_index(elem_id_ptr(self), v) }}
429 pub fn set_interface(&mut self, v: ElemIface) { unsafe { alsa::snd_ctl_elem_id_set_interface(elem_id_ptr(self), v as u32) }}
430 pub fn set_name(&mut self, v: &CStr) { unsafe { alsa::snd_ctl_elem_id_set_name(elem_id_ptr(self), v.as_ptr()) }}
431
432 pub fn new(iface: ElemIface) -> Self {
436 let mut r = elem_id_new().unwrap();
437 r.set_interface(iface);
438 r
439 }
440}
441
442impl cmp::Eq for ElemId {}
443
444impl cmp::PartialEq for ElemId {
445 fn eq(&self, a: &ElemId) -> bool {
446 self.get_numid() == a.get_numid() && self.get_interface() == a.get_interface() &&
447 self.get_index() == a.get_index() && self.get_device() == a.get_device() &&
448 self.get_subdevice() == a.get_subdevice() && self.get_name().ok() == a.get_name().ok()
449 }
450}
451
452impl fmt::Debug for ElemId {
453 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
454 let index = self.get_index();
455 let device = self.get_device();
456 let subdevice = self.get_subdevice();
457
458 write!(f, "ElemId(#{}, {:?}, {:?}", self.get_numid(), self.get_interface(), self.get_name())?;
459 if index > 0 { write!(f, ", index={}", index)? };
460 if device > 0 || subdevice > 0 { write!(f, ", device={}", device)? };
461 if subdevice > 0 { write!(f, ", subdevice={}", device)? };
462 write!(f, ")")
463 }
464}
465
466#[derive(Debug)]
468pub struct ElemList(*mut alsa::snd_ctl_elem_list_t);
469
470impl Drop for ElemList {
471 fn drop(&mut self) {
472 unsafe { alsa::snd_ctl_elem_list_free_space(self.0) };
473 unsafe { alsa::snd_ctl_elem_list_free(self.0) };
474 }
475}
476
477fn elem_list_new<F: FnOnce(&ElemList) -> Result<u32>>(f: F) -> Result<ElemList> {
478 let mut p = ptr::null_mut();
479 let list = acheck!(snd_ctl_elem_list_malloc(&mut p)).map(|_| ElemList(p))?;
480 let count = f(&list)?;
481 if count > 0 {
482 acheck!(snd_ctl_elem_list_alloc_space(list.0, count))?;
483 }
484 Ok(list)
485}
486
487impl ElemList {
488 #[inline]
489 fn ensure_valid_index(&self, index: u32) -> Result<()> {
490 if index >= self.get_used() {
491 Err(Error::new("snd_ctl_elem_list_*", libc::EINVAL))
492 } else {
493 Ok(())
494 }
495 }
496
497 pub(crate) fn get_count(&self) -> u32 { unsafe { alsa::snd_ctl_elem_list_get_count(self.0) } }
498 pub fn get_used(&self) -> u32 { unsafe { alsa::snd_ctl_elem_list_get_used(self.0) } }
499 pub fn get_id(&self, index: u32) -> Result<ElemId> {
500 self.ensure_valid_index(index)?;
501 let elem_id = elem_id_new()?;
502 unsafe { alsa::snd_ctl_elem_list_get_id(self.0, index, elem_id_ptr(&elem_id)) };
503 Ok(elem_id)
504 }
505 pub fn get_numid(&self, index: u32) -> Result<u32> { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_numid(self.0, index) }) }
506 pub fn get_interface(&self, index: u32) -> Result<ElemIface> {
507 self.ensure_valid_index(index)?;
508 ElemIface::from_c_int(unsafe { alsa::snd_ctl_elem_list_get_interface(self.0, index) } as c_int, "snd_ctl_elem_list_get_interface")
509 }
510 pub fn get_device(&self, index: u32) -> Result<u32> { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_device(self.0, index) }) }
511 pub fn get_subdevice(&self, index: u32) -> Result<u32> { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_subdevice(self.0, index) }) }
512 pub fn get_name(&self, index: u32) -> Result<&str> {
513 self.ensure_valid_index(index)?;
514 from_const("snd_ctl_elem_list_get_name", unsafe { alsa::snd_ctl_elem_list_get_name(self.0, index) })
515 }
516 pub fn get_index(&self, index: u32) -> Result<u32> { self.ensure_valid_index(index)?; Ok(unsafe { alsa::snd_ctl_elem_list_get_index(self.0, index) }) }
517}
518
519#[derive(Debug)]
521pub struct Event(*mut alsa::snd_ctl_event_t);
522
523impl Drop for Event {
524 fn drop(&mut self) { unsafe { alsa::snd_ctl_event_free(self.0) }; }
525}
526
527pub fn event_new() -> Result<Event> {
528 let mut p = ptr::null_mut();
529 acheck!(snd_ctl_event_malloc(&mut p)).map(|_| Event(p))
530}
531
532impl Event {
533 pub fn get_mask(&self) -> EventMask { EventMask(unsafe { alsa::snd_ctl_event_elem_get_mask(self.0) as u32 })}
534 pub fn get_id(&self) -> ElemId {
535 let r = elem_id_new().unwrap();
536 unsafe { alsa::snd_ctl_event_elem_get_id(self.0, elem_id_ptr(&r)) };
537 r
538 }
539}
540
541
542#[derive(Default, Debug, Copy, Clone, Eq, PartialEq, Ord, PartialOrd)]
544pub struct EventMask(pub u32);
545
546impl EventMask {
547 pub fn remove(&self) -> bool { return self.0 & 0xffffffff == 0xffffffff }
548 pub fn value(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 0) != 0); }
549 pub fn info(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 1) != 0); }
550 pub fn add(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 2) != 0); }
551 pub fn tlv(&self) -> bool { return (!self.remove()) && (self.0 & (1 << 3) != 0); }
552}
553
554#[test]
555fn print_sizeof() {
556 extern crate std;
557 let elemid = unsafe { alsa::snd_ctl_elem_id_sizeof() } as usize;
558 let elemvalue = unsafe { alsa::snd_ctl_elem_value_sizeof() } as usize;
559 let eleminfo = unsafe { alsa::snd_ctl_elem_info_sizeof() } as usize;
560
561 assert!(elemid <= ELEM_ID_SIZE);
562std::println!("Elem id: {}, Elem value: {}, Elem info: {}", elemid, elemvalue, eleminfo);
566}