From 1164ffdd986d226c2e7b8aeb8e4eba6c343c17de Mon Sep 17 00:00:00 2001 From: rob thijssen Date: Wed, 6 May 2026 14:31:37 +0300 Subject: [PATCH] fix: send SetPixelFormat to request 8bpp RGB332 The OmniView defaults to 16bpp when no SetPixelFormat is sent. The Java applet sends SetPixelFormat (msg type 0) at ByteColorRFBRenderer.new() line 76 to request 8bpp RGB332 (bpp=8, depth=8, true_color, red_max=7, green_max=7, blue_max=3, shifts 0/3/6). Without this, pixel data arrives as 16bpp pairs that produce green stripe artifacts when interpreted as 8bpp. Verified: snapshot now matches the reference screenshot from http://10.3.0.130/screenshot.jpg (dark screen with "Free" label). Co-Authored-By: Claude Opus 4.6 (1M context) --- crates/ericrfb/src/msg.rs | 26 ++++++++++++++++++++++++++ crates/ericrfb/src/session.rs | 3 +++ 2 files changed, 29 insertions(+) diff --git a/crates/ericrfb/src/msg.rs b/crates/ericrfb/src/msg.rs index 7d4e760..c6bb002 100644 --- a/crates/ericrfb/src/msg.rs +++ b/crates/ericrfb/src/msg.rs @@ -6,6 +6,32 @@ use crate::proto::{self, read_exact, read_i32_be, read_modified_utf8, read_u8, r // Client-to-server message writers // --------------------------------------------------------------------------- +/// Msg type 0: SetPixelFormat — aw.a(...), line 572. +/// Sets the server to send pixels in 8bpp RGB332 format. +/// Matches ByteColorRFBRenderer.new() line 76: +/// a(D.o, 8, false, true, 7, 7, 3, 0, 3, 6) +pub fn write_set_pixel_format_rgb332(w: &mut impl Write) -> proto::Result<()> { + #[rustfmt::skip] + let buf: [u8; 20] = [ + 0, // msg type 0 = SetPixelFormat + 0, 0, 0, // padding + 8, // bits-per-pixel + 8, // depth + 0, // big-endian = false + 1, // true-colour = true + 0, 7, // red-max = 7 (u16-BE) + 0, 7, // green-max = 7 (u16-BE) + 0, 3, // blue-max = 3 (u16-BE) + 0, // red-shift = 0 + 3, // green-shift = 3 + 6, // blue-shift = 6 + 0, 0, 0, // padding + ]; + w.write_all(&buf)?; + w.flush()?; + Ok(()) +} + /// Msg type 2: SetEncodings — aw.a(int[], int), line 597. /// Encoding IDs are i32 (negative values are pseudo-encodings). pub fn write_set_encodings(w: &mut impl Write, encodings: &[i32]) -> proto::Result<()> { diff --git a/crates/ericrfb/src/session.rs b/crates/ericrfb/src/session.rs index 2b145f8..94d3476 100644 --- a/crates/ericrfb/src/session.rs +++ b/crates/ericrfb/src/session.rs @@ -58,6 +58,9 @@ impl ActiveSession { server_init: raw.server_init, }; + // Tell server to send 8bpp RGB332 pixels + msg::write_set_pixel_format_rgb332(&mut session.writer)?; + // Send SetEncodings msg::write_set_encodings(&mut session.writer, encodings)?;