Skip to main content

alsa/
seq.rs

1//! MIDI sequencer I/O and enumeration
2
3use libc::{c_uint, c_int, c_short, c_uchar, c_void, c_long, size_t, pollfd};
4use super::error::*;
5use crate::alsa;
6use super::{Direction, poll};
7use core::{ptr, fmt, mem, slice, time, cell};
8use core::str::{FromStr, Split};
9use core::ffi::CStr;
10use ::alloc::borrow::Cow;
11use ::alloc::boxed::Box;
12
13// Workaround for improper alignment of snd_seq_ev_ext_t in alsa-sys
14#[repr(packed)]
15struct EvExtPacked {
16    len: c_uint,
17    ptr: *mut c_void,
18}
19
20/// [snd_seq_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___sequencer.html) wrapper
21///
22/// To access the functions `event_input`, `event_input_pending` and `set_input_buffer_size`,
23/// you first have to obtain an instance of `Input` by calling `input()`. Only one instance of
24/// `Input` may exist at any time for a given `Seq`.
25#[derive(Debug)]
26pub struct Seq(*mut alsa::snd_seq_t, cell::Cell<bool>);
27
28unsafe impl Send for Seq {}
29
30impl Drop for Seq {
31    fn drop(&mut self) { unsafe { alsa::snd_seq_close(self.0) }; }
32}
33
34impl Seq {
35    fn check_has_input(&self) {
36        if self.1.get() { panic!("No additional Input object allowed")}
37    }
38
39    /// Opens the sequencer.
40    ///
41    /// If name is None, "default" will be used. That's almost always what you usually want to use anyway.
42    pub fn open(name: Option<&CStr>, dir: Option<Direction>, nonblock: bool) -> Result<Seq> {
43        let n2 = name.unwrap_or(unsafe { CStr::from_bytes_with_nul_unchecked(b"default\0") });
44        let mut h = ptr::null_mut();
45        let mode = if nonblock { alsa::SND_SEQ_NONBLOCK } else { 0 };
46        let streams = match dir {
47            None => alsa::SND_SEQ_OPEN_DUPLEX,
48            Some(Direction::Playback) => alsa::SND_SEQ_OPEN_OUTPUT,
49            Some(Direction::Capture) => alsa::SND_SEQ_OPEN_INPUT,
50        };
51        acheck!(snd_seq_open(&mut h, n2.as_ptr(), streams, mode))
52            .map(|_| Seq(h, cell::Cell::new(false)))
53    }
54
55    pub fn set_client_name(&self, name: &CStr) -> Result<()> {
56        acheck!(snd_seq_set_client_name(self.0, name.as_ptr())).map(|_| ())
57    }
58
59    pub fn set_client_event_filter(&self, event_type: i32) -> Result<()> {
60        acheck!(snd_seq_set_client_event_filter(self.0, event_type as c_int)).map(|_| ())
61    }
62
63    pub fn set_client_pool_output(&self, size: u32) -> Result<()> {
64        acheck!(snd_seq_set_client_pool_output(self.0, size as size_t)).map(|_| ())
65    }
66
67    pub fn set_client_pool_input(&self, size: u32) -> Result<()> {
68        acheck!(snd_seq_set_client_pool_input(self.0, size as size_t)).map(|_| ())
69    }
70
71    pub fn set_client_pool_output_room(&self, size: u32) -> Result<()> {
72        acheck!(snd_seq_set_client_pool_output_room(self.0, size as size_t)).map(|_| ())
73    }
74
75    pub fn client_id(&self) -> Result<i32> {
76        acheck!(snd_seq_client_id(self.0)).map(|q| q as i32)
77    }
78
79    pub fn drain_output(&self) -> Result<i32> {
80        acheck!(snd_seq_drain_output(self.0)).map(|q| q as i32)
81    }
82
83    pub fn get_any_client_info(&self, client: i32) -> Result<ClientInfo> {
84        let c = ClientInfo::new()?;
85        acheck!(snd_seq_get_any_client_info(self.0, client, c.0)).map(|_| c)
86    }
87
88    pub fn get_any_port_info(&self, a: Addr) -> Result<PortInfo> {
89        let c = PortInfo::new()?;
90        acheck!(snd_seq_get_any_port_info(self.0, a.client as c_int, a.port as c_int, c.0)).map(|_| c)
91    }
92
93    pub fn create_port(&self, port: &PortInfo) -> Result<()> {
94        acheck!(snd_seq_create_port(self.0, port.0)).map(|_| ())
95    }
96
97    pub fn create_simple_port(&self, name: &CStr, caps: PortCap, t: PortType) -> Result<i32> {
98        acheck!(snd_seq_create_simple_port(self.0, name.as_ptr(), caps.bits() as c_uint, t.bits() as c_uint)).map(|q| q as i32)
99    }
100
101    pub fn set_port_info(&self, port: i32, info: &mut PortInfo) -> Result<()> {
102        acheck!(snd_seq_set_port_info(self.0, port, info.0)).map(|_| ())
103    }
104
105    pub fn delete_port(&self, port: i32) -> Result<()> {
106        acheck!(snd_seq_delete_port(self.0, port as c_int)).map(|_| ())
107    }
108
109    pub fn subscribe_port(&self, info: &PortSubscribe) -> Result<()> {
110        acheck!(snd_seq_subscribe_port(self.0, info.0)).map(|_| ())
111    }
112
113    pub fn unsubscribe_port(&self, sender: Addr, dest: Addr) -> Result<()> {
114        let z = PortSubscribe::new()?;
115        z.set_sender(sender);
116        z.set_dest(dest);
117        acheck!(snd_seq_unsubscribe_port(self.0, z.0)).map(|_| ())
118    }
119
120    pub fn control_queue(&self, q: i32, t: EventType, value: i32, e: Option<&mut Event>) -> Result<()> {
121        assert!(EvQueueControl::<()>::has_data(t) || EvQueueControl::<i32>::has_data(t) || EvQueueControl::<u32>::has_data(t));
122        let p = e.map(|e| &mut e.0 as *mut _).unwrap_or(ptr::null_mut());
123        acheck!(snd_seq_control_queue(self.0, q as c_int, t as c_int, value as c_int, p)).map(|_| ())
124    }
125
126    pub fn event_output(&self, e: &mut Event) -> Result<u32> {
127        e.ensure_buf();
128        acheck!(snd_seq_event_output(self.0, &mut e.0)).map(|q| q as u32)
129    }
130
131    pub fn event_output_buffer(&self, e: &mut Event) -> Result<u32> {
132        e.ensure_buf();
133        acheck!(snd_seq_event_output_buffer(self.0, &mut e.0)).map(|q| q as u32)
134    }
135
136    pub fn event_output_direct(&self, e: &mut Event) -> Result<u32> {
137        e.ensure_buf();
138        acheck!(snd_seq_event_output_direct(self.0, &mut e.0)).map(|q| q as u32)
139    }
140
141    pub fn get_queue_tempo(&self, q: i32) -> Result<QueueTempo> {
142        let value = QueueTempo::new()?;
143        acheck!(snd_seq_get_queue_tempo(self.0, q as c_int, value.0)).map(|_| value)
144    }
145
146    pub fn set_queue_tempo(&self, q: i32, value: &QueueTempo) -> Result<()> {
147        acheck!(snd_seq_set_queue_tempo(self.0, q as c_int, value.0)).map(|_| ())
148    }
149
150    pub fn get_queue_status(&self, q: i32) -> Result<QueueStatus> {
151        let value = QueueStatus::new()?;
152        acheck!(snd_seq_get_queue_status(self.0, q as c_int, value.0)).map(|_| value)
153    }
154
155    pub fn free_queue(&self, q: i32) -> Result<()> { acheck!(snd_seq_free_queue(self.0, q)).map(|_| ()) }
156    pub fn alloc_queue(&self) -> Result<i32> { acheck!(snd_seq_alloc_queue(self.0)).map(|q| q as i32) }
157    pub fn alloc_named_queue(&self, n: &CStr) -> Result<i32> {
158        acheck!(snd_seq_alloc_named_queue(self.0, n.as_ptr())).map(|q| q as i32)
159    }
160
161    pub fn sync_output_queue(&self) -> Result<()> {
162        acheck!(snd_seq_sync_output_queue(self.0)).map(|_| ())
163    }
164
165    pub fn drop_output(&self) -> Result<()> {
166        acheck!(snd_seq_drop_output(self.0)).map(|_| ())
167    }
168
169    /// Call this function to obtain an instance of `Input` to access the functions `event_input`,
170    /// `event_input_pending` and `set_input_buffer_size`. See the documentation of `Input` for details.
171    pub fn input(&self) -> Input<'_> {
172        Input::new(self)
173    }
174
175    pub fn remove_events(&self, condition: RemoveEvents) -> Result<()> {
176        acheck!(snd_seq_remove_events(self.0, condition.0)).map(|_| ())
177    }
178}
179
180/// Struct for receiving input events from a sequencer. The methods offered by this
181/// object may modify the internal input buffer of the sequencer, which must not happen
182/// while an `Event` is alive that has been obtained from a call to `event_input` (which
183/// takes `Input` by mutable reference for this reason). This is because the event might
184/// directly reference the sequencer's input buffer for variable-length messages (e.g. Sysex).
185///
186/// Note: Only one `Input` object is allowed in scope at a time.
187#[derive(Debug)]
188pub struct Input<'a>(&'a Seq);
189
190impl<'a> Drop for Input<'a> {
191    fn drop(&mut self) { (self.0).1.set(false) }
192}
193
194impl<'a> Input<'a> {
195    fn new(s: &'a Seq) -> Input<'a> {
196        s.check_has_input();
197        s.1.set(true);
198        Input(s)
199    }
200
201    pub fn event_input(&mut self) -> Result<Event<'_>> {
202        // The returned event might reference the input buffer of the `Seq`.
203        // Therefore we mutably borrow the `Input` structure, preventing any
204        // other function call that might change the input buffer while the
205        // event is alive.
206        let mut z = ptr::null_mut();
207        acheck!(snd_seq_event_input((self.0).0, &mut z))?;
208        unsafe { Event::extract (&mut *z, "snd_seq_event_input") }
209    }
210
211    pub fn event_input_pending(&self, fetch_sequencer: bool) -> Result<u32> {
212        acheck!(snd_seq_event_input_pending((self.0).0, if fetch_sequencer {1} else {0})).map(|q| q as u32)
213    }
214
215    pub fn set_input_buffer_size(&self, size: u32)  -> Result<()> {
216        acheck!(snd_seq_set_input_buffer_size((self.0).0, size as size_t)).map(|_| ())
217    }
218
219    pub fn drop_input(&self) -> Result<()> {
220        acheck!(snd_seq_drop_input((self.0).0)).map(|_| ())
221    }
222}
223
224fn polldir(o: Option<Direction>) -> c_short {
225    match o {
226        None => poll::Flags::IN | poll::Flags::OUT,
227        Some(Direction::Playback) => poll::Flags::OUT,
228        Some(Direction::Capture) => poll::Flags::IN,
229    }.bits()
230}
231
232impl<'a> poll::Descriptors for (&'a Seq, Option<Direction>) {
233
234    fn count(&self) -> usize {
235        unsafe { alsa::snd_seq_poll_descriptors_count((self.0).0, polldir(self.1)) as usize }
236    }
237
238    fn fill(&self, p: &mut [pollfd]) -> Result<usize> {
239        let z = unsafe { alsa::snd_seq_poll_descriptors((self.0).0, p.as_mut_ptr(), p.len() as c_uint, polldir(self.1)) };
240        from_code("snd_seq_poll_descriptors", z).map(|_| z as usize)
241    }
242
243    fn revents(&self, p: &[pollfd]) -> Result<poll::Flags> {
244        let mut r = 0;
245        let z = unsafe { alsa::snd_seq_poll_descriptors_revents((self.0).0, p.as_ptr() as *mut pollfd, p.len() as c_uint, &mut r) };
246        from_code("snd_seq_poll_descriptors_revents", z).map(|_| poll::Flags::from_bits_truncate(r as c_short))
247    }
248}
249
250/// [snd_seq_client_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_client.html) wrapper
251pub struct ClientInfo(*mut alsa::snd_seq_client_info_t);
252
253unsafe impl Send for ClientInfo {}
254
255impl Drop for ClientInfo {
256    fn drop(&mut self) {
257        unsafe { alsa::snd_seq_client_info_free(self.0) };
258    }
259}
260
261impl ClientInfo {
262    fn new() -> Result<Self> {
263        let mut p = ptr::null_mut();
264        acheck!(snd_seq_client_info_malloc(&mut p)).map(|_| ClientInfo(p))
265    }
266
267    // Not sure if it's useful for this one to be public.
268    fn set_client(&self, client: i32) {
269        unsafe { alsa::snd_seq_client_info_set_client(self.0, client as c_int) };
270    }
271
272    pub fn get_client(&self) -> i32 {
273        unsafe { alsa::snd_seq_client_info_get_client(self.0) as i32 }
274    }
275
276    pub fn get_name(&self) -> Result<&str> {
277        let c = unsafe { alsa::snd_seq_client_info_get_name(self.0) };
278        from_const("snd_seq_client_info_get_name", c)
279    }
280
281    pub fn get_card(&self) -> Result<i32> {
282        acheck!(snd_seq_client_info_get_card(self.0))
283    }
284}
285
286impl fmt::Debug for ClientInfo {
287    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
288        write!(f, "ClientInfo({},{:?})", self.get_client(), self.get_name())
289    }
290}
291
292#[derive(Copy, Clone, Debug)]
293/// Iterates over clients connected to the seq API (both kernel and userspace clients).
294pub struct ClientIter<'a>(&'a Seq, i32);
295
296impl<'a> ClientIter<'a> {
297    pub fn new(seq: &'a Seq) -> Self { ClientIter(seq, -1) }
298}
299
300impl<'a> Iterator for ClientIter<'a> {
301    type Item = ClientInfo;
302    fn next(&mut self) -> Option<Self::Item> {
303        let z = ClientInfo::new().unwrap();
304        z.set_client(self.1);
305        let r = unsafe { alsa::snd_seq_query_next_client((self.0).0, z.0) };
306        if r < 0 { self.1 = -1; return None };
307        self.1 = z.get_client();
308        Some(z)
309    }
310}
311
312/// [snd_seq_port_info_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_port.html) wrapper
313pub struct PortInfo(*mut alsa::snd_seq_port_info_t);
314
315unsafe impl Send for PortInfo {}
316
317impl Drop for PortInfo {
318    fn drop(&mut self) {
319        unsafe { alsa::snd_seq_port_info_free(self.0) };
320    }
321}
322
323impl PortInfo {
324    fn new() -> Result<Self> {
325        let mut p = ptr::null_mut();
326        acheck!(snd_seq_port_info_malloc(&mut p)).map(|_| PortInfo(p))
327    }
328
329    /// Creates a new PortInfo with all fields set to zero.
330    pub fn empty() -> Result<Self> {
331        let z = Self::new()?;
332        unsafe { ptr::write_bytes(z.0 as *mut u8, 0, alsa::snd_seq_port_info_sizeof()) };
333        Ok(z)
334    }
335
336    pub fn get_client(&self) -> i32 {
337        unsafe { alsa::snd_seq_port_info_get_client(self.0) as i32 }
338    }
339
340    pub fn get_port(&self) -> i32 {
341        unsafe { alsa::snd_seq_port_info_get_port(self.0) as i32 }
342    }
343
344    // Not sure if it's useful for this one to be public.
345    fn set_client(&self, client: i32) {
346        unsafe { alsa::snd_seq_port_info_set_client(self.0, client as c_int) };
347    }
348
349    // Not sure if it's useful for this one to be public.
350    fn set_port(&self, port: i32) {
351        unsafe { alsa::snd_seq_port_info_set_port(self.0, port as c_int) };
352    }
353
354    pub fn get_name(&self) -> Result<&str> {
355        let c = unsafe { alsa::snd_seq_port_info_get_name(self.0) };
356        from_const("snd_seq_port_info_get_name", c)
357    }
358
359    pub fn set_name(&mut self, name: &CStr) {
360        // Note: get_name returns an interior reference, so this one must take &mut self
361        unsafe { alsa::snd_seq_port_info_set_name(self.0, name.as_ptr()) };
362    }
363
364    pub fn get_capability(&self) -> PortCap {
365        PortCap::from_bits_truncate(unsafe { alsa::snd_seq_port_info_get_capability(self.0) as u32 })
366    }
367
368    pub fn get_type(&self) -> PortType {
369        PortType::from_bits_truncate(unsafe { alsa::snd_seq_port_info_get_type(self.0) as u32 })
370    }
371
372    pub fn set_capability(&self, c: PortCap) {
373        unsafe { alsa::snd_seq_port_info_set_capability(self.0, c.bits() as c_uint) }
374    }
375
376    pub fn set_type(&self, c: PortType) {
377        unsafe { alsa::snd_seq_port_info_set_type(self.0, c.bits() as c_uint) }
378    }
379
380    /// Returns an Addr containing this PortInfo's client and port id.
381    pub fn addr(&self) -> Addr {
382        Addr {
383            client: self.get_client(),
384            port: self.get_port(),
385        }
386    }
387
388    pub fn get_midi_channels(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_channels(self.0) as i32 } }
389    pub fn get_midi_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_midi_voices(self.0) as i32 } }
390    pub fn get_synth_voices(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_synth_voices(self.0) as i32 } }
391    pub fn get_read_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_read_use(self.0) as i32 } }
392    pub fn get_write_use(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_write_use(self.0) as i32 } }
393    pub fn get_port_specified(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_port_specified(self.0) == 1 } }
394    pub fn get_timestamping(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamping(self.0) == 1 } }
395    pub fn get_timestamp_real(&self) -> bool { unsafe { alsa::snd_seq_port_info_get_timestamp_real(self.0) == 1 } }
396    pub fn get_timestamp_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_info_get_timestamp_queue(self.0) as i32 } }
397
398    pub fn set_midi_channels(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_channels(self.0, value as c_int) } }
399    pub fn set_midi_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_midi_voices(self.0, value as c_int) } }
400    pub fn set_synth_voices(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_synth_voices(self.0, value as c_int) } }
401    pub fn set_port_specified(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_port_specified(self.0, if value { 1 } else { 0 } ) } }
402    pub fn set_timestamping(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamping(self.0, if value { 1 } else { 0 } ) } }
403    pub fn set_timestamp_real(&self, value: bool) { unsafe { alsa::snd_seq_port_info_set_timestamp_real(self.0, if value { 1 } else { 0 } ) } }
404    pub fn set_timestamp_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_info_set_timestamp_queue(self.0, value as c_int) } }
405}
406
407impl fmt::Debug for PortInfo {
408    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
409        write!(f, "PortInfo({}:{},{:?})", self.get_client(), self.get_port(), self.get_name())
410    }
411}
412
413#[derive(Copy, Clone, Debug)]
414/// Iterates over clients connected to the seq API (both kernel and userspace clients).
415pub struct PortIter<'a>(&'a Seq, i32, i32);
416
417impl<'a> PortIter<'a> {
418    pub fn new(seq: &'a Seq, client: i32) -> Self { PortIter(seq, client, -1) }
419}
420
421impl<'a> Iterator for PortIter<'a> {
422    type Item = PortInfo;
423    fn next(&mut self) -> Option<Self::Item> {
424        let z = PortInfo::new().unwrap();
425        z.set_client(self.1);
426        z.set_port(self.2);
427        let r = unsafe { alsa::snd_seq_query_next_port((self.0).0, z.0) };
428        if r < 0 { self.2 = -1; return None };
429        self.2 = z.get_port();
430        Some(z)
431    }
432}
433
434bitflags! {
435    #[repr(transparent)]
436    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
437    /// [SND_SEQ_PORT_CAP_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_port.html) constants
438    pub struct PortCap: u32 {
439        const READ = 1<<0;
440        const WRITE = 1<<1;
441        const SYNC_READ = 1<<2;
442        const SYNC_WRITE = 1<<3;
443        const DUPLEX = 1<<4;
444        const SUBS_READ = 1<<5;
445        const SUBS_WRITE = 1<<6;
446        const NO_EXPORT = 1<<7;
447   }
448}
449
450bitflags! {
451    #[repr(transparent)]
452    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
453    /// [SND_SEQ_PORT_TYPE_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_port.html) constants
454    pub struct PortType: u32 {
455        const SPECIFIC = (1<<0);
456        const MIDI_GENERIC = (1<<1);
457        const MIDI_GM = (1<<2);
458        const MIDI_GS = (1<<3);
459        const MIDI_XG = (1<<4);
460        const MIDI_MT32 = (1<<5);
461        const MIDI_GM2 = (1<<6);
462        const SYNTH = (1<<10);
463        const DIRECT_SAMPLE = (1<<11);
464        const SAMPLE = (1<<12);
465        const HARDWARE = (1<<16);
466        const SOFTWARE = (1<<17);
467        const SYNTHESIZER = (1<<18);
468        const PORT = (1<<19);
469        const APPLICATION = (1<<20);
470    }
471}
472
473bitflags! {
474    #[repr(transparent)]
475    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
476    /// [SND_SEQ_REMOVE_xxx](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html) constants
477    pub struct Remove: u32 {
478        const INPUT = (1<<0);
479        const OUTPUT = (1<<1);
480        const DEST = (1<<2);
481        const DEST_CHANNEL = (1<<3);
482        const TIME_BEFORE = (1<<4);
483        const TIME_AFTER = (1<<5);
484        const TIME_TICK = (1<<6);
485        const EVENT_TYPE = (1<<7);
486        const IGNORE_OFF = (1<<8);
487        const TAG_MATCH = (1<<9);
488    }
489}
490
491
492/// [snd_seq_addr_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__addr__t.html) wrapper
493#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash, Default)]
494pub struct Addr {
495    pub client: i32,
496    pub port: i32,
497}
498
499impl FromStr for Addr {
500    type Err = Box<dyn core::error::Error>;
501
502    fn from_str(s: &str) -> core::result::Result<Self, Self::Err> {
503        let mut split: Split<'_, char> = s.trim().split(':');
504        let client = split.next()
505                          .ok_or("no client provided")?
506                          .parse::<i32>()?;
507        let port = split.next()
508                        .ok_or("no port provided")?
509                        .parse::<i32>()?;
510        match split.next() {
511            Some(_) => {
512                Err("too many arguments".into())
513            },
514            None => {
515                Ok(Addr { client, port })
516            }
517        }
518    }
519}
520
521impl Addr {
522    pub fn system_timer() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_TIMER as i32 } }
523    pub fn system_announce() -> Addr { Addr { client: alsa::SND_SEQ_CLIENT_SYSTEM as i32, port: alsa::SND_SEQ_PORT_SYSTEM_ANNOUNCE as i32 } }
524    pub fn broadcast() -> Addr { Addr { client: alsa::SND_SEQ_ADDRESS_BROADCAST as i32, port: alsa::SND_SEQ_ADDRESS_BROADCAST as i32 } }
525}
526
527/// [snd_seq_port_subscribe_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper
528#[derive(Debug)]
529pub struct PortSubscribe(*mut alsa::snd_seq_port_subscribe_t);
530
531unsafe impl Send for PortSubscribe {}
532
533impl Drop for PortSubscribe {
534    fn drop(&mut self) { unsafe { alsa::snd_seq_port_subscribe_free(self.0) }; }
535}
536
537impl PortSubscribe {
538    fn new() -> Result<Self> {
539        let mut p = ptr::null_mut();
540        acheck!(snd_seq_port_subscribe_malloc(&mut p)).map(|_| PortSubscribe(p))
541    }
542
543    /// Creates a new PortSubscribe with all fields set to zero.
544    pub fn empty() -> Result<Self> {
545        let z = Self::new()?;
546        unsafe { ptr::write_bytes(z.0 as *mut u8, 0, alsa::snd_seq_port_subscribe_sizeof()) };
547        Ok(z)
548    }
549
550    pub fn get_sender(&self) -> Addr { unsafe {
551        let z = alsa::snd_seq_port_subscribe_get_sender(self.0);
552        Addr { client: (*z).client as i32, port: (*z).port as i32 }
553    } }
554
555    pub fn get_dest(&self) -> Addr { unsafe {
556        let z = alsa::snd_seq_port_subscribe_get_dest(self.0);
557        Addr { client: (*z).client as i32, port: (*z).port as i32 }
558    } }
559
560    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_port_subscribe_get_queue(self.0) as i32 } }
561    pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_exclusive(self.0) == 1 } }
562    pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_update(self.0) == 1 } }
563    pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_port_subscribe_get_time_real(self.0) == 1 } }
564
565    pub fn set_sender(&self, value: Addr) {
566        let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar };
567        unsafe { alsa::snd_seq_port_subscribe_set_sender(self.0, &z) };
568    }
569
570    pub fn set_dest(&self, value: Addr) {
571        let z = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar };
572        unsafe { alsa::snd_seq_port_subscribe_set_dest(self.0, &z) };
573    }
574
575    pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_port_subscribe_set_queue(self.0, value as c_int) } }
576    pub fn set_exclusive(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_exclusive(self.0, if value { 1 } else { 0 } ) } }
577    pub fn set_time_update(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_update(self.0, if value { 1 } else { 0 } ) } }
578    pub fn set_time_real(&self, value: bool) { unsafe { alsa::snd_seq_port_subscribe_set_time_real(self.0, if value { 1 } else { 0 } ) } }
579
580}
581
582/// [snd_seq_query_subs_type_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper
583#[derive(Copy, Clone, Debug)]
584pub enum QuerySubsType {
585    READ = alsa::SND_SEQ_QUERY_SUBS_READ as isize,
586    WRITE = alsa::SND_SEQ_QUERY_SUBS_WRITE as isize,
587}
588
589/// [snd_seq_query_subscribe_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_subscribe.html) wrapper
590//(kept private, functionality exposed by PortSubscribeIter)
591struct QuerySubscribe(*mut alsa::snd_seq_query_subscribe_t);
592
593unsafe impl Send for QuerySubscribe {}
594
595impl Drop for QuerySubscribe {
596    fn drop(&mut self) { unsafe { alsa::snd_seq_query_subscribe_free(self.0) } }
597}
598
599impl QuerySubscribe {
600    pub fn new() -> Result<Self> {
601        let mut q = ptr::null_mut();
602        acheck!(snd_seq_query_subscribe_malloc(&mut q)).map(|_| QuerySubscribe(q))
603    }
604
605    pub fn get_index(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_index(self.0) as i32 } }
606    pub fn get_addr(&self) -> Addr { unsafe {
607        let a = &(*alsa::snd_seq_query_subscribe_get_addr(self.0));
608        Addr { client: a.client as i32, port: a.port as i32 }
609    } }
610    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_query_subscribe_get_queue(self.0) as i32 } }
611    pub fn get_exclusive(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_exclusive(self.0) == 1 } }
612    pub fn get_time_update(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_update(self.0) == 1 } }
613    pub fn get_time_real(&self) -> bool { unsafe { alsa::snd_seq_query_subscribe_get_time_real(self.0) == 1 } }
614
615    pub fn set_root(&self, value: Addr) { unsafe {
616        let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar};
617        alsa::snd_seq_query_subscribe_set_root(self.0, &a);
618    } }
619    pub fn set_type(&self, value: QuerySubsType) { unsafe {
620        alsa::snd_seq_query_subscribe_set_type(self.0, value as alsa::snd_seq_query_subs_type_t)
621    } }
622    pub fn set_index(&self, value: i32) { unsafe { alsa::snd_seq_query_subscribe_set_index(self.0, value as c_int) } }
623}
624
625#[derive(Copy, Clone, Debug)]
626/// Iterates over port subscriptions for a given client:port/type.
627pub struct PortSubscribeIter<'a> {
628    seq: &'a Seq,
629    addr: Addr,
630    query_subs_type: QuerySubsType,
631    index: i32
632}
633
634impl<'a> PortSubscribeIter<'a> {
635    pub fn new(seq: &'a Seq, addr: Addr, query_subs_type: QuerySubsType) -> Self {
636        PortSubscribeIter {seq, addr, query_subs_type, index: 0 }
637    }
638}
639
640impl<'a> Iterator for PortSubscribeIter<'a> {
641    type Item = PortSubscribe;
642
643    fn next(&mut self) -> Option<Self::Item> {
644        let query = QuerySubscribe::new().unwrap();
645
646        query.set_root(self.addr);
647        query.set_type(self.query_subs_type);
648        query.set_index(self.index);
649
650        let r = unsafe { alsa::snd_seq_query_port_subscribers((self.seq).0, query.0) };
651        if r < 0 {
652            self.index = 0;
653            return None;
654        }
655
656        self.index = query.get_index() + 1;
657        let vtr = PortSubscribe::new().unwrap();
658        match self.query_subs_type {
659            QuerySubsType::READ => {
660                vtr.set_sender(self.addr);
661                vtr.set_dest(query.get_addr());
662            },
663            QuerySubsType:: WRITE => {
664                vtr.set_sender(query.get_addr());
665                vtr.set_dest(self.addr);
666            }
667        };
668        vtr.set_queue(query.get_queue());
669        vtr.set_exclusive(query.get_exclusive());
670        vtr.set_time_update(query.get_time_update());
671        vtr.set_time_real(query.get_time_real());
672
673        Some(vtr)
674    }
675}
676
677/// [snd_seq_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__event__t.html) wrapper
678///
679/// Fields of the event is not directly exposed. Instead call `Event::new` to set data (which can be, e g, an EvNote).
680/// Use `get_type` and `get_data` to retrieve data.
681///
682/// The lifetime parameter refers to the lifetime of an associated external buffer that might be used for
683/// variable-length messages (e.g. SysEx).
684pub struct Event<'a>(alsa::snd_seq_event_t, EventType, Option<Cow<'a, [u8]>>);
685
686unsafe impl<'a> Send for Event<'a> {}
687
688impl<'a> Event<'a> {
689    /// Creates a new event. For events that carry variable-length data (e.g. Sysex), `new_ext` has to be used instead.
690    pub fn new<D: EventData>(t: EventType, data: &D) -> Event<'static> {
691        assert!(!Event::has_ext_data(t), "event type must not carry variable-length data");
692        let mut z = Event(unsafe { mem::zeroed() }, t, None);
693        (z.0).type_ = t as c_uchar;
694        (z.0).flags |= Event::get_length_flag(t);
695        debug_assert!(D::has_data(t));
696        data.set_data(&mut z);
697        z
698    }
699
700    /// Creates a new event carrying variable-length data. This is required for event types `Sysex`, `Bounce`, and the `UsrVar` types.
701    pub fn new_ext<D: Into<Cow<'a, [u8]>>>(t: EventType, data: D) -> Event<'a> {
702        assert!(Event::has_ext_data(t), "event type must carry variable-length data");
703        let mut z = Event(unsafe { mem::zeroed() }, t, Some(data.into()));
704        (z.0).type_ = t as c_uchar;
705        (z.0).flags |= Event::get_length_flag(t);
706        z
707    }
708
709    /// Consumes this event and returns an (otherwise unchanged) event where the externally referenced
710    /// buffer for variable length messages (e.g. SysEx) has been copied into the event.
711    /// The returned event has a static lifetime, i e, it's decoupled from the original buffer.
712    pub fn into_owned(self) -> Event<'static> {
713        Event(self.0, self.1, self.2.map(|cow| Cow::Owned(cow.into_owned())))
714    }
715
716    fn get_length_flag(t: EventType) -> u8 {
717        match t {
718            EventType::Sysex => alsa::SND_SEQ_EVENT_LENGTH_VARIABLE,
719            EventType::Bounce => alsa::SND_SEQ_EVENT_LENGTH_VARIABLE, // not clear whether this should be VARIABLE or VARUSR
720            EventType::UsrVar0 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
721            EventType::UsrVar1 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
722            EventType::UsrVar2 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
723            EventType::UsrVar3 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
724            EventType::UsrVar4 => alsa::SND_SEQ_EVENT_LENGTH_VARUSR,
725            _ => alsa::SND_SEQ_EVENT_LENGTH_FIXED
726        }
727    }
728
729    fn has_ext_data(t: EventType) -> bool {
730        Event::get_length_flag(t) != alsa::SND_SEQ_EVENT_LENGTH_FIXED
731    }
732
733    /// Extracts event type and data. Produces a result with an arbitrary lifetime, hence the unsafety.
734    unsafe fn extract<'any>(z: &mut alsa::snd_seq_event_t, func: &'static str) -> Result<Event<'any>> {
735        let t = EventType::from_c_int((*z).type_ as c_int, func)?;
736        let ext_data = if Event::has_ext_data(t) {
737            assert_ne!((*z).flags & alsa::SND_SEQ_EVENT_LENGTH_MASK, alsa::SND_SEQ_EVENT_LENGTH_FIXED);
738            Some(Cow::Borrowed({
739                let zz: &EvExtPacked = &*(&(*z).data as *const alsa::snd_seq_event_data as *const _);
740                slice::from_raw_parts((*zz).ptr as *mut u8, (*zz).len as usize)
741            }))
742        } else {
743            None
744        };
745        Ok(Event(ptr::read(z), t, ext_data))
746    }
747
748    /// Ensures that the ev.ext union element points to the correct resize_buffer for events
749    /// with variable length content
750    fn ensure_buf(&mut self) {
751        if !Event::has_ext_data(self.1) { return; }
752        let slice: &[u8] = match self.2 {
753            Some(Cow::Owned(ref mut vec)) => &vec[..],
754            Some(Cow::Borrowed(buf)) => buf,
755            // The following case is always a logic error in the program, thus panicking is okay.
756            None => panic!("event type requires variable-length data, but none was provided")
757        };
758        let z: &mut EvExtPacked = unsafe { &mut *(&mut self.0.data as *mut alsa::snd_seq_event_data as *mut _) };
759        z.len = slice.len() as c_uint;
760        z.ptr = slice.as_ptr() as *mut c_void;
761    }
762
763    #[inline]
764    pub fn get_type(&self) -> EventType { self.1 }
765
766    /// Extract the event data from an event.
767    /// Use `get_ext` instead for events carrying variable-length data.
768    pub fn get_data<D: EventData>(&self) -> Option<D> { if D::has_data(self.1) { Some(D::get_data(self)) } else { None } }
769
770    /// Extract the variable-length data carried by events of type `Sysex`, `Bounce`, or the `UsrVar` types.
771    pub fn get_ext(&self) -> Option<&[u8]> {
772        if Event::has_ext_data(self.1) {
773            match self.2 {
774                Some(Cow::Owned(ref vec)) => Some(&vec[..]),
775                Some(Cow::Borrowed(buf)) => Some(buf),
776                // The following case is always a logic error in the program, thus panicking is okay.
777                None => panic!("event type requires variable-length data, but none was found")
778            }
779        } else {
780            None
781        }
782    }
783
784    pub fn set_subs(&mut self) {
785        self.0.dest.client = alsa::SND_SEQ_ADDRESS_SUBSCRIBERS;
786        self.0.dest.port = alsa::SND_SEQ_ADDRESS_UNKNOWN;
787    }
788
789    pub fn set_source(&mut self, p: i32) { self.0.source.port = p as u8 }
790    pub fn set_dest(&mut self, d: Addr) { self.0.dest.client = d.client as c_uchar; self.0.dest.port = d.port as c_uchar; }
791    pub fn set_tag(&mut self, t: u8) { self.0.tag = t as c_uchar;  }
792    pub fn set_queue(&mut self, q: i32) { self.0.queue = q as c_uchar;  }
793
794    pub fn get_source(&self) -> Addr { Addr { client: self.0.source.client as i32, port: self.0.source.port as i32 } }
795    pub fn get_dest(&self) -> Addr { Addr { client: self.0.dest.client as i32, port: self.0.dest.port as i32 } }
796    pub fn get_tag(&self) -> u8 { self.0.tag as u8  }
797    pub fn get_queue(&self) -> i32 { self.0.queue as i32 }
798
799    pub fn schedule_real(&mut self, queue: i32, relative: bool, rtime: time::Duration) {
800        self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK);
801        self.0.flags |= alsa::SND_SEQ_TIME_STAMP_REAL | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS });
802        self.0.queue = queue as u8;
803        let t = unsafe { &mut self.0.time.time };
804        t.tv_sec = rtime.as_secs() as c_uint;
805        t.tv_nsec = rtime.subsec_nanos() as c_uint;
806    }
807
808    pub fn schedule_tick(&mut self, queue: i32, relative: bool, ttime: u32) {
809        self.0.flags &= !(alsa::SND_SEQ_TIME_STAMP_MASK | alsa::SND_SEQ_TIME_MODE_MASK);
810        self.0.flags |= alsa::SND_SEQ_TIME_STAMP_TICK | (if relative { alsa::SND_SEQ_TIME_MODE_REL } else { alsa::SND_SEQ_TIME_MODE_ABS });
811        self.0.queue = queue as u8;
812        let t = unsafe { &mut self.0.time.tick };
813        *t = ttime as c_uint;
814    }
815
816    pub fn set_direct(&mut self) { self.0.queue = alsa::SND_SEQ_QUEUE_DIRECT }
817
818    pub fn get_relative(&self) -> bool { (self.0.flags & alsa::SND_SEQ_TIME_MODE_REL) != 0 }
819
820    pub fn get_time(&self) -> Option<time::Duration> {
821        if (self.0.flags & alsa::SND_SEQ_TIME_STAMP_REAL) != 0 {
822            let d = self.0.time;
823            let t = unsafe { &d.time };
824            Some(time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32))
825        } else { None }
826    }
827
828    pub fn get_tick(&self) -> Option<u32> {
829        if (self.0.flags & alsa::SND_SEQ_TIME_STAMP_REAL) == 0 {
830            let d = self.0.time;
831            let t = unsafe { &d.tick };
832            Some(*t)
833        } else { None }
834    }
835
836    /// Returns true if the message is high priority.
837    pub fn get_priority(&self) -> bool { (self.0.flags & alsa::SND_SEQ_PRIORITY_HIGH) != 0 }
838
839    pub fn set_priority(&mut self, is_high_prio: bool) {
840        if is_high_prio { self.0.flags |= alsa::SND_SEQ_PRIORITY_HIGH; }
841        else { self.0.flags &= !alsa::SND_SEQ_PRIORITY_HIGH; }
842    }
843}
844
845impl<'a> Clone for Event<'a> {
846    fn clone(&self) -> Self { Event(unsafe { ptr::read(&self.0) }, self.1, self.2.clone()) }
847}
848
849impl<'a> fmt::Debug for Event<'a> {
850    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
851        let mut x = f.debug_tuple("Event");
852        x.field(&self.1);
853        if let Some(z) = self.get_data::<EvNote>() { x.field(&z); }
854        if let Some(z) = self.get_data::<EvCtrl>() { x.field(&z); }
855        if let Some(z) = self.get_data::<Addr>() { x.field(&z); }
856        if let Some(z) = self.get_data::<Connect>() { x.field(&z); }
857        if let Some(z) = self.get_data::<EvQueueControl<()>>() { x.field(&z); }
858        if let Some(z) = self.get_data::<EvQueueControl<i32>>() { x.field(&z); }
859        if let Some(z) = self.get_data::<EvQueueControl<u32>>() { x.field(&z); }
860        if let Some(z) = self.get_data::<EvQueueControl<time::Duration>>() { x.field(&z); }
861        if let Some(z) = self.get_data::<EvResult>() { x.field(&z); }
862        if let Some(z) = self.get_data::<[u8; 12]>() { x.field(&z); }
863        if let Some(z) = self.get_ext() { x.field(&z); }
864        x.finish()
865    }
866}
867
868/// Internal trait implemented for different event type structs (`EvNote`, `EvCtrl`, etc).
869///
870/// Use it through `Event::get_data` and `Event::new`.
871pub trait EventData {
872    #[doc(hidden)]
873    fn get_data(ev: &Event) -> Self;
874    #[doc(hidden)]
875    fn has_data(e: EventType) -> bool;
876    #[doc(hidden)]
877    fn set_data(&self, ev: &mut Event);
878}
879
880impl EventData for () {
881    fn get_data(_: &Event) -> Self {}
882    fn has_data(e: EventType) -> bool {
883         matches!(e,
884             EventType::TuneRequest |
885             EventType::Reset |
886             EventType::Sensing |
887             EventType::None)
888    }
889    fn set_data(&self, _: &mut Event) {}
890}
891
892impl EventData for [u8; 12] {
893    fn get_data(ev: &Event) -> Self {
894         let d = unsafe { ptr::read(&ev.0.data) };
895         let z = unsafe { &d.raw8 };
896         z.d
897    }
898    fn has_data(e: EventType) -> bool {
899         matches!(e,
900             EventType::Echo |
901             EventType::Oss |
902             EventType::Usr0 |
903             EventType::Usr1 |
904             EventType::Usr2 |
905             EventType::Usr3 |
906             EventType::Usr4 |
907             EventType::Usr5 |
908             EventType::Usr6 |
909             EventType::Usr7 |
910             EventType::Usr8 |
911             EventType::Usr9)
912    }
913    fn set_data(&self, ev: &mut Event) {
914         let z = unsafe { &mut ev.0.data.raw8 };
915         z.d = *self;
916    }
917}
918
919
920#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
921pub struct EvNote {
922    pub channel: u8,
923    pub note: u8,
924    pub velocity: u8,
925    pub off_velocity: u8,
926    pub duration: u32,
927}
928
929impl EventData for EvNote {
930    fn get_data(ev: &Event) -> Self {
931         let z: &alsa::snd_seq_ev_note_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };
932         EvNote { channel: z.channel as u8, note: z.note as u8, velocity: z.velocity as u8, off_velocity: z.off_velocity as u8, duration: z.duration as u32 }
933    }
934    fn has_data(e: EventType) -> bool {
935         matches!(e,
936             EventType::Note |
937             EventType::Noteon |
938             EventType::Noteoff |
939             EventType::Keypress)
940    }
941    fn set_data(&self, ev: &mut Event) {
942         let z: &mut alsa::snd_seq_ev_note_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };
943         z.channel = self.channel as c_uchar;
944         z.note = self.note as c_uchar;
945         z.velocity = self.velocity as c_uchar;
946         z.off_velocity = self.off_velocity as c_uchar;
947         z.duration = self.duration as c_uint;
948    }
949}
950
951#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
952pub struct EvCtrl {
953    pub channel: u8,
954    pub param: u32,
955    pub value: i32,
956}
957
958impl EventData for EvCtrl {
959    fn get_data(ev: &Event) -> Self {
960         let z: &alsa::snd_seq_ev_ctrl_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };
961         EvCtrl { channel: z.channel as u8, param: z.param as u32, value: z.value as i32 }
962    }
963    fn has_data(e: EventType) -> bool {
964         matches!(e,
965             EventType::Controller |
966             EventType::Pgmchange |
967             EventType::Chanpress |
968             EventType::Pitchbend |
969             EventType::Control14 |
970             EventType::Nonregparam |
971             EventType::Regparam |
972             EventType::Songpos |
973             EventType::Songsel |
974             EventType::Qframe |
975             EventType::Timesign |
976             EventType::Keysign)
977    }
978    fn set_data(&self, ev: &mut Event) {
979         let z: &mut alsa::snd_seq_ev_ctrl_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };
980         z.channel = self.channel as c_uchar;
981         z.param = self.param as c_uint;
982         z.value = self.value as c_int;
983    }
984}
985
986impl EventData for Addr {
987    fn get_data(ev: &Event) -> Self {
988         let z: &alsa::snd_seq_addr_t = unsafe { &*(&ev.0.data as *const alsa::snd_seq_event_data as *const _) };
989         Addr { client: z.client as i32, port: z.port as i32 }
990    }
991    fn has_data(e: EventType) -> bool {
992         matches!(e,
993             EventType::ClientStart |
994             EventType::ClientExit |
995             EventType::ClientChange |
996             EventType::PortStart |
997             EventType::PortExit |
998             EventType::PortChange)
999    }
1000    fn set_data(&self, ev: &mut Event) {
1001         let z: &mut alsa::snd_seq_addr_t = unsafe { &mut *(&mut ev.0.data as *mut alsa::snd_seq_event_data as *mut _) };
1002         z.client = self.client as c_uchar;
1003         z.port = self.port as c_uchar;
1004    }
1005}
1006
1007#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
1008/// [snd_seq_connect_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__connect__t.html) wrapper
1009pub struct Connect {
1010    pub sender: Addr,
1011    pub dest: Addr,
1012}
1013
1014impl EventData for Connect {
1015    fn get_data(ev: &Event) -> Self {
1016         let d = unsafe { ptr::read(&ev.0.data) };
1017         let z = unsafe { &d.connect };
1018         Connect {
1019             sender: Addr { client: z.sender.client as i32, port: z.sender.port as i32 },
1020             dest: Addr { client: z.dest.client as i32, port: z.dest.port as i32 }
1021         }
1022    }
1023    fn has_data(e: EventType) -> bool {
1024         matches!(e,
1025             EventType::PortSubscribed |
1026             EventType::PortUnsubscribed)
1027    }
1028    fn set_data(&self, ev: &mut Event) {
1029         let z = unsafe { &mut ev.0.data.connect };
1030         z.sender.client = self.sender.client as c_uchar;
1031         z.sender.port = self.sender.port as c_uchar;
1032         z.dest.client = self.dest.client as c_uchar;
1033         z.dest.port = self.dest.port as c_uchar;
1034    }
1035}
1036
1037#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
1038/// [snd_seq_ev_queue_control_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__ev__queue__control__t.html) wrapper
1039///
1040/// Note: This struct is generic, but what types of T are required for the different EvQueueControl messages is
1041/// not very well documented in alsa-lib. Right now, Tempo is i32, Tick, SetposTick and SyncPos are u32, SetposTime is time::Duration,
1042/// and the rest is (). If I guessed wrong, let me know.
1043pub struct EvQueueControl<T> {
1044    pub queue: i32,
1045    pub value: T,
1046}
1047
1048impl EventData for EvQueueControl<()> {
1049    fn get_data(ev: &Event) -> Self {
1050         let d = unsafe { ptr::read(&ev.0.data) };
1051         let z = unsafe { &d.queue };
1052         EvQueueControl { queue: z.queue as i32, value: () }
1053    }
1054    fn has_data(e: EventType) -> bool {
1055         matches!(e,
1056             EventType::Start |
1057             EventType::Continue |
1058             EventType::Stop |
1059             EventType::Clock |
1060             EventType::QueueSkew)
1061    }
1062    fn set_data(&self, ev: &mut Event) {
1063         let z = unsafe { &mut ev.0.data.queue };
1064         z.queue = self.queue as c_uchar;
1065    }
1066}
1067
1068impl EventData for EvQueueControl<i32> {
1069    fn get_data(ev: &Event) -> Self { unsafe {
1070         let mut d = ptr::read(&ev.0.data);
1071         let z = &mut d.queue;
1072         EvQueueControl { queue: z.queue as i32, value: z.param.value as i32 }
1073    } }
1074    fn has_data(e: EventType) -> bool {
1075         matches!(e,
1076             EventType::Tempo)
1077    }
1078    fn set_data(&self, ev: &mut Event) { unsafe {
1079         let z = &mut ev.0.data.queue;
1080         z.queue = self.queue as c_uchar;
1081         z.param.value = self.value as c_int;
1082    } }
1083}
1084
1085impl EventData for EvQueueControl<u32> {
1086    fn get_data(ev: &Event) -> Self { unsafe {
1087         let mut d = ptr::read(&ev.0.data);
1088         let z = &mut d.queue;
1089         EvQueueControl { queue: z.queue as i32, value: z.param.position as u32 }
1090    } }
1091    fn has_data(e: EventType) -> bool {
1092         matches!(e,
1093             EventType::SyncPos |
1094             EventType::Tick |
1095             EventType::SetposTick)
1096    }
1097    fn set_data(&self, ev: &mut Event) { unsafe {
1098         let z = &mut ev.0.data.queue;
1099         z.queue = self.queue as c_uchar;
1100         z.param.position = self.value as c_uint;
1101    } }
1102}
1103
1104impl EventData for EvQueueControl<time::Duration> {
1105    fn get_data(ev: &Event) -> Self { unsafe {
1106         let mut d = ptr::read(&ev.0.data);
1107         let z = &mut d.queue;
1108         let t = &mut z.param.time.time;
1109         EvQueueControl { queue: z.queue as i32, value: time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32) }
1110    } }
1111    fn has_data(e: EventType) -> bool {
1112         matches!(e,
1113             EventType::SetposTime)
1114    }
1115    fn set_data(&self, ev: &mut Event) { unsafe {
1116         let z = &mut ev.0.data.queue;
1117         z.queue = self.queue as c_uchar;
1118         let t = &mut z.param.time.time;
1119         t.tv_sec = self.value.as_secs() as c_uint;
1120         t.tv_nsec = self.value.subsec_nanos() as c_uint;
1121    } }
1122}
1123
1124#[derive(Copy, Clone, Debug, PartialEq, Eq, Ord, PartialOrd, Hash, Default)]
1125/// [snd_seq_result_t](http://www.alsa-project.org/alsa-doc/alsa-lib/structsnd__seq__result__t.html) wrapper
1126///
1127/// It's called EvResult instead of Result, in order to not be confused with Rust's Result type.
1128pub struct EvResult {
1129    pub event: i32,
1130    pub result: i32,
1131}
1132
1133impl EventData for EvResult {
1134    fn get_data(ev: &Event) -> Self {
1135         let d = unsafe { ptr::read(&ev.0.data) };
1136         let z = unsafe { &d.result };
1137         EvResult { event: z.event as i32, result: z.result as i32 }
1138    }
1139    fn has_data(e: EventType) -> bool {
1140         matches!(e,
1141             EventType::System |
1142             EventType::Result)
1143    }
1144    fn set_data(&self, ev: &mut Event) {
1145         let z = unsafe { &mut ev.0.data.result };
1146         z.event = self.event as c_int;
1147         z.result = self.result as c_int;
1148    }
1149}
1150
1151
1152
1153alsa_enum!(
1154    /// [SND_SEQ_EVENT_xxx](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_events.html) constants
1155
1156    EventType, ALL_EVENT_TYPES[59],
1157
1158    Bounce = SND_SEQ_EVENT_BOUNCE,
1159    Chanpress = SND_SEQ_EVENT_CHANPRESS,
1160    ClientChange = SND_SEQ_EVENT_CLIENT_CHANGE,
1161    ClientExit = SND_SEQ_EVENT_CLIENT_EXIT,
1162    ClientStart = SND_SEQ_EVENT_CLIENT_START,
1163    Clock = SND_SEQ_EVENT_CLOCK,
1164    Continue = SND_SEQ_EVENT_CONTINUE,
1165    Control14 = SND_SEQ_EVENT_CONTROL14,
1166    Controller = SND_SEQ_EVENT_CONTROLLER,
1167    Echo = SND_SEQ_EVENT_ECHO,
1168    Keypress = SND_SEQ_EVENT_KEYPRESS,
1169    Keysign = SND_SEQ_EVENT_KEYSIGN,
1170    None = SND_SEQ_EVENT_NONE,
1171    Nonregparam = SND_SEQ_EVENT_NONREGPARAM,
1172    Note = SND_SEQ_EVENT_NOTE,
1173    Noteoff = SND_SEQ_EVENT_NOTEOFF,
1174    Noteon = SND_SEQ_EVENT_NOTEON,
1175    Oss = SND_SEQ_EVENT_OSS,
1176    Pgmchange = SND_SEQ_EVENT_PGMCHANGE,
1177    Pitchbend = SND_SEQ_EVENT_PITCHBEND,
1178    PortChange = SND_SEQ_EVENT_PORT_CHANGE,
1179    PortExit = SND_SEQ_EVENT_PORT_EXIT,
1180    PortStart = SND_SEQ_EVENT_PORT_START,
1181    PortSubscribed = SND_SEQ_EVENT_PORT_SUBSCRIBED,
1182    PortUnsubscribed = SND_SEQ_EVENT_PORT_UNSUBSCRIBED,
1183    Qframe = SND_SEQ_EVENT_QFRAME,
1184    QueueSkew = SND_SEQ_EVENT_QUEUE_SKEW,
1185    Regparam = SND_SEQ_EVENT_REGPARAM,
1186    Reset = SND_SEQ_EVENT_RESET,
1187    Result = SND_SEQ_EVENT_RESULT,
1188    Sensing = SND_SEQ_EVENT_SENSING,
1189    SetposTick = SND_SEQ_EVENT_SETPOS_TICK,
1190    SetposTime = SND_SEQ_EVENT_SETPOS_TIME,
1191    Songpos = SND_SEQ_EVENT_SONGPOS,
1192    Songsel = SND_SEQ_EVENT_SONGSEL,
1193    Start = SND_SEQ_EVENT_START,
1194    Stop = SND_SEQ_EVENT_STOP,
1195    SyncPos = SND_SEQ_EVENT_SYNC_POS,
1196    Sysex = SND_SEQ_EVENT_SYSEX,
1197    System = SND_SEQ_EVENT_SYSTEM,
1198    Tempo = SND_SEQ_EVENT_TEMPO,
1199    Tick = SND_SEQ_EVENT_TICK,
1200    Timesign = SND_SEQ_EVENT_TIMESIGN,
1201    TuneRequest = SND_SEQ_EVENT_TUNE_REQUEST,
1202    Usr0 = SND_SEQ_EVENT_USR0,
1203    Usr1 = SND_SEQ_EVENT_USR1,
1204    Usr2 = SND_SEQ_EVENT_USR2,
1205    Usr3 = SND_SEQ_EVENT_USR3,
1206    Usr4 = SND_SEQ_EVENT_USR4,
1207    Usr5 = SND_SEQ_EVENT_USR5,
1208    Usr6 = SND_SEQ_EVENT_USR6,
1209    Usr7 = SND_SEQ_EVENT_USR7,
1210    Usr8 = SND_SEQ_EVENT_USR8,
1211    Usr9 = SND_SEQ_EVENT_USR9,
1212    UsrVar0 = SND_SEQ_EVENT_USR_VAR0,
1213    UsrVar1 = SND_SEQ_EVENT_USR_VAR1,
1214    UsrVar2 = SND_SEQ_EVENT_USR_VAR2,
1215    UsrVar3 = SND_SEQ_EVENT_USR_VAR3,
1216    UsrVar4 = SND_SEQ_EVENT_USR_VAR4,
1217);
1218
1219/// [snd_seq_queue_tempo_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html) wrapper
1220#[derive(Debug)]
1221pub struct QueueTempo(*mut alsa::snd_seq_queue_tempo_t);
1222
1223unsafe impl Send for QueueTempo {}
1224
1225impl Drop for QueueTempo {
1226    fn drop(&mut self) { unsafe { alsa::snd_seq_queue_tempo_free(self.0) } }
1227}
1228
1229impl QueueTempo {
1230    fn new() -> Result<Self> {
1231        let mut q = ptr::null_mut();
1232        acheck!(snd_seq_queue_tempo_malloc(&mut q)).map(|_| QueueTempo(q))
1233    }
1234
1235    /// Creates a new QueueTempo with all fields set to zero.
1236    pub fn empty() -> Result<Self> {
1237        let q = QueueTempo::new()?;
1238        unsafe { ptr::write_bytes(q.0 as *mut u8, 0, alsa::snd_seq_queue_tempo_sizeof()) };
1239        Ok(q)
1240    }
1241
1242    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_queue(self.0) as i32 } }
1243    pub fn get_tempo(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_tempo(self.0) as u32 } }
1244    pub fn get_ppq(&self) -> i32 { unsafe { alsa::snd_seq_queue_tempo_get_ppq(self.0) as i32 } }
1245    pub fn get_skew(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew(self.0) as u32 } }
1246    pub fn get_skew_base(&self) -> u32 { unsafe { alsa::snd_seq_queue_tempo_get_skew_base(self.0) as u32 } }
1247
1248//    pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_queue(self.0, value as c_int) } }
1249    pub fn set_tempo(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_tempo(self.0, value as c_uint) } }
1250    pub fn set_ppq(&self, value: i32) { unsafe { alsa::snd_seq_queue_tempo_set_ppq(self.0, value as c_int) } }
1251    pub fn set_skew(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew(self.0, value as c_uint) } }
1252    pub fn set_skew_base(&self, value: u32) { unsafe { alsa::snd_seq_queue_tempo_set_skew_base(self.0, value as c_uint) } }
1253}
1254
1255/// [snd_seq_queue_status_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_queue.html) wrapper
1256#[derive(Debug)]
1257pub struct QueueStatus(*mut alsa::snd_seq_queue_status_t);
1258
1259unsafe impl Send for QueueStatus {}
1260
1261impl Drop for QueueStatus {
1262    fn drop(&mut self) { unsafe { alsa::snd_seq_queue_status_free(self.0) } }
1263}
1264
1265impl QueueStatus {
1266    fn new() -> Result<Self> {
1267        let mut q = ptr::null_mut();
1268        acheck!(snd_seq_queue_status_malloc(&mut q)).map(|_| QueueStatus(q))
1269    }
1270
1271    /// Creates a new QueueStatus with all fields set to zero.
1272    pub fn empty() -> Result<Self> {
1273        let q = QueueStatus::new()?;
1274        unsafe { ptr::write_bytes(q.0 as *mut u8, 0, alsa::snd_seq_queue_status_sizeof()) };
1275        Ok(q)
1276    }
1277
1278    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_queue(self.0) as i32 } }
1279    pub fn get_events(&self) -> i32 { unsafe { alsa::snd_seq_queue_status_get_events(self.0) as i32 } }
1280    pub fn get_tick_time(&self) -> u32 { unsafe {alsa::snd_seq_queue_status_get_tick_time(self.0) as u32 } }
1281    pub fn get_real_time(&self) -> time::Duration { unsafe {
1282        let t = &(*alsa::snd_seq_queue_status_get_real_time(self.0));
1283        time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32)
1284    } }
1285    pub fn get_status(&self) -> u32 { unsafe { alsa::snd_seq_queue_status_get_status(self.0) as u32 } }
1286}
1287
1288/// [snd_seq_remove_events_t](https://www.alsa-project.org/alsa-doc/alsa-lib/group___seq_event.html) wrapper
1289#[derive(Debug)]
1290pub struct RemoveEvents(*mut alsa::snd_seq_remove_events_t);
1291
1292unsafe impl Send for RemoveEvents {}
1293
1294impl Drop for RemoveEvents {
1295    fn drop(&mut self) { unsafe { alsa::snd_seq_remove_events_free(self.0) } }
1296}
1297
1298impl RemoveEvents {
1299    pub fn new() -> Result<Self> {
1300        let mut q = ptr::null_mut();
1301        acheck!(snd_seq_remove_events_malloc(&mut q)).map(|_| RemoveEvents(q))
1302    }
1303
1304    pub fn get_condition(&self) -> Remove { unsafe {
1305        Remove::from_bits_truncate(alsa::snd_seq_remove_events_get_condition(self.0) as u32)
1306    } }
1307    pub fn get_queue(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_queue(self.0) as i32 } }
1308    pub fn get_time(&self) -> time::Duration { unsafe {
1309        let d = ptr::read(alsa::snd_seq_remove_events_get_time(self.0));
1310        let t = &d.time;
1311
1312        time::Duration::new(t.tv_sec as u64, t.tv_nsec as u32)
1313    } }
1314    pub fn get_dest(&self) -> Addr { unsafe {
1315        let a = &(*alsa::snd_seq_remove_events_get_dest(self.0));
1316
1317        Addr { client: a.client as i32, port: a.port as i32 }
1318    } }
1319    pub fn get_channel(&self) -> i32 { unsafe { alsa::snd_seq_remove_events_get_channel(self.0) as i32 } }
1320    pub fn get_event_type(&self) -> Result<EventType> { unsafe {
1321        EventType::from_c_int(alsa::snd_seq_remove_events_get_event_type(self.0), "snd_seq_remove_events_get_event_type")
1322    } }
1323    pub fn get_tag(&self) -> u8 { unsafe { alsa::snd_seq_remove_events_get_tag(self.0) as u8 } }
1324
1325
1326    pub fn set_condition(&self, value: Remove) { unsafe {
1327        alsa::snd_seq_remove_events_set_condition(self.0, value.bits() as c_uint);
1328    } }
1329    pub fn set_queue(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_queue(self.0, value as c_int) } }
1330    pub fn set_time(&self, value: time::Duration) { unsafe {
1331        let mut d: alsa::snd_seq_timestamp_t = mem::zeroed();
1332        let t = &mut d.time;
1333
1334        t.tv_sec = value.as_secs() as c_uint;
1335        t.tv_nsec = value.subsec_nanos() as c_uint;
1336
1337        alsa::snd_seq_remove_events_set_time(self.0, &d);
1338    } }
1339    pub fn set_dest(&self, value: Addr) { unsafe {
1340        let a = alsa::snd_seq_addr_t { client: value.client as c_uchar, port: value.port as c_uchar};
1341
1342        alsa::snd_seq_remove_events_set_dest(self.0, &a);
1343    } }
1344    pub fn set_channel(&self, value: i32) { unsafe { alsa::snd_seq_remove_events_set_channel(self.0, value as c_int) } }
1345    pub fn set_event_type(&self, value: EventType) { unsafe { alsa::snd_seq_remove_events_set_event_type(self.0, value as i32); } }
1346    pub fn set_tag(&self, value: u8) { unsafe { alsa::snd_seq_remove_events_set_tag(self.0, value as c_int) } }
1347}
1348
1349/// [snd_midi_event_t](http://www.alsa-project.org/alsa-doc/alsa-lib/group___m_i_d_i___event.html) Wrapper
1350///
1351/// Sequencer event <-> MIDI byte stream coder
1352#[derive(Debug)]
1353pub struct MidiEvent(*mut alsa::snd_midi_event_t);
1354
1355impl Drop for MidiEvent {
1356    fn drop(&mut self) { unsafe { alsa::snd_midi_event_free(self.0) } }
1357}
1358
1359impl MidiEvent {
1360    pub fn new(bufsize: u32) -> Result<MidiEvent> {
1361        let mut q = ptr::null_mut();
1362        acheck!(snd_midi_event_new(bufsize as size_t, &mut q)).map(|_| MidiEvent(q))
1363    }
1364
1365    pub fn resize_buffer(&self, bufsize: u32) -> Result<()> { acheck!(snd_midi_event_resize_buffer(self.0, bufsize as size_t)).map(|_| ()) }
1366
1367    /// Note: this corresponds to snd_midi_event_no_status, but on and off are switched.
1368    ///
1369    /// Alsa-lib is a bit confusing here. Anyhow, set "enable" to true to enable running status.
1370    pub fn enable_running_status(&self, enable: bool) { unsafe { alsa::snd_midi_event_no_status(self.0, if enable {0} else {1}) } }
1371
1372    /// Resets both encoder and decoder
1373    pub fn init(&self) { unsafe { alsa::snd_midi_event_init(self.0) } }
1374
1375    pub fn reset_encode(&self) { unsafe { alsa::snd_midi_event_reset_encode(self.0) } }
1376
1377    pub fn reset_decode(&self) { unsafe { alsa::snd_midi_event_reset_decode(self.0) } }
1378
1379    pub fn decode(&self, buf: &mut [u8], ev: &mut Event) -> Result<usize> {
1380        ev.ensure_buf();
1381        acheck!(snd_midi_event_decode(self.0, buf.as_mut_ptr() as *mut c_uchar, buf.len() as c_long, &ev.0)).map(|r| r as usize)
1382    }
1383
1384    /// In case of success, returns a tuple of (bytes consumed from buf, found Event).
1385    pub fn encode<'a>(&'a mut self, buf: &[u8]) -> Result<(usize, Option<Event<'a>>)> {
1386        // The ALSA documentation clearly states that the event will be valid as long as the Encoder
1387        // is not messed with (because the data pointer for sysex events may point into the Encoder's
1388        // buffer). We make this safe by taking self by unique reference and coupling it to
1389        // the event's lifetime.
1390        let mut ev = unsafe { mem::zeroed() };
1391        let r = acheck!(snd_midi_event_encode(self.0, buf.as_ptr() as *const c_uchar, buf.len() as c_long, &mut ev))?;
1392        let e = if ev.type_ == alsa::SND_SEQ_EVENT_NONE as u8 {
1393                None
1394            } else {
1395                Some(unsafe { Event::extract(&mut ev, "snd_midi_event_encode") }?)
1396            };
1397        Ok((r as usize, e))
1398    }
1399}
1400
1401#[test]
1402fn print_seqs() {
1403    extern crate std;
1404    use ::alloc::ffi::CString;
1405    use ::alloc::vec::Vec;
1406    let s = super::Seq::open(None, None, false).unwrap();
1407    s.set_client_name(&CString::new("rust_test_print_seqs").unwrap()).unwrap();
1408    let clients: Vec<_> = ClientIter::new(&s).collect();
1409    for a in &clients {
1410        let ports: Vec<_> = PortIter::new(&s, a.get_client()).collect();
1411        std::println!("{:?}: {:?}", a, ports);
1412    }
1413}
1414
1415#[test]
1416fn seq_subscribe() {
1417    use ::alloc::ffi::CString;
1418    let s = super::Seq::open(None, None, false).unwrap();
1419    s.set_client_name(&CString::new("rust_test_seq_subscribe").unwrap()).unwrap();
1420    let timer_info = s.get_any_port_info(Addr { client: 0, port: 0 }).unwrap();
1421    assert_eq!(timer_info.get_name().unwrap(), "Timer");
1422    let info = PortInfo::empty().unwrap();
1423    let _port = s.create_port(&info);
1424    let subs = PortSubscribe::empty().unwrap();
1425    subs.set_sender(Addr { client: 0, port: 0 });
1426    subs.set_dest(Addr { client: s.client_id().unwrap(), port: info.get_port() });
1427    s.subscribe_port(&subs).unwrap();
1428}
1429
1430#[test]
1431fn seq_loopback() {
1432    extern crate std;
1433    use ::alloc::ffi::CString;
1434    let s = super::Seq::open(Some(&CString::new("default").unwrap()), None, false).unwrap();
1435    s.set_client_name(&CString::new("rust_test_seq_loopback").unwrap()).unwrap();
1436
1437    // Create ports
1438    let sinfo = PortInfo::empty().unwrap();
1439    sinfo.set_capability(PortCap::READ | PortCap::SUBS_READ);
1440    sinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);
1441    s.create_port(&sinfo).unwrap();
1442    let sport = sinfo.get_port();
1443    let dinfo = PortInfo::empty().unwrap();
1444    dinfo.set_capability(PortCap::WRITE | PortCap::SUBS_WRITE);
1445    dinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);
1446    s.create_port(&dinfo).unwrap();
1447    let dport = dinfo.get_port();
1448
1449    // Connect them
1450    let subs = PortSubscribe::empty().unwrap();
1451    subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport });
1452    subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport });
1453    s.subscribe_port(&subs).unwrap();
1454    std::println!("Connected {:?} to {:?}", subs.get_sender(), subs.get_dest());
1455
1456    // Send a note!
1457    let note = EvNote { channel: 0, note: 64, duration: 100, velocity: 100, off_velocity: 64 };
1458    let mut e = Event::new(EventType::Noteon, &note);
1459    e.set_subs();
1460    e.set_direct();
1461    e.set_source(sport);
1462    std::println!("Sending {:?}", e);
1463    s.event_output(&mut e).unwrap();
1464    s.drain_output().unwrap();
1465
1466    // Receive the note!
1467    let mut input = s.input();
1468    let e2 = input.event_input().unwrap();
1469    std::println!("Receiving {:?}", e2);
1470    assert_eq!(e2.get_type(), EventType::Noteon);
1471    assert_eq!(e2.get_data(), Some(note));
1472}
1473
1474#[test]
1475fn seq_encode_sysex() {
1476    let mut me = MidiEvent::new(16).unwrap();
1477    let sysex = &[0xf0, 1, 2, 3, 4, 5, 6, 7, 0xf7];
1478    let (s, ev) = me.encode(sysex).unwrap();
1479    assert_eq!(s, 9);
1480    let ev = ev.unwrap();
1481    let v = ev.get_ext().unwrap();
1482    assert_eq!(&*v, sysex);
1483}
1484
1485#[test]
1486fn seq_decode_sysex() {
1487    let sysex = [0xf0, 1, 2, 3, 4, 5, 6, 7, 0xf7];
1488    let mut ev = Event::new_ext(EventType::Sysex, &sysex[..]);
1489    let me = MidiEvent::new(0).unwrap();
1490    let mut buffer = ::alloc::vec![0; sysex.len()];
1491    assert_eq!(me.decode(&mut buffer[..], &mut ev).unwrap(), sysex.len());
1492    assert_eq!(buffer, sysex);
1493}
1494
1495#[test]
1496#[should_panic]
1497fn seq_get_input_twice() {
1498    use ::alloc::ffi::CString;
1499    let s = super::Seq::open(None, None, false).unwrap();
1500    s.set_client_name(&CString::new("rust_test_seq_get_input_twice").unwrap()).unwrap();
1501    let input1 = s.input();
1502    let input2 = s.input(); // this should panic
1503    let _ = (input1, input2);
1504}
1505
1506#[test]
1507fn seq_has_data() {
1508    for v in EventType::all() {
1509        let v = *v;
1510        let mut i = 0;
1511        if <() as EventData>::has_data(v) { i += 1; }
1512        if <[u8; 12] as EventData>::has_data(v) { i += 1; }
1513        if Event::has_ext_data(v) { i += 1; }
1514        if EvNote::has_data(v) { i += 1; }
1515        if EvCtrl::has_data(v) { i += 1; }
1516        if Addr::has_data(v) { i += 1; }
1517        if Connect::has_data(v) { i += 1; }
1518        if EvResult::has_data(v) { i += 1; }
1519        if EvQueueControl::<()>::has_data(v) { i += 1; }
1520        if EvQueueControl::<u32>::has_data(v) { i += 1; }
1521        if EvQueueControl::<i32>::has_data(v) { i += 1; }
1522        if EvQueueControl::<time::Duration>::has_data(v) { i += 1; }
1523        if i != 1 { panic!("{:?}: {} has_data", v, i) }
1524    }
1525}
1526
1527#[test]
1528fn seq_remove_events() -> core::result::Result<(), Box<dyn core::error::Error>> {
1529    let info = RemoveEvents::new()?;
1530
1531
1532    info.set_condition(Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH);
1533    info.set_queue(123);
1534    info.set_time(time::Duration::new(456, 789));
1535    info.set_dest(Addr { client: 212, port: 121 });
1536    info.set_channel(15);
1537    info.set_event_type(EventType::Noteon);
1538    info.set_tag(213);
1539
1540    assert_eq!(info.get_condition(), Remove::INPUT | Remove::DEST | Remove::TIME_BEFORE | Remove::TAG_MATCH);
1541    assert_eq!(info.get_queue(), 123);
1542    assert_eq!(info.get_time(), time::Duration::new(456, 789));
1543    assert_eq!(info.get_dest(), Addr { client: 212, port: 121 });
1544    assert_eq!(info.get_channel(), 15);
1545    assert_eq!(info.get_event_type()?, EventType::Noteon);
1546    assert_eq!(info.get_tag(), 213);
1547
1548    Ok(())
1549}
1550
1551#[test]
1552fn seq_portsubscribeiter() {
1553    use ::alloc::vec::Vec;
1554
1555    let s = super::Seq::open(None, None, false).unwrap();
1556
1557    // Create ports
1558    let sinfo = PortInfo::empty().unwrap();
1559    sinfo.set_capability(PortCap::READ | PortCap::SUBS_READ);
1560    sinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);
1561    s.create_port(&sinfo).unwrap();
1562    let sport = sinfo.get_port();
1563    let dinfo = PortInfo::empty().unwrap();
1564    dinfo.set_capability(PortCap::WRITE | PortCap::SUBS_WRITE);
1565    dinfo.set_type(PortType::MIDI_GENERIC | PortType::APPLICATION);
1566    s.create_port(&dinfo).unwrap();
1567    let dport = dinfo.get_port();
1568
1569    // Connect them
1570    let subs = PortSubscribe::empty().unwrap();
1571    subs.set_sender(Addr { client: s.client_id().unwrap(), port: sport });
1572    subs.set_dest(Addr { client: s.client_id().unwrap(), port: dport });
1573    s.subscribe_port(&subs).unwrap();
1574
1575    // Query READ subs from sport's point of view
1576    let read_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,
1577                        Addr {client: s.client_id().unwrap(), port: sport },
1578                        QuerySubsType::READ).collect();
1579    assert_eq!(read_subs.len(), 1);
1580    assert_eq!(read_subs[0].get_sender(), subs.get_sender());
1581    assert_eq!(read_subs[0].get_dest(), subs.get_dest());
1582
1583    let write_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,
1584                        Addr {client: s.client_id().unwrap(), port: sport },
1585                        QuerySubsType::WRITE).collect();
1586    assert_eq!(write_subs.len(), 0);
1587
1588    // Now query WRITE subs from dport's point of view
1589    let write_subs: Vec<PortSubscribe> = PortSubscribeIter::new(&s,
1590                        Addr {client: s.client_id().unwrap(), port: dport },
1591                        QuerySubsType::WRITE).collect();
1592    assert_eq!(write_subs.len(), 1);
1593    assert_eq!(write_subs[0].get_sender(), subs.get_sender());
1594    assert_eq!(write_subs[0].get_dest(), subs.get_dest());
1595}