Improve evdev detect implementation
This commit is contained in:
parent
1d6b152c15
commit
2f04f174b7
|
@ -1,2 +1,3 @@
|
||||||
This is a great starting point for wayland support:
|
This module is used to detect keyboard and mouse input using EVDEV layer, which is necessary on Wayland.
|
||||||
|
The module started as a port of this xkbcommon example
|
||||||
https://github.com/xkbcommon/libxkbcommon/blob/master/tools/interactive-evdev.c
|
https://github.com/xkbcommon/libxkbcommon/blob/master/tools/interactive-evdev.c
|
|
@ -9,7 +9,6 @@ use std::os::unix::io::AsRawFd;
|
||||||
use std::{
|
use std::{
|
||||||
ffi::{c_void, CStr},
|
ffi::{c_void, CStr},
|
||||||
fs::OpenOptions,
|
fs::OpenOptions,
|
||||||
mem::zeroed,
|
|
||||||
};
|
};
|
||||||
use std::{fs::File, os::unix::fs::OpenOptionsExt};
|
use std::{fs::File, os::unix::fs::OpenOptionsExt};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
@ -31,19 +30,19 @@ const KEY_STATE_REPEAT: i32 = 2;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum RawInputEvent {
|
pub enum RawInputEvent {
|
||||||
Keyboard(KeyboardEvent),
|
Keyboard(RawKeyboardEvent),
|
||||||
Mouse(MouseEvent),
|
Mouse(RawMouseEvent),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct KeyboardEvent {
|
pub struct RawKeyboardEvent {
|
||||||
pub sym: u32,
|
pub sym: u32,
|
||||||
pub value: String,
|
pub value: String,
|
||||||
pub is_down: bool,
|
pub is_down: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct MouseEvent {
|
pub struct RawMouseEvent {
|
||||||
pub code: u16,
|
pub code: u16,
|
||||||
pub is_down: bool,
|
pub is_down: bool,
|
||||||
}
|
}
|
||||||
|
@ -143,7 +142,7 @@ impl Device {
|
||||||
// Check if the current event originated from a mouse
|
// Check if the current event originated from a mouse
|
||||||
if code >= 0x110 && code <= 0x117 {
|
if code >= 0x110 && code <= 0x117 {
|
||||||
// Mouse event
|
// Mouse event
|
||||||
return Some(RawInputEvent::Mouse(MouseEvent { code, is_down }));
|
return Some(RawInputEvent::Mouse(RawMouseEvent { code, is_down }));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keyboard event
|
// Keyboard event
|
||||||
|
@ -173,7 +172,7 @@ impl Device {
|
||||||
let content_raw = unsafe { CStr::from_ptr(buffer.as_ptr() as *mut i8) };
|
let content_raw = unsafe { CStr::from_ptr(buffer.as_ptr() as *mut i8) };
|
||||||
let content = content_raw.to_string_lossy().to_string();
|
let content = content_raw.to_string_lossy().to_string();
|
||||||
|
|
||||||
let event = KeyboardEvent {
|
let event = RawKeyboardEvent {
|
||||||
is_down,
|
is_down,
|
||||||
sym,
|
sym,
|
||||||
value: content,
|
value: content,
|
||||||
|
|
|
@ -250,35 +250,21 @@ fn raw_to_mouse_button(raw: u16) -> Option<MouseButton> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* TODO convert tests
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::ffi::CString;
|
use device::RawMouseEvent;
|
||||||
|
|
||||||
use super::*;
|
use crate::event::{InputEvent, KeyboardEvent, Key::Other};
|
||||||
|
|
||||||
fn default_raw_input_event() -> RawInputEvent {
|
use super::{*, device::{RawInputEvent, RawKeyboardEvent}};
|
||||||
RawInputEvent {
|
|
||||||
event_type: INPUT_EVENT_TYPE_KEYBOARD,
|
|
||||||
buffer: [0; 24],
|
|
||||||
buffer_len: 0,
|
|
||||||
key_code: 0,
|
|
||||||
key_sym: 0,
|
|
||||||
status: INPUT_STATUS_PRESSED,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_to_input_event_keyboard_works_correctly() {
|
fn raw_to_input_event_keyboard_works_correctly() {
|
||||||
let c_string = CString::new("k".to_string()).unwrap();
|
let raw = RawInputEvent::Keyboard(RawKeyboardEvent {
|
||||||
let mut buffer: [u8; 24] = [0; 24];
|
sym: 0x4B,
|
||||||
buffer[..1].copy_from_slice(c_string.as_bytes());
|
value: "k".to_owned(),
|
||||||
|
is_down: false,
|
||||||
let mut raw = default_raw_input_event();
|
});
|
||||||
raw.buffer = buffer;
|
|
||||||
raw.buffer_len = 1;
|
|
||||||
raw.status = INPUT_STATUS_RELEASED;
|
|
||||||
raw.key_sym = 0x4B;
|
|
||||||
|
|
||||||
let result: Option<InputEvent> = raw.into();
|
let result: Option<InputEvent> = raw.into();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -294,10 +280,10 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn raw_to_input_event_mouse_works_correctly() {
|
fn raw_to_input_event_mouse_works_correctly() {
|
||||||
let mut raw = default_raw_input_event();
|
let raw = RawInputEvent::Mouse(RawMouseEvent {
|
||||||
raw.event_type = INPUT_EVENT_TYPE_MOUSE;
|
code: BTN_RIGHT,
|
||||||
raw.status = INPUT_STATUS_RELEASED;
|
is_down: false,
|
||||||
raw.key_code = INPUT_MOUSE_RIGHT_BUTTON;
|
});
|
||||||
|
|
||||||
let result: Option<InputEvent> = raw.into();
|
let result: Option<InputEvent> = raw.into();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
@ -308,26 +294,4 @@ mod tests {
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#[test]
|
|
||||||
fn raw_to_input_invalid_buffer() {
|
|
||||||
let buffer: [u8; 24] = [123; 24];
|
|
||||||
|
|
||||||
let mut raw = default_raw_input_event();
|
|
||||||
raw.buffer = buffer;
|
|
||||||
raw.buffer_len = 5;
|
|
||||||
|
|
||||||
let result: Option<InputEvent> = raw.into();
|
|
||||||
assert!(result.unwrap().into_keyboard().unwrap().value.is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn raw_to_input_event_returns_none_when_missing_type() {
|
|
||||||
let mut raw = default_raw_input_event();
|
|
||||||
raw.event_type = 0;
|
|
||||||
let result: Option<InputEvent> = raw.into();
|
|
||||||
assert!(result.is_none());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
Loading…
Reference in New Issue
Block a user