diff --git a/Cargo.lock b/Cargo.lock index b9ad7ea..ef1a970 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1702,8 +1702,7 @@ dependencies = [ [[package]] name = "servicepoint" version = "0.13.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33abd53582a995aaf5d387be4a1f7eb294a084185f88f8cf61652b6272041660" +source = "git+https://git.berlin.ccc.de/servicepoint/servicepoint/?branch=next#300bb5d6474f0f6152ab04feed4478995fcb3ec8" dependencies = [ "bitvec", "log", diff --git a/Cargo.toml b/Cargo.toml index a8cd60f..4d79b06 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ homepage = "https://crates.io/crates/servicepoint-cli" keywords = ["cccb", "cccb-servicepoint", "cli"] [dependencies] -servicepoint = { version = "0.13.2", features = ["protocol_websocket"] } +servicepoint = {features = ["protocol_websocket"] , git = "https://git.berlin.ccc.de/servicepoint/servicepoint/", branch = "next"} clap = { version = "4.5", features = ["derive"] } env_logger = "0.11" log = "0.4" diff --git a/src/brightness.rs b/src/brightness.rs index adead44..4dc086c 100644 --- a/src/brightness.rs +++ b/src/brightness.rs @@ -1,8 +1,8 @@ use crate::cli::BrightnessCommand; use log::info; -use servicepoint::{Brightness, Command, Connection}; +use servicepoint::{Brightness, Connection}; -pub(crate) fn brightness(connection: &Connection, brightness_command: BrightnessCommand) { +pub(crate) fn brightness(connection: &impl Connection, brightness_command: BrightnessCommand) { match brightness_command { BrightnessCommand::Max => brightness_set(connection, Brightness::MAX), BrightnessCommand::Min => brightness_set(connection, Brightness::MIN), @@ -12,9 +12,9 @@ pub(crate) fn brightness(connection: &Connection, brightness_command: Brightness } } -pub(crate) fn brightness_set(connection: &Connection, brightness: Brightness) { +pub(crate) fn brightness_set(connection: &impl Connection, brightness: Brightness) { connection - .send(Command::Brightness(brightness)) + .send(servicepoint::BrightnessCommand::from(brightness)) .expect("Failed to set brightness"); info!("set brightness to {brightness:?}"); } diff --git a/src/image_processing.rs b/src/image_processing.rs index 4e6baa8..9048dd3 100644 --- a/src/image_processing.rs +++ b/src/image_processing.rs @@ -100,7 +100,7 @@ impl ImageProcessingPipeline { let result = if self.options.no_dither { let cutoff = median_brightness(&orig); let bits = orig.iter().map(move |x| x > &cutoff).collect(); - Bitmap::from_bitvec(orig.width() as usize, bits) + Bitmap::from_bitvec(orig.width() as usize, bits).unwrap() } else { ostromoukhov_dither(orig, u8::MAX / 2) }; @@ -113,7 +113,7 @@ impl ImageProcessingPipeline { let width = source.width(); let result_height = Self::calc_height_without_spacers(source.height()); - let mut result = Bitmap::new(width, result_height); + let mut result = Bitmap::new(width, result_height).unwrap(); let mut source_y = 0; for result_y in 0..result_height { diff --git a/src/ledwand_dither.rs b/src/ledwand_dither.rs index d0e4b43..8e338e9 100644 --- a/src/ledwand_dither.rs +++ b/src/ledwand_dither.rs @@ -200,7 +200,7 @@ pub(crate) fn ostromoukhov_dither(source: GrayImage, bias: u8) -> Bitmap { } } - Bitmap::from_bitvec(width as usize, destination) + Bitmap::from_bitvec(width as usize, destination).unwrap() } #[inline] diff --git a/src/main.rs b/src/main.rs index 4ca1df4..01ef7c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use crate::{ }; use clap::Parser; use log::debug; -use servicepoint::{Brightness, Connection}; +use servicepoint::{Brightness, Connection, FakeConnection, UdpConnection, WebsocketConnection}; mod brightness; mod cli; @@ -22,13 +22,23 @@ fn main() { init_logging(cli.verbose); debug!("running with arguments: {:?}", cli); - let connection = make_connection(cli.destination, cli.transport); - debug!("connection established: {:#?}", connection); - - execute_mode(cli.command, connection); + + match cli.transport { + Protocol::Udp => { + let connection = UdpConnection::open(cli.destination).expect("Failed to open UDP connection"); + execute_mode(cli.command, connection);}, + Protocol::WebSocket => { + let url = cli.destination.parse().expect( + "provided destination is not a valid url - make sure it starts with 'ws://'", + ); + let connection = WebsocketConnection::open(url).expect("Failed to open WebSocket connection"); + execute_mode(cli.command, connection); + } + Protocol::Fake => execute_mode(cli.command, FakeConnection), + } } -pub fn execute_mode(mode: Mode, connection: Connection) { +pub fn execute_mode(mode: Mode, connection: impl Connection) { match mode { Mode::ResetEverything => { brightness_set(&connection, Brightness::MAX); @@ -40,19 +50,6 @@ pub fn execute_mode(mode: Mode, connection: Connection) { } } -fn make_connection(destination: String, transport: Protocol) -> Connection { - match transport { - Protocol::Udp => Connection::open(destination).expect("Failed to open UDP connection"), - Protocol::WebSocket => { - let url = destination.parse().expect( - "provided destination is not a valid url - make sure it starts with 'ws://'", - ); - Connection::open_websocket(url).expect("Failed to open WebSocket connection") - } - Protocol::Fake => Connection::Fake, - } -} - fn init_logging(debug: bool) { let filter = if debug { log::LevelFilter::Debug diff --git a/src/pixels.rs b/src/pixels.rs index da1aa6d..be97b17 100644 --- a/src/pixels.rs +++ b/src/pixels.rs @@ -1,12 +1,15 @@ use crate::{ - image_processing::ImageProcessingPipeline, cli::{ImageProcessingOptions, PixelCommand, SendImageOptions}, - stream_window::stream_window + image_processing::ImageProcessingPipeline, + stream_window::stream_window, }; use log::info; -use servicepoint::{BitVec, Command, CompressionCode, Connection, Origin, PIXEL_COUNT}; +use servicepoint::{ + BinaryOperation, BitVec, BitVecCommand, BitmapCommand, ClearCommand, CompressionCode, + Connection, Origin, PIXEL_COUNT, +}; -pub(crate) fn pixels(connection: &Connection, pixel_command: PixelCommand) { +pub(crate) fn pixels(connection: &impl Connection, pixel_command: PixelCommand) { match pixel_command { PixelCommand::Off => pixels_off(connection), PixelCommand::Flip => pixels_invert(connection), @@ -22,31 +25,37 @@ pub(crate) fn pixels(connection: &Connection, pixel_command: PixelCommand) { } } -fn pixels_on(connection: &Connection) { - let mask = BitVec::repeat(true, PIXEL_COUNT); - connection - .send(Command::BitmapLinear(0, mask, CompressionCode::Lzma)) - .expect("could not send command"); +fn pixels_on(connection: &impl Connection) { + let command = BitVecCommand { + offset: 0, + bitvec: BitVec::repeat(true, PIXEL_COUNT), + compression: CompressionCode::Lzma, + operation: BinaryOperation::Or, + }; + connection.send(command).expect("could not send command"); info!("turned on all pixels") } -fn pixels_invert(connection: &Connection) { - let mask = BitVec::repeat(true, PIXEL_COUNT); - connection - .send(Command::BitmapLinearXor(0, mask, CompressionCode::Lzma)) - .expect("could not send command"); +fn pixels_invert(connection: &impl Connection) { + let command = BitVecCommand { + offset: 0, + bitvec: BitVec::repeat(true, PIXEL_COUNT), + compression: CompressionCode::Lzma, + operation: BinaryOperation::Xor, + }; + connection.send(command).expect("could not send command"); info!("inverted all pixels"); } -pub(crate) fn pixels_off(connection: &Connection) { +pub(crate) fn pixels_off(connection: &impl Connection) { connection - .send(Command::Clear) + .send(ClearCommand) .expect("failed to clear pixels"); info!("reset pixels"); } fn pixels_image( - connection: &Connection, + connection: &impl Connection, options: SendImageOptions, processing_options: ImageProcessingOptions, ) { @@ -54,11 +63,11 @@ fn pixels_image( let mut pipeline = ImageProcessingPipeline::new(processing_options); let bitmap = pipeline.process(image); connection - .send(Command::BitmapLinearWin( - Origin::ZERO, + .send(BitmapCommand { + origin: Origin::ZERO, bitmap, - CompressionCode::default(), - )) + compression: CompressionCode::default(), + }) .expect("failed to send image command"); info!("sent image to display"); } diff --git a/src/stream_stdin.rs b/src/stream_stdin.rs index b8b6cfb..d9bfd7d 100644 --- a/src/stream_stdin.rs +++ b/src/stream_stdin.rs @@ -2,7 +2,7 @@ use log::warn; use servicepoint::*; use std::thread::sleep; -pub(crate) fn stream_stdin(connection: &Connection, slow: bool) { +pub(crate) fn stream_stdin(connection: &impl Connection, slow: bool) { warn!("This mode will break when using multi-byte characters and does not support ANSI escape sequences yet."); let mut app = App { connection, @@ -13,17 +13,17 @@ pub(crate) fn stream_stdin(connection: &Connection, slow: bool) { app.run() } -struct App<'t> { - connection: &'t Connection, +struct App<'t, TConnection: Connection> { + connection: &'t TConnection, mirror: CharGrid, y: usize, slow: bool, } -impl App<'_> { +impl App<'_, TConnection> { fn run(&mut self) { self.connection - .send(Command::Clear) + .send(ClearCommand) .expect("couldn't clear screen"); let last_y = self.mirror.height() - 1; for line in std::io::stdin().lines() { @@ -62,11 +62,12 @@ impl App<'_> { } fn send_mirror(&self) { + let command = CharGridCommand { + origin: Origin::ZERO, + grid: self.mirror.clone(), + }; self.connection - .send(Command::Utf8Data( - Origin::ZERO, - self.mirror.clone(), - )) + .send(command) .expect("couldn't send screen to display"); } @@ -75,8 +76,12 @@ impl App<'_> { line_grid.fill(' '); Self::line_onto_grid(&mut line_grid, 0, line); Self::line_onto_grid(&mut self.mirror, self.y, line); + let command = CharGridCommand { + origin: Origin::new(0, self.y), + grid: line_grid, + }; self.connection - .send(Command::Utf8Data(Origin::new(0, self.y), line_grid)) + .send(command) .expect("couldn't send single line to screen"); } } diff --git a/src/stream_window.rs b/src/stream_window.rs index f8e41ec..64cccf0 100644 --- a/src/stream_window.rs +++ b/src/stream_window.rs @@ -9,11 +9,11 @@ use scap::{ frame::convert_bgra_to_rgb, frame::Frame, }; -use servicepoint::{Command, CompressionCode, Connection, Origin, FRAME_PACING}; +use servicepoint::{BitmapCommand, CompressionCode, Connection, Origin, FRAME_PACING}; use std::time::{Duration, Instant}; pub fn stream_window( - connection: &Connection, + connection: &impl Connection, options: StreamScreenOptions, processing_options: ImageProcessingOptions, ) { @@ -35,12 +35,13 @@ pub fn stream_window( trace!("bitmap ready to send in: {:?}", start.elapsed()); + let command = BitmapCommand { + compression: CompressionCode::default(), + bitmap: bitmap.clone(), + origin: Origin::ZERO, + }; connection - .send(Command::BitmapLinearWin( - Origin::ZERO, - bitmap.clone(), - CompressionCode::default(), - )) + .send(command) .expect("failed to send frame to display"); debug!("frame time: {:?}", start.elapsed()); diff --git a/src/text.rs b/src/text.rs index 247b9ad..fb584e7 100644 --- a/src/text.rs +++ b/src/text.rs @@ -2,6 +2,6 @@ use servicepoint::Connection; use crate::cli::TextCommand; use crate::stream_stdin::stream_stdin; -pub fn text(connection: &Connection, command: TextCommand) { +pub fn text(connection: &impl Connection, command: TextCommand) { match command { TextCommand::Stdin { slow } => stream_stdin(connection, slow), } }