WIP: next #4

Draft
vinzenz wants to merge 12 commits from next into main
7 changed files with 360 additions and 66 deletions
Showing only changes of commit 373725c648 - Show all commits

View file

@ -32,7 +32,7 @@ features = ["full"]
[export] [export]
include = [] include = []
exclude = [] exclude = ["BitVec"]
[export.rename] [export.rename]
"SpBitVec" = "BitVec" "SpBitVec" = "BitVec"

View file

@ -179,6 +179,22 @@ enum CompressionCode
typedef uint16_t CompressionCode; typedef uint16_t CompressionCode;
#endif // __cplusplus #endif // __cplusplus
/**
* 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 [`DisplayBitVec`] is always uncompressed.
*/
typedef struct BitVecCommand BitVecCommand;
/** /**
* A fixed-size 2D grid of booleans. * A fixed-size 2D grid of booleans.
* *
@ -196,6 +212,38 @@ typedef uint16_t CompressionCode;
*/ */
typedef struct Bitmap Bitmap; typedef struct Bitmap Bitmap;
/**
* Overwrites a rectangular region of pixels.
*
* Origin coordinates must be divisible by 8.
*
* # Examples
*
* ```rust
* # use servicepoint::*;
* # let connection = FakeConnection;
* #
* let mut bitmap = Bitmap::max_sized();
* // draw something to the pixels here
* # bitmap.set(2, 5, true);
*
* // create command to send pixels
* let command = BitmapCommand {
* bitmap,
* origin: Origin::ZERO,
* compression: CompressionCode::Uncompressed
* };
*
* connection.send_command(command).expect("send failed");
* ```
*/
typedef struct BitmapCommand BitmapCommand;
/**
* This is a type only used by cbindgen to have a type for pointers.
*/
typedef struct DisplayBitVec DisplayBitVec;
/** /**
* The raw packet. * The raw packet.
* *
@ -348,6 +396,11 @@ typedef uint8_t Brightness;
*/ */
typedef ValueGrid_char CharGrid; typedef ValueGrid_char CharGrid;
/**
* Type alias for documenting the meaning of the u16 in enum values
*/
typedef size_t Offset;
/** /**
* A grid containing codepage 437 characters. * A grid containing codepage 437 characters.
* *
@ -908,18 +961,65 @@ void sp_char_grid_set(CharGrid */*notnull*/ char_grid,
*/ */
size_t sp_char_grid_width(CharGrid */*notnull*/ char_grid); size_t sp_char_grid_width(CharGrid */*notnull*/ char_grid);
BitmapCommand */*notnull*/ sp_cmd_bitmap_from_bitmap(Bitmap */*notnull*/ bitmap);
/**
* Returns a pointer to the provided `BitmapCommand`.
*
* # Safety
*
* - The returned bitmap inherits the lifetime of the command in which it is contained.
* - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
*/
Bitmap */*notnull*/ sp_cmd_bitmap_get(BitmapCommand */*notnull*/ command);
CompressionCode sp_cmd_bitmap_get_compression(BitmapCommand */*notnull*/ command);
void sp_cmd_bitmap_get_origin(BitmapCommand */*notnull*/ command,
size_t */*notnull*/ origin_x,
size_t */*notnull*/ origin_y);
Packet *sp_cmd_bitmap_into_packet(BitmapCommand */*notnull*/ command);
TypedCommand */*notnull*/ sp_cmd_bitmap_into_typed(BitmapCommand */*notnull*/ command);
/** /**
* Sets a window of pixels to the specified values. * Sets a window of pixels to the specified values.
* *
* The passed [Bitmap] gets consumed. * The passed [Bitmap] gets consumed.
* *
* Returns: a new [servicepoint::BitmapCommand] instance. * Returns: a new [BitmapCommand] instance.
*/ */
TypedCommand *sp_command_bitmap(size_t x, BitmapCommand */*notnull*/ sp_cmd_bitmap_new(Bitmap */*notnull*/ bitmap,
size_t y, size_t origin_x,
Bitmap */*notnull*/ bitmap, size_t origin_y,
CompressionCode compression); CompressionCode compression);
/**
* Moves the provided bitmap to be contained in the command.
*/
void sp_cmd_bitmap_set(BitmapCommand */*notnull*/ command,
Bitmap */*notnull*/ bitmap);
void sp_cmd_bitmap_set_compression(BitmapCommand */*notnull*/ command,
CompressionCode compression);
void sp_cmd_bitmap_set_origin(BitmapCommand */*notnull*/ command,
size_t origin_x,
size_t origin_y);
DisplayBitVec *sp_cmd_bitvec_get(BitVecCommand */*notnull*/ command);
CompressionCode sp_cmd_bitvec_get_compression(BitVecCommand */*notnull*/ command);
Offset sp_cmd_bitvec_get_offset(BitVecCommand */*notnull*/ command);
BinaryOperation sp_cmd_bitvec_get_operation(BitVecCommand */*notnull*/ command);
Packet *sp_cmd_bitvec_into_packet(BitVecCommand */*notnull*/ command);
TypedCommand */*notnull*/ sp_cmd_bitvec_into_typed(BitVecCommand */*notnull*/ command);
/** /**
* Set pixel data starting at the pixel offset on screen. * Set pixel data starting at the pixel offset on screen.
* *
@ -932,11 +1032,26 @@ TypedCommand *sp_command_bitmap(size_t x,
* *
* For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels. * For example, [`BinaryOperation::Or`] can be used to turn on some pixels without affecting other pixels.
* *
* The contained [`BitVecU8Msb0`] is always uncompressed. * The contained [`DisplayBitVec`] is always uncompressed.
*/ */
TypedCommand *sp_command_bitvec(size_t offset, BitVecCommand */*notnull*/ sp_cmd_bitvec_new(DisplayBitVec */*notnull*/ bitvec,
SPBitVec */*notnull*/ bit_vec, size_t offset,
CompressionCode compression, BinaryOperation operation,
CompressionCode compression);
/**
* Moves the provided bitmap to be contained in the command.
*/
void sp_cmd_bitvec_set(BitVecCommand */*notnull*/ command,
DisplayBitVec */*notnull*/ bitvec);
void sp_cmd_bitvec_set_compression(BitVecCommand */*notnull*/ command,
CompressionCode compression);
void sp_cmd_bitvec_set_offset(BitVecCommand */*notnull*/ command,
Offset offset);
void sp_cmd_bitvec_set_operation(BitVecCommand */*notnull*/ command,
BinaryOperation operation); BinaryOperation operation);
/** /**

View file

@ -0,0 +1,110 @@
use crate::{heap_move_nonnull, heap_move_ok, heap_remove};
use servicepoint::{
Bitmap, BitmapCommand, CompressionCode, Origin, Packet, TypedCommand,
};
use std::ptr::NonNull;
/// Sets a window of pixels to the specified values.
///
/// The passed [Bitmap] gets consumed.
///
/// Returns: a new [BitmapCommand] instance.
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_new(
bitmap: NonNull<Bitmap>,
origin_x: usize,
origin_y: usize,
compression: CompressionCode,
) -> NonNull<BitmapCommand> {
heap_move_nonnull(BitmapCommand {
bitmap: unsafe { heap_remove(bitmap) },
origin: Origin::new(origin_x, origin_y),
compression,
})
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_from_bitmap(
bitmap: NonNull<Bitmap>,
) -> NonNull<BitmapCommand> {
heap_move_nonnull(unsafe { heap_remove(bitmap) }.into())
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_into_typed(
command: NonNull<BitmapCommand>,
) -> NonNull<TypedCommand> {
heap_move_nonnull(unsafe { heap_remove(command) }.into())
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_into_packet(
command: NonNull<BitmapCommand>,
) -> *mut Packet {
heap_move_ok(unsafe { heap_remove(command) }.try_into())
}
/// Returns a pointer to the provided `BitmapCommand`.
///
/// # Safety
///
/// - The returned bitmap inherits the lifetime of the command in which it is contained.
/// - The returned pointer may not be used in a function that consumes the instance, e.g. to create a command.
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_get(
mut command: NonNull<BitmapCommand>,
) -> NonNull<Bitmap> {
unsafe { NonNull::from(&mut (command.as_mut().bitmap)) }
}
/// Moves the provided bitmap to be contained in the command.
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_set(
mut command: NonNull<BitmapCommand>,
bitmap: NonNull<Bitmap>,
) {
unsafe {
command.as_mut().bitmap = heap_remove(bitmap);
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_get_origin(
command: NonNull<BitmapCommand>,
origin_x: NonNull<usize>,
origin_y: NonNull<usize>,
) {
unsafe {
let origin = &command.as_ref().origin;
*origin_x.as_ptr() = origin.x;
*origin_y.as_ptr() = origin.y;
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_set_origin(
mut command: NonNull<BitmapCommand>,
origin_x: usize,
origin_y: usize,
) {
unsafe {
command.as_mut().origin = Origin::new(origin_x, origin_y);
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_set_compression(
mut command: NonNull<BitmapCommand>,
compression: CompressionCode,
) {
unsafe {
command.as_mut().compression = compression;
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitmap_get_compression(
command: NonNull<BitmapCommand>,
) -> CompressionCode {
unsafe { command.as_ref().compression }
}

View file

@ -0,0 +1,115 @@
use crate::{heap_move_nonnull, heap_move_ok, heap_remove};
use servicepoint::{
BinaryOperation, BitVecCommand, CompressionCode, DisplayBitVec, Offset,
Packet, TypedCommand,
};
use std::ptr::NonNull;
/// 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 [`DisplayBitVec`] is always uncompressed.
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_new(
bitvec: NonNull<DisplayBitVec>,
offset: usize,
operation: BinaryOperation,
compression: CompressionCode,
) -> NonNull<BitVecCommand> {
heap_move_nonnull(BitVecCommand {
bitvec: unsafe { heap_remove(bitvec) },
offset,
operation,
compression,
})
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_into_typed(
command: NonNull<BitVecCommand>,
) -> NonNull<TypedCommand> {
heap_move_nonnull(unsafe { heap_remove(command) }.into())
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_into_packet(
command: NonNull<BitVecCommand>,
) -> *mut Packet {
heap_move_ok(unsafe { heap_remove(command) }.try_into())
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_get(
mut command: NonNull<BitVecCommand>,
) -> *mut DisplayBitVec {
&mut unsafe { command.as_mut() }.bitvec
}
/// Moves the provided bitmap to be contained in the command.
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_set(
mut command: NonNull<BitVecCommand>,
bitvec: NonNull<DisplayBitVec>,
) {
unsafe {
command.as_mut().bitvec = heap_remove(bitvec);
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_get_offset(
command: NonNull<BitVecCommand>,
) -> Offset {
unsafe { command.as_ref().offset }
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_set_offset(
mut command: NonNull<BitVecCommand>,
offset: Offset,
) {
unsafe {
command.as_mut().offset = offset;
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_get_operation(
command: NonNull<BitVecCommand>,
) -> BinaryOperation {
unsafe { command.as_ref().operation.clone() } // TODO remove clone
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_set_operation(
mut command: NonNull<BitVecCommand>,
operation: BinaryOperation,
) {
unsafe {
command.as_mut().operation = operation;
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_set_compression(
mut command: NonNull<BitVecCommand>,
compression: CompressionCode,
) {
unsafe {
command.as_mut().compression = compression;
}
}
#[no_mangle]
pub unsafe extern "C" fn sp_cmd_bitvec_get_compression(
command: NonNull<BitVecCommand>,
) -> CompressionCode {
unsafe { command.as_ref().compression }
}

2
src/commands/mod.rs Normal file
View file

@ -0,0 +1,2 @@
mod bitmap_command;
mod bitvec_command;

View file

@ -42,6 +42,7 @@ mod bitvec;
mod brightness_grid; mod brightness_grid;
mod byte_slice; mod byte_slice;
mod char_grid; mod char_grid;
mod commands;
mod cp437_grid; mod cp437_grid;
mod packet; mod packet;
mod typed_command; mod typed_command;
@ -78,3 +79,6 @@ pub(crate) unsafe fn heap_remove<T>(x: NonNull<T>) -> T {
/// This is a type only used by cbindgen to have a type for pointers. /// This is a type only used by cbindgen to have a type for pointers.
pub struct UdpSocket; pub struct UdpSocket;
/// This is a type only used by cbindgen to have a type for pointers.
pub struct DisplayBitVec;

View file

@ -1,7 +1,7 @@
use crate::{heap_drop, heap_move, heap_move_nonnull, heap_move_ok, SPBitVec}; use crate::{heap_drop, heap_move_nonnull, heap_move_ok};
use servicepoint::{ use servicepoint::{
BinaryOperation, Bitmap, Brightness, BrightnessGrid, CharGrid, Brightness, BrightnessGrid, CharGrid, Cp437Grid, GlobalBrightnessCommand,
CompressionCode, Cp437Grid, GlobalBrightnessCommand, Packet, TypedCommand, Packet, TypedCommand,
}; };
use std::ptr::NonNull; use std::ptr::NonNull;
@ -92,36 +92,6 @@ pub unsafe extern "C" fn sp_command_brightness_grid(
heap_move_nonnull(result) 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. /// Show codepage 437 encoded text on the screen.
/// ///
/// The passed [Cp437Grid] gets consumed. /// The passed [Cp437Grid] gets consumed.
@ -162,28 +132,6 @@ pub unsafe extern "C" fn sp_command_char_grid(
heap_move_nonnull(result) 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]. /// Deallocates a [TypedCommand].
/// ///
/// # Examples /// # Examples