feat(web): support for hardware cursor (#290)

Adds support for native cursors for `IronRDP-web`.

- Uses CSS `cursor` property to set the custom cursor (which we encode as Base64 data URL
- Software rendering is still in place and could be enabled via the config flag
- "Inverted colors" are implemented for native cursors as a "checkerboard pattern" (As in FreeRDP)
- Native cursors have size **limitation** - _Any remote cursor bigger than 32x32 will be scaled down._ This is due to browser limitations described [here](https://chromestatus.com/feature/5825971391299584) and [here](https://bugs.chromium.org/p/chromium/issues/detail?id=880863)

Closes #250
This commit is contained in:
Vladyslav Nikonov 2023-11-21 19:20:03 +02:00 committed by GitHub
parent 723a91a432
commit 5b210f2fc7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 436 additions and 166 deletions

View file

@ -1,5 +1,5 @@
use expect_test::expect;
use ironrdp_graphics::pointer::DecodedPointer;
use ironrdp_graphics::pointer::{DecodedPointer, PointerBitmapTarget};
use ironrdp_pdu::pointer::{
CachedPointerAttribute, ColorPointerAttribute, LargePointerAttribute, Point16, PointerAttribute,
PointerPositionAttribute,
@ -38,7 +38,7 @@ fn expect_pointer_png(pointer: &DecodedPointer, expected_file_path: &str) {
fn new_pointer_32bpp() {
let data = include_bytes!("../../test_data/pdu/pointer/new_pointer_32bpp.bin");
let mut parsed = ironrdp_pdu::decode::<PointerAttribute>(data).unwrap();
let decoded = DecodedPointer::decode_pointer_attribute(&parsed).unwrap();
let decoded = DecodedPointer::decode_pointer_attribute(&parsed, PointerBitmapTarget::Software).unwrap();
expect_pointer_png(&decoded, "pdu/pointer/new_pointer_32bpp.png");
let encoded = ironrdp_pdu::encode_vec(&parsed).unwrap();
@ -69,7 +69,7 @@ fn new_pointer_32bpp() {
fn large_pointer_32bpp() {
let data = include_bytes!("../../test_data/pdu/pointer/large_pointer_32bpp.bin");
let mut parsed = ironrdp_pdu::decode::<LargePointerAttribute>(data).unwrap();
let decoded = DecodedPointer::decode_large_pointer_attribute(&parsed).unwrap();
let decoded = DecodedPointer::decode_large_pointer_attribute(&parsed, PointerBitmapTarget::Software).unwrap();
expect_pointer_png(&decoded, "pdu/pointer/large_pointer_32bpp.png");
let encoded = ironrdp_pdu::encode_vec(&parsed).unwrap();
@ -98,7 +98,7 @@ fn large_pointer_32bpp() {
fn color_pointer_24bpp() {
let data = include_bytes!("../../test_data/pdu/pointer/color_pointer_24bpp.bin");
let mut parsed = ironrdp_pdu::decode::<ColorPointerAttribute>(data).unwrap();
let decoded = DecodedPointer::decode_color_pointer_attribute(&parsed).unwrap();
let decoded = DecodedPointer::decode_color_pointer_attribute(&parsed, PointerBitmapTarget::Software).unwrap();
expect_pointer_png(&decoded, "pdu/pointer/color_pointer_24bpp.png");
let encoded = ironrdp_pdu::encode_vec(&parsed).unwrap();
@ -152,7 +152,7 @@ fn color_pointer_1bpp() {
let decoded = ironrdp_pdu::decode::<PointerAttribute>(&encoded).unwrap();
assert_eq!(&decoded, &value);
let decoded = DecodedPointer::decode_pointer_attribute(&value).unwrap();
let decoded = DecodedPointer::decode_pointer_attribute(&value, PointerBitmapTarget::Software).unwrap();
expect_pointer_png(&decoded, "pdu/pointer/color_pointer_1bpp.png");
}
@ -179,7 +179,7 @@ fn color_pointer_16bpp() {
let decoded = ironrdp_pdu::decode::<PointerAttribute>(&encoded).unwrap();
assert_eq!(&decoded, &value);
let decoded = DecodedPointer::decode_pointer_attribute(&value).unwrap();
let decoded = DecodedPointer::decode_pointer_attribute(&value, PointerBitmapTarget::Software).unwrap();
expect_pointer_png(&decoded, "pdu/pointer/color_pointer_16bpp.png");
}