201 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			201 lines
		
	
	
	
		
			5.7 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use crate::{heap_drop, heap_move, heap_move_nonnull, SPBitVec};
 | |
| use servicepoint::{
 | |
|     BinaryOperation, Bitmap, Brightness, BrightnessGrid, CharGrid,
 | |
|     CompressionCode, Cp437Grid, GlobalBrightnessCommand, Packet, TypedCommand,
 | |
| };
 | |
| use std::ptr::NonNull;
 | |
| 
 | |
| /// Tries to turn a [Packet] into a [TypedCommand].
 | |
| ///
 | |
| /// The packet is deallocated in the process.
 | |
| ///
 | |
| /// Returns: pointer to new [TypedCommand] instance or NULL if parsing failed.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_try_from_packet(
 | |
|     packet: NonNull<Packet>,
 | |
| ) -> *mut TypedCommand {
 | |
|     let packet = *unsafe { Box::from_raw(packet.as_ptr()) };
 | |
|     match servicepoint::TypedCommand::try_from(packet) {
 | |
|         Err(_) => std::ptr::null_mut(),
 | |
|         Ok(command) => heap_move(command),
 | |
|     }
 | |
| }
 | |
| 
 | |
| /// Clones a [TypedCommand] instance.
 | |
| ///
 | |
| /// returns: new [TypedCommand] instance.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_clone(
 | |
|     command: NonNull<TypedCommand>,
 | |
| ) -> NonNull<TypedCommand> {
 | |
|     heap_move_nonnull(unsafe { command.as_ref().clone() })
 | |
| }
 | |
| 
 | |
| /// Set all pixels to the off state.
 | |
| ///
 | |
| /// Does not affect brightness.
 | |
| ///
 | |
| /// Returns: a new [servicepoint::Command::Clear] instance.
 | |
| ///
 | |
| /// # Examples
 | |
| ///
 | |
| /// ```C
 | |
| /// sp_udp_send_command(connection, sp_command_clear());
 | |
| /// ```
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_clear() -> NonNull<TypedCommand> {
 | |
|     heap_move_nonnull(servicepoint::ClearCommand.into())
 | |
| }
 | |
| 
 | |
| /// Kills the udp daemon on the display, which usually results in a restart.
 | |
| ///
 | |
| /// Please do not send this in your normal program flow.
 | |
| ///
 | |
| /// Returns: a new [servicepoint::Command::HardReset] instance.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_hard_reset() -> NonNull<TypedCommand> {
 | |
|     heap_move_nonnull(servicepoint::HardResetCommand.into())
 | |
| }
 | |
| 
 | |
| /// A yet-to-be-tested command.
 | |
| ///
 | |
| /// Returns: a new [servicepoint::Command::FadeOut] instance.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_fade_out() -> NonNull<TypedCommand> {
 | |
|     heap_move_nonnull(servicepoint::FadeOutCommand.into())
 | |
| }
 | |
| 
 | |
| /// Set the brightness of all tiles to the same value.
 | |
| ///
 | |
| /// Returns: a new [servicepoint::Command::Brightness] instance.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_global_brightness(
 | |
|     brightness: Brightness,
 | |
| ) -> NonNull<TypedCommand> {
 | |
|     heap_move_nonnull(GlobalBrightnessCommand::from(brightness).into())
 | |
| }
 | |
| 
 | |
| /// Set the brightness of individual tiles in a rectangular area of the display.
 | |
| ///
 | |
| /// The passed [BrightnessGrid] gets consumed.
 | |
| ///
 | |
| /// Returns: a new [servicepoint::Command::CharBrightness] instance.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_brightness_grid(
 | |
|     x: usize,
 | |
|     y: usize,
 | |
|     grid: NonNull<BrightnessGrid>,
 | |
| ) -> NonNull<TypedCommand> {
 | |
|     let grid = unsafe { *Box::from_raw(grid.as_ptr()) };
 | |
|     let result = servicepoint::BrightnessGridCommand {
 | |
|         origin: servicepoint::Origin::new(x, y),
 | |
|         grid,
 | |
|     }
 | |
|     .into();
 | |
|     heap_move_nonnull(result)
 | |
| }
 | |
| 
 | |
| /// Set pixel data starting at the pixel offset on screen.
 | |
| ///
 | |
| /// The screen will continuously overwrite more pixel data without regarding the offset, meaning
 | |
| /// once the starting row is full, overwriting will continue on column 0.
 | |
| ///
 | |
| /// The [`BinaryOperation`] will be applied on the display comparing old and sent bit.
 | |
| ///
 | |
| /// `new_bit = old_bit op sent_bit`
 | |
| ///
 | |
| /// For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels.
 | |
| ///
 | |
| /// The contained [`BitVecU8Msb0`] is always uncompressed.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_bitvec(
 | |
|     offset: usize,
 | |
|     bit_vec: NonNull<SPBitVec>,
 | |
|     compression: CompressionCode,
 | |
|     operation: BinaryOperation,
 | |
| ) -> *mut TypedCommand {
 | |
|     let bit_vec = unsafe { *Box::from_raw(bit_vec.as_ptr()) };
 | |
|     let command = servicepoint::BitVecCommand {
 | |
|         offset,
 | |
|         operation,
 | |
|         bitvec: bit_vec.0,
 | |
|         compression,
 | |
|     }
 | |
|     .into();
 | |
|     heap_move(command)
 | |
| }
 | |
| 
 | |
| /// Show codepage 437 encoded text on the screen.
 | |
| ///
 | |
| /// The passed [Cp437Grid] gets consumed.
 | |
| ///
 | |
| /// Returns: a new [servicepoint::Cp437GridCommand] instance.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_cp437_grid(
 | |
|     x: usize,
 | |
|     y: usize,
 | |
|     grid: NonNull<Cp437Grid>,
 | |
| ) -> NonNull<TypedCommand> {
 | |
|     let grid = *unsafe { Box::from_raw(grid.as_ptr()) };
 | |
|     let result = servicepoint::Cp437GridCommand {
 | |
|         origin: servicepoint::Origin::new(x, y),
 | |
|         grid,
 | |
|     }
 | |
|     .into();
 | |
|     heap_move_nonnull(result)
 | |
| }
 | |
| 
 | |
| /// Show UTF-8 encoded text on the screen.
 | |
| ///
 | |
| /// The passed [CharGrid] gets consumed.
 | |
| ///
 | |
| /// Returns: a new [servicepoint::CharGridCommand] instance.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_char_grid(
 | |
|     x: usize,
 | |
|     y: usize,
 | |
|     grid: NonNull<CharGrid>,
 | |
| ) -> NonNull<TypedCommand> {
 | |
|     let grid = unsafe { *Box::from_raw(grid.as_ptr()) };
 | |
|     let result = servicepoint::CharGridCommand {
 | |
|         origin: servicepoint::Origin::new(x, y),
 | |
|         grid,
 | |
|     }
 | |
|     .into();
 | |
|     heap_move_nonnull(result)
 | |
| }
 | |
| 
 | |
| /// Sets a window of pixels to the specified values.
 | |
| ///
 | |
| /// The passed [Bitmap] gets consumed.
 | |
| ///
 | |
| /// Returns: a new [servicepoint::BitmapCommand] instance.
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_bitmap(
 | |
|     x: usize,
 | |
|     y: usize,
 | |
|     bitmap: NonNull<Bitmap>,
 | |
|     compression: CompressionCode,
 | |
| ) -> *mut TypedCommand {
 | |
|     let bitmap = unsafe { *Box::from_raw(bitmap.as_ptr()) };
 | |
|     let command = servicepoint::BitmapCommand {
 | |
|         origin: servicepoint::Origin::new(x, y),
 | |
|         bitmap,
 | |
|         compression,
 | |
|     }
 | |
|     .into();
 | |
|     heap_move(command)
 | |
| }
 | |
| 
 | |
| /// Deallocates a [TypedCommand].
 | |
| ///
 | |
| /// # Examples
 | |
| ///
 | |
| /// ```C
 | |
| /// TypedCommand c = sp_command_clear();
 | |
| /// sp_command_free(c);
 | |
| /// ```
 | |
| #[no_mangle]
 | |
| pub unsafe extern "C" fn sp_command_free(command: NonNull<TypedCommand>) {
 | |
|     unsafe { heap_drop(command) }
 | |
| }
 | 
