mirror of
https://github.com/feschber/lan-mouse.git
synced 2026-03-07 11:59:59 +03:00
split into input-{event,capture,emulation}
This commit is contained in:
committed by
Ferdinand Schober
parent
7b511bb97d
commit
4db2d37f32
14
input-event/Cargo.toml
Normal file
14
input-event/Cargo.toml
Normal file
@@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "input-event"
|
||||
description = "cross-platform input-event types for input-capture / input-emulation"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
license = "GPL-3.0-or-later"
|
||||
repository = "https://github.com/ferdinandschober/lan-mouse"
|
||||
|
||||
[dependencies]
|
||||
anyhow = "1.0.86"
|
||||
futures-core = "0.3.30"
|
||||
log = "0.4.22"
|
||||
num_enum = "0.7.2"
|
||||
serde = "1.0.203"
|
||||
587
input-event/src/lib.rs
Normal file
587
input-event/src/lib.rs
Normal file
@@ -0,0 +1,587 @@
|
||||
use anyhow::{anyhow, Result};
|
||||
use std::{
|
||||
error::Error,
|
||||
fmt::{self, Display},
|
||||
};
|
||||
|
||||
pub mod scancode;
|
||||
|
||||
// FIXME
|
||||
pub const BTN_LEFT: u32 = 0x110;
|
||||
pub const BTN_RIGHT: u32 = 0x111;
|
||||
pub const BTN_MIDDLE: u32 = 0x112;
|
||||
pub const BTN_BACK: u32 = 0x113;
|
||||
pub const BTN_FORWARD: u32 = 0x114;
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum PointerEvent {
|
||||
Motion {
|
||||
time: u32,
|
||||
relative_x: f64,
|
||||
relative_y: f64,
|
||||
},
|
||||
Button {
|
||||
time: u32,
|
||||
button: u32,
|
||||
state: u32,
|
||||
},
|
||||
Axis {
|
||||
time: u32,
|
||||
axis: u8,
|
||||
value: f64,
|
||||
},
|
||||
AxisDiscrete120 {
|
||||
axis: u8,
|
||||
value: i32,
|
||||
},
|
||||
Frame {},
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone, Copy)]
|
||||
pub enum KeyboardEvent {
|
||||
Key {
|
||||
time: u32,
|
||||
key: u32,
|
||||
state: u8,
|
||||
},
|
||||
Modifiers {
|
||||
mods_depressed: u32,
|
||||
mods_latched: u32,
|
||||
mods_locked: u32,
|
||||
group: u32,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(PartialEq, Debug, Clone, Copy)]
|
||||
pub enum Event {
|
||||
/// pointer event (motion / button / axis)
|
||||
Pointer(PointerEvent),
|
||||
/// keyboard events (key / modifiers)
|
||||
Keyboard(KeyboardEvent),
|
||||
/// enter event: request to enter a client.
|
||||
/// The client must release the pointer if it is grabbed
|
||||
/// and reply with a leave event, as soon as its ready to
|
||||
/// receive events
|
||||
Enter(),
|
||||
/// leave event: this client is now ready to receive events and will
|
||||
/// not send any events after until it sends an enter event
|
||||
Leave(),
|
||||
/// ping a client, to see if it is still alive. A client that does
|
||||
/// not respond with a pong event will be assumed to be offline.
|
||||
Ping(),
|
||||
/// response to a ping event: this event signals that a client
|
||||
/// is still alive but must otherwise be ignored
|
||||
Pong(),
|
||||
/// explicit disconnect request. The client will no longer
|
||||
/// send events until the next Enter event. All of its keys should be released.
|
||||
Disconnect(),
|
||||
}
|
||||
|
||||
impl Display for PointerEvent {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
PointerEvent::Motion {
|
||||
time: _,
|
||||
relative_x,
|
||||
relative_y,
|
||||
} => write!(f, "motion({relative_x},{relative_y})"),
|
||||
PointerEvent::Button {
|
||||
time: _,
|
||||
button,
|
||||
state,
|
||||
} => {
|
||||
let str = match *button {
|
||||
BTN_LEFT => Some("left"),
|
||||
BTN_RIGHT => Some("right"),
|
||||
BTN_MIDDLE => Some("middle"),
|
||||
BTN_FORWARD => Some("forward"),
|
||||
BTN_BACK => Some("back"),
|
||||
_ => None,
|
||||
};
|
||||
if let Some(button) = str {
|
||||
write!(f, "button({button}, {state})")
|
||||
} else {
|
||||
write!(f, "button({button}, {state}")
|
||||
}
|
||||
}
|
||||
PointerEvent::Axis {
|
||||
time: _,
|
||||
axis,
|
||||
value,
|
||||
} => write!(f, "scroll({axis}, {value})"),
|
||||
PointerEvent::AxisDiscrete120 { axis, value } => {
|
||||
write!(f, "scroll-120 ({axis}, {value})")
|
||||
}
|
||||
PointerEvent::Frame {} => write!(f, "frame()"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for KeyboardEvent {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
KeyboardEvent::Key {
|
||||
time: _,
|
||||
key,
|
||||
state,
|
||||
} => {
|
||||
let scan = scancode::Linux::try_from(*key);
|
||||
if let Ok(scan) = scan {
|
||||
write!(f, "key({scan:?}, {state})")
|
||||
} else {
|
||||
write!(f, "key({key}, {state})")
|
||||
}
|
||||
}
|
||||
KeyboardEvent::Modifiers {
|
||||
mods_depressed,
|
||||
mods_latched,
|
||||
mods_locked,
|
||||
group,
|
||||
} => write!(
|
||||
f,
|
||||
"modifiers({mods_depressed},{mods_latched},{mods_locked},{group})"
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for Event {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
Event::Pointer(p) => write!(f, "{}", p),
|
||||
Event::Keyboard(k) => write!(f, "{}", k),
|
||||
Event::Enter() => write!(f, "enter"),
|
||||
Event::Leave() => write!(f, "leave"),
|
||||
Event::Ping() => write!(f, "ping"),
|
||||
Event::Pong() => write!(f, "pong"),
|
||||
Event::Disconnect() => write!(f, "disconnect"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Event {
|
||||
fn event_type(&self) -> EventType {
|
||||
match self {
|
||||
Self::Pointer(_) => EventType::Pointer,
|
||||
Self::Keyboard(_) => EventType::Keyboard,
|
||||
Self::Enter() => EventType::Enter,
|
||||
Self::Leave() => EventType::Leave,
|
||||
Self::Ping() => EventType::Ping,
|
||||
Self::Pong() => EventType::Pong,
|
||||
Self::Disconnect() => EventType::Disconnect,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl PointerEvent {
|
||||
fn event_type(&self) -> PointerEventType {
|
||||
match self {
|
||||
Self::Motion { .. } => PointerEventType::Motion,
|
||||
Self::Button { .. } => PointerEventType::Button,
|
||||
Self::Axis { .. } => PointerEventType::Axis,
|
||||
Self::AxisDiscrete120 { .. } => PointerEventType::AxisDiscrete120,
|
||||
Self::Frame { .. } => PointerEventType::Frame,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl KeyboardEvent {
|
||||
fn event_type(&self) -> KeyboardEventType {
|
||||
match self {
|
||||
KeyboardEvent::Key { .. } => KeyboardEventType::Key,
|
||||
KeyboardEvent::Modifiers { .. } => KeyboardEventType::Modifiers,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum PointerEventType {
|
||||
Motion,
|
||||
Button,
|
||||
Axis,
|
||||
AxisDiscrete120,
|
||||
Frame,
|
||||
}
|
||||
enum KeyboardEventType {
|
||||
Key,
|
||||
Modifiers,
|
||||
}
|
||||
enum EventType {
|
||||
Pointer,
|
||||
Keyboard,
|
||||
Enter,
|
||||
Leave,
|
||||
Ping,
|
||||
Pong,
|
||||
Disconnect,
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for PointerEventType {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self> {
|
||||
match value {
|
||||
x if x == Self::Motion as u8 => Ok(Self::Motion),
|
||||
x if x == Self::Button as u8 => Ok(Self::Button),
|
||||
x if x == Self::Axis as u8 => Ok(Self::Axis),
|
||||
x if x == Self::AxisDiscrete120 as u8 => Ok(Self::AxisDiscrete120),
|
||||
x if x == Self::Frame as u8 => Ok(Self::Frame),
|
||||
_ => Err(anyhow!(ProtocolError {
|
||||
msg: format!("invalid pointer event type {}", value),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<u8> for KeyboardEventType {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: u8) -> Result<Self> {
|
||||
match value {
|
||||
x if x == Self::Key as u8 => Ok(Self::Key),
|
||||
x if x == Self::Modifiers as u8 => Ok(Self::Modifiers),
|
||||
_ => Err(anyhow!(ProtocolError {
|
||||
msg: format!("invalid keyboard event type {}", value),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&Event> for Vec<u8> {
|
||||
fn from(event: &Event) -> Self {
|
||||
let event_id = vec![event.event_type() as u8];
|
||||
let event_data = match event {
|
||||
Event::Pointer(p) => p.into(),
|
||||
Event::Keyboard(k) => k.into(),
|
||||
Event::Enter() => vec![],
|
||||
Event::Leave() => vec![],
|
||||
Event::Ping() => vec![],
|
||||
Event::Pong() => vec![],
|
||||
Event::Disconnect() => vec![],
|
||||
};
|
||||
[event_id, event_data].concat()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct ProtocolError {
|
||||
msg: String,
|
||||
}
|
||||
|
||||
impl fmt::Display for ProtocolError {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
write!(f, "Protocol violation: {}", self.msg)
|
||||
}
|
||||
}
|
||||
impl Error for ProtocolError {}
|
||||
|
||||
impl TryFrom<Vec<u8>> for Event {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(value: Vec<u8>) -> Result<Self> {
|
||||
let event_id = u8::from_be_bytes(value[..1].try_into()?);
|
||||
match event_id {
|
||||
i if i == (EventType::Pointer as u8) => Ok(Event::Pointer(value.try_into()?)),
|
||||
i if i == (EventType::Keyboard as u8) => Ok(Event::Keyboard(value.try_into()?)),
|
||||
i if i == (EventType::Enter as u8) => Ok(Event::Enter()),
|
||||
i if i == (EventType::Leave as u8) => Ok(Event::Leave()),
|
||||
i if i == (EventType::Ping as u8) => Ok(Event::Ping()),
|
||||
i if i == (EventType::Pong as u8) => Ok(Event::Pong()),
|
||||
i if i == (EventType::Disconnect as u8) => Ok(Event::Disconnect()),
|
||||
_ => Err(anyhow!(ProtocolError {
|
||||
msg: format!("invalid event_id {}", event_id),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&PointerEvent> for Vec<u8> {
|
||||
fn from(event: &PointerEvent) -> Self {
|
||||
let id = vec![event.event_type() as u8];
|
||||
let data = match event {
|
||||
PointerEvent::Motion {
|
||||
time,
|
||||
relative_x,
|
||||
relative_y,
|
||||
} => {
|
||||
let time = time.to_be_bytes();
|
||||
let relative_x = relative_x.to_be_bytes();
|
||||
let relative_y = relative_y.to_be_bytes();
|
||||
[&time[..], &relative_x[..], &relative_y[..]].concat()
|
||||
}
|
||||
PointerEvent::Button {
|
||||
time,
|
||||
button,
|
||||
state,
|
||||
} => {
|
||||
let time = time.to_be_bytes();
|
||||
let button = button.to_be_bytes();
|
||||
let state = state.to_be_bytes();
|
||||
[&time[..], &button[..], &state[..]].concat()
|
||||
}
|
||||
PointerEvent::Axis { time, axis, value } => {
|
||||
let time = time.to_be_bytes();
|
||||
let axis = axis.to_be_bytes();
|
||||
let value = value.to_be_bytes();
|
||||
[&time[..], &axis[..], &value[..]].concat()
|
||||
}
|
||||
PointerEvent::AxisDiscrete120 { axis, value } => {
|
||||
let axis = axis.to_be_bytes();
|
||||
let value = value.to_be_bytes();
|
||||
[&axis[..], &value[..]].concat()
|
||||
}
|
||||
PointerEvent::Frame {} => {
|
||||
vec![]
|
||||
}
|
||||
};
|
||||
[id, data].concat()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Vec<u8>> for PointerEvent {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(data: Vec<u8>) -> Result<Self> {
|
||||
match data.get(1) {
|
||||
Some(id) => {
|
||||
let event_type = match id.to_owned().try_into() {
|
||||
Ok(event_type) => event_type,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
match event_type {
|
||||
PointerEventType::Motion => {
|
||||
let time = match data.get(2..6) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 2".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let relative_x = match data.get(6..14) {
|
||||
Some(d) => f64::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 8 Bytes at index 6".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let relative_y = match data.get(14..22) {
|
||||
Some(d) => f64::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 8 Bytes at index 14".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
Ok(Self::Motion {
|
||||
time,
|
||||
relative_x,
|
||||
relative_y,
|
||||
})
|
||||
}
|
||||
PointerEventType::Button => {
|
||||
let time = match data.get(2..6) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 2".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let button = match data.get(6..10) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 10".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let state = match data.get(10..14) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 14".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
Ok(Self::Button {
|
||||
time,
|
||||
button,
|
||||
state,
|
||||
})
|
||||
}
|
||||
PointerEventType::Axis => {
|
||||
let time = match data.get(2..6) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 2".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let axis = match data.get(6) {
|
||||
Some(d) => *d,
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 1 Byte at index 6".into(),
|
||||
}));
|
||||
}
|
||||
};
|
||||
let value = match data.get(7..15) {
|
||||
Some(d) => f64::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 8 Bytes at index 7".into(),
|
||||
}));
|
||||
}
|
||||
};
|
||||
Ok(Self::Axis { time, axis, value })
|
||||
}
|
||||
PointerEventType::AxisDiscrete120 => {
|
||||
let axis = match data.get(2) {
|
||||
Some(d) => *d,
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 1 Byte at index 2".into(),
|
||||
}));
|
||||
}
|
||||
};
|
||||
let value = match data.get(3..7) {
|
||||
Some(d) => i32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 3".into(),
|
||||
}));
|
||||
}
|
||||
};
|
||||
Ok(Self::AxisDiscrete120 { axis, value })
|
||||
}
|
||||
PointerEventType::Frame => Ok(Self::Frame {}),
|
||||
}
|
||||
}
|
||||
None => Err(anyhow!(ProtocolError {
|
||||
msg: "Expected an element at index 0".into(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&KeyboardEvent> for Vec<u8> {
|
||||
fn from(event: &KeyboardEvent) -> Self {
|
||||
let id = vec![event.event_type() as u8];
|
||||
let data = match event {
|
||||
KeyboardEvent::Key { time, key, state } => {
|
||||
let time = time.to_be_bytes();
|
||||
let key = key.to_be_bytes();
|
||||
let state = state.to_be_bytes();
|
||||
[&time[..], &key[..], &state[..]].concat()
|
||||
}
|
||||
KeyboardEvent::Modifiers {
|
||||
mods_depressed,
|
||||
mods_latched,
|
||||
mods_locked,
|
||||
group,
|
||||
} => {
|
||||
let mods_depressed = mods_depressed.to_be_bytes();
|
||||
let mods_latched = mods_latched.to_be_bytes();
|
||||
let mods_locked = mods_locked.to_be_bytes();
|
||||
let group = group.to_be_bytes();
|
||||
[
|
||||
&mods_depressed[..],
|
||||
&mods_latched[..],
|
||||
&mods_locked[..],
|
||||
&group[..],
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
};
|
||||
[id, data].concat()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<Vec<u8>> for KeyboardEvent {
|
||||
type Error = anyhow::Error;
|
||||
|
||||
fn try_from(data: Vec<u8>) -> Result<Self> {
|
||||
match data.get(1) {
|
||||
Some(id) => {
|
||||
let event_type = match id.to_owned().try_into() {
|
||||
Ok(event_type) => event_type,
|
||||
Err(e) => return Err(e),
|
||||
};
|
||||
match event_type {
|
||||
KeyboardEventType::Key => {
|
||||
let time = match data.get(2..6) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 6".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let key = match data.get(6..10) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 10".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let state = match data.get(10) {
|
||||
Some(d) => *d,
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 1 Bytes at index 14".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
Ok(KeyboardEvent::Key { time, key, state })
|
||||
}
|
||||
KeyboardEventType::Modifiers => {
|
||||
let mods_depressed = match data.get(2..6) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 6".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let mods_latched = match data.get(6..10) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 10".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let mods_locked = match data.get(10..14) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 14".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
let group = match data.get(14..18) {
|
||||
Some(d) => u32::from_be_bytes(d.try_into()?),
|
||||
None => {
|
||||
return Err(anyhow!(ProtocolError {
|
||||
msg: "Expected 4 Bytes at index 18".into(),
|
||||
}))
|
||||
}
|
||||
};
|
||||
Ok(KeyboardEvent::Modifiers {
|
||||
mods_depressed,
|
||||
mods_latched,
|
||||
mods_locked,
|
||||
group,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
None => Err(anyhow!(ProtocolError {
|
||||
msg: "Expected an element at index 0".into(),
|
||||
})),
|
||||
}
|
||||
}
|
||||
}
|
||||
851
input-event/src/scancode.rs
Normal file
851
input-event/src/scancode.rs
Normal file
@@ -0,0 +1,851 @@
|
||||
use num_enum::TryFromPrimitive;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/*
|
||||
* https://learn.microsoft.com/en-us/windows/win32/inputdev/about-keyboard-input
|
||||
* https://download.microsoft.com/download/1/6/1/161ba512-40e2-4cc9-843a-923143f3456c/translate.pdf
|
||||
* https://kbd-project.org/docs/scancodes/scancodes-1.html
|
||||
*/
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Clone, Copy, TryFromPrimitive)]
|
||||
pub enum Windows {
|
||||
Shutdown = 0xE05E,
|
||||
SystemSleep = 0xE05F,
|
||||
SystemWakeUp = 0xE063,
|
||||
ErrorRollOver = 0x00FF,
|
||||
KeyA = 0x001E,
|
||||
KeyB = 0x0030,
|
||||
KeyC = 0x002E,
|
||||
KeyD = 0x0020,
|
||||
KeyE = 0x0012,
|
||||
KeyF = 0x0021,
|
||||
KeyG = 0x0022,
|
||||
KeyH = 0x0023,
|
||||
KeyI = 0x0017,
|
||||
KeyJ = 0x0024,
|
||||
KeyK = 0x0025,
|
||||
KeyL = 0x0026,
|
||||
KeyM = 0x0032,
|
||||
KeyN = 0x0031,
|
||||
KeyO = 0x0018,
|
||||
KeyP = 0x0019,
|
||||
KeyQ = 0x0010,
|
||||
KeyR = 0x0013,
|
||||
KeyS = 0x001F,
|
||||
KeyT = 0x0014,
|
||||
KeyU = 0x0016,
|
||||
KeyV = 0x002F,
|
||||
KeyW = 0x0011,
|
||||
KeyX = 0x002D,
|
||||
KeyY = 0x0015,
|
||||
KeyZ = 0x002C,
|
||||
Key1 = 0x0002,
|
||||
Key2 = 0x0003,
|
||||
Key3 = 0x0004,
|
||||
Key4 = 0x0005,
|
||||
Key5 = 0x0006,
|
||||
Key6 = 0x0007,
|
||||
Key7 = 0x0008,
|
||||
Key8 = 0x0009,
|
||||
Key9 = 0x000A,
|
||||
Key0 = 0x000B,
|
||||
KeyEnter = 0x001C,
|
||||
KeyEsc = 0x0001,
|
||||
KeyDelete = 0x000E,
|
||||
KeyTab = 0x000F,
|
||||
KeySpace = 0x0039,
|
||||
KeyMinus = 0x000C,
|
||||
KeyEqual = 0x000D,
|
||||
KeyLeftBrace = 0x001A,
|
||||
KeyRightBrace = 0x001B,
|
||||
KeyBackslash = 0x002B,
|
||||
KeySemiColon = 0x0027,
|
||||
KeyApostrophe = 0x0028,
|
||||
KeyGrave = 0x0029,
|
||||
KeyComma = 0x0033,
|
||||
KeyDot = 0x0034,
|
||||
KeySlash = 0x0035,
|
||||
KeyCapsLock = 0x003A,
|
||||
KeyF1 = 0x003B,
|
||||
KeyF2 = 0x003C,
|
||||
KeyF3 = 0x003D,
|
||||
KeyF4 = 0x003E,
|
||||
KeyF5 = 0x003F,
|
||||
KeyF6 = 0x0040,
|
||||
KeyF7 = 0x0041,
|
||||
KeyF8 = 0x0042,
|
||||
KeyF9 = 0x0043,
|
||||
KeyF10 = 0x0044,
|
||||
KeyF11 = 0x0057,
|
||||
KeyF12 = 0x0058,
|
||||
KeyPrintScreen = 0xE037,
|
||||
KeyScrollLock = 0x0046,
|
||||
KeyPause = 0xE11D45,
|
||||
KeyInsert = 0xE052,
|
||||
KeyHome = 0xE047,
|
||||
KeyPageUp = 0xE049,
|
||||
KeyDeleteForward = 0xE053,
|
||||
KeyEnd = 0xE04F,
|
||||
KeyPageDown = 0xE051,
|
||||
KeyRight = 0xE04D,
|
||||
KeyLeft = 0xE04B,
|
||||
KeyDown = 0xE050,
|
||||
KeyUp = 0xE048,
|
||||
KeypadNumLock = 0x0045,
|
||||
KeypadSlash = 0xE035,
|
||||
KeypadStar = 0x0037,
|
||||
KeypadDash = 0x004A,
|
||||
KeypadPlus = 0x004E,
|
||||
KeypadEnter = 0xE01C,
|
||||
Keypad1End = 0x004F,
|
||||
Keypad2DownArrow = 0x0050,
|
||||
Keypad3PageDn = 0x0051,
|
||||
Keypad4LeftArrow = 0x004B,
|
||||
Keypad5 = 0x004C,
|
||||
Keypad6RightArrow = 0x004D,
|
||||
Keypad7Home = 0x0047,
|
||||
Keypad8UpArrow = 0x0048,
|
||||
Keypad9PageUp = 0x0049,
|
||||
Keypad0Insert = 0x0052,
|
||||
KeypadDot = 0x0053,
|
||||
KeyNonUSSlashBar = 0x0056,
|
||||
KeyApplication = 0xE05D,
|
||||
KeypadEquals = 0x0059,
|
||||
KeyF13 = 0x0064,
|
||||
KeyF14 = 0x0065,
|
||||
KeyF15 = 0x0066,
|
||||
KeyF16 = 0x0067,
|
||||
KeyF17 = 0x0068,
|
||||
KeyF18 = 0x0069,
|
||||
KeyF19 = 0x006A,
|
||||
KeyF20 = 0x006B,
|
||||
KeyF21 = 0x006C,
|
||||
KeyF22 = 0x006D,
|
||||
KeyF23 = 0x006E,
|
||||
KeyF24 = 0x0076, // KeyLANG5
|
||||
KeypadComma = 0x007E,
|
||||
KeyInternational1 = 0x0073,
|
||||
KeyInternational2 = 0x0070,
|
||||
KeyInternational3 = 0x007D, // typo in doc -> its Int'l 3 not Int'l 2
|
||||
#[allow(dead_code)]
|
||||
KeyInternational4 = 0x0079,
|
||||
#[allow(dead_code)]
|
||||
KeyInternational5 = 0x007B,
|
||||
// KeyInternational6 = 0x005C,
|
||||
KeyLANG1 = 0x0072,
|
||||
KeyLANG2 = 0x0071,
|
||||
KeyLANG3 = 0x0078,
|
||||
KeyLANG4 = 0x0077,
|
||||
// KeyLANG5 = 0x0076,
|
||||
KeyLeftCtrl = 0x001D,
|
||||
KeyLeftShift = 0x002A,
|
||||
KeyLeftAlt = 0x0038,
|
||||
KeyLeftGUI = 0xE05B,
|
||||
KeyRightCtrl = 0xE01D,
|
||||
KeyRightShift = 0x0036,
|
||||
KeyFakeRightShift = 0xE036,
|
||||
KeyRightAlt = 0xE038,
|
||||
KeyRightGUI = 0xE05C,
|
||||
KeyScanNextTrack = 0xE019,
|
||||
KeyScanPreviousTrack = 0xE010,
|
||||
KeyStop = 0xE024,
|
||||
KeyPlayPause = 0xE022,
|
||||
KeyMute = 0xE020,
|
||||
KeyVolumeUp = 0xE030,
|
||||
KeyVolumeDown = 0xE02E,
|
||||
#[allow(dead_code)]
|
||||
ALConsumerControlConfiguration = 0xE06D, // TODO Unused
|
||||
ALEmailReader = 0xE06C,
|
||||
ALCalculator = 0xE021,
|
||||
ALLocalMachineBrowser = 0xE06B,
|
||||
ACSearch = 0xE065,
|
||||
ACHome = 0xE032,
|
||||
ACBack = 0xE06A,
|
||||
ACForward = 0xE069,
|
||||
ACStop = 0xE068,
|
||||
ACRefresh = 0xE067,
|
||||
ACBookmarks = 0xE066,
|
||||
}
|
||||
|
||||
/*
|
||||
* https://github.com/torvalds/linux/blob/master/include/uapi/linux/input-event-codes.h
|
||||
*/
|
||||
#[repr(u32)]
|
||||
#[derive(Serialize, Deserialize, Debug, Clone, Copy, Eq, Hash, PartialEq, TryFromPrimitive)]
|
||||
#[allow(dead_code)]
|
||||
pub enum Linux {
|
||||
KeyReserved = 0,
|
||||
KeyEsc = 1,
|
||||
Key1 = 2,
|
||||
Key2 = 3,
|
||||
Key3 = 4,
|
||||
Key4 = 5,
|
||||
Key5 = 6,
|
||||
Key6 = 7,
|
||||
Key7 = 8,
|
||||
Key8 = 9,
|
||||
Key9 = 10,
|
||||
Key0 = 11,
|
||||
KeyMinus = 12,
|
||||
KeyEqual = 13,
|
||||
KeyBackspace = 14,
|
||||
KeyTab = 15,
|
||||
KeyQ = 16,
|
||||
KeyW = 17,
|
||||
KeyE = 18,
|
||||
KeyR = 19,
|
||||
KeyT = 20,
|
||||
KeyY = 21,
|
||||
KeyU = 22,
|
||||
KeyI = 23,
|
||||
KeyO = 24,
|
||||
KeyP = 25,
|
||||
KeyLeftbrace = 26,
|
||||
KeyRightbrace = 27,
|
||||
KeyEnter = 28,
|
||||
KeyLeftCtrl = 29,
|
||||
KeyA = 30,
|
||||
KeyS = 31,
|
||||
KeyD = 32,
|
||||
KeyF = 33,
|
||||
KeyG = 34,
|
||||
KeyH = 35,
|
||||
KeyJ = 36,
|
||||
KeyK = 37,
|
||||
KeyL = 38,
|
||||
KeySemicolon = 39,
|
||||
KeyApostrophe = 40,
|
||||
KeyGrave = 41,
|
||||
KeyLeftShift = 42,
|
||||
KeyBackslash = 43,
|
||||
KeyZ = 44,
|
||||
KeyX = 45,
|
||||
KeyC = 46,
|
||||
KeyV = 47,
|
||||
KeyB = 48,
|
||||
KeyN = 49,
|
||||
KeyM = 50,
|
||||
KeyComma = 51,
|
||||
KeyDot = 52,
|
||||
KeySlash = 53,
|
||||
KeyRightShift = 54,
|
||||
KeyKpAsterisk = 55,
|
||||
KeyLeftAlt = 56,
|
||||
KeySpace = 57,
|
||||
KeyCapsLock = 58,
|
||||
KeyF1 = 59,
|
||||
KeyF2 = 60,
|
||||
KeyF3 = 61,
|
||||
KeyF4 = 62,
|
||||
KeyF5 = 63,
|
||||
KeyF6 = 64,
|
||||
KeyF7 = 65,
|
||||
KeyF8 = 66,
|
||||
KeyF9 = 67,
|
||||
KeyF10 = 68,
|
||||
KeyNumlock = 69,
|
||||
KeyScrollLock = 70,
|
||||
KeyKp7 = 71,
|
||||
KeyKp8 = 72,
|
||||
KeyKp9 = 73,
|
||||
KeyKpMinus = 74,
|
||||
KeyKp4 = 75,
|
||||
KeyKp5 = 76,
|
||||
KeyKp6 = 77,
|
||||
KeyKpplus = 78,
|
||||
KeyKp1 = 79,
|
||||
KeyKp2 = 80,
|
||||
KeyKp3 = 81,
|
||||
KeyKp0 = 82,
|
||||
KeyKpDot = 83,
|
||||
Invalid = 84,
|
||||
KeyZenkakuhankaku = 85,
|
||||
Key102nd = 86,
|
||||
KeyF11 = 87,
|
||||
KeyF12 = 88,
|
||||
KeyRo = 89,
|
||||
KeyKatakana = 90,
|
||||
KeyHiragana = 91,
|
||||
KeyHenkan = 92,
|
||||
KeyKatakanahiragana = 93,
|
||||
KeyMuhenkan = 94,
|
||||
KeyKpJpComma = 95,
|
||||
KeyKpEnter = 96,
|
||||
KeyRightCtrl = 97,
|
||||
KeyKpslash = 98,
|
||||
KeySysrq = 99,
|
||||
KeyRightalt = 100,
|
||||
KeyLinefeed = 101,
|
||||
KeyHome = 102,
|
||||
KeyUp = 103,
|
||||
KeyPageup = 104,
|
||||
KeyLeft = 105,
|
||||
KeyRight = 106,
|
||||
KeyEnd = 107,
|
||||
KeyDown = 108,
|
||||
KeyPagedown = 109,
|
||||
KeyInsert = 110,
|
||||
KeyDelete = 111,
|
||||
KeyMacro = 112,
|
||||
KeyMute = 113,
|
||||
KeyVolumeDown = 114,
|
||||
KeyVolumeUp = 115,
|
||||
KeyPower = 116, /* SC System Power Down */
|
||||
KeyKpequal = 117,
|
||||
KeyKpplusminus = 118,
|
||||
KeyPause = 119,
|
||||
KeyScale = 120, /* AL Compiz Scale (Expose) */
|
||||
KeyKpcomma = 121,
|
||||
KeyHanguel = 122,
|
||||
// KEY_HANGUEL = KeyHangeul,
|
||||
KeyHanja = 123,
|
||||
KeyYen = 124,
|
||||
KeyLeftMeta = 125,
|
||||
KeyRightmeta = 126,
|
||||
KeyCompose = 127,
|
||||
KeyStop = 128, /* AC Stop */
|
||||
KeyAgain = 129,
|
||||
KeyProps = 130, /* AC Properties */
|
||||
KeyUndo = 131, /* AC Undo */
|
||||
KeyFront = 132,
|
||||
KeyCopy = 133, /* AC Copy */
|
||||
KeyOpen = 134, /* AC Open */
|
||||
KeyPaste = 135, /* AC Paste */
|
||||
KeyFind = 136, /* AC Search */
|
||||
KeyCut = 137, /* AC Cut */
|
||||
KeyHelp = 138, /* AL Integrated Help Center */
|
||||
KeyMenu = 139, /* Menu (show menu) */
|
||||
KeyCalc = 140, /* AL Calculator */
|
||||
KeySetup = 141,
|
||||
KeySleep = 142, /* SC System Sleep */
|
||||
KeyWakeup = 143, /* System Wake Up */
|
||||
KeyFile = 144, /* AL Local Machine Browser */
|
||||
KeySendfile = 145,
|
||||
KeyDeletefile = 146,
|
||||
KeyXfer = 147,
|
||||
KeyProg1 = 148,
|
||||
KeyProg2 = 149,
|
||||
KeyWww = 150, /* AL Internet Browser */
|
||||
KeyMsdos = 151,
|
||||
KeyCoffee = 152, /* AL Terminal Lock/Screensaver */
|
||||
// KEY_SCREENLOCK = KeyCoffee,
|
||||
KeyRotateDisplay = 153, /* Display orientation for e.g. tablets */
|
||||
// KEY_DIRECTION = KeyRotateDisplay,
|
||||
KeyCyclewindows = 154,
|
||||
KeyMail = 155,
|
||||
KeyBookmarks = 156, /* AC Bookmarks */
|
||||
KeyComputer = 157,
|
||||
KeyBack = 158, /* AC Back */
|
||||
KeyForward = 159, /* AC Forward */
|
||||
KeyClosecd = 160,
|
||||
KeyEjectcd = 161,
|
||||
KeyEjectclosecd = 162,
|
||||
KeyNextsong = 163,
|
||||
KeyPlaypause = 164,
|
||||
KeyPrevioussong = 165,
|
||||
KeyStopcd = 166,
|
||||
KeyRecord = 167,
|
||||
KeyRewind = 168,
|
||||
KeyPhone = 169, /* Media Select Telephone */
|
||||
KeyIso = 170,
|
||||
KeyConfig = 171, /* AL Consumer Control Configuration */
|
||||
KeyHomepage = 172, /* AC Home */
|
||||
KeyRefresh = 173, /* AC Refresh */
|
||||
KeyExit = 174, /* AC Exit */
|
||||
KeyMove = 175,
|
||||
KeyEdit = 176,
|
||||
KeyScrollup = 177,
|
||||
KeyScrolldown = 178,
|
||||
KeyKpleftparen = 179,
|
||||
KeyKprightparen = 180,
|
||||
KeyNew = 181, /* AC New */
|
||||
KeyRedo = 182, /* AC Redo/Repeat */
|
||||
KeyF13 = 183,
|
||||
KeyF14 = 184,
|
||||
KeyF15 = 185,
|
||||
KeyF16 = 186,
|
||||
KeyF17 = 187,
|
||||
KeyF18 = 188,
|
||||
KeyF19 = 189,
|
||||
KeyF20 = 190,
|
||||
KeyF21 = 191,
|
||||
KeyF22 = 192,
|
||||
KeyF23 = 193,
|
||||
KeyF24 = 194,
|
||||
Invalid1 = 195,
|
||||
Invalid2 = 196,
|
||||
Invalid3 = 197,
|
||||
Invalid4 = 198,
|
||||
Invalid5 = 199,
|
||||
KeyPlaycd = 200,
|
||||
KeyPausecd = 201,
|
||||
KeyProg3 = 202,
|
||||
KeyProg4 = 203,
|
||||
KeyAllApplications = 204, /* AC Desktop Show All Applications */
|
||||
// KEY_DASHBOARD = KeyAllApplications,
|
||||
KeySuspend = 205,
|
||||
KeyClose = 206, /* AC Close */
|
||||
KeyPlay = 207,
|
||||
KeyFastforward = 208,
|
||||
KeyBassboost = 209,
|
||||
KeyPrint = 210, /* AC Print */
|
||||
KeyHp = 211,
|
||||
KeyCamera = 212,
|
||||
KeySound = 213,
|
||||
KeyQuestion = 214,
|
||||
KeyEmail = 215,
|
||||
KeyChat = 216,
|
||||
KeySearch = 217,
|
||||
KeyConnect = 218,
|
||||
KeyFinance = 219, /* AL Checkbook/Finance */
|
||||
KeySport = 220,
|
||||
KeyShop = 221,
|
||||
KeyAlterase = 222,
|
||||
KeyCancel = 223, /* AC Cancel */
|
||||
KeyBrightnessdown = 224,
|
||||
KeyBrightnessup = 225,
|
||||
KeyMedia = 226,
|
||||
KeySwitchvideomode = 227, /* Cycle between available video, outputs (Monitor/LCD/TV-out/etc) */
|
||||
KeyKbdillumtoggle = 228,
|
||||
KeyKbdillumdown = 229,
|
||||
KeyKbdillumup = 230,
|
||||
KeySend = 231, /* AC Send */
|
||||
KeyReply = 232, /* AC Reply */
|
||||
KeyForwardmail = 233, /* AC Forward Msg */
|
||||
KeySave = 234, /* AC Save */
|
||||
KeyDocuments = 235,
|
||||
KeyBattery = 236,
|
||||
KeyBluetooth = 237,
|
||||
KeyWlan = 238,
|
||||
KeyUwb = 239,
|
||||
KeyUnknown = 240,
|
||||
KeyVideoNext = 241, /* drive next video source */
|
||||
KeyVideoPrev = 242, /* drive previous video source */
|
||||
KeyBrightnessCycle = 243, /* brightness up, after max is min */
|
||||
KeyBrightnessAuto = 244, /* Set Auto Brightness: manual, brightness control is off, rely on ambient */
|
||||
// KEY_BRIGHTNESS_ZERO=KeyBrightnessAuto,
|
||||
KeyDisplayOff = 245, /* display device to off state */
|
||||
KeyWwan = 246, /* Wireless WAN (LTE, UMTS, GSM, etc.) */
|
||||
// KEY_WIMAX = KeyWwan,
|
||||
KeyRfkill = 247, /* Key that controls all radios */
|
||||
KeyMicmute = 248, /* Mute / unmute the microphone */
|
||||
KeyCount = 249,
|
||||
}
|
||||
|
||||
impl TryFrom<Linux> for Windows {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: Linux) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
Linux::KeyReserved => Err(()),
|
||||
Linux::KeyEsc => Ok(Self::KeyEsc),
|
||||
Linux::Key1 => Ok(Self::Key1),
|
||||
Linux::Key2 => Ok(Self::Key2),
|
||||
Linux::Key3 => Ok(Self::Key3),
|
||||
Linux::Key4 => Ok(Self::Key4),
|
||||
Linux::Key5 => Ok(Self::Key5),
|
||||
Linux::Key6 => Ok(Self::Key6),
|
||||
Linux::Key7 => Ok(Self::Key7),
|
||||
Linux::Key8 => Ok(Self::Key8),
|
||||
Linux::Key9 => Ok(Self::Key9),
|
||||
Linux::Key0 => Ok(Self::Key0),
|
||||
Linux::KeyMinus => Ok(Self::KeyMinus),
|
||||
Linux::KeyEqual => Ok(Self::KeyEqual),
|
||||
Linux::KeyBackspace => Ok(Self::KeyDelete),
|
||||
Linux::KeyTab => Ok(Self::KeyTab),
|
||||
Linux::KeyQ => Ok(Self::KeyQ),
|
||||
Linux::KeyW => Ok(Self::KeyW),
|
||||
Linux::KeyE => Ok(Self::KeyE),
|
||||
Linux::KeyR => Ok(Self::KeyR),
|
||||
Linux::KeyT => Ok(Self::KeyT),
|
||||
Linux::KeyY => Ok(Self::KeyY),
|
||||
Linux::KeyU => Ok(Self::KeyU),
|
||||
Linux::KeyI => Ok(Self::KeyI),
|
||||
Linux::KeyO => Ok(Self::KeyO),
|
||||
Linux::KeyP => Ok(Self::KeyP),
|
||||
Linux::KeyLeftbrace => Ok(Self::KeyLeftBrace),
|
||||
Linux::KeyRightbrace => Ok(Self::KeyRightBrace),
|
||||
Linux::KeyEnter => Ok(Self::KeyEnter),
|
||||
Linux::KeyLeftCtrl => Ok(Self::KeyLeftCtrl),
|
||||
Linux::KeyA => Ok(Self::KeyA),
|
||||
Linux::KeyS => Ok(Self::KeyS),
|
||||
Linux::KeyD => Ok(Self::KeyD),
|
||||
Linux::KeyF => Ok(Self::KeyF),
|
||||
Linux::KeyG => Ok(Self::KeyG),
|
||||
Linux::KeyH => Ok(Self::KeyH),
|
||||
Linux::KeyJ => Ok(Self::KeyJ),
|
||||
Linux::KeyK => Ok(Self::KeyK),
|
||||
Linux::KeyL => Ok(Self::KeyL),
|
||||
Linux::KeySemicolon => Ok(Self::KeySemiColon),
|
||||
Linux::KeyApostrophe => Ok(Self::KeyApostrophe),
|
||||
Linux::KeyGrave => Ok(Self::KeyGrave),
|
||||
Linux::KeyLeftShift => Ok(Self::KeyLeftShift),
|
||||
Linux::KeyBackslash => Ok(Self::KeyBackslash),
|
||||
Linux::KeyZ => Ok(Self::KeyZ),
|
||||
Linux::KeyX => Ok(Self::KeyX),
|
||||
Linux::KeyC => Ok(Self::KeyC),
|
||||
Linux::KeyV => Ok(Self::KeyV),
|
||||
Linux::KeyB => Ok(Self::KeyB),
|
||||
Linux::KeyN => Ok(Self::KeyN),
|
||||
Linux::KeyM => Ok(Self::KeyM),
|
||||
Linux::KeyComma => Ok(Self::KeyComma),
|
||||
Linux::KeyDot => Ok(Self::KeyDot),
|
||||
Linux::KeySlash => Ok(Self::KeySlash),
|
||||
Linux::KeyRightShift => Ok(Self::KeyRightShift),
|
||||
Linux::KeyKpAsterisk => Ok(Self::KeypadStar),
|
||||
Linux::KeyLeftAlt => Ok(Self::KeyLeftAlt),
|
||||
Linux::KeySpace => Ok(Self::KeySpace),
|
||||
Linux::KeyCapsLock => Ok(Self::KeyCapsLock),
|
||||
Linux::KeyF1 => Ok(Self::KeyF1),
|
||||
Linux::KeyF2 => Ok(Self::KeyF2),
|
||||
Linux::KeyF3 => Ok(Self::KeyF3),
|
||||
Linux::KeyF4 => Ok(Self::KeyF4),
|
||||
Linux::KeyF5 => Ok(Self::KeyF5),
|
||||
Linux::KeyF6 => Ok(Self::KeyF6),
|
||||
Linux::KeyF7 => Ok(Self::KeyF7),
|
||||
Linux::KeyF8 => Ok(Self::KeyF8),
|
||||
Linux::KeyF9 => Ok(Self::KeyF9),
|
||||
Linux::KeyF10 => Ok(Self::KeyF10),
|
||||
Linux::KeyNumlock => Ok(Self::KeypadNumLock),
|
||||
Linux::KeyScrollLock => Ok(Self::KeyScrollLock),
|
||||
Linux::KeyKp7 => Ok(Self::Keypad7Home),
|
||||
Linux::KeyKp8 => Ok(Self::Keypad8UpArrow),
|
||||
Linux::KeyKp9 => Ok(Self::Keypad9PageUp),
|
||||
Linux::KeyKpMinus => Ok(Self::KeypadDash),
|
||||
Linux::KeyKp4 => Ok(Self::Keypad4LeftArrow),
|
||||
Linux::KeyKp5 => Ok(Self::Keypad5),
|
||||
Linux::KeyKp6 => Ok(Self::Keypad6RightArrow),
|
||||
Linux::KeyKpplus => Ok(Self::KeypadPlus),
|
||||
Linux::KeyKp1 => Ok(Self::Keypad1End),
|
||||
Linux::KeyKp2 => Ok(Self::Keypad2DownArrow),
|
||||
Linux::KeyKp3 => Ok(Self::Keypad3PageDn),
|
||||
Linux::KeyKp0 => Ok(Self::Keypad0Insert),
|
||||
Linux::KeyKpDot => Ok(Self::KeypadDot),
|
||||
Linux::KeyZenkakuhankaku => Ok(Self::KeyF24), // KeyLANG5
|
||||
Linux::Key102nd => Ok(Self::KeyNonUSSlashBar), // TODO unsure
|
||||
Linux::KeyF11 => Ok(Self::KeyF11),
|
||||
Linux::KeyF12 => Ok(Self::KeyF12),
|
||||
Linux::KeyRo => Ok(Self::KeyInternational1),
|
||||
Linux::KeyKatakana => Ok(Self::KeyLANG3),
|
||||
Linux::KeyHiragana => Ok(Self::KeyLANG4),
|
||||
Linux::KeyHenkan => Ok(Self::KeyInternational4),
|
||||
Linux::KeyKatakanahiragana => Ok(Self::KeyInternational2),
|
||||
Linux::KeyMuhenkan => Ok(Self::KeyInternational5),
|
||||
Linux::KeyKpJpComma => Ok(Self::KeypadComma),
|
||||
Linux::KeyKpEnter => Ok(Self::KeypadEnter),
|
||||
Linux::KeyRightCtrl => Ok(Self::KeyRightCtrl),
|
||||
Linux::KeyKpslash => Ok(Self::KeypadSlash),
|
||||
Linux::KeySysrq => Ok(Self::KeyPrintScreen), // TODO Windows does not have Sysrq, right?
|
||||
Linux::KeyRightalt => Ok(Self::KeyRightAlt),
|
||||
Linux::KeyLinefeed => Ok(Self::KeyEnter), // TODO unsure
|
||||
Linux::KeyHome => Ok(Self::KeyHome),
|
||||
Linux::KeyUp => Ok(Self::KeyUp),
|
||||
Linux::KeyPageup => Ok(Self::KeyPageUp),
|
||||
Linux::KeyLeft => Ok(Self::KeyLeft),
|
||||
Linux::KeyRight => Ok(Self::KeyRight),
|
||||
Linux::KeyEnd => Ok(Self::KeyEnd),
|
||||
Linux::KeyDown => Ok(Self::KeyDown),
|
||||
Linux::KeyPagedown => Ok(Self::KeyPageDown),
|
||||
Linux::KeyInsert => Ok(Self::KeyInsert),
|
||||
Linux::KeyDelete => Ok(Self::KeyDeleteForward),
|
||||
Linux::KeyMacro => Err(()), // TODO
|
||||
Linux::KeyMute => Ok(Self::KeyMute),
|
||||
Linux::KeyVolumeDown => Ok(Self::KeyVolumeDown),
|
||||
Linux::KeyVolumeUp => Ok(Self::KeyVolumeUp),
|
||||
Linux::KeyPower => Ok(Self::Shutdown),
|
||||
Linux::KeyKpequal => Ok(Self::KeypadEquals),
|
||||
Linux::KeyKpplusminus => Ok(Self::KeypadPlus),
|
||||
Linux::KeyPause => Ok(Self::KeyPause),
|
||||
Linux::KeyScale => Err(()), // TODO
|
||||
Linux::KeyKpcomma => Ok(Self::KeypadComma),
|
||||
Linux::KeyHanguel => Ok(Self::KeyLANG1), // FIXME should be 00F2?
|
||||
Linux::KeyHanja => Ok(Self::KeyLANG2), // FIXME should be 00F1?
|
||||
Linux::KeyYen => Ok(Self::KeyInternational3),
|
||||
Linux::KeyLeftMeta => Ok(Self::KeyLeftGUI),
|
||||
Linux::KeyRightmeta => Ok(Self::KeyRightGUI),
|
||||
Linux::KeyCompose => Ok(Self::KeyApplication),
|
||||
Linux::KeyStop => Ok(Self::ACStop),
|
||||
Linux::KeyAgain => Err(()),
|
||||
Linux::KeyProps => Err(()),
|
||||
Linux::KeyUndo => Err(()),
|
||||
Linux::KeyFront => Err(()),
|
||||
Linux::KeyCopy => Err(()),
|
||||
Linux::KeyOpen => Err(()),
|
||||
Linux::KeyPaste => Err(()),
|
||||
Linux::KeyFind => Ok(Self::ACSearch),
|
||||
Linux::KeyCut => Err(()),
|
||||
Linux::KeyHelp => Ok(Self::KeyF1), // AL Integrated Help Center?
|
||||
Linux::KeyMenu => Ok(Self::KeyApplication),
|
||||
Linux::KeyCalc => Ok(Self::ALCalculator),
|
||||
Linux::KeySetup => Err(()),
|
||||
Linux::KeySleep => Ok(Self::SystemSleep),
|
||||
Linux::KeyWakeup => Ok(Self::SystemWakeUp),
|
||||
Linux::KeyFile => Ok(Self::ALLocalMachineBrowser),
|
||||
Linux::KeySendfile => Err(()),
|
||||
Linux::KeyDeletefile => Err(()),
|
||||
Linux::KeyXfer => Err(()),
|
||||
Linux::KeyProg1 => Err(()),
|
||||
Linux::KeyProg2 => Err(()),
|
||||
Linux::KeyWww => Ok(Self::ACSearch), // TODO unsure
|
||||
Linux::KeyMsdos => Err(()),
|
||||
Linux::KeyCoffee => Err(()),
|
||||
Linux::KeyRotateDisplay => Err(()),
|
||||
Linux::KeyCyclewindows => Err(()),
|
||||
Linux::KeyMail => Ok(Self::ALEmailReader),
|
||||
Linux::KeyBookmarks => Ok(Self::ACBookmarks),
|
||||
Linux::KeyComputer => Ok(Self::ACHome),
|
||||
Linux::KeyBack => Ok(Self::ACBack),
|
||||
Linux::KeyForward => Ok(Self::ACForward),
|
||||
Linux::KeyClosecd => Err(()),
|
||||
Linux::KeyEjectcd => Err(()),
|
||||
Linux::KeyEjectclosecd => Err(()),
|
||||
Linux::KeyNextsong => Ok(Self::KeyScanNextTrack),
|
||||
Linux::KeyPlaypause => Ok(Self::KeyPlayPause),
|
||||
Linux::KeyPrevioussong => Ok(Self::KeyScanPreviousTrack),
|
||||
Linux::KeyStopcd => Ok(Self::KeyStop),
|
||||
Linux::KeyRecord => Err(()),
|
||||
Linux::KeyRewind => Err(()),
|
||||
Linux::KeyPhone => Err(()),
|
||||
Linux::KeyIso => Err(()),
|
||||
Linux::KeyConfig => Err(()),
|
||||
Linux::KeyHomepage => Ok(Self::ACHome),
|
||||
Linux::KeyRefresh => Ok(Self::ACRefresh),
|
||||
Linux::KeyExit => Err(()),
|
||||
Linux::KeyMove => Err(()),
|
||||
Linux::KeyEdit => Err(()),
|
||||
Linux::KeyScrollup => Err(()),
|
||||
Linux::KeyScrolldown => Err(()),
|
||||
Linux::KeyKpleftparen => Err(()),
|
||||
Linux::KeyKprightparen => Err(()),
|
||||
Linux::KeyNew => Err(()),
|
||||
Linux::KeyRedo => Err(()),
|
||||
Linux::KeyF13 => Ok(Self::KeyF13),
|
||||
Linux::KeyF14 => Ok(Self::KeyF14),
|
||||
Linux::KeyF15 => Ok(Self::KeyF15),
|
||||
Linux::KeyF16 => Ok(Self::KeyF16),
|
||||
Linux::KeyF17 => Ok(Self::KeyF17),
|
||||
Linux::KeyF18 => Ok(Self::KeyF18),
|
||||
Linux::KeyF19 => Ok(Self::KeyF19),
|
||||
Linux::KeyF20 => Ok(Self::KeyF20),
|
||||
Linux::KeyF21 => Ok(Self::KeyF21),
|
||||
Linux::KeyF22 => Ok(Self::KeyF22),
|
||||
Linux::KeyF23 => Ok(Self::KeyF23),
|
||||
Linux::KeyF24 => Ok(Self::KeyF24),
|
||||
Linux::KeyPlaycd => Err(()),
|
||||
Linux::KeyPausecd => Err(()),
|
||||
Linux::KeyProg3 => Err(()),
|
||||
Linux::KeyProg4 => Err(()),
|
||||
Linux::KeyAllApplications => Err(()),
|
||||
Linux::KeySuspend => Err(()),
|
||||
Linux::KeyClose => Err(()),
|
||||
Linux::KeyPlay => Err(()),
|
||||
Linux::KeyFastforward => Err(()),
|
||||
Linux::KeyBassboost => Err(()),
|
||||
Linux::KeyPrint => Err(()),
|
||||
Linux::KeyHp => Err(()),
|
||||
Linux::KeyCamera => Err(()),
|
||||
Linux::KeySound => Err(()),
|
||||
Linux::KeyQuestion => Err(()),
|
||||
Linux::KeyEmail => Err(()),
|
||||
Linux::KeyChat => Err(()),
|
||||
Linux::KeySearch => Err(()),
|
||||
Linux::KeyConnect => Err(()),
|
||||
Linux::KeyFinance => Err(()),
|
||||
Linux::KeySport => Err(()),
|
||||
Linux::KeyShop => Err(()),
|
||||
Linux::KeyAlterase => Err(()),
|
||||
Linux::KeyCancel => Err(()),
|
||||
Linux::KeyBrightnessdown => Err(()),
|
||||
Linux::KeyBrightnessup => Err(()),
|
||||
Linux::KeyMedia => Err(()),
|
||||
Linux::KeySwitchvideomode => Err(()),
|
||||
Linux::KeyKbdillumtoggle => Err(()),
|
||||
Linux::KeyKbdillumdown => Err(()),
|
||||
Linux::KeyKbdillumup => Err(()),
|
||||
Linux::KeySend => Err(()),
|
||||
Linux::KeyReply => Err(()),
|
||||
Linux::KeyForwardmail => Err(()),
|
||||
Linux::KeySave => Err(()),
|
||||
Linux::KeyDocuments => Err(()),
|
||||
Linux::KeyBattery => Err(()),
|
||||
Linux::KeyBluetooth => Err(()),
|
||||
Linux::KeyWlan => Err(()),
|
||||
Linux::KeyUwb => Err(()),
|
||||
Linux::KeyUnknown => Err(()),
|
||||
Linux::KeyVideoNext => Err(()),
|
||||
Linux::KeyVideoPrev => Err(()),
|
||||
Linux::KeyBrightnessCycle => Err(()),
|
||||
Linux::KeyBrightnessAuto => Err(()),
|
||||
Linux::KeyDisplayOff => Err(()),
|
||||
Linux::KeyWwan => Err(()),
|
||||
Linux::KeyRfkill => Err(()),
|
||||
Linux::KeyMicmute => Err(()),
|
||||
Linux::KeyCount => Err(()),
|
||||
Linux::Invalid => Err(()),
|
||||
Linux::Invalid1 => Err(()),
|
||||
Linux::Invalid2 => Err(()),
|
||||
Linux::Invalid3 => Err(()),
|
||||
Linux::Invalid4 => Err(()),
|
||||
Linux::Invalid5 => Err(()),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl TryFrom<Windows> for Linux {
|
||||
type Error = ();
|
||||
|
||||
fn try_from(value: Windows) -> Result<Self, Self::Error> {
|
||||
match value {
|
||||
Windows::Shutdown => Ok(Self::KeyPower),
|
||||
Windows::SystemSleep => Ok(Self::KeySleep),
|
||||
Windows::SystemWakeUp => Ok(Self::KeyWakeup),
|
||||
Windows::ErrorRollOver => Ok(Self::KeyRo),
|
||||
Windows::KeyA => Ok(Self::KeyA),
|
||||
Windows::KeyB => Ok(Self::KeyB),
|
||||
Windows::KeyC => Ok(Self::KeyC),
|
||||
Windows::KeyD => Ok(Self::KeyD),
|
||||
Windows::KeyE => Ok(Self::KeyE),
|
||||
Windows::KeyF => Ok(Self::KeyF),
|
||||
Windows::KeyG => Ok(Self::KeyG),
|
||||
Windows::KeyH => Ok(Self::KeyH),
|
||||
Windows::KeyI => Ok(Self::KeyI),
|
||||
Windows::KeyJ => Ok(Self::KeyJ),
|
||||
Windows::KeyK => Ok(Self::KeyK),
|
||||
Windows::KeyL => Ok(Self::KeyL),
|
||||
Windows::KeyM => Ok(Self::KeyM),
|
||||
Windows::KeyN => Ok(Self::KeyN),
|
||||
Windows::KeyO => Ok(Self::KeyO),
|
||||
Windows::KeyP => Ok(Self::KeyP),
|
||||
Windows::KeyQ => Ok(Self::KeyQ),
|
||||
Windows::KeyR => Ok(Self::KeyR),
|
||||
Windows::KeyS => Ok(Self::KeyS),
|
||||
Windows::KeyT => Ok(Self::KeyT),
|
||||
Windows::KeyU => Ok(Self::KeyU),
|
||||
Windows::KeyV => Ok(Self::KeyV),
|
||||
Windows::KeyW => Ok(Self::KeyW),
|
||||
Windows::KeyX => Ok(Self::KeyX),
|
||||
Windows::KeyY => Ok(Self::KeyY),
|
||||
Windows::KeyZ => Ok(Self::KeyZ),
|
||||
Windows::Key1 => Ok(Self::Key1),
|
||||
Windows::Key2 => Ok(Self::Key2),
|
||||
Windows::Key3 => Ok(Self::Key3),
|
||||
Windows::Key4 => Ok(Self::Key4),
|
||||
Windows::Key5 => Ok(Self::Key5),
|
||||
Windows::Key6 => Ok(Self::Key6),
|
||||
Windows::Key7 => Ok(Self::Key7),
|
||||
Windows::Key8 => Ok(Self::Key8),
|
||||
Windows::Key9 => Ok(Self::Key9),
|
||||
Windows::Key0 => Ok(Self::Key0),
|
||||
Windows::KeyEnter => Ok(Self::KeyEnter),
|
||||
Windows::KeyEsc => Ok(Self::KeyEsc),
|
||||
Windows::KeyDelete => Ok(Self::KeyBackspace),
|
||||
Windows::KeyTab => Ok(Self::KeyTab),
|
||||
Windows::KeySpace => Ok(Self::KeySpace),
|
||||
Windows::KeyMinus => Ok(Self::KeyMinus),
|
||||
Windows::KeyEqual => Ok(Self::KeyEqual),
|
||||
Windows::KeyLeftBrace => Ok(Self::KeyLeftbrace),
|
||||
Windows::KeyRightBrace => Ok(Self::KeyRightbrace),
|
||||
Windows::KeyBackslash => Ok(Self::KeyBackslash),
|
||||
Windows::KeySemiColon => Ok(Self::KeySemicolon),
|
||||
Windows::KeyApostrophe => Ok(Self::KeyApostrophe),
|
||||
Windows::KeyGrave => Ok(Self::KeyGrave),
|
||||
Windows::KeyComma => Ok(Self::KeyComma),
|
||||
Windows::KeyDot => Ok(Self::KeyDot),
|
||||
Windows::KeySlash => Ok(Self::KeySlash),
|
||||
Windows::KeyCapsLock => Ok(Self::KeyCapsLock),
|
||||
Windows::KeyF1 => Ok(Self::KeyF1),
|
||||
Windows::KeyF2 => Ok(Self::KeyF2),
|
||||
Windows::KeyF3 => Ok(Self::KeyF3),
|
||||
Windows::KeyF4 => Ok(Self::KeyF4),
|
||||
Windows::KeyF5 => Ok(Self::KeyF5),
|
||||
Windows::KeyF6 => Ok(Self::KeyF6),
|
||||
Windows::KeyF7 => Ok(Self::KeyF7),
|
||||
Windows::KeyF8 => Ok(Self::KeyF8),
|
||||
Windows::KeyF9 => Ok(Self::KeyF9),
|
||||
Windows::KeyF10 => Ok(Self::KeyF10),
|
||||
Windows::KeyF11 => Ok(Self::KeyF11),
|
||||
Windows::KeyF12 => Ok(Self::KeyF12),
|
||||
Windows::KeyPrintScreen => Ok(Self::KeySysrq),
|
||||
Windows::KeyScrollLock => Ok(Self::KeyScrollLock),
|
||||
Windows::KeyPause => Ok(Self::KeyPause),
|
||||
Windows::KeyInsert => Ok(Self::KeyInsert),
|
||||
Windows::KeyHome => Ok(Self::KeyHome),
|
||||
Windows::KeyPageUp => Ok(Self::KeyPageup),
|
||||
Windows::KeyDeleteForward => Ok(Self::KeyDelete),
|
||||
Windows::KeyEnd => Ok(Self::KeyEnd),
|
||||
Windows::KeyPageDown => Ok(Self::KeyPagedown),
|
||||
Windows::KeyRight => Ok(Self::KeyRight),
|
||||
Windows::KeyLeft => Ok(Self::KeyLeft),
|
||||
Windows::KeyDown => Ok(Self::KeyDown),
|
||||
Windows::KeyUp => Ok(Self::KeyUp),
|
||||
Windows::KeypadNumLock => Ok(Self::KeyNumlock),
|
||||
Windows::KeypadSlash => Ok(Self::KeyKpslash),
|
||||
Windows::KeypadStar => Ok(Self::KeyKpAsterisk),
|
||||
Windows::KeypadDash => Ok(Self::KeyKpMinus),
|
||||
Windows::KeypadPlus => Ok(Self::KeyKpplus),
|
||||
Windows::KeypadEnter => Ok(Self::KeyKpEnter),
|
||||
Windows::Keypad1End => Ok(Self::KeyKp1),
|
||||
Windows::Keypad2DownArrow => Ok(Self::KeyKp2),
|
||||
Windows::Keypad3PageDn => Ok(Self::KeyKp3),
|
||||
Windows::Keypad4LeftArrow => Ok(Self::KeyKp4),
|
||||
Windows::Keypad5 => Ok(Self::KeyKp5),
|
||||
Windows::Keypad6RightArrow => Ok(Self::KeyKp6),
|
||||
Windows::Keypad7Home => Ok(Self::KeyKp7),
|
||||
Windows::Keypad8UpArrow => Ok(Self::KeyKp8),
|
||||
Windows::Keypad9PageUp => Ok(Self::KeyKp9),
|
||||
Windows::Keypad0Insert => Ok(Self::KeyKp0),
|
||||
Windows::KeypadDot => Ok(Self::KeyKpDot),
|
||||
Windows::KeyNonUSSlashBar => Ok(Self::Key102nd),
|
||||
Windows::KeyApplication => Ok(Self::KeyMenu),
|
||||
Windows::KeypadEquals => Ok(Self::KeyKpequal),
|
||||
Windows::KeyF13 => Ok(Self::KeyF13),
|
||||
Windows::KeyF14 => Ok(Self::KeyF14),
|
||||
Windows::KeyF15 => Ok(Self::KeyF15),
|
||||
Windows::KeyF16 => Ok(Self::KeyF16),
|
||||
Windows::KeyF17 => Ok(Self::KeyF17),
|
||||
Windows::KeyF18 => Ok(Self::KeyF18),
|
||||
Windows::KeyF19 => Ok(Self::KeyF19),
|
||||
Windows::KeyF20 => Ok(Self::KeyF20),
|
||||
Windows::KeyF21 => Ok(Self::KeyF21),
|
||||
Windows::KeyF22 => Ok(Self::KeyF22),
|
||||
Windows::KeyF23 => Ok(Self::KeyF23),
|
||||
Windows::KeyF24 => Ok(Self::KeyF24),
|
||||
Windows::KeypadComma => Ok(Self::KeyKpcomma),
|
||||
Windows::KeyInternational1 => Ok(Self::KeyRo),
|
||||
Windows::KeyInternational2 => Ok(Self::KeyKatakanahiragana),
|
||||
Windows::KeyInternational3 => Ok(Self::KeyYen),
|
||||
Windows::KeyInternational4 => Ok(Self::KeyHenkan),
|
||||
Windows::KeyInternational5 => Ok(Self::KeyMuhenkan),
|
||||
Windows::KeyLANG1 => Ok(Self::KeyHanguel),
|
||||
Windows::KeyLANG2 => Ok(Self::KeyHanja),
|
||||
Windows::KeyLANG3 => Ok(Self::KeyKatakana),
|
||||
Windows::KeyLANG4 => Ok(Self::KeyHiragana),
|
||||
Windows::KeyLeftCtrl => Ok(Self::KeyLeftCtrl),
|
||||
Windows::KeyLeftShift => Ok(Self::KeyLeftShift),
|
||||
Windows::KeyLeftAlt => Ok(Self::KeyLeftAlt),
|
||||
Windows::KeyLeftGUI => Ok(Self::KeyLeftMeta),
|
||||
Windows::KeyRightCtrl => Ok(Self::KeyRightCtrl),
|
||||
Windows::KeyRightShift => Ok(Self::KeyRightShift),
|
||||
Windows::KeyFakeRightShift => Ok(Self::KeyRightShift),
|
||||
Windows::KeyRightAlt => Ok(Self::KeyRightalt),
|
||||
Windows::KeyRightGUI => Ok(Self::KeyRightmeta),
|
||||
Windows::KeyScanNextTrack => Ok(Self::KeyNextsong),
|
||||
Windows::KeyScanPreviousTrack => Ok(Self::KeyPrevioussong),
|
||||
Windows::KeyStop => Ok(Self::KeyStopcd),
|
||||
Windows::KeyPlayPause => Ok(Self::KeyPlaypause),
|
||||
Windows::KeyMute => Ok(Self::KeyMute),
|
||||
Windows::KeyVolumeUp => Ok(Self::KeyVolumeUp),
|
||||
Windows::KeyVolumeDown => Ok(Self::KeyVolumeDown),
|
||||
Windows::ALConsumerControlConfiguration => Err(()),
|
||||
Windows::ALEmailReader => Ok(Self::KeyMail),
|
||||
Windows::ALCalculator => Ok(Self::KeyCalc),
|
||||
Windows::ALLocalMachineBrowser => Ok(Self::KeyFile),
|
||||
Windows::ACSearch => Ok(Self::KeyWww),
|
||||
Windows::ACHome => Ok(Self::KeyHomepage),
|
||||
Windows::ACBack => Ok(Self::KeyBack),
|
||||
Windows::ACForward => Ok(Self::KeyForward),
|
||||
Windows::ACStop => Ok(Self::KeyStop),
|
||||
Windows::ACRefresh => Ok(Self::KeyRefresh),
|
||||
Windows::ACBookmarks => Ok(Self::KeyBookmarks),
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user