led-matrix-rs 0.1.6

LED-Matrix bindings
Documentation
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]

use bindings::RGBLedMatrixOptions;
use std::{env, ffi::CString, ptr};

use crate::bindings::RGBLedRuntimeOptions;

pub mod bindings {
    include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
}

impl Default for bindings::RGBLedMatrixOptions {
    fn default() -> Self {
        Self {
            hardware_mapping: std::ptr::null(),
            rows: 32,
            cols: 0,
            chain_length: 1,
            parallel: 1,
            pwm_bits: 0,
            pwm_lsb_nanoseconds: 50,
            pwm_dither_bits: 0,
            brightness: 0,
            scan_mode: 0,
            row_address_type: 0,
            multiplexing: 0,
            disable_hardware_pulsing: 0,
            show_refresh_rate: 1,
            inverse_colors: 0,
            led_rgb_sequence: std::ptr::null(),
            pixel_mapper_config: std::ptr::null(),
            panel_type: std::ptr::null(),
            limit_refresh_rate_hz: 0,
        }
    }
}

impl bindings::RGBLedMatrixOptions {
    pub fn new() -> Self {
        Self::default()
    }

    pub fn hardware_mapping(mut self, mapping: &str) -> Self {
        self.hardware_mapping = std::ffi::CString::new(mapping).unwrap().into_raw();
        self
    }

    pub fn rows(mut self, rows: u16) -> Self {
        self.rows = rows as i32;
        self
    }
    pub fn cols(mut self, cols: u16) -> Self {
        self.cols = cols as i32;
        self
    }
    pub fn chain_length(mut self, length: u16) -> Self {
        self.chain_length = length as i32;
        self
    }
    pub fn parallel(mut self, parallel: u16) -> Self {
        self.parallel = parallel as i32;
        self
    }
    pub fn pwm_bits(mut self, bits: u16) -> Self {
        self.pwm_bits = bits as i32;
        self
    }
    pub fn pwm_lsb_nanoseconds(mut self, ns: u16) -> Self {
        self.pwm_lsb_nanoseconds = ns as i32;
        self
    }
    pub fn pwm_dither_bits(mut self, bits: u16) -> Self {
        self.pwm_dither_bits = bits as i32;
        self
    }
    pub fn brightness(mut self, brightness: u16) -> Self {
        self.brightness = brightness as i32;
        self
    }
    pub fn scan_mode(mut self, mode: u16) -> Self {
        self.scan_mode = mode as i32;
        self
    }
    pub fn row_address_type(mut self, address_type: u16) -> Self {
        self.row_address_type = address_type as i32;
        self
    }
    pub fn multiplexing(mut self, multiplexing: u16) -> Self {
        self.multiplexing = multiplexing as i32;
        self
    }
    pub fn disable_hardware_pulsing(mut self, disable: bool) -> Self {
        self.disable_hardware_pulsing = disable.into();
        self
    }
    pub fn show_refresh_rate(mut self, show: bool) -> Self {
        self.show_refresh_rate = show.into();
        self
    }
    pub fn inverse_colors(mut self, inverse: bool) -> Self {
        self.inverse_colors = inverse.into();
        self
    }
    pub fn led_rgb_sequence(mut self, sequence: &str) -> Self {
        self.led_rgb_sequence = std::ffi::CString::new(sequence).unwrap().into_raw();
        self
    }
    pub fn pixel_mapper_config(mut self, config: &str) -> Self {
        self.pixel_mapper_config = std::ffi::CString::new(config).unwrap().into_raw();
        self
    }
    pub fn panel_type(mut self, panel_type: &str) -> Self {
        self.panel_type = std::ffi::CString::new(panel_type).unwrap().into_raw();
        self
    }
    pub fn limit_refresh_rate_hz(mut self, hz: u32) -> Self {
        self.limit_refresh_rate_hz = hz as i32;
        self
    }

    pub fn build(mut self) -> Box<bindings::RGBLedMatrix> {
        unsafe {
            Box::from_raw(bindings::led_matrix_create_from_options(
                &mut self as *mut bindings::RGBLedMatrixOptions,
                std::ptr::null_mut(),
                std::ptr::null_mut(),
            ))
        }
    }

    pub fn build_with_rt_options(
        mut self,
        mut rt_options: RGBLedRuntimeOptions,
    ) -> Box<bindings::RGBLedMatrix> {
        unsafe {
            Box::from_raw(bindings::led_matrix_create_from_options_and_rt_options(
                &mut self,
                &mut rt_options,
            ))
        }
    }
}

impl Default for bindings::RGBLedRuntimeOptions {
    fn default() -> Self {
        Self {
            gpio_slowdown: 1,
            daemon: 0,
            drop_privileges: 0,
            do_gpio_init: true,
        }
    }
}

impl bindings::RGBLedRuntimeOptions {
    pub fn new() -> Self {
        Self::default()
    }
    pub fn gpio_slowdown(mut self, slowdown: u32) -> Self {
        self.gpio_slowdown = slowdown as i32;
        self
    }

    pub fn daemon(mut self, run_as_daemon: bool) -> Self {
        self.daemon = run_as_daemon as i32;
        self
    }

    pub fn drop_priviliges(mut self, do_drop_privileges: bool) -> Self {
        self.drop_privileges = do_drop_privileges as i32;
        self
    }

    pub fn do_gpio_init(mut self, do_gpio_init: bool) -> Self {
        self.do_gpio_init = do_gpio_init;
        self
    }
}

impl bindings::RGBLedMatrix {
    pub fn create_offscreen_canvas(&self) -> Box<bindings::LedCanvas> {
        unsafe {
            Box::from_raw(bindings::led_matrix_create_offscreen_canvas(
                self as *const Self as *mut bindings::RGBLedMatrix,
            ))
        }
    }

    pub fn swap_on_vsync(&mut self, canvas: &mut bindings::LedCanvas) -> Box<bindings::LedCanvas> {
        unsafe {
            Box::from_raw(bindings::led_matrix_swap_on_vsync(
                self as *mut Self,
                canvas as *mut bindings::LedCanvas,
            ))
        }
    }
}

impl bindings::LedCanvas {
    pub fn clear(&mut self) {
        unsafe {
            bindings::led_canvas_clear(self);
        }
    }

    pub fn set_pixel(&mut self, x: i32, y: i32, r: u8, g: u8, b: u8) {
        unsafe {
            bindings::led_canvas_set_pixel(self, x, y, r, g, b);
        }
    }

    pub fn get_size(&self) -> (i32, i32) {
        let mut width = 0;
        let mut height = 0;
        unsafe {
            bindings::led_canvas_get_size(
                self,
                &mut width as *mut i32,
                &mut height as *mut i32,
            );
        }
        (width, height)
    }
}

#[test]
fn test() {
    let mut matrix = RGBLedMatrixOptions::new().build();

    let mut canvas = matrix.create_offscreen_canvas();

    canvas.clear();

    loop {
        for i in 0..255 {
            for y in 0..32 {
                for x in 0..32 {
                    canvas.set_pixel(x, y, i & 0xFF, x.try_into().unwrap(), y.try_into().unwrap());
                }
            }
            canvas = matrix.swap_on_vsync(&mut canvas);
        }
    }
}