diff --git a/examples/lang_c/.gitignore b/examples/lang_c/.gitignore new file mode 100644 index 0000000..b4242bd --- /dev/null +++ b/examples/lang_c/.gitignore @@ -0,0 +1,4 @@ +.idea +out +rust-target +include diff --git a/examples/lang_c/CMakeLists.txt b/examples/lang_c/CMakeLists.txt deleted file mode 100644 index 0ae7052..0000000 --- a/examples/lang_c/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -cmake_minimum_required(VERSION 3.28) -project(lang_c C) -set(CMAKE_C_STANDARD 17) - -include(FetchContent) -FetchContent_Declare( - Corrosion - GIT_REPOSITORY https://github.com/corrosion-rs/corrosion.git - GIT_TAG v0.5 # Optionally specify a commit hash, version tag or branch here -) -FetchContent_MakeAvailable(Corrosion) - -# Import targets defined in a package or workspace manifest `Cargo.toml` file -corrosion_import_crate( - MANIFEST_PATH ../../servicepoint2/Cargo.toml - PROFILE release - FEATURES c-api - ALL_FEATURES) - -add_executable(lang_c main.c) - -target_link_libraries(lang_c PRIVATE servicepoint2) - diff --git a/examples/lang_c/Makefile b/examples/lang_c/Makefile new file mode 100644 index 0000000..12fb78e --- /dev/null +++ b/examples/lang_c/Makefile @@ -0,0 +1,23 @@ +ROOT_DIR := $(dir $(realpath $(lastword $(MAKEFILE_LIST)))) +RUST_TARGET_DIR := ${ROOT_DIR}rust-target +export SP2_INCLUDE_DIR := ${ROOT_DIR}sp2 +OUT_DIR := ${ROOT_DIR}out + +.PHONY: clean + +run: ${OUT_DIR}/lang_c + out/lang_c + +all: ${OUT_DIR}/lang_c + +${OUT_DIR}/lang_c: ${SP2_INCLUDE_DIR}/sp2-bindings.h main.c + mkdir -p ${OUT_DIR} + gcc ${SP2_INCLUDE_DIR}/sp2-bindings.h main.c -L ${RUST_TARGET_DIR}/release/ -Wl,-Bstatic -l servicepoint2 -Wl,-Bdynamic -o ${OUT_DIR}/lang_c --verbose + +${SP2_INCLUDE_DIR}/sp2-bindings.h: + cd ../../servicepoint2/ && cargo build --release --target-dir ${RUST_TARGET_DIR} --all-features + +clean: + rm -r ${SP2_INCLUDE_DIR} || true + rm -r ${OUT_DIR} || true + rm -r ${RUST_TARGET_DIR} || true \ No newline at end of file diff --git a/examples/lang_c/main.c b/examples/lang_c/main.c index 04476e3..1fc4341 100644 --- a/examples/lang_c/main.c +++ b/examples/lang_c/main.c @@ -1,5 +1,5 @@ #include -#include "../../servicepoint2/sp2-bindings.h" +#include "sp2/sp2-bindings.h" int main(void) { sp2_Connection *connection = sp2_connection_open("localhost:2342"); diff --git a/servicepoint2/build.rs b/servicepoint2/build.rs index 033e717..9b87547 100644 --- a/servicepoint2/build.rs +++ b/servicepoint2/build.rs @@ -1,12 +1,21 @@ extern crate cbindgen; use std::env; + use cbindgen::Language; fn main() { let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - println!("cargo:rerun-if-changed=src"); + let out_dir = env::var("SP2_INCLUDE_DIR") + .or(env::var("OUT_DIR")) + .unwrap(); + + println!("cargo::warning={out_dir}"); + + println!("cargo::rerun-if-changed=src"); + println!("cargo::rerun-if-env-changed=SP2_INCLUDE_DIR"); + println!("cargo::rerun-if-env-changed=OUT_DIR"); cbindgen::Builder::new() .with_crate(crate_dir) @@ -16,5 +25,5 @@ fn main() { .with_parse_expand_all_features(true) .generate() .expect("Unable to generate bindings") - .write_to_file("sp2-bindings.h"); + .write_to_file(format!("{out_dir}/sp2-bindings.h")); } \ No newline at end of file diff --git a/servicepoint2/sp2-bindings.h b/servicepoint2/sp2-bindings.h deleted file mode 100644 index 946adaa..0000000 --- a/servicepoint2/sp2-bindings.h +++ /dev/null @@ -1,353 +0,0 @@ -#include -#include -#include -#include - -/** - * size of a single tile in one dimension - */ -#define sp2_TILE_SIZE 8 - -/** - * tile count in the x-direction - */ -#define sp2_TILE_WIDTH 56 - -/** - * tile count in the y-direction - */ -#define sp2_TILE_HEIGHT 20 - -/** - * screen width in pixels - */ -#define sp2_PIXEL_WIDTH (sp2_TILE_WIDTH * sp2_TILE_SIZE) - -/** - * screen height in pixels - */ -#define sp2_PIXEL_HEIGHT (sp2_TILE_HEIGHT * sp2_TILE_SIZE) - -/** - * pixel count on whole screen - */ -#define sp2_PIXEL_COUNT ((uintptr_t)sp2_PIXEL_WIDTH * (uintptr_t)sp2_PIXEL_HEIGHT) - -/** - * Specifies the kind of compression to use. Availability depends on features. - */ -enum sp2_CompressionCode -#ifdef __cplusplus - : uint16_t -#endif // __cplusplus - { - Uncompressed = 0, - Gz = 26490, - Bz = 25210, - Lz = 27770, - Zs = 31347, -}; -#ifndef __cplusplus -typedef uint16_t sp2_CompressionCode; -#endif // __cplusplus - -/** - * A vector of bits - */ -typedef struct sp2_BitVec sp2_BitVec; - -/** - * A grid of bytes - */ -typedef struct sp2_ByteGrid sp2_ByteGrid; - -/** - * A command to send to the display. - */ -typedef struct sp2_Command sp2_Command; - -/** - * A connection to the display. - */ -typedef struct sp2_Connection sp2_Connection; - -/** - * A grid of pixels stored in packed bytes. - */ -typedef struct sp2_PixelGrid sp2_PixelGrid; - -typedef uint8_t sp2_Brightness; - -typedef uint16_t sp2_Offset; - -#ifdef __cplusplus -extern "C" { -#endif // __cplusplus - -/** - * Creates a new `BitVec` instance. - * The returned instance has to be freed with `bit_vec_dealloc`. - */ -struct sp2_BitVec *sp2_bit_vec_new(uintptr_t size); - -/** - * Loads a `BitVec` from the provided data. - * The returned instance has to be freed with `bit_vec_dealloc`. - */ -struct sp2_BitVec *sp2_bit_vec_load(const uint8_t *data, uintptr_t data_length); - -/** - * Clones a `BitVec`. - * The returned instance has to be freed with `bit_vec_dealloc`. - */ -struct sp2_BitVec *sp2_bit_vec_clone(const struct sp2_BitVec *this_); - -/** - * Deallocates a `BitVec`. - * - * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - */ -void sp2_bit_vec_dealloc(struct sp2_BitVec *this_); - -/** - * Gets the value of a bit from the `BitVec`. - */ -bool sp2_bit_vec_get(const struct sp2_BitVec *this_, uintptr_t index); - -/** - * Sets the value of a bit in the `BitVec`. - */ -bool sp2_bit_vec_set(struct sp2_BitVec *this_, uintptr_t index, bool value); - -/** - * Sets the value of all bits in the `BitVec`. - */ -void sp2_bit_vec_fill(struct sp2_BitVec *this_, bool value); - -/** - * Gets the length of the `BitVec` in bits. - */ -uintptr_t sp2_bit_vec_len(const struct sp2_BitVec *this_); - -/** - * Creates a new `ByteGrid` instance. - * The returned instance has to be freed with `byte_grid_dealloc`. - */ -struct sp2_ByteGrid *sp2_byte_grid_new(uintptr_t width, uintptr_t height); - -/** - * Loads a `ByteGrid` with the specified dimensions from the provided data. - * The returned instance has to be freed with `byte_grid_dealloc`. - */ -struct sp2_ByteGrid *sp2_byte_grid_load(uintptr_t width, - uintptr_t height, - const uint8_t *data, - uintptr_t data_length); - -/** - * Clones a `ByteGrid`. - * The returned instance has to be freed with `byte_grid_dealloc`. - */ -struct sp2_ByteGrid *sp2_byte_grid_clone(const struct sp2_ByteGrid *this_); - -/** - * Deallocates a `ByteGrid`. - * - * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - */ -void sp2_byte_grid_dealloc(struct sp2_ByteGrid *this_); - -/** - * Get the current value at the specified position - */ -uint8_t sp2_byte_grid_get(const struct sp2_ByteGrid *this_, uintptr_t x, uintptr_t y); - -/** - * Sets the current value at the specified position - */ -void sp2_byte_grid_set(struct sp2_ByteGrid *this_, uintptr_t x, uintptr_t y, uint8_t value); - -/** - * Fills the whole `ByteGrid` with the specified value - */ -void sp2_byte_grid_fill(struct sp2_ByteGrid *this_, uint8_t value); - -/** - * Gets the width in pixels of the `ByteGrid` instance. - */ -uintptr_t sp2_byte_grid_width(const struct sp2_PixelGrid *this_); - -/** - * Gets the height in pixels of the `ByteGrid` instance. - */ -uintptr_t sp2_byte_grid_height(const struct sp2_PixelGrid *this_); - -/** - * Tries to load a `Command` from the passed array with the specified length. - * - * returns: NULL in case of an error, pointer to the allocated command otherwise - */ -struct sp2_Command *sp2_command_try_load(const uint8_t *data, uintptr_t length); - -/** - * Clones a `Command` instance - */ -struct sp2_Command *sp2_command_clone(const struct sp2_Command *original); - -/** - * Allocates a new `Command::Clear` instance - */ -struct sp2_Command *sp2_command_clear(void); - -/** - * Allocates a new `Command::HardReset` instance - */ -struct sp2_Command *sp2_command_hard_reset(void); - -/** - * Allocates a new `Command::FadeOut` instance - */ -struct sp2_Command *sp2_command_fade_out(void); - -/** - * Allocates a new `Command::Brightness` instance - */ -struct sp2_Command *sp2_command_brightness(sp2_Brightness brightness); - -/** - * Allocates a new `Command::CharBrightness` instance. - * The passed `ByteGrid` gets deallocated in the process. - */ -struct sp2_Command *sp2_command_char_brightness(uint16_t x, - uint16_t y, - struct sp2_ByteGrid *byte_grid); - -/** - * Allocates a new `Command::BitmapLinear` instance. - * The passed `BitVec` gets deallocated in the process. - */ -struct sp2_Command *sp2_command_bitmap_linear(sp2_Offset offset, - struct sp2_BitVec *bit_vec, - sp2_CompressionCode compression); - -/** - * Allocates a new `Command::BitmapLinearAnd` instance. - * The passed `BitVec` gets deallocated in the process. - */ -struct sp2_Command *sp2_command_bitmap_linear_and(sp2_Offset offset, - struct sp2_BitVec *bit_vec, - sp2_CompressionCode compression); - -/** - * Allocates a new `Command::BitmapLinearOr` instance. - * The passed `BitVec` gets deallocated in the process. - */ -struct sp2_Command *sp2_command_bitmap_linear_or(sp2_Offset offset, - struct sp2_BitVec *bit_vec, - sp2_CompressionCode compression); - -/** - * Allocates a new `Command::BitmapLinearXor` instance. - * The passed `BitVec` gets deallocated in the process. - */ -struct sp2_Command *sp2_command_bitmap_linear_xor(sp2_Offset offset, - struct sp2_BitVec *bit_vec, - sp2_CompressionCode compression); - -/** - * Allocates a new `Command::Cp437Data` instance. - * The passed `ByteGrid` gets deallocated in the process. - */ -struct sp2_Command *sp2_command_cp437_data(uint16_t x, uint16_t y, struct sp2_ByteGrid *byte_grid); - -/** - * Allocates a new `Command::BitmapLinearWin` instance. - * The passed `PixelGrid` gets deallocated in the process. - */ -struct sp2_Command *sp2_command_bitmap_linear_win(uint16_t x, - uint16_t y, - struct sp2_PixelGrid *byte_grid); - -/** - * Deallocates a `Command`. Note that connection_send does this implicitly, so you only need - * to do this if you use the library for parsing commands. - */ -void sp2_command_dealloc(struct sp2_Command *ptr); - -/** - * Creates a new instance of Connection. - * The returned instance has to be deallocated with `connection_dealloc`. - * - * returns: NULL if connection fails or connected instance - * - * Panics: bad string encoding - */ -struct sp2_Connection *sp2_connection_open(const char *host); - -/** - * Sends the command instance. The instance is consumed / destroyed and cannot be used after this call. - */ -bool sp2_connection_send(const struct sp2_Connection *connection, - struct sp2_Command *command_ptr); - -/** - * Closes and deallocates a connection instance - */ -void sp2_connection_dealloc(struct sp2_Connection *ptr); - -/** - * Creates a new `PixelGrid` instance. - * The returned instance has to be freed with `pixel_grid_dealloc`. - */ -struct sp2_PixelGrid *sp2_pixel_grid_new(uintptr_t width, uintptr_t height); - -/** - * Loads a `PixelGrid` with the specified dimensions from the provided data. - * The returned instance has to be freed with `pixel_grid_dealloc`. - */ -struct sp2_PixelGrid *sp2_pixel_grid_load(uintptr_t width, - uintptr_t height, - const uint8_t *data, - uintptr_t data_length); - -/** - * Clones a `PixelGrid`. - * The returned instance has to be freed with `pixel_grid_dealloc`. - */ -struct sp2_PixelGrid *sp2_pixel_grid_clone(const struct sp2_PixelGrid *this_); - -/** - * Deallocates a `PixelGrid`. - * - * Note: do not call this if the grid has been consumed in another way, e.g. to create a command. - */ -void sp2_pixel_grid_dealloc(struct sp2_PixelGrid *this_); - -/** - * Get the current value at the specified position - */ -bool sp2_pixel_grid_get(const struct sp2_PixelGrid *this_, uintptr_t x, uintptr_t y); - -/** - * Sets the current value at the specified position - */ -void sp2_pixel_grid_set(struct sp2_PixelGrid *this_, uintptr_t x, uintptr_t y, bool value); - -/** - * Fills the whole `PixelGrid` with the specified value - */ -void sp2_pixel_grid_fill(struct sp2_PixelGrid *this_, bool value); - -/** - * Gets the width in pixels of the `PixelGrid` instance. - */ -uintptr_t sp2_pixel_grid_width(const struct sp2_PixelGrid *this_); - -/** - * Gets the height in pixels of the `PixelGrid` instance. - */ -uintptr_t sp2_pixel_grid_height(const struct sp2_PixelGrid *this_); - -#ifdef __cplusplus -} // extern "C" -#endif // __cplusplus