diff --git a/.gitignore b/.gitignore index 1e859a2..023f499 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ target .idea -cmake-* +out diff --git a/Cargo.lock b/Cargo.lock index 8962317..9862a35 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,7 +21,7 @@ dependencies = [ name = "announce" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap", "env_logger", "servicepoint2", ] @@ -75,35 +75,6 @@ dependencies = [ "windows-sys", ] -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" - -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - -[[package]] -name = "bitflags" -version = "2.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1" - [[package]] name = "bzip2" version = "0.4.4" @@ -125,25 +96,6 @@ dependencies = [ "pkg-config", ] -[[package]] -name = "cbindgen" -version = "0.26.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da6bc11b07529f16944307272d5bd9b22530bc7d05751717c9d416586cedab49" -dependencies = [ - "clap 3.2.25", - "heck 0.4.1", - "indexmap", - "log", - "proc-macro2", - "quote", - "serde", - "serde_json", - "syn 1.0.109", - "tempfile", - "toml", -] - [[package]] name = "cc" version = "1.0.97" @@ -161,21 +113,6 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" -[[package]] -name = "clap" -version = "3.2.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ea181bf566f71cb9a5d17a59e1871af638180a18fb0035c92ae62b705207123" -dependencies = [ - "atty", - "bitflags 1.3.2", - "clap_lex 0.2.4", - "indexmap", - "strsim 0.10.0", - "termcolor", - "textwrap", -] - [[package]] name = "clap" version = "4.5.4" @@ -194,8 +131,8 @@ checksum = "ae129e2e766ae0ec03484e609954119f123cc1fe650337e155d03b022f24f7b4" dependencies = [ "anstream", "anstyle", - "clap_lex 0.7.0", - "strsim 0.11.1", + "clap_lex", + "strsim", ] [[package]] @@ -204,19 +141,10 @@ version = "4.5.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "528131438037fd55894f62d6e9f068b8f45ac57ffa77517819645d10aed04f64" dependencies = [ - "heck 0.5.0", + "heck", "proc-macro2", "quote", - "syn 2.0.63", -] - -[[package]] -name = "clap_lex" -version = "0.2.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" -dependencies = [ - "os_str_bytes", + "syn", ] [[package]] @@ -263,22 +191,6 @@ dependencies = [ "log", ] -[[package]] -name = "errno" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" -dependencies = [ - "libc", - "windows-sys", -] - -[[package]] -name = "fastrand" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" - [[package]] name = "flate2" version = "1.0.30" @@ -293,7 +205,7 @@ dependencies = [ name = "game_of_life" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap", "env_logger", "rand", "servicepoint2", @@ -310,61 +222,24 @@ dependencies = [ "wasi", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - -[[package]] -name = "heck" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" - [[package]] name = "heck" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" -[[package]] -name = "hermit-abi" -version = "0.1.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" -dependencies = [ - "libc", -] - [[package]] name = "humantime" version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "is_terminal_polyfill" version = "1.70.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800" -[[package]] -name = "itoa" -version = "1.0.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" - [[package]] name = "jobserver" version = "0.1.31" @@ -380,12 +255,6 @@ version = "0.2.154" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ae743338b92ff9146ce83992f766a31066a91a8c84a45e0e9f21e7cf6de6d346" -[[package]] -name = "linux-raw-sys" -version = "0.4.13" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01cda141df6706de531b6c46c3a33ecca755538219bd484262fa09410c13539c" - [[package]] name = "log" version = "0.4.21" @@ -431,7 +300,7 @@ dependencies = [ name = "moving_line" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap", "env_logger", "servicepoint2", ] @@ -442,12 +311,6 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" -[[package]] -name = "os_str_bytes" -version = "6.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2355d85b9a3786f481747ced0e0ff2ba35213a1f9bd406ed906554d7af805a1" - [[package]] name = "pkg-config" version = "0.3.30" @@ -512,7 +375,7 @@ dependencies = [ name = "random_brightness" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap", "env_logger", "rand", "servicepoint2", @@ -547,91 +410,23 @@ version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "adad44e29e4c806119491a7f06f03de4d1af22c3a680dd47f1e6e179439d1f56" -[[package]] -name = "rustix" -version = "0.38.34" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" -dependencies = [ - "bitflags 2.5.0", - "errno", - "libc", - "linux-raw-sys", - "windows-sys", -] - -[[package]] -name = "ryu" -version = "1.0.18" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" - -[[package]] -name = "serde" -version = "1.0.201" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "780f1cebed1629e4753a1a38a3c72d30b97ec044f0aef68cb26650a3c5cf363c" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.201" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5e405930b9796f1c00bee880d03fc7e0bb4b9a11afc776885ffe84320da2865" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.63", -] - -[[package]] -name = "serde_json" -version = "1.0.117" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" -dependencies = [ - "itoa", - "ryu", - "serde", -] - [[package]] name = "servicepoint2" version = "0.2.0" dependencies = [ "bzip2", - "cbindgen", "flate2", "log", "lz4", "zstd", ] -[[package]] -name = "strsim" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" - [[package]] name = "strsim" version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.63" @@ -643,42 +438,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "tempfile" -version = "3.10.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1" -dependencies = [ - "cfg-if", - "fastrand", - "rustix", - "windows-sys", -] - -[[package]] -name = "termcolor" -version = "1.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06794f8f6c5c898b3275aebefa6b8a1cb24cd2c6c79397ab15774837a0bc5755" -dependencies = [ - "winapi-util", -] - -[[package]] -name = "textwrap" -version = "0.16.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23d434d3f8967a09480fb04132ebe0a3e088c173e6d0ee7897abbdf4eab0f8b9" - -[[package]] -name = "toml" -version = "0.5.11" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f4f7f0dd8d50a853a531c426359045b1998f04219d88799810762cd4ad314234" -dependencies = [ - "serde", -] - [[package]] name = "unicode-ident" version = "1.0.12" @@ -697,37 +456,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-util" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4d4cc384e1e73b93bafa6fb4f1df8c41695c8a91cf9c4c64358067d15a7b6c6b" -dependencies = [ - "windows-sys", -] - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - [[package]] name = "windows-sys" version = "0.52.0" @@ -805,7 +533,7 @@ checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" name = "wiping_clear" version = "0.1.0" dependencies = [ - "clap 4.5.4", + "clap", "env_logger", "servicepoint2", ] diff --git a/examples/lang_c/.gitignore b/examples/lang_c/.gitignore deleted file mode 100644 index b4242bd..0000000 --- a/examples/lang_c/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -.idea -out -rust-target -include diff --git a/examples/lang_c/Makefile b/examples/lang_c/Makefile index 12fb78e..cac2abf 100644 --- a/examples/lang_c/Makefile +++ b/examples/lang_c/Makefile @@ -1,7 +1,9 @@ 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 +OUT_DIR := ${ROOT_DIR}/out + +SP2_DIR := ${ROOT_DIR}/../../servicepoint2 +SP2_INCLUDE := ${SP2_DIR}/include +SP2_TARGET_RELEASE := ${ROOT_DIR}/../../target/release .PHONY: clean @@ -10,14 +12,14 @@ run: ${OUT_DIR}/lang_c all: ${OUT_DIR}/lang_c -${OUT_DIR}/lang_c: ${SP2_INCLUDE_DIR}/sp2-bindings.h main.c +${OUT_DIR}/lang_c: ${SP2_TARGET_RELEASE} 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 + gcc main.c -I ${SP2_INCLUDE} -L ${SP2_TARGET_RELEASE} -Wl,-Bstatic -lservicepoint2 -Wl,-Bdynamic -o ${OUT_DIR}/lang_c -${SP2_INCLUDE_DIR}/sp2-bindings.h: - cd ../../servicepoint2/ && cargo build --release --target-dir ${RUST_TARGET_DIR} --all-features +${SP2_TARGET_RELEASE}: + cd ${SP2_DIR} && cargo build --release --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 + rm -r ${SP2_TARGET_RELEASE} || true \ No newline at end of file diff --git a/examples/lang_c/main.c b/examples/lang_c/main.c index 1fc4341..3f2dcd0 100644 --- a/examples/lang_c/main.c +++ b/examples/lang_c/main.c @@ -1,5 +1,5 @@ #include -#include "sp2/sp2-bindings.h" +#include "servicepoint2.h" int main(void) { sp2_Connection *connection = sp2_connection_open("localhost:2342"); diff --git a/servicepoint2/Cargo.toml b/servicepoint2/Cargo.toml index 9646afe..783663f 100644 --- a/servicepoint2/Cargo.toml +++ b/servicepoint2/Cargo.toml @@ -27,6 +27,3 @@ compression-lz = ["dep:lz4", "compression"] compression-zs = ["dep:zstd", "compression"] compression = [] c-api = [] - -[build-dependencies] -cbindgen = "0.26.0" diff --git a/servicepoint2/build.rs b/servicepoint2/build.rs deleted file mode 100644 index 9b87547..0000000 --- a/servicepoint2/build.rs +++ /dev/null @@ -1,29 +0,0 @@ -extern crate cbindgen; - -use std::env; - -use cbindgen::Language; - -fn main() { - let crate_dir = env::var("CARGO_MANIFEST_DIR").unwrap(); - - 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) - .with_item_prefix("sp2_") - .with_language(Language::C) - .with_cpp_compat(true) - .with_parse_expand_all_features(true) - .generate() - .expect("Unable to generate bindings") - .write_to_file(format!("{out_dir}/sp2-bindings.h")); -} \ No newline at end of file diff --git a/servicepoint2/cbindgen.toml b/servicepoint2/cbindgen.toml new file mode 100644 index 0000000..dca125d --- /dev/null +++ b/servicepoint2/cbindgen.toml @@ -0,0 +1,33 @@ +language = "C" +include_version = true +cpp_compat = true + +############################ Code Style Options ################################ + +braces = "SameLine" +line_length = 80 +tab_width = 4 +documentation = true +documentation_style = "auto" +documentation_length = "full" +line_endings = "LF" + +############################# Codegen Options ################################## + +style = "both" +sort_by = "Name" +usize_is_size_t = true + +[defines] +"feature = compression-gz" = "SP2_FEATURE_compression_gz" +"feature = compression-bz" = "SP2_FEATURE_compression_bz" +"feature = compression-lz" = "SP2_FEATURE_compression_lz" +"feature = compression-zs" = "SP2_FEATURE_compression_zs" +#"feature = c-api" = "SP2_FEATURE_c-api" + +[export] +prefix = "sp2_" + +[parse.expand] +features = ["c-api"] +all_features = true diff --git a/servicepoint2/generate-include b/servicepoint2/generate-include new file mode 100755 index 0000000..9b1085a --- /dev/null +++ b/servicepoint2/generate-include @@ -0,0 +1,5 @@ +#!/usr/bin/env sh +rm -r include || true + +# if the script crashes here, run `cargo install cbindgen` +cbindgen --config cbindgen.toml --clean --output include/servicepoint2.h diff --git a/servicepoint2/include/servicepoint2.h b/servicepoint2/include/servicepoint2.h new file mode 100644 index 0000000..0b9e9d6 --- /dev/null +++ b/servicepoint2/include/servicepoint2.h @@ -0,0 +1,372 @@ +/* Generated with cbindgen:0.26.0 */ + +#include +#include +#include +#include +#include + +/** + * pixel count on whole screen + */ +#define sp2_PIXEL_COUNT ((size_t)sp2_PIXEL_WIDTH * (size_t)sp2_PIXEL_HEIGHT) + +/** + * screen height in pixels + */ +#define sp2_PIXEL_HEIGHT (sp2_TILE_HEIGHT * sp2_TILE_SIZE) + +/** + * screen width in pixels + */ +#define sp2_PIXEL_WIDTH (sp2_TILE_WIDTH * sp2_TILE_SIZE) + +/** + * tile count in the y-direction + */ +#define sp2_TILE_HEIGHT 20 + +/** + * size of a single tile in one dimension + */ +#define sp2_TILE_SIZE 8 + +/** + * tile count in the x-direction + */ +#define sp2_TILE_WIDTH 56 + +/** + * Specifies the kind of compression to use. Availability depends on features. + */ +enum sp2_CompressionCode +#ifdef __cplusplus + : uint16_t +#endif // __cplusplus + { + Uncompressed = 0, +#if defined(SP2_FEATURE_compression_gz) + Gz = 26490, +#endif +#if defined(SP2_FEATURE_compression_bz) + Bz = 25210, +#endif +#if defined(SP2_FEATURE_compression_lz) + Lz = 27770, +#endif +#if defined(SP2_FEATURE_compression_zs) + Zs = 31347, +#endif +}; +#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 uint16_t sp2_Offset; + +typedef uint8_t sp2_Brightness; + +#ifdef __cplusplus +extern "C" { +#endif // __cplusplus + +/** + * 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_); + +/** + * Sets the value of all bits in the `BitVec`. + */ +void sp2_bit_vec_fill(struct sp2_BitVec *this_, bool value); + +/** + * Gets the value of a bit from the `BitVec`. + */ +bool sp2_bit_vec_get(const struct sp2_BitVec *this_, size_t index); + +/** + * Gets the length of the `BitVec` in bits. + */ +size_t sp2_bit_vec_len(const struct sp2_BitVec *this_); + +/** + * 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, size_t data_length); + +/** + * Creates a new `BitVec` instance. + * The returned instance has to be freed with `bit_vec_dealloc`. + */ +struct sp2_BitVec *sp2_bit_vec_new(size_t size); + +/** + * Sets the value of a bit in the `BitVec`. + */ +bool sp2_bit_vec_set(struct sp2_BitVec *this_, size_t index, bool value); + +/** + * 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_); + +/** + * Fills the whole `ByteGrid` with the specified value + */ +void sp2_byte_grid_fill(struct sp2_ByteGrid *this_, uint8_t value); + +/** + * Get the current value at the specified position + */ +uint8_t sp2_byte_grid_get(const struct sp2_ByteGrid *this_, size_t x, size_t y); + +/** + * Gets the height in pixels of the `ByteGrid` instance. + */ +size_t sp2_byte_grid_height(const struct sp2_PixelGrid *this_); + +/** + * 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(size_t width, + size_t height, + const uint8_t *data, + size_t data_length); + +/** + * Creates a new `ByteGrid` instance. + * The returned instance has to be freed with `byte_grid_dealloc`. + */ +struct sp2_ByteGrid *sp2_byte_grid_new(size_t width, size_t height); + +/** + * Sets the current value at the specified position + */ +void sp2_byte_grid_set(struct sp2_ByteGrid *this_, + size_t x, + size_t y, + uint8_t value); + +/** + * Gets the width in pixels of the `ByteGrid` instance. + */ +size_t sp2_byte_grid_width(const struct sp2_PixelGrid *this_); + +/** + * 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::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); + +/** + * 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::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::Clear` instance + */ +struct sp2_Command *sp2_command_clear(void); + +/** + * Clones a `Command` instance + */ +struct sp2_Command *sp2_command_clone(const struct sp2_Command *original); + +/** + * 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); + +/** + * 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); + +/** + * Allocates a new `Command::FadeOut` instance + */ +struct sp2_Command *sp2_command_fade_out(void); + +/** + * Allocates a new `Command::HardReset` instance + */ +struct sp2_Command *sp2_command_hard_reset(void); + +/** + * 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, size_t length); + +/** + * Closes and deallocates a connection instance + */ +void sp2_connection_dealloc(struct sp2_Connection *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); + +/** + * 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_); + +/** + * Fills the whole `PixelGrid` with the specified value + */ +void sp2_pixel_grid_fill(struct sp2_PixelGrid *this_, bool value); + +/** + * Get the current value at the specified position + */ +bool sp2_pixel_grid_get(const struct sp2_PixelGrid *this_, size_t x, size_t y); + +/** + * Gets the height in pixels of the `PixelGrid` instance. + */ +size_t sp2_pixel_grid_height(const struct sp2_PixelGrid *this_); + +/** + * 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(size_t width, + size_t height, + const uint8_t *data, + size_t data_length); + +/** + * Creates a new `PixelGrid` instance. + * The returned instance has to be freed with `pixel_grid_dealloc`. + */ +struct sp2_PixelGrid *sp2_pixel_grid_new(size_t width, size_t height); + +/** + * Sets the current value at the specified position + */ +void sp2_pixel_grid_set(struct sp2_PixelGrid *this_, + size_t x, + size_t y, + bool value); + +/** + * Gets the width in pixels of the `PixelGrid` instance. + */ +size_t sp2_pixel_grid_width(const struct sp2_PixelGrid *this_); + +#ifdef __cplusplus +} // extern "C" +#endif // __cplusplus