mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-03-07 20:09:59 +03:00
committed by
GitHub
parent
daf8818a9f
commit
9e56c546cd
@@ -8,6 +8,8 @@ use std::{error::Error, fs};
|
||||
use toml;
|
||||
|
||||
use crate::client::Position;
|
||||
use crate::scancode;
|
||||
use crate::scancode::Linux::{KeyLeftAlt, KeyLeftCtrl, KeyLeftMeta, KeyLeftShift};
|
||||
|
||||
pub const DEFAULT_PORT: u16 = 4242;
|
||||
|
||||
@@ -15,6 +17,7 @@ pub const DEFAULT_PORT: u16 = 4242;
|
||||
pub struct ConfigToml {
|
||||
pub port: Option<u16>,
|
||||
pub frontend: Option<String>,
|
||||
pub release_bind: Option<Vec<scancode::Linux>>,
|
||||
pub left: Option<TomlClient>,
|
||||
pub right: Option<TomlClient>,
|
||||
pub top: Option<TomlClient>,
|
||||
@@ -70,6 +73,7 @@ pub struct Config {
|
||||
pub port: u16,
|
||||
pub clients: Vec<(TomlClient, Position)>,
|
||||
pub daemon: bool,
|
||||
pub release_bind: Vec<scancode::Linux>,
|
||||
}
|
||||
|
||||
pub struct ConfigClient {
|
||||
@@ -80,6 +84,9 @@ pub struct ConfigClient {
|
||||
pub active: bool,
|
||||
}
|
||||
|
||||
const DEFAULT_RELEASE_KEYS: [scancode::Linux; 4] =
|
||||
[KeyLeftCtrl, KeyLeftShift, KeyLeftMeta, KeyLeftAlt];
|
||||
|
||||
impl Config {
|
||||
pub fn new() -> Result<Self> {
|
||||
let args = CliArgs::parse();
|
||||
@@ -138,6 +145,12 @@ impl Config {
|
||||
},
|
||||
};
|
||||
|
||||
log::debug!("{config_toml:?}");
|
||||
let release_bind = config_toml
|
||||
.as_ref()
|
||||
.and_then(|c| c.release_bind.clone())
|
||||
.unwrap_or(Vec::from_iter(DEFAULT_RELEASE_KEYS.iter().cloned()));
|
||||
|
||||
let mut clients: Vec<(TomlClient, Position)> = vec![];
|
||||
|
||||
if let Some(config_toml) = config_toml {
|
||||
@@ -162,6 +175,7 @@ impl Config {
|
||||
frontend,
|
||||
clients,
|
||||
port,
|
||||
release_bind,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -29,6 +29,7 @@ pub fn run() -> Result<()> {
|
||||
// parse config file + cli args
|
||||
let config = Config::new()?;
|
||||
log::debug!("{config:?}");
|
||||
log::info!("release bind: {:?}", config.release_bind);
|
||||
|
||||
if config.daemon {
|
||||
// if daemon is specified we run the service
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/*
|
||||
* https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input
|
||||
*/
|
||||
@@ -165,7 +167,7 @@ pub enum Windows {
|
||||
* https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
|
||||
*/
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, Hash, PartialEq)]
|
||||
#[allow(dead_code)]
|
||||
pub enum Linux {
|
||||
KeyReserved = 0,
|
||||
@@ -210,7 +212,7 @@ pub enum Linux {
|
||||
KeySemicolon = 39,
|
||||
KeyApostrophe = 40,
|
||||
KeyGrave = 41,
|
||||
KeyLeftshift = 42,
|
||||
KeyLeftShift = 42,
|
||||
KeyBackslash = 43,
|
||||
KeyZ = 44,
|
||||
KeyX = 45,
|
||||
@@ -224,7 +226,7 @@ pub enum Linux {
|
||||
KeySlash = 53,
|
||||
KeyRightShift = 54,
|
||||
KeyKpAsterisk = 55,
|
||||
KeyLeftalt = 56,
|
||||
KeyLeftAlt = 56,
|
||||
KeySpace = 57,
|
||||
KeyCapsLock = 58,
|
||||
KeyF1 = 59,
|
||||
@@ -294,7 +296,7 @@ pub enum Linux {
|
||||
// KEY_HANGUEL = KeyHangeul,
|
||||
KeyHanja = 123,
|
||||
KeyYen = 124,
|
||||
KeyLeftmeta = 125,
|
||||
KeyLeftMeta = 125,
|
||||
KeyRightmeta = 126,
|
||||
KeyCompose = 127,
|
||||
KeyStop = 128, /* AC Stop */
|
||||
@@ -485,7 +487,7 @@ impl TryFrom<Linux> for Windows {
|
||||
Linux::KeySemicolon => Ok(Self::KeySemiColon),
|
||||
Linux::KeyApostrophe => Ok(Self::KeyApostrophe),
|
||||
Linux::KeyGrave => Ok(Self::KeyGrave),
|
||||
Linux::KeyLeftshift => Ok(Self::KeyLeftShift),
|
||||
Linux::KeyLeftShift => Ok(Self::KeyLeftShift),
|
||||
Linux::KeyBackslash => Ok(Self::KeyBackslash),
|
||||
Linux::KeyZ => Ok(Self::KeyZ),
|
||||
Linux::KeyX => Ok(Self::KeyX),
|
||||
@@ -499,7 +501,7 @@ impl TryFrom<Linux> for Windows {
|
||||
Linux::KeySlash => Ok(Self::KeySlash),
|
||||
Linux::KeyRightShift => Ok(Self::KeyRightShift),
|
||||
Linux::KeyKpAsterisk => Ok(Self::KeypadStar),
|
||||
Linux::KeyLeftalt => Ok(Self::KeyLeftAlt),
|
||||
Linux::KeyLeftAlt => Ok(Self::KeyLeftAlt),
|
||||
Linux::KeySpace => Ok(Self::KeySpace),
|
||||
Linux::KeyCapsLock => Ok(Self::KeyCapsLock),
|
||||
Linux::KeyF1 => Ok(Self::KeyF1),
|
||||
@@ -567,7 +569,7 @@ impl TryFrom<Linux> for Windows {
|
||||
Linux::KeyHangeul => Ok(Self::KeyInternational1), // TODO unsure
|
||||
Linux::KeyHanja => Ok(Self::KeyInternational2), // TODO unsure
|
||||
Linux::KeyYen => Ok(Self::KeyInternational3), // TODO unsure
|
||||
Linux::KeyLeftmeta => Ok(Self::KeyLeftGUI),
|
||||
Linux::KeyLeftMeta => Ok(Self::KeyLeftGUI),
|
||||
Linux::KeyRightmeta => Ok(Self::KeyRightGUI),
|
||||
Linux::KeyCompose => Ok(Self::KeyApplication),
|
||||
Linux::KeyStop => Ok(Self::ACStop),
|
||||
|
||||
@@ -40,6 +40,7 @@ pub struct Server {
|
||||
client_manager: Rc<RefCell<ClientManager>>,
|
||||
port: Rc<Cell<u16>>,
|
||||
state: Rc<Cell<State>>,
|
||||
release_bind: Vec<crate::scancode::Linux>,
|
||||
}
|
||||
|
||||
impl Server {
|
||||
@@ -57,11 +58,13 @@ impl Server {
|
||||
config_client.active,
|
||||
);
|
||||
}
|
||||
let release_bind = config.release_bind.clone();
|
||||
Self {
|
||||
active_client,
|
||||
client_manager,
|
||||
port,
|
||||
state,
|
||||
release_bind,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,8 +88,13 @@ impl Server {
|
||||
network_task::new(self.clone(), frontend_notify_tx).await?;
|
||||
|
||||
// event producer
|
||||
let (mut producer_task, producer_channel) =
|
||||
producer_task::new(producer, self.clone(), sender_tx.clone(), timer_tx.clone());
|
||||
let (mut producer_task, producer_channel) = producer_task::new(
|
||||
producer,
|
||||
self.clone(),
|
||||
sender_tx.clone(),
|
||||
timer_tx.clone(),
|
||||
self.release_bind.clone(),
|
||||
);
|
||||
|
||||
// event consumer
|
||||
let (mut consumer_task, consumer_channel) = consumer_task::new(
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use futures::StreamExt;
|
||||
use std::net::SocketAddr;
|
||||
use std::{collections::HashSet, net::SocketAddr};
|
||||
|
||||
use tokio::{sync::mpsc::Sender, task::JoinHandle};
|
||||
|
||||
@@ -8,6 +8,7 @@ use crate::{
|
||||
client::{ClientEvent, ClientHandle},
|
||||
event::{Event, KeyboardEvent},
|
||||
producer::EventProducer,
|
||||
scancode,
|
||||
server::State,
|
||||
};
|
||||
|
||||
@@ -28,14 +29,16 @@ pub fn new(
|
||||
server: Server,
|
||||
sender_tx: Sender<(Event, SocketAddr)>,
|
||||
timer_tx: Sender<()>,
|
||||
release_bind: Vec<scancode::Linux>,
|
||||
) -> (JoinHandle<Result<()>>, Sender<ProducerEvent>) {
|
||||
let (tx, mut rx) = tokio::sync::mpsc::channel(32);
|
||||
let task = tokio::task::spawn_local(async move {
|
||||
let mut pressed_keys = HashSet::new();
|
||||
loop {
|
||||
tokio::select! {
|
||||
event = producer.next() => {
|
||||
let event = event.ok_or(anyhow!("event producer closed"))??;
|
||||
handle_producer_event(&server, &mut producer, &sender_tx, &timer_tx, event).await?;
|
||||
handle_producer_event(&server, &mut producer, &sender_tx, &timer_tx, event, &mut pressed_keys, &release_bind).await?;
|
||||
}
|
||||
e = rx.recv() => {
|
||||
log::debug!("producer notify rx: {e:?}");
|
||||
@@ -59,7 +62,15 @@ pub fn new(
|
||||
(task, tx)
|
||||
}
|
||||
|
||||
const RELEASE_MODIFIERDS: u32 = 77; // ctrl+shift+super+alt
|
||||
fn update_pressed_keys(pressed_keys: &mut HashSet<scancode::Linux>, key: u32, state: u8) {
|
||||
if let Ok(scancode) = scancode::Linux::try_from(key) {
|
||||
log::debug!("key: {key}, state: {state}, scancode: {scancode:?}");
|
||||
match state {
|
||||
1 => pressed_keys.insert(scancode),
|
||||
_ => pressed_keys.remove(&scancode),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_producer_event(
|
||||
server: &Server,
|
||||
@@ -67,12 +78,18 @@ async fn handle_producer_event(
|
||||
sender_tx: &Sender<(Event, SocketAddr)>,
|
||||
timer_tx: &Sender<()>,
|
||||
event: (ClientHandle, Event),
|
||||
pressed_keys: &mut HashSet<scancode::Linux>,
|
||||
release_bind: &[scancode::Linux],
|
||||
) -> Result<()> {
|
||||
let (c, mut e) = event;
|
||||
log::trace!("({c}) {e:?}");
|
||||
|
||||
if let Event::Keyboard(KeyboardEvent::Modifiers { mods_depressed, .. }) = e {
|
||||
if mods_depressed == RELEASE_MODIFIERDS {
|
||||
if let Event::Keyboard(KeyboardEvent::Key { key, state, .. }) = e {
|
||||
update_pressed_keys(pressed_keys, key, state);
|
||||
log::debug!("{pressed_keys:?}");
|
||||
if release_bind.iter().all(|k| pressed_keys.contains(k)) {
|
||||
pressed_keys.clear();
|
||||
log::info!("releasing pointer");
|
||||
producer.release()?;
|
||||
server.state.replace(State::Receiving);
|
||||
log::trace!("STATE ===> Receiving");
|
||||
|
||||
Reference in New Issue
Block a user