Skip to content

Commit

Permalink
Add support for the TS_SYNC_EVENT (#34)
Browse files Browse the repository at this point in the history
This is used to synchronize the state of the toggle keys
(like caps lock), as well as to reset the server state to
"all keys up."
  • Loading branch information
zmb3 authored Nov 2, 2023
1 parent 0ddb504 commit f0ca847
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 1 deletion.
3 changes: 3 additions & 0 deletions src/core/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ impl<S: Read + Write> RdpClient<S> {
}
// Raw keyboard input
RdpEvent::Key(key) => self.global.write_input_event(key.into(), &mut self.mcs),
// Input sync
RdpEvent::Sync(sync) => self.global.write_input_event(sync.into(), &mut self.mcs),

_ => Err(Error::RdpError(RdpError::new(
RdpErrorKind::UnexpectedType,
"RDPCLIENT: This event can't be sent",
Expand Down
8 changes: 8 additions & 0 deletions src/core/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,12 @@ pub struct KeyboardEvent {
pub down: bool,
}

#[derive(Debug)]
pub struct InputSyncEvent {
/// Indicates which of the toggle keys are active.
pub flags: u32,
}

/// All event handle by RDP protocol implemented by rdp-rs
#[derive(Debug)]
pub enum RdpEvent {
Expand All @@ -178,4 +184,6 @@ pub enum RdpEvent {
Pointer(PointerEvent),
/// Keyboard event
Key(KeyboardEvent),
/// Input sync event
Sync(InputSyncEvent),
}
30 changes: 29 additions & 1 deletion src/core/global.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::core::capability;
use crate::core::capability::{capability_set, Capability};
use crate::core::event::{
BitmapEvent, KeyboardEvent, PointerButton, PointerEvent, PointerWheel, RdpEvent,
BitmapEvent, InputSyncEvent, KeyboardEvent, PointerButton, PointerEvent, PointerWheel, RdpEvent,
};
use crate::core::gcc::KeyboardLayout;
use crate::core::mcs;
Expand Down Expand Up @@ -601,6 +601,34 @@ pub fn ts_keyboard_event(flags: Option<u16>, key_code: Option<u16>) -> TSInputEv
}
}

#[repr(u32)]
pub enum InputSyncFlags {
TsSyncScrollLock = 0x00000001,
TsSyncNumLock = 0x00000002,
TsSyncCapsLock = 0x00000004,
TsSyncKanaLock = 0x00000008,
}

/// The TS_SYNC_EVENT is used to synchronize the value of the toggle keys
/// and to reset the server state to "all keys up."
///
/// See https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/6c5d0ef9-4653-4d69-9ba9-09ba3acd660f
pub fn ts_sync_event(toggle_flags: Option<u32>) -> TSInputEvent {
TSInputEvent {
event_type: InputEventType::InputEventSync,
message: component![
"pad2Octets" => U16::LE(0),
"toggleFlags" => U32::LE(toggle_flags.unwrap_or(0))
],
}
}

impl From<InputSyncEvent> for TSInputEvent {
fn from(evt: InputSyncEvent) -> Self {
ts_sync_event(Some(evt.flags))
}
}

/// Fast Path update (Not a PDU)
///
/// https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-rdpbcgr/a1c4caa8-00ed-45bb-a06e-5177473766d3
Expand Down

0 comments on commit f0ca847

Please sign in to comment.