mirror of
https://github.com/netbirdio/IronRDP.git
synced 2026-05-22 18:43:12 -07:00
feat(server): add pointer DisplayUpdate
Add DisplayUpdate API to set the pointer simply (no cache, with 32bpp RGBA etc) Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
This commit is contained in:
committed by
Benoît Cortier
parent
704084952f
commit
d46e7964bf
@@ -1,4 +1,5 @@
|
||||
use anyhow::Result;
|
||||
use ironrdp_pdu::pointer::PointerPositionAttribute;
|
||||
use std::num::NonZeroU16;
|
||||
|
||||
pub use ironrdp_acceptor::DesktopSize;
|
||||
@@ -12,6 +13,11 @@ pub use ironrdp_graphics::image_processing::PixelFormat;
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DisplayUpdate {
|
||||
Bitmap(BitmapUpdate),
|
||||
PointerPosition(PointerPositionAttribute),
|
||||
ColorPointer(ColorPointer),
|
||||
RGBAPointer(RGBAPointer),
|
||||
HidePointer,
|
||||
DefaultPointer,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
@@ -20,6 +26,25 @@ pub enum PixelOrder {
|
||||
BottomToTop,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RGBAPointer {
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
pub hot_x: u16,
|
||||
pub hot_y: u16,
|
||||
pub data: Vec<u8>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct ColorPointer {
|
||||
pub width: u16,
|
||||
pub height: u16,
|
||||
pub hot_x: u16,
|
||||
pub hot_y: u16,
|
||||
pub and_mask: Vec<u8>,
|
||||
pub xor_mask: Vec<u8>,
|
||||
}
|
||||
|
||||
/// Bitmap Display Update
|
||||
///
|
||||
/// Bitmap updates are encoded using RDP 6.0 compression, fragmented and sent using
|
||||
|
||||
@@ -7,11 +7,12 @@ use std::{cmp, mem};
|
||||
use ironrdp_pdu::cursor::WriteCursor;
|
||||
use ironrdp_pdu::fast_path::{EncryptionFlags, FastPathHeader, FastPathUpdatePdu, Fragmentation, UpdateCode};
|
||||
use ironrdp_pdu::geometry::ExclusiveRectangle;
|
||||
use ironrdp_pdu::pointer::{ColorPointerAttribute, Point16, PointerAttribute, PointerPositionAttribute};
|
||||
use ironrdp_pdu::rdp::capability_sets::{CmdFlags, EntropyBits};
|
||||
use ironrdp_pdu::surface_commands::{ExtendedBitmapDataPdu, SurfaceBitsPdu, SurfaceCommand};
|
||||
use ironrdp_pdu::PduEncode;
|
||||
|
||||
use crate::PixelOrder;
|
||||
use crate::{ColorPointer, PixelOrder, RGBAPointer};
|
||||
|
||||
use self::bitmap::BitmapEncoder;
|
||||
use self::rfx::RfxEncoder;
|
||||
@@ -70,6 +71,61 @@ impl UpdateEncoder {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn rgba_pointer(&mut self, ptr: RGBAPointer) -> Result<UpdateFragmenter<'_>> {
|
||||
let xor_mask = ptr.data;
|
||||
|
||||
let hot_spot = Point16 {
|
||||
x: ptr.hot_x,
|
||||
y: ptr.hot_y,
|
||||
};
|
||||
let color_pointer = ColorPointerAttribute {
|
||||
cache_index: 0,
|
||||
hot_spot,
|
||||
width: ptr.width,
|
||||
height: ptr.height,
|
||||
xor_mask: &xor_mask,
|
||||
and_mask: &[],
|
||||
};
|
||||
let ptr = PointerAttribute {
|
||||
xor_bpp: 32,
|
||||
color_pointer,
|
||||
};
|
||||
let len = self.encode_pdu(ptr)?;
|
||||
Ok(UpdateFragmenter::new(UpdateCode::NewPointer, &self.buffer[..len]))
|
||||
}
|
||||
|
||||
pub(crate) fn color_pointer(&mut self, ptr: ColorPointer) -> Result<UpdateFragmenter<'_>> {
|
||||
let hot_spot = Point16 {
|
||||
x: ptr.hot_x,
|
||||
y: ptr.hot_y,
|
||||
};
|
||||
let ptr = ColorPointerAttribute {
|
||||
cache_index: 0,
|
||||
hot_spot,
|
||||
width: ptr.width,
|
||||
height: ptr.height,
|
||||
xor_mask: &ptr.xor_mask,
|
||||
and_mask: &ptr.and_mask,
|
||||
};
|
||||
let len = self.encode_pdu(ptr)?;
|
||||
Ok(UpdateFragmenter::new(UpdateCode::ColorPointer, &self.buffer[..len]))
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_self)]
|
||||
pub(crate) fn default_pointer(&mut self) -> Result<UpdateFragmenter<'_>> {
|
||||
Ok(UpdateFragmenter::new(UpdateCode::DefaultPointer, &[]))
|
||||
}
|
||||
|
||||
#[allow(clippy::unused_self)]
|
||||
pub(crate) fn hide_pointer(&mut self) -> Result<UpdateFragmenter<'_>> {
|
||||
Ok(UpdateFragmenter::new(UpdateCode::HiddenPointer, &[]))
|
||||
}
|
||||
|
||||
pub(crate) fn pointer_position(&mut self, pos: PointerPositionAttribute) -> Result<UpdateFragmenter<'_>> {
|
||||
let len = self.encode_pdu(pos)?;
|
||||
Ok(UpdateFragmenter::new(UpdateCode::PositionPointer, &self.buffer[..len]))
|
||||
}
|
||||
|
||||
pub(crate) fn bitmap(&mut self, bitmap: BitmapUpdate) -> Result<UpdateFragmenter<'_>> {
|
||||
let update = self.update;
|
||||
|
||||
|
||||
@@ -348,6 +348,11 @@ impl RdpServer {
|
||||
Some(update) = display_updates.next_update() => {
|
||||
let fragmenter = match update {
|
||||
DisplayUpdate::Bitmap(bitmap) => encoder.bitmap(bitmap),
|
||||
DisplayUpdate::PointerPosition(pos) => { encoder.pointer_position(pos) },
|
||||
DisplayUpdate::RGBAPointer(ptr) => { encoder.rgba_pointer(ptr) },
|
||||
DisplayUpdate::ColorPointer(ptr) => { encoder.color_pointer(ptr) },
|
||||
DisplayUpdate::HidePointer => { encoder.hide_pointer() },
|
||||
DisplayUpdate::DefaultPointer => { encoder.default_pointer() },
|
||||
};
|
||||
|
||||
let mut fragmenter = match fragmenter {
|
||||
|
||||
Reference in New Issue
Block a user