Skip to content

Commit

Permalink
make release bind configurable
Browse files Browse the repository at this point in the history
closes #85
  • Loading branch information
feschber committed Mar 17, 2024
1 parent daf8818 commit 15d8f02
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 13 deletions.
15 changes: 15 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ 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;

#[derive(Serialize, Deserialize, Debug)]
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>,
Expand Down Expand Up @@ -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 {
Expand All @@ -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();
Expand Down Expand Up @@ -138,6 +145,13 @@ impl Config {
},
};

log::debug!("{config_toml:?}");
let release_bind = config_toml
.as_ref()
.map(|c| c.release_bind.clone())
.flatten()
.unwrap_or(Vec::from_iter(DEFAULT_RELEASE_KEYS.iter().cloned()));

let mut clients: Vec<(TomlClient, Position)> = vec![];

if let Some(config_toml) = config_toml {
Expand All @@ -162,6 +176,7 @@ impl Config {
frontend,
clients,
port,
release_bind,
})
}

Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 9 additions & 7 deletions src/scancode.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use serde::{Deserialize, Serialize};

/*
* https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input
*/
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -210,7 +212,7 @@ pub enum Linux {
KeySemicolon = 39,
KeyApostrophe = 40,
KeyGrave = 41,
KeyLeftshift = 42,
KeyLeftShift = 42,
KeyBackslash = 43,
KeyZ = 44,
KeyX = 45,
Expand All @@ -224,7 +226,7 @@ pub enum Linux {
KeySlash = 53,
KeyRightShift = 54,
KeyKpAsterisk = 55,
KeyLeftalt = 56,
KeyLeftAlt = 56,
KeySpace = 57,
KeyCapsLock = 58,
KeyF1 = 59,
Expand Down Expand Up @@ -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 */
Expand Down Expand Up @@ -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),
Expand All @@ -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),
Expand Down Expand Up @@ -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),
Expand Down
5 changes: 4 additions & 1 deletion src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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,
}
}

Expand All @@ -86,7 +89,7 @@ impl Server {

// event producer
let (mut producer_task, producer_channel) =
producer_task::new(producer, self.clone(), sender_tx.clone(), timer_tx.clone());
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(
Expand Down
27 changes: 22 additions & 5 deletions src/server/producer_task.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use anyhow::{anyhow, Result};
use futures::StreamExt;
use std::net::SocketAddr;
use std::{collections::HashSet, net::SocketAddr};

use tokio::{sync::mpsc::Sender, task::JoinHandle};

use crate::{
client::{ClientEvent, ClientHandle},
event::{Event, KeyboardEvent},
producer::EventProducer,
scancode,
server::State,
};

Expand All @@ -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:?}");
Expand All @@ -59,20 +62,34 @@ 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,
producer: &mut Box<dyn EventProducer>,
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");
Expand Down

0 comments on commit 15d8f02

Please sign in to comment.