ironrdp_server/
handler.rsuse ironrdp_ainput as ainput;
use ironrdp_pdu::input::fast_path::{self, SynchronizeFlags};
use ironrdp_pdu::input::mouse::PointerFlags;
use ironrdp_pdu::input::mouse_rel::PointerRelFlags;
use ironrdp_pdu::input::mouse_x::PointerXFlags;
use ironrdp_pdu::input::sync::SyncToggleFlags;
use ironrdp_pdu::input::{scan_code, unicode, MousePdu, MouseRelPdu, MouseXPdu};
#[derive(Debug)]
pub enum KeyboardEvent {
Pressed { code: u8, extended: bool },
Released { code: u8, extended: bool },
UnicodePressed(u16),
UnicodeReleased(u16),
Synchronize(SynchronizeFlags),
}
#[derive(Debug)]
pub enum MouseEvent {
Move { x: u16, y: u16 },
RightPressed,
RightReleased,
LeftPressed,
LeftReleased,
MiddlePressed,
MiddleReleased,
Button4Pressed,
Button4Released,
Button5Pressed,
Button5Released,
VerticalScroll { value: i16 },
Scroll { x: i32, y: i32 },
RelMove { x: i32, y: i32 },
}
pub trait RdpServerInputHandler: Send {
fn keyboard(&mut self, event: KeyboardEvent);
fn mouse(&mut self, event: MouseEvent);
}
impl From<(u8, fast_path::KeyboardFlags)> for KeyboardEvent {
fn from((key, flags): (u8, fast_path::KeyboardFlags)) -> Self {
let extended = flags.contains(fast_path::KeyboardFlags::EXTENDED);
if flags.contains(fast_path::KeyboardFlags::RELEASE) {
KeyboardEvent::Released { code: key, extended }
} else {
KeyboardEvent::Pressed { code: key, extended }
}
}
}
impl From<(u16, fast_path::KeyboardFlags)> for KeyboardEvent {
fn from((key, flags): (u16, fast_path::KeyboardFlags)) -> Self {
if flags.contains(fast_path::KeyboardFlags::RELEASE) {
KeyboardEvent::UnicodeReleased(key)
} else {
KeyboardEvent::UnicodePressed(key)
}
}
}
impl From<(u16, scan_code::KeyboardFlags)> for KeyboardEvent {
#[allow(clippy::cast_possible_truncation)] fn from((key, flags): (u16, scan_code::KeyboardFlags)) -> Self {
let extended = flags.contains(scan_code::KeyboardFlags::EXTENDED);
if flags.contains(scan_code::KeyboardFlags::RELEASE) {
KeyboardEvent::Released {
code: key as u8,
extended,
}
} else {
KeyboardEvent::Pressed {
code: key as u8,
extended,
}
}
}
}
impl From<(u16, unicode::KeyboardFlags)> for KeyboardEvent {
fn from((key, flags): (u16, unicode::KeyboardFlags)) -> Self {
if flags.contains(unicode::KeyboardFlags::RELEASE) {
KeyboardEvent::UnicodeReleased(key)
} else {
KeyboardEvent::UnicodePressed(key)
}
}
}
impl From<SynchronizeFlags> for KeyboardEvent {
fn from(value: SynchronizeFlags) -> Self {
KeyboardEvent::Synchronize(value)
}
}
impl From<SyncToggleFlags> for KeyboardEvent {
#[allow(clippy::cast_possible_truncation)] fn from(value: SyncToggleFlags) -> Self {
KeyboardEvent::Synchronize(SynchronizeFlags::from_bits_truncate(value.bits() as u8))
}
}
impl From<MousePdu> for MouseEvent {
fn from(value: MousePdu) -> Self {
if value.flags.contains(PointerFlags::LEFT_BUTTON) {
if value.flags.contains(PointerFlags::DOWN) {
MouseEvent::LeftPressed
} else {
MouseEvent::LeftReleased
}
} else if value.flags.contains(PointerFlags::RIGHT_BUTTON) {
if value.flags.contains(PointerFlags::DOWN) {
MouseEvent::RightPressed
} else {
MouseEvent::RightReleased
}
} else if value.flags.contains(PointerFlags::VERTICAL_WHEEL) {
MouseEvent::VerticalScroll {
value: value.number_of_wheel_rotation_units,
}
} else {
MouseEvent::Move {
x: value.x_position,
y: value.y_position,
}
}
}
}
impl From<MouseXPdu> for MouseEvent {
fn from(value: MouseXPdu) -> Self {
if value.flags.contains(PointerXFlags::BUTTON1) {
if value.flags.contains(PointerXFlags::DOWN) {
MouseEvent::LeftPressed
} else {
MouseEvent::LeftReleased
}
} else if value.flags.contains(PointerXFlags::BUTTON2) {
if value.flags.contains(PointerXFlags::DOWN) {
MouseEvent::RightPressed
} else {
MouseEvent::RightReleased
}
} else {
MouseEvent::Move {
x: value.x_position,
y: value.y_position,
}
}
}
}
impl From<MouseRelPdu> for MouseEvent {
fn from(value: MouseRelPdu) -> Self {
if value.flags.contains(PointerRelFlags::BUTTON1) {
if value.flags.contains(PointerRelFlags::DOWN) {
MouseEvent::LeftPressed
} else {
MouseEvent::LeftReleased
}
} else if value.flags.contains(PointerRelFlags::BUTTON2) {
if value.flags.contains(PointerRelFlags::DOWN) {
MouseEvent::RightPressed
} else {
MouseEvent::RightReleased
}
} else if value.flags.contains(PointerRelFlags::BUTTON3) {
if value.flags.contains(PointerRelFlags::DOWN) {
MouseEvent::MiddlePressed
} else {
MouseEvent::MiddleReleased
}
} else if value.flags.contains(PointerRelFlags::XBUTTON1) {
if value.flags.contains(PointerRelFlags::DOWN) {
MouseEvent::Button4Pressed
} else {
MouseEvent::Button4Released
}
} else if value.flags.contains(PointerRelFlags::XBUTTON2) {
if value.flags.contains(PointerRelFlags::DOWN) {
MouseEvent::Button5Pressed
} else {
MouseEvent::Button5Released
}
} else {
MouseEvent::RelMove {
x: value.x_delta.into(),
y: value.y_delta.into(),
}
}
}
}
impl From<ainput::MousePdu> for MouseEvent {
fn from(value: ainput::MousePdu) -> Self {
use ainput::MouseEventFlags;
if value.flags.contains(MouseEventFlags::BUTTON1) {
if value.flags.contains(MouseEventFlags::DOWN) {
MouseEvent::LeftPressed
} else {
MouseEvent::LeftReleased
}
} else if value.flags.contains(MouseEventFlags::BUTTON2) {
if value.flags.contains(MouseEventFlags::DOWN) {
MouseEvent::RightPressed
} else {
MouseEvent::RightReleased
}
} else if value.flags.contains(MouseEventFlags::BUTTON3) {
if value.flags.contains(MouseEventFlags::DOWN) {
MouseEvent::MiddlePressed
} else {
MouseEvent::MiddleReleased
}
} else if value.flags.contains(MouseEventFlags::WHEEL) {
MouseEvent::Scroll { x: value.x, y: value.y }
} else if value.flags.contains(MouseEventFlags::REL) {
MouseEvent::RelMove { x: value.x, y: value.y }
} else if value.flags.contains(MouseEventFlags::MOVE) {
MouseEvent::Move {
x: value.x.try_into().unwrap_or(0),
y: value.y.try_into().unwrap_or(0),
}
} else {
MouseEvent::Move { x: 0, y: 0 }
}
}
}