From 7c24f6bb12964df3d152b2518fb299fe85d0233c Mon Sep 17 00:00:00 2001 From: Asura Date: Sun, 17 Jul 2022 14:14:51 -0700 Subject: [PATCH] Refactor listening keyboard to support switching keyboard modes --- libs/enigo/src/win/win_impl.rs | 2 +- libs/hbb_common/protos/message.proto | 1 + src/ui/remote.rs | 600 ++++++++++++++------------- 3 files changed, 306 insertions(+), 297 deletions(-) diff --git a/libs/enigo/src/win/win_impl.rs b/libs/enigo/src/win/win_impl.rs index 0967d07c9..b8f3d0fa3 100644 --- a/libs/enigo/src/win/win_impl.rs +++ b/libs/enigo/src/win/win_impl.rs @@ -2,7 +2,7 @@ use self::winapi::ctypes::c_int; use self::winapi::shared::{basetsd::ULONG_PTR, minwindef::*, windef::*}; use self::winapi::um::winbase::*; use self::winapi::um::winuser::*; -use rdev::{simulate, EventType, EventType::*, Key as RdevKey, SimulateError}; +use rdev::{simulate, EventType, Key as RdevKey, SimulateError}; use winapi; use crate::win::keycodes::*; diff --git a/libs/hbb_common/protos/message.proto b/libs/hbb_common/protos/message.proto index 0538f1aef..645930eb4 100644 --- a/libs/hbb_common/protos/message.proto +++ b/libs/hbb_common/protos/message.proto @@ -190,6 +190,7 @@ message KeyEvent { string seq = 6; } repeated ControlKey modifiers = 8; + uint32 mode = 9; } message CursorData { diff --git a/src/ui/remote.rs b/src/ui/remote.rs index cc2ce8154..8ebced2c4 100644 --- a/src/ui/remote.rs +++ b/src/ui/remote.rs @@ -43,6 +43,7 @@ use hbb_common::{ Stream, }; use hbb_common::{config::TransferSerde, fs::TransferJobMeta}; +use rdev::{Event, EventType::*, Key as RdevKey}; #[cfg(windows)] use crate::clipboard_file::*; @@ -288,288 +289,54 @@ impl Handler { crate::platform::windows::enable_lowlevel_keyboard(std::ptr::null_mut() as _); std::thread::spawn(move || { // This will block. - std::env::set_var("KEYBOARD_ONLY", "y"); // pass to rdev - let keyboard_mode = 1; - if keyboard_mode == 1 { - use rdev::{Event, EventType::*, Key as RdevKey}; - lazy_static::lazy_static! { - static ref MUTEX_SPECIAL_KEYS: Mutex> = { - let mut m = HashMap::new(); - // m.insert(RdevKey::PrintScreen, false); // TODO - m.insert(RdevKey::ShiftLeft, false); - m.insert(RdevKey::ShiftRight, false); - m.insert(RdevKey::ControlLeft, false); - m.insert(RdevKey::ControlRight, false); - m.insert(RdevKey::Alt, false); - m.insert(RdevKey::AltGr, false); - Mutex::new(m) - }; - } - // todo: auto change paltform - let func = move |evt: Event| { - if !IS_IN.load(Ordering::SeqCst) - || !SERVER_KEYBOARD_ENABLED.load(Ordering::SeqCst) - { - return; - } - let (key, down) = match evt.event_type { - KeyPress(k) => { - // keyboard long press - if MUTEX_SPECIAL_KEYS.lock().unwrap().contains_key(&k) { - if *MUTEX_SPECIAL_KEYS.lock().unwrap().get(&k).unwrap() { - return; - } - MUTEX_SPECIAL_KEYS.lock().unwrap().insert(k, true); - } - (k, 1) - } - KeyRelease(k) => { - // keyboard long press - if MUTEX_SPECIAL_KEYS.lock().unwrap().contains_key(&k) { - MUTEX_SPECIAL_KEYS.lock().unwrap().insert(k, false); - } - (k, 0) - } - _ => return, - }; - - // todo: clear key - #[cfg(target_os = "windows")] - let key = rdev::get_win_key(evt.code.into(), evt.scan_code); - - let mut key_event = KeyEvent::new(); - // According to peer platform. - if peer == "Linux" { - let keycode: u32 = rdev::linux_keycode_from_key(key).unwrap().into(); - key_event.set_chr(keycode); - } else if peer == "Windows" { - let keycode: u32 = rdev::win_keycode_from_key(key).unwrap().into(); - key_event.set_chr(keycode); - } else if peer == "Mac OS" { - let keycode: u32 = rdev::macos_keycode_from_key(key).unwrap().into(); - key_event.set_chr(keycode); - } - me.key_down_or_up(down, key_event, false, false, false, false); + std::env::set_var("KEYBOARD_ONLY", "y"); + lazy_static::lazy_static! { + static ref MUTEX_SPECIAL_KEYS: Mutex> = { + let mut m = HashMap::new(); + m.insert(RdevKey::ShiftLeft, false); + m.insert(RdevKey::ShiftRight, false); + m.insert(RdevKey::ControlLeft, false); + m.insert(RdevKey::ControlRight, false); + m.insert(RdevKey::Alt, false); + m.insert(RdevKey::AltGr, false); + Mutex::new(m) }; - if let Err(error) = rdev::listen(func) { - log::error!("rdev: {:?}", error); + } + + let func = move |evt: Event| { + if !IS_IN.load(Ordering::SeqCst) || !SERVER_KEYBOARD_ENABLED.load(Ordering::SeqCst) + { + return; } - } else { - use rdev::{EventType::*, *}; - let func = move |evt: Event| { - if !IS_IN.load(Ordering::SeqCst) - || !SERVER_KEYBOARD_ENABLED.load(Ordering::SeqCst) - { - return; + let (key, down) = match evt.event_type { + KeyPress(k) => { + // keyboard long press + if MUTEX_SPECIAL_KEYS.lock().unwrap().contains_key(&k) { + if *MUTEX_SPECIAL_KEYS.lock().unwrap().get(&k).unwrap() { + return; + } + MUTEX_SPECIAL_KEYS.lock().unwrap().insert(k, true); + } + (k, true) } - let (key, down) = match evt.event_type { - KeyPress(k) => (k, 1), - KeyRelease(k) => (k, 0), - _ => return, - }; - let alt = get_key_state(enigo::Key::Alt); - #[cfg(windows)] - let ctrl = { - let mut tmp = get_key_state(enigo::Key::Control); - unsafe { - if IS_ALT_GR { - if alt || key == Key::AltGr { - if tmp { - tmp = false; - } - } else { - IS_ALT_GR = false; - } - } - } - tmp - }; - #[cfg(not(windows))] - let ctrl = get_key_state(enigo::Key::Control); - let shift = get_key_state(enigo::Key::Shift); - #[cfg(windows)] - let command = crate::platform::windows::get_win_key_state(); - #[cfg(not(windows))] - let command = get_key_state(enigo::Key::Meta); - let control_key = match key { - Key::Alt => Some(ControlKey::Alt), - Key::AltGr => Some(ControlKey::RAlt), - Key::Backspace => Some(ControlKey::Backspace), - Key::ControlLeft => { - // when pressing AltGr, an extra VK_LCONTROL with a special - // scancode with bit 9 set is sent, let's ignore this. - #[cfg(windows)] - if evt.scan_code & 0x200 != 0 { - unsafe { - IS_ALT_GR = true; - } - return; - } - Some(ControlKey::Control) - } - Key::ControlRight => Some(ControlKey::RControl), - Key::DownArrow => Some(ControlKey::DownArrow), - Key::Escape => Some(ControlKey::Escape), - Key::F1 => Some(ControlKey::F1), - Key::F10 => Some(ControlKey::F10), - Key::F11 => Some(ControlKey::F11), - Key::F12 => Some(ControlKey::F12), - Key::F2 => Some(ControlKey::F2), - Key::F3 => Some(ControlKey::F3), - Key::F4 => Some(ControlKey::F4), - Key::F5 => Some(ControlKey::F5), - Key::F6 => Some(ControlKey::F6), - Key::F7 => Some(ControlKey::F7), - Key::F8 => Some(ControlKey::F8), - Key::F9 => Some(ControlKey::F9), - Key::LeftArrow => Some(ControlKey::LeftArrow), - Key::MetaLeft => Some(ControlKey::Meta), - Key::MetaRight => Some(ControlKey::RWin), - Key::Return => Some(ControlKey::Return), - Key::RightArrow => Some(ControlKey::RightArrow), - Key::ShiftLeft => Some(ControlKey::Shift), - Key::ShiftRight => Some(ControlKey::RShift), - Key::Space => Some(ControlKey::Space), - Key::Tab => Some(ControlKey::Tab), - Key::UpArrow => Some(ControlKey::UpArrow), - Key::Delete => { - if is_win && ctrl && alt { - me.ctrl_alt_del(); - return; - } - Some(ControlKey::Delete) - } - Key::Apps => Some(ControlKey::Apps), - Key::Cancel => Some(ControlKey::Cancel), - Key::Clear => Some(ControlKey::Clear), - Key::Kana => Some(ControlKey::Kana), - Key::Hangul => Some(ControlKey::Hangul), - Key::Junja => Some(ControlKey::Junja), - Key::Final => Some(ControlKey::Final), - Key::Hanja => Some(ControlKey::Hanja), - Key::Hanji => Some(ControlKey::Hanja), - Key::Convert => Some(ControlKey::Convert), - Key::Print => Some(ControlKey::Print), - Key::Select => Some(ControlKey::Select), - Key::Execute => Some(ControlKey::Execute), - Key::PrintScreen => Some(ControlKey::Snapshot), - Key::Help => Some(ControlKey::Help), - Key::Sleep => Some(ControlKey::Sleep), - Key::Separator => Some(ControlKey::Separator), - Key::KpReturn => Some(ControlKey::NumpadEnter), - Key::Kp0 => Some(ControlKey::Numpad0), - Key::Kp1 => Some(ControlKey::Numpad1), - Key::Kp2 => Some(ControlKey::Numpad2), - Key::Kp3 => Some(ControlKey::Numpad3), - Key::Kp4 => Some(ControlKey::Numpad4), - Key::Kp5 => Some(ControlKey::Numpad5), - Key::Kp6 => Some(ControlKey::Numpad6), - Key::Kp7 => Some(ControlKey::Numpad7), - Key::Kp8 => Some(ControlKey::Numpad8), - Key::Kp9 => Some(ControlKey::Numpad9), - Key::KpDivide => Some(ControlKey::Divide), - Key::KpMultiply => Some(ControlKey::Multiply), - Key::KpDecimal => Some(ControlKey::Decimal), - Key::KpMinus => Some(ControlKey::Subtract), - Key::KpPlus => Some(ControlKey::Add), - Key::CapsLock | Key::NumLock | Key::ScrollLock => { - return; - } - Key::Home => Some(ControlKey::Home), - Key::End => Some(ControlKey::End), - Key::Insert => Some(ControlKey::Insert), - Key::PageUp => Some(ControlKey::PageUp), - Key::PageDown => Some(ControlKey::PageDown), - Key::Pause => Some(ControlKey::Pause), - _ => None, - }; - let mut key_event = KeyEvent::new(); - if let Some(k) = control_key { - key_event.set_control_key(k); - } else { - let mut chr = match evt.name { - Some(ref s) => { - if s.len() <= 2 { - // exclude chinese characters - s.chars().next().unwrap_or('\0') - } else { - '\0' - } - } - _ => '\0', - }; - if chr == '·' { - // special for Chinese - chr = '`'; - } - if chr == '\0' { - chr = match key { - Key::Num1 => '1', - Key::Num2 => '2', - Key::Num3 => '3', - Key::Num4 => '4', - Key::Num5 => '5', - Key::Num6 => '6', - Key::Num7 => '7', - Key::Num8 => '8', - Key::Num9 => '9', - Key::Num0 => '0', - Key::KeyA => 'a', - Key::KeyB => 'b', - Key::KeyC => 'c', - Key::KeyD => 'd', - Key::KeyE => 'e', - Key::KeyF => 'f', - Key::KeyG => 'g', - Key::KeyH => 'h', - Key::KeyI => 'i', - Key::KeyJ => 'j', - Key::KeyK => 'k', - Key::KeyL => 'l', - Key::KeyM => 'm', - Key::KeyN => 'n', - Key::KeyO => 'o', - Key::KeyP => 'p', - Key::KeyQ => 'q', - Key::KeyR => 'r', - Key::KeyS => 's', - Key::KeyT => 't', - Key::KeyU => 'u', - Key::KeyV => 'v', - Key::KeyW => 'w', - Key::KeyX => 'x', - Key::KeyY => 'y', - Key::KeyZ => 'z', - Key::Comma => ',', - Key::Dot => '.', - Key::SemiColon => ';', - Key::Quote => '\'', - Key::LeftBracket => '[', - Key::RightBracket => ']', - Key::BackSlash => '\\', - Key::Minus => '-', - Key::Equal => '=', - Key::BackQuote => '`', - _ => '\0', - } - } - if chr != '\0' { - if chr == 'l' && is_win && command { - me.lock_screen(); - return; - } - key_event.set_chr(chr as _); - } else { - log::error!("Unknown key {:?}", evt); - return; + KeyRelease(k) => { + // keyboard long press + if MUTEX_SPECIAL_KEYS.lock().unwrap().contains_key(&k) { + MUTEX_SPECIAL_KEYS.lock().unwrap().insert(k, false); } + (k, false) } - me.key_down_or_up(down, key_event, alt, ctrl, shift, command); + _ => return, }; - if let Err(error) = rdev::listen(func) { - log::error!("rdev: {:?}", error); - } + + #[cfg(target_os = "windows")] + let key = rdev::get_win_key(evt.code.into(), evt.scan_code); + + me.key_down_or_up(down, key, evt); }; + if let Err(error) = rdev::listen(func) { + log::error!("rdev: {:?}", error); + } }); } @@ -1150,18 +917,19 @@ impl Handler { if self.peer_platform() == "Windows" { let mut key_event = KeyEvent::new(); key_event.set_control_key(ControlKey::CtrlAltDel); - self.key_down_or_up(1, key_event, false, false, false, false); + // todo + self.send_key_event(key_event, 2); } else { let mut key_event = KeyEvent::new(); key_event.set_control_key(ControlKey::Delete); - self.key_down_or_up(3, key_event, true, true, false, false); + // self.key_down_or_up(3, key_event, true, true, false, false); } } fn lock_screen(&mut self) { let mut key_event = KeyEvent::new(); key_event.set_control_key(ControlKey::LockScreen); - self.key_down_or_up(1, key_event, false, false, false, false); + // self.key_down_or_up(1, key_event, false, false, false, false); } fn transfer_file(&mut self) { @@ -1180,16 +948,246 @@ impl Handler { } } - fn key_down_or_up( - &mut self, - down_or_up: i32, - evt: KeyEvent, - alt: bool, - ctrl: bool, - shift: bool, - command: bool, - ) { - let mut key_event = evt; + fn send_key_event(&mut self, mut evt: KeyEvent, keyboard_mode: u32) { + // mode: map(1), translate(2), legacy(3), auto(4) + evt.mode = keyboard_mode; + let mut msg_out = Message::new(); + msg_out.set_key_event(evt); + log::info!("{:?}", msg_out); + self.send(Data::Message(msg_out)); + } + + fn map_keyboard_mode(&mut self, down_or_up: bool, key: RdevKey) { + // map mode(1): Send keycode according to the peer platform. + let peer = self.peer_platform(); + + let mut key_event = KeyEvent::new(); + // According to peer platform. + if peer == "Linux" { + let keycode: u32 = rdev::linux_keycode_from_key(key).unwrap_or_default().into(); + key_event.set_chr(keycode); + } else if peer == "Windows" { + let keycode: u32 = rdev::win_keycode_from_key(key).unwrap_or_default().into(); + key_event.set_chr(keycode); + } else if peer == "Mac OS" { + let keycode: u32 = rdev::macos_keycode_from_key(key).unwrap_or_default().into(); + key_event.set_chr(keycode); + } + if down_or_up == true { + key_event.down = true; + } else if down_or_up == true { + key_event.press = true; + } + self.send_key_event(key_event, 1); + } + + fn translate_keyboard_mode(&mut self, down_or_up: bool, key: RdevKey) { + // translate mode(2): locally generated characters are send to the peer. + } + + fn legacy_keyboard_mode(&mut self, down_or_up: bool, key: RdevKey, evt: Event) { + // legacy mode(3): Generate characters locally, look for keycode on other side. + println!("legacy_keyboard_mode {:?}", key); + let peer = self.peer_platform(); + let is_win = peer == "Windows"; + + let alt = get_key_state(enigo::Key::Alt); + #[cfg(windows)] + let ctrl = { + let mut tmp = get_key_state(enigo::Key::Control); + unsafe { + if IS_ALT_GR { + if alt || key == RdevKey::AltGr { + if tmp { + tmp = false; + } + } else { + IS_ALT_GR = false; + } + } + } + tmp + }; + #[cfg(not(windows))] + let ctrl = get_key_state(enigo::Key::Control); + let shift = get_key_state(enigo::Key::Shift); + #[cfg(windows)] + let command = crate::platform::windows::get_win_key_state(); + #[cfg(not(windows))] + let command = get_key_state(enigo::Key::Meta); + let control_key = match key { + RdevKey::Alt => Some(ControlKey::Alt), + RdevKey::AltGr => Some(ControlKey::RAlt), + RdevKey::Backspace => Some(ControlKey::Backspace), + RdevKey::ControlLeft => { + // when pressing AltGr, an extra VK_LCONTROL with a special + // scancode with bit 9 set is sent, let's ignore this. + #[cfg(windows)] + if evt.scan_code & 0x200 != 0 { + unsafe { + IS_ALT_GR = true; + } + return; + } + Some(ControlKey::Control) + } + RdevKey::ControlRight => Some(ControlKey::RControl), + RdevKey::DownArrow => Some(ControlKey::DownArrow), + RdevKey::Escape => Some(ControlKey::Escape), + RdevKey::F1 => Some(ControlKey::F1), + RdevKey::F10 => Some(ControlKey::F10), + RdevKey::F11 => Some(ControlKey::F11), + RdevKey::F12 => Some(ControlKey::F12), + RdevKey::F2 => Some(ControlKey::F2), + RdevKey::F3 => Some(ControlKey::F3), + RdevKey::F4 => Some(ControlKey::F4), + RdevKey::F5 => Some(ControlKey::F5), + RdevKey::F6 => Some(ControlKey::F6), + RdevKey::F7 => Some(ControlKey::F7), + RdevKey::F8 => Some(ControlKey::F8), + RdevKey::F9 => Some(ControlKey::F9), + RdevKey::LeftArrow => Some(ControlKey::LeftArrow), + RdevKey::MetaLeft => Some(ControlKey::Meta), + RdevKey::MetaRight => Some(ControlKey::RWin), + RdevKey::Return => Some(ControlKey::Return), + RdevKey::RightArrow => Some(ControlKey::RightArrow), + RdevKey::ShiftLeft => Some(ControlKey::Shift), + RdevKey::ShiftRight => Some(ControlKey::RShift), + RdevKey::Space => Some(ControlKey::Space), + RdevKey::Tab => Some(ControlKey::Tab), + RdevKey::UpArrow => Some(ControlKey::UpArrow), + RdevKey::Delete => { + if is_win && ctrl && alt { + self.ctrl_alt_del(); + return; + } + Some(ControlKey::Delete) + } + RdevKey::Apps => Some(ControlKey::Apps), + RdevKey::Cancel => Some(ControlKey::Cancel), + RdevKey::Clear => Some(ControlKey::Clear), + RdevKey::Kana => Some(ControlKey::Kana), + RdevKey::Hangul => Some(ControlKey::Hangul), + RdevKey::Junja => Some(ControlKey::Junja), + RdevKey::Final => Some(ControlKey::Final), + RdevKey::Hanja => Some(ControlKey::Hanja), + RdevKey::Hanji => Some(ControlKey::Hanja), + RdevKey::Convert => Some(ControlKey::Convert), + RdevKey::Print => Some(ControlKey::Print), + RdevKey::Select => Some(ControlKey::Select), + RdevKey::Execute => Some(ControlKey::Execute), + RdevKey::PrintScreen => Some(ControlKey::Snapshot), + RdevKey::Help => Some(ControlKey::Help), + RdevKey::Sleep => Some(ControlKey::Sleep), + RdevKey::Separator => Some(ControlKey::Separator), + RdevKey::KpReturn => Some(ControlKey::NumpadEnter), + RdevKey::Kp0 => Some(ControlKey::Numpad0), + RdevKey::Kp1 => Some(ControlKey::Numpad1), + RdevKey::Kp2 => Some(ControlKey::Numpad2), + RdevKey::Kp3 => Some(ControlKey::Numpad3), + RdevKey::Kp4 => Some(ControlKey::Numpad4), + RdevKey::Kp5 => Some(ControlKey::Numpad5), + RdevKey::Kp6 => Some(ControlKey::Numpad6), + RdevKey::Kp7 => Some(ControlKey::Numpad7), + RdevKey::Kp8 => Some(ControlKey::Numpad8), + RdevKey::Kp9 => Some(ControlKey::Numpad9), + RdevKey::KpDivide => Some(ControlKey::Divide), + RdevKey::KpMultiply => Some(ControlKey::Multiply), + RdevKey::KpDecimal => Some(ControlKey::Decimal), + RdevKey::KpMinus => Some(ControlKey::Subtract), + RdevKey::KpPlus => Some(ControlKey::Add), + RdevKey::CapsLock | RdevKey::NumLock | RdevKey::ScrollLock => { + return; + } + RdevKey::Home => Some(ControlKey::Home), + RdevKey::End => Some(ControlKey::End), + RdevKey::Insert => Some(ControlKey::Insert), + RdevKey::PageUp => Some(ControlKey::PageUp), + RdevKey::PageDown => Some(ControlKey::PageDown), + RdevKey::Pause => Some(ControlKey::Pause), + _ => None, + }; + let mut key_event = KeyEvent::new(); + if let Some(k) = control_key { + key_event.set_control_key(k); + } else { + let mut chr = match evt.name { + Some(ref s) => { + if s.len() <= 2 { + // exclude chinese characters + s.chars().next().unwrap_or('\0') + } else { + '\0' + } + } + _ => '\0', + }; + if chr == '·' { + // special for Chinese + chr = '`'; + } + if chr == '\0' { + chr = match key { + RdevKey::Num1 => '1', + RdevKey::Num2 => '2', + RdevKey::Num3 => '3', + RdevKey::Num4 => '4', + RdevKey::Num5 => '5', + RdevKey::Num6 => '6', + RdevKey::Num7 => '7', + RdevKey::Num8 => '8', + RdevKey::Num9 => '9', + RdevKey::Num0 => '0', + RdevKey::KeyA => 'a', + RdevKey::KeyB => 'b', + RdevKey::KeyC => 'c', + RdevKey::KeyD => 'd', + RdevKey::KeyE => 'e', + RdevKey::KeyF => 'f', + RdevKey::KeyG => 'g', + RdevKey::KeyH => 'h', + RdevKey::KeyI => 'i', + RdevKey::KeyJ => 'j', + RdevKey::KeyK => 'k', + RdevKey::KeyL => 'l', + RdevKey::KeyM => 'm', + RdevKey::KeyN => 'n', + RdevKey::KeyO => 'o', + RdevKey::KeyP => 'p', + RdevKey::KeyQ => 'q', + RdevKey::KeyR => 'r', + RdevKey::KeyS => 's', + RdevKey::KeyT => 't', + RdevKey::KeyU => 'u', + RdevKey::KeyV => 'v', + RdevKey::KeyW => 'w', + RdevKey::KeyX => 'x', + RdevKey::KeyY => 'y', + RdevKey::KeyZ => 'z', + RdevKey::Comma => ',', + RdevKey::Dot => '.', + RdevKey::SemiColon => ';', + RdevKey::Quote => '\'', + RdevKey::LeftBracket => '[', + RdevKey::RightBracket => ']', + RdevKey::BackSlash => '\\', + RdevKey::Minus => '-', + RdevKey::Equal => '=', + RdevKey::BackQuote => '`', + _ => '\0', + } + } + if chr != '\0' { + if chr == 'l' && is_win && command { + self.lock_screen(); + return; + } + key_event.set_chr(chr as _); + } else { + log::error!("Unknown key {:?}", evt); + return; + } + } if alt && !crate::is_control_key(&key_event, &ControlKey::Alt) @@ -1223,15 +1221,25 @@ impl Handler { key_event.modifiers.push(ControlKey::NumLock.into()); } } - if down_or_up == 1 { + if down_or_up == true { key_event.down = true; - } else if down_or_up == 3 { - key_event.press = true; } - let mut msg_out = Message::new(); - msg_out.set_key_event(key_event); - log::debug!("{:?}", msg_out); - self.send(Data::Message(msg_out)); + dbg!(&key_event); + self.send_key_event(key_event, 2) + } + + fn key_down_or_up(&mut self, down_or_up: bool, key: RdevKey, evt: Event) { + // Call different functions according to keyboard mode. + let mode = std::env::var("KEYBOARD_MOAD").unwrap_or(String::from("map")); + match mode.as_str() { + "map" => { + self.map_keyboard_mode(down_or_up, key); + } + "legacy" => self.legacy_keyboard_mode(down_or_up, key, evt), + _ => { + self.map_keyboard_mode(down_or_up, key); + } + } } #[inline] @@ -2692,4 +2700,4 @@ impl Handler { async fn send_note(url: String, id: String, conn_id: i32, note: String) { let body = serde_json::json!({ "id": id, "Id": conn_id, "note": note }); allow_err!(crate::post_request(url, body.to_string(), "").await); -} +} \ No newline at end of file