update to the (unreleased) version of servicepoint
All checks were successful
Rust / build (pull_request) Successful in 8m2s
All checks were successful
Rust / build (pull_request) Successful in 8m2s
This commit is contained in:
parent
a903cbed85
commit
63a2fd00b9
11 changed files with 94 additions and 304 deletions
|
@ -1,8 +1,9 @@
|
|||
use std::net::UdpSocket;
|
||||
use crate::cli::BrightnessCommand;
|
||||
use log::info;
|
||||
use servicepoint::{Brightness, Command, Connection};
|
||||
use servicepoint::{Brightness, GlobalBrightnessCommand, SendCommandExt};
|
||||
|
||||
pub(crate) fn brightness(connection: &Connection, brightness_command: BrightnessCommand) {
|
||||
pub(crate) fn brightness(connection: &UdpSocket, brightness_command: BrightnessCommand) {
|
||||
match brightness_command {
|
||||
BrightnessCommand::Max => brightness_set(connection, Brightness::MAX),
|
||||
BrightnessCommand::Min => brightness_set(connection, Brightness::MIN),
|
||||
|
@ -12,9 +13,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: &UdpSocket, brightness: Brightness) {
|
||||
connection
|
||||
.send(Command::Brightness(brightness))
|
||||
.send_command(GlobalBrightnessCommand::from(brightness))
|
||||
.expect("Failed to set brightness");
|
||||
info!("set brightness to {brightness:?}");
|
||||
}
|
||||
|
|
28
src/cli.rs
28
src/cli.rs
|
@ -12,14 +12,14 @@ pub struct Cli {
|
|||
default_value = "127.0.0.1:2342"
|
||||
)]
|
||||
pub destination: String,
|
||||
#[arg(
|
||||
short,
|
||||
long,
|
||||
help = "protocol to use for communication with display",
|
||||
value_enum,
|
||||
default_value = "udp"
|
||||
)]
|
||||
pub transport: Protocol,
|
||||
//#[arg(
|
||||
// short,
|
||||
// long,
|
||||
// help = "protocol to use for communication with display",
|
||||
// value_enum,
|
||||
// default_value = "udp"
|
||||
//)]
|
||||
//pub transport: Protocol,
|
||||
#[clap(subcommand)]
|
||||
pub command: Mode,
|
||||
#[clap(short, long, help = "verbose logging")]
|
||||
|
@ -103,12 +103,12 @@ pub enum BrightnessCommand {
|
|||
Min,
|
||||
}
|
||||
|
||||
#[derive(clap::ValueEnum, Clone, Debug)]
|
||||
pub enum Protocol {
|
||||
Udp,
|
||||
WebSocket,
|
||||
Fake,
|
||||
}
|
||||
//#[derive(clap::ValueEnum, Clone, Debug)]
|
||||
//pub enum Protocol {
|
||||
// Udp,
|
||||
// WebSocket,
|
||||
// Fake,
|
||||
//}
|
||||
|
||||
#[derive(clap::Parser, std::fmt::Debug)]
|
||||
#[clap(about = "Commands for sending text to the screen")]
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Based on https://github.com/WarkerAnhaltRanger/CCCB_Ledwand
|
||||
|
||||
use image::GrayImage;
|
||||
use servicepoint::{BitVec, Bitmap, PIXEL_HEIGHT};
|
||||
use servicepoint::{BitVecU8Msb0, Bitmap, PIXEL_HEIGHT};
|
||||
|
||||
type GrayHistogram = [usize; 256];
|
||||
|
||||
|
@ -169,7 +169,7 @@ pub(crate) fn ostromoukhov_dither(source: GrayImage, bias: u8) -> Bitmap {
|
|||
assert_eq!(width % 8, 0);
|
||||
|
||||
let mut source = source.into_raw();
|
||||
let mut destination = BitVec::repeat(false, source.len());
|
||||
let mut destination = BitVecU8Msb0::repeat(false, source.len());
|
||||
|
||||
for y in 0..height as usize {
|
||||
let start = y * width as usize;
|
||||
|
@ -200,13 +200,13 @@ 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]
|
||||
fn ostromoukhov_dither_pixel(
|
||||
source: &mut [u8],
|
||||
destination: &mut BitVec,
|
||||
destination: &mut BitVecU8Msb0,
|
||||
position: usize,
|
||||
width: usize,
|
||||
last_row: bool,
|
||||
|
|
23
src/main.rs
23
src/main.rs
|
@ -1,12 +1,13 @@
|
|||
use std::net::UdpSocket;
|
||||
use crate::{
|
||||
brightness::{brightness, brightness_set},
|
||||
cli::{Cli, Mode, Protocol},
|
||||
cli::{Cli, Mode},
|
||||
pixels::{pixels, pixels_off},
|
||||
text::text
|
||||
};
|
||||
use clap::Parser;
|
||||
use log::debug;
|
||||
use servicepoint::{Brightness, Connection};
|
||||
use servicepoint::{Brightness, UdpSocketExt};
|
||||
|
||||
mod brightness;
|
||||
mod cli;
|
||||
|
@ -22,13 +23,14 @@ fn main() {
|
|||
init_logging(cli.verbose);
|
||||
debug!("running with arguments: {:?}", cli);
|
||||
|
||||
let connection = make_connection(cli.destination, cli.transport);
|
||||
let connection = UdpSocket::bind_connect(cli.destination)
|
||||
.expect("Failed to connect");
|
||||
debug!("connection established: {:#?}", connection);
|
||||
|
||||
execute_mode(cli.command, connection);
|
||||
}
|
||||
|
||||
pub fn execute_mode(mode: Mode, connection: Connection) {
|
||||
pub fn execute_mode(mode: Mode, connection: UdpSocket) {
|
||||
match mode {
|
||||
Mode::ResetEverything => {
|
||||
brightness_set(&connection, Brightness::MAX);
|
||||
|
@ -40,19 +42,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
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use std::net::UdpSocket;
|
||||
use crate::{
|
||||
image_processing::ImageProcessingPipeline,
|
||||
cli::{ImageProcessingOptions, PixelCommand, SendImageOptions},
|
||||
stream_window::stream_window
|
||||
};
|
||||
use log::info;
|
||||
use servicepoint::{BitVec, Command, CompressionCode, Connection, Origin, PIXEL_COUNT};
|
||||
use servicepoint::{BinaryOperation, BitVecCommand, BitVecU8Msb0, BitmapCommand, ClearCommand, CompressionCode, Origin, SendCommandExt, PIXEL_COUNT};
|
||||
|
||||
pub(crate) fn pixels(connection: &Connection, pixel_command: PixelCommand) {
|
||||
pub(crate) fn pixels(connection: &UdpSocket, pixel_command: PixelCommand) {
|
||||
match pixel_command {
|
||||
PixelCommand::Off => pixels_off(connection),
|
||||
PixelCommand::Flip => pixels_invert(connection),
|
||||
|
@ -22,31 +23,33 @@ pub(crate) fn pixels(connection: &Connection, pixel_command: PixelCommand) {
|
|||
}
|
||||
}
|
||||
|
||||
fn pixels_on(connection: &Connection) {
|
||||
let mask = BitVec::repeat(true, PIXEL_COUNT);
|
||||
fn pixels_on(connection: &UdpSocket) {
|
||||
let mask = BitVecU8Msb0::repeat(true, PIXEL_COUNT);
|
||||
let command = BitVecCommand{offset: 0, bitvec: mask, compression: CompressionCode::Lzma, operation: BinaryOperation::Overwrite};
|
||||
connection
|
||||
.send(Command::BitmapLinear(0, mask, CompressionCode::Lzma))
|
||||
.send_command(command)
|
||||
.expect("could not send command");
|
||||
info!("turned on all pixels")
|
||||
}
|
||||
|
||||
fn pixels_invert(connection: &Connection) {
|
||||
let mask = BitVec::repeat(true, PIXEL_COUNT);
|
||||
fn pixels_invert(connection: &UdpSocket) {
|
||||
let mask = BitVecU8Msb0::repeat(true, PIXEL_COUNT);
|
||||
let command = BitVecCommand{offset: 0, bitvec: mask, compression: CompressionCode::Lzma, operation: BinaryOperation::Xor};
|
||||
connection
|
||||
.send(Command::BitmapLinearXor(0, mask, CompressionCode::Lzma))
|
||||
.send_command(command)
|
||||
.expect("could not send command");
|
||||
info!("inverted all pixels");
|
||||
}
|
||||
|
||||
pub(crate) fn pixels_off(connection: &Connection) {
|
||||
pub(crate) fn pixels_off(connection: &UdpSocket) {
|
||||
connection
|
||||
.send(Command::Clear)
|
||||
.send_command(ClearCommand)
|
||||
.expect("failed to clear pixels");
|
||||
info!("reset pixels");
|
||||
}
|
||||
|
||||
fn pixels_image(
|
||||
connection: &Connection,
|
||||
connection: &UdpSocket,
|
||||
options: SendImageOptions,
|
||||
processing_options: ImageProcessingOptions,
|
||||
) {
|
||||
|
@ -54,11 +57,11 @@ fn pixels_image(
|
|||
let mut pipeline = ImageProcessingPipeline::new(processing_options);
|
||||
let bitmap = pipeline.process(image);
|
||||
connection
|
||||
.send(Command::BitmapLinearWin(
|
||||
Origin::ZERO,
|
||||
.send_command(BitmapCommand {
|
||||
origin: Origin::ZERO,
|
||||
bitmap,
|
||||
CompressionCode::default(),
|
||||
))
|
||||
compression: CompressionCode::default(),
|
||||
})
|
||||
.expect("failed to send image command");
|
||||
info!("sent image to display");
|
||||
}
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
use std::net::UdpSocket;
|
||||
use log::warn;
|
||||
use servicepoint::*;
|
||||
use std::thread::sleep;
|
||||
|
||||
pub(crate) fn stream_stdin(connection: &Connection, slow: bool) {
|
||||
pub(crate) fn stream_stdin(connection: &UdpSocket, 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,
|
||||
|
@ -14,7 +15,7 @@ pub(crate) fn stream_stdin(connection: &Connection, slow: bool) {
|
|||
}
|
||||
|
||||
struct App<'t> {
|
||||
connection: &'t Connection,
|
||||
connection: &'t UdpSocket,
|
||||
mirror: CharGrid,
|
||||
y: usize,
|
||||
slow: bool,
|
||||
|
@ -23,7 +24,7 @@ struct App<'t> {
|
|||
impl App<'_> {
|
||||
fn run(&mut self) {
|
||||
self.connection
|
||||
.send(Command::Clear)
|
||||
.send_command(ClearCommand)
|
||||
.expect("couldn't clear screen");
|
||||
let last_y = self.mirror.height() - 1;
|
||||
for line in std::io::stdin().lines() {
|
||||
|
@ -63,10 +64,10 @@ impl App<'_> {
|
|||
|
||||
fn send_mirror(&self) {
|
||||
self.connection
|
||||
.send(Command::Utf8Data(
|
||||
Origin::ZERO,
|
||||
self.mirror.clone(),
|
||||
))
|
||||
.send_command(CharGridCommand {
|
||||
origin: Origin::ZERO,
|
||||
grid: self.mirror.clone(),
|
||||
})
|
||||
.expect("couldn't send screen to display");
|
||||
}
|
||||
|
||||
|
@ -76,7 +77,10 @@ impl App<'_> {
|
|||
Self::line_onto_grid(&mut line_grid, 0, line);
|
||||
Self::line_onto_grid(&mut self.mirror, self.y, line);
|
||||
self.connection
|
||||
.send(Command::Utf8Data(Origin::new(0, self.y), line_grid))
|
||||
.send_command(CharGridCommand {
|
||||
origin: Origin::new(0, self.y),
|
||||
grid: line_grid
|
||||
})
|
||||
.expect("couldn't send single line to screen");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
use std::net::UdpSocket;
|
||||
use crate::{
|
||||
cli::{ImageProcessingOptions, StreamScreenOptions},
|
||||
image_processing::ImageProcessingPipeline,
|
||||
|
@ -9,11 +10,11 @@ use scap::{
|
|||
frame::convert_bgra_to_rgb,
|
||||
frame::Frame,
|
||||
};
|
||||
use servicepoint::{Command, CompressionCode, Connection, Origin, FRAME_PACING};
|
||||
use servicepoint::{BitmapCommand, CompressionCode, Origin, SendCommandExt, FRAME_PACING};
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
pub fn stream_window(
|
||||
connection: &Connection,
|
||||
connection: &UdpSocket,
|
||||
options: StreamScreenOptions,
|
||||
processing_options: ImageProcessingOptions,
|
||||
) {
|
||||
|
@ -36,11 +37,11 @@ pub fn stream_window(
|
|||
trace!("bitmap ready to send in: {:?}", start.elapsed());
|
||||
|
||||
connection
|
||||
.send(Command::BitmapLinearWin(
|
||||
Origin::ZERO,
|
||||
bitmap.clone(),
|
||||
CompressionCode::default(),
|
||||
))
|
||||
.send_command(BitmapCommand {
|
||||
origin: Origin::ZERO,
|
||||
bitmap: bitmap.clone(),
|
||||
compression: CompressionCode::default(),
|
||||
})
|
||||
.expect("failed to send frame to display");
|
||||
|
||||
debug!("frame time: {:?}", start.elapsed());
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use servicepoint::Connection;
|
||||
use std::net::UdpSocket;
|
||||
use crate::cli::TextCommand;
|
||||
use crate::stream_stdin::stream_stdin;
|
||||
|
||||
pub fn text(connection: &Connection, command: TextCommand) {
|
||||
pub fn text(connection: &UdpSocket, command: TextCommand) {
|
||||
match command { TextCommand::Stdin { slow } => stream_stdin(connection, slow), }
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue