alsarawmidi 0.8.0

API binding for alsarawmidi library
Documentation
// This file was generated by gir (https://github.com/gtk-rs/gir)
// from
// from gir-files (https://github.com/gtk-rs/gir-files)
// DO NOT EDIT

use crate::{ffi, StreamDirection, StreamPairInfoFlag, SubstreamInfo, SubstreamParams};
use glib::{
    prelude::*,
    signal::{connect_raw, SignalHandlerId},
    translate::*,
};
use std::boxed::Box as Box_;

glib::wrapper! {
    /// GObject-derived object to express a pair of Rawmidi stream.
    ///
    /// A [`StreamPair`][crate::StreamPair] is a GObject-derived object to express a pair of Rawmidi stream to which
    /// substreams are attached. The substream is pointed by the combination of the numeric identifier
    /// of device, subdevice, and direction. When the call of [`StreamPairExt::open()`][crate::prelude::StreamPairExt::open()] with the
    /// combination, corresponding substreams are attached to the object. Then the object maintains file
    /// descriptor till object destruction. The call of [`StreamPairExt::create_source()`][crate::prelude::StreamPairExt::create_source()] returns the
    /// instance of [`glib::Source`][crate::glib::Source]. Once attached to the [`glib::Source`][crate::glib::Source],
    /// `GLib::MainContext` / `GLib::MainLoop` is available as event dispatcher. The
    /// [`handle-messages`][struct@crate::StreamPair#handle-messages] signal is emitted in the event dispatcher to notify the
    /// intermediate buffer of capture substream has available messages. The call of
    /// [`StreamPairExtManual::read_from_substream()`][crate::prelude::StreamPairExtManual::read_from_substream()] fills the given buffer with the available messages. The
    /// call of [`StreamPairExt::write_to_substream()`][crate::prelude::StreamPairExt::write_to_substream()] write messages in the given buffer into the
    /// intermediate buffer of playback substream. The call of [`StreamPairExtManual::substream_status()`][crate::prelude::StreamPairExtManual::substream_status()]
    /// is available to check the space in the intermediate buffer according to direction argument.
    ///
    /// ## Properties
    ///
    ///
    /// #### `devnode`
    ///  The full path to special file of rawmidi character device.
    ///
    /// Readable
    ///
    /// ## Signals
    ///
    ///
    /// #### `handle-disconnection`
    ///  When the sound card is not available anymore due to unbinding driver or hot unplugging,
    /// this signal is emit. The owner of this object should call `GObject::Object::unref()` as
    /// quickly as possible to release ALSA rawmidi character device.
    ///
    ///
    ///
    ///
    /// #### `handle-messages`
    ///  When any input message is available, this event is emit.
    ///
    ///
    ///
    /// # Implements
    ///
    /// [`StreamPairExt`][trait@crate::prelude::StreamPairExt], [`StreamPairExtManual`][trait@crate::prelude::StreamPairExtManual]
    #[doc(alias = "ALSARawmidiStreamPair")]
    pub struct StreamPair(Object<ffi::ALSARawmidiStreamPair, ffi::ALSARawmidiStreamPairClass>);

    match fn {
        type_ => || ffi::alsarawmidi_stream_pair_get_type(),
    }
}

impl StreamPair {
    pub const NONE: Option<&'static StreamPair> = None;

    /// Allocate and return an instance of [`StreamPair`][crate::StreamPair].
    ///
    /// # Returns
    ///
    /// An instance of [`StreamPair`][crate::StreamPair].
    #[doc(alias = "alsarawmidi_stream_pair_new")]
    pub fn new() -> StreamPair {
        unsafe { from_glib_full(ffi::alsarawmidi_stream_pair_new()) }
    }
}

impl Default for StreamPair {
    fn default() -> Self {
        Self::new()
    }
}

/// Trait containing the part of [`struct@StreamPair`] methods.
///
/// # Implementors
///
/// [`StreamPair`][struct@crate::StreamPair]
pub trait StreamPairExt: IsA<StreamPair> + 'static {
    /// Allocate [`glib::Source`][crate::glib::Source] structure to handle events from ALSA rawmidi character device for
    /// input substream. In each iteration of `GLib::MainContext`, the `read(2)` system call is
    /// executed to dispatch control event for [`handle-messages`][struct@crate::StreamPair#handle-messages] signal, according to
    /// the result of `poll(2)` system call.
    ///
    /// # Returns
    ///
    /// [`true`] when the overall operation finishes successfully, else [`false`].
    ///
    /// ## `gsrc`
    /// A [`glib::Source`][crate::glib::Source] to handle events from ALSA rawmidi character device.
    #[doc(alias = "alsarawmidi_stream_pair_create_source")]
    fn create_source(&self) -> Result<glib::Source, glib::Error> {
        unsafe {
            let mut gsrc = std::ptr::null_mut();
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::alsarawmidi_stream_pair_create_source(
                self.as_ref().to_glib_none().0,
                &mut gsrc,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(from_glib_full(gsrc))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "alsarawmidi_stream_pair_drain_substream")]
    fn drain_substream(&self, direction: StreamDirection) -> Result<(), glib::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::alsarawmidi_stream_pair_drain_substream(
                self.as_ref().to_glib_none().0,
                direction.into_glib(),
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    #[doc(alias = "alsarawmidi_stream_pair_drop_substream")]
    fn drop_substream(&self, direction: StreamDirection) -> Result<(), glib::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::alsarawmidi_stream_pair_drop_substream(
                self.as_ref().to_glib_none().0,
                direction.into_glib(),
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Get information of substream attached to the stream pair.
    ///
    /// The call of function executes `ioctl(2)` system call with `SNDRV_RAWMIDI_IOCTL_INFO` command
    /// for ALSA rawmidi character device.
    /// ## `direction`
    /// The direction of substream attached to the stream pair.
    ///
    /// # Returns
    ///
    /// [`true`] when the overall operation finishes successfully, else [`false`].
    ///
    /// ## `substream_info`
    /// The information for requested substream.
    #[doc(alias = "alsarawmidi_stream_pair_get_substream_info")]
    #[doc(alias = "get_substream_info")]
    fn substream_info(&self, direction: StreamDirection) -> Result<SubstreamInfo, glib::Error> {
        unsafe {
            let mut substream_info = std::ptr::null_mut();
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::alsarawmidi_stream_pair_get_substream_info(
                self.as_ref().to_glib_none().0,
                direction.into_glib(),
                &mut substream_info,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(from_glib_full(substream_info))
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Open file descriptor for a pair of streams to attach input/output substreams corresponding to
    /// the given subdevice.
    ///
    /// The call of function executes `open(2)` system call for ALSA rawmidi character device.
    /// ## `card_id`
    /// The numeric identifier of sound card.
    /// ## `device_id`
    /// The numeric identifier of rawmidi device for the sound card.
    /// ## `subdevice_id`
    /// The numeric identifier of subdevice for the rawmidi device.
    /// ## `access_modes`
    /// Access flags for stream direction.
    /// ## `open_flag`
    /// The flag of `open(2)` system call. `O_RDWR`, `O_WRONLY` and `O_RDONLY` are forced
    ///             to fulfil internally according to the access_modes.
    ///
    /// # Returns
    ///
    /// [`true`] when the overall operation finishes successfully, else [`false`].
    #[doc(alias = "alsarawmidi_stream_pair_open")]
    fn open(
        &self,
        card_id: u32,
        device_id: u32,
        subdevice_id: u32,
        access_modes: StreamPairInfoFlag,
        open_flag: i32,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::alsarawmidi_stream_pair_open(
                self.as_ref().to_glib_none().0,
                card_id,
                device_id,
                subdevice_id,
                access_modes.into_glib(),
                open_flag,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Set parameters of substream for given direction, which is attached to the pair of streams.
    ///
    /// The call of function executes `ioctl(2)` system call with `SNDRV_RAWMIDI_IOCTL_PARAMS` command
    /// for ALSA rawmidi character device.
    /// ## `direction`
    /// The direction of substream attached to the stream pair.
    /// ## `substream_params`
    /// The parameters of substream.
    ///
    /// # Returns
    ///
    /// [`true`] when the overall operation finishes successfully, else [`false`].
    #[doc(alias = "alsarawmidi_stream_pair_set_substream_params")]
    fn set_substream_params(
        &self,
        direction: StreamDirection,
        substream_params: &impl IsA<SubstreamParams>,
    ) -> Result<(), glib::Error> {
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::alsarawmidi_stream_pair_set_substream_params(
                self.as_ref().to_glib_none().0,
                direction.into_glib(),
                substream_params.as_ref().to_glib_none().0,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// Copy data from given buffer to intermediate buffer for substream attached to the pair of
    /// streams. In a case that the instance is opened without `O_NONBLOCK` flag and the intermediate
    /// buffer is full, call of the API is blocked till the buffer has space for the data.
    ///
    /// The call of function executes `write(2) system for ALSA rawmidi character device.
    /// ## `buf`
    /// The buffer to copy data.
    ///
    /// # Returns
    ///
    /// [`true`] when the overall operation finishes successfully, else [`false`].
    #[doc(alias = "alsarawmidi_stream_pair_write_to_substream")]
    fn write_to_substream(&self, buf: &[u8]) -> Result<(), glib::Error> {
        let buf_size = buf.len() as _;
        unsafe {
            let mut error = std::ptr::null_mut();
            let is_ok = ffi::alsarawmidi_stream_pair_write_to_substream(
                self.as_ref().to_glib_none().0,
                buf.to_glib_none().0,
                buf_size,
                &mut error,
            );
            debug_assert_eq!(is_ok == glib::ffi::GFALSE, !error.is_null());
            if error.is_null() {
                Ok(())
            } else {
                Err(from_glib_full(error))
            }
        }
    }

    /// The full path to special file of rawmidi character device.
    fn devnode(&self) -> Option<glib::GString> {
        ObjectExt::property(self.as_ref(), "devnode")
    }

    /// When the sound card is not available anymore due to unbinding driver or hot unplugging,
    /// this signal is emit. The owner of this object should call `GObject::Object::unref()` as
    /// quickly as possible to release ALSA rawmidi character device.
    #[doc(alias = "handle-disconnection")]
    fn connect_handle_disconnection<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn handle_disconnection_trampoline<
            P: IsA<StreamPair>,
            F: Fn(&P) + 'static,
        >(
            this: *mut ffi::ALSARawmidiStreamPair,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(StreamPair::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"handle-disconnection".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    handle_disconnection_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    /// When any input message is available, this event is emit.
    #[doc(alias = "handle-messages")]
    fn connect_handle_messages<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn handle_messages_trampoline<P: IsA<StreamPair>, F: Fn(&P) + 'static>(
            this: *mut ffi::ALSARawmidiStreamPair,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(StreamPair::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"handle-messages".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    handle_messages_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }

    #[doc(alias = "devnode")]
    fn connect_devnode_notify<F: Fn(&Self) + 'static>(&self, f: F) -> SignalHandlerId {
        unsafe extern "C" fn notify_devnode_trampoline<P: IsA<StreamPair>, F: Fn(&P) + 'static>(
            this: *mut ffi::ALSARawmidiStreamPair,
            _param_spec: glib::ffi::gpointer,
            f: glib::ffi::gpointer,
        ) {
            let f: &F = &*(f as *const F);
            f(StreamPair::from_glib_borrow(this).unsafe_cast_ref())
        }
        unsafe {
            let f: Box_<F> = Box_::new(f);
            connect_raw(
                self.as_ptr() as *mut _,
                c"notify::devnode".as_ptr() as *const _,
                Some(std::mem::transmute::<*const (), unsafe extern "C" fn()>(
                    notify_devnode_trampoline::<Self, F> as *const (),
                )),
                Box_::into_raw(f),
            )
        }
    }
}

impl<O: IsA<StreamPair>> StreamPairExt for O {}