Switch to bitvec (#30)
This commit is contained in:
parent
98183712f9
commit
a55f319854
3 changed files with 29 additions and 42 deletions
|
@ -11,7 +11,7 @@ edition = "2018"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bitflags = "1.2"
|
bitflags = "1.2"
|
||||||
libc = "0.2.22"
|
libc = "0.2.22"
|
||||||
fixedbitset = "0.3.2"
|
bitvec = "0.21"
|
||||||
num-derive = "0.3.3"
|
num-derive = "0.3.3"
|
||||||
num-traits = { version = "0.2", default-features = false }
|
num-traits = { version = "0.2", default-features = false }
|
||||||
nix = "0.19.0"
|
nix = "0.19.0"
|
||||||
|
|
|
@ -185,7 +185,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Switch {
|
impl Switch {
|
||||||
pub(crate) const MAX: usize = 0xf;
|
pub(crate) const MAX: usize = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
@ -210,7 +210,7 @@ bitflags! {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Led {
|
impl Led {
|
||||||
pub(crate) const MAX: usize = 0x0f;
|
pub(crate) const MAX: usize = 0x10;
|
||||||
}
|
}
|
||||||
|
|
||||||
bitflags! {
|
bitflags! {
|
||||||
|
|
65
src/lib.rs
65
src/lib.rs
|
@ -38,7 +38,7 @@ mod constants;
|
||||||
pub mod raw;
|
pub mod raw;
|
||||||
mod scancodes;
|
mod scancodes;
|
||||||
|
|
||||||
use fixedbitset::FixedBitSet;
|
use bitvec::prelude::*;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::fs::OpenOptions;
|
use std::fs::OpenOptions;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
@ -57,6 +57,8 @@ pub use crate::Synchronization::*;
|
||||||
pub use crate::constants::*;
|
pub use crate::constants::*;
|
||||||
use crate::raw::*;
|
use crate::raw::*;
|
||||||
|
|
||||||
|
type ByteBitBox = BitBox<Lsb0, u8>;
|
||||||
|
|
||||||
fn ioctl_get_cstring(
|
fn ioctl_get_cstring(
|
||||||
f: unsafe fn(RawFd, &mut [u8]) -> nix::Result<libc::c_int>,
|
f: unsafe fn(RawFd, &mut [u8]) -> nix::Result<libc::c_int>,
|
||||||
fd: RawFd,
|
fd: RawFd,
|
||||||
|
@ -129,12 +131,12 @@ pub struct DeviceState {
|
||||||
/// The state corresponds to kernel state at this timestamp.
|
/// The state corresponds to kernel state at this timestamp.
|
||||||
pub timestamp: libc::timeval,
|
pub timestamp: libc::timeval,
|
||||||
/// Set = key pressed
|
/// Set = key pressed
|
||||||
pub key_vals: Option<FixedBitSet>,
|
pub key_vals: Option<ByteBitBox>,
|
||||||
pub abs_vals: Option<Vec<input_absinfo>>,
|
pub abs_vals: Option<Vec<input_absinfo>>,
|
||||||
/// Set = switch enabled (closed)
|
/// Set = switch enabled (closed)
|
||||||
pub switch_vals: Option<FixedBitSet>,
|
pub switch_vals: Option<ByteBitBox>,
|
||||||
/// Set = LED lit
|
/// Set = LED lit
|
||||||
pub led_vals: Option<FixedBitSet>,
|
pub led_vals: Option<ByteBitBox>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DeviceState {
|
impl Default for DeviceState {
|
||||||
|
@ -171,13 +173,13 @@ pub struct Device {
|
||||||
id: input_id,
|
id: input_id,
|
||||||
props: Props,
|
props: Props,
|
||||||
driver_version: (u8, u8, u8),
|
driver_version: (u8, u8, u8),
|
||||||
supported_keys: Option<FixedBitSet>,
|
supported_keys: Option<ByteBitBox>,
|
||||||
supported_relative: Option<RelativeAxis>,
|
supported_relative: Option<RelativeAxis>,
|
||||||
supported_absolute: Option<AbsoluteAxis>,
|
supported_absolute: Option<AbsoluteAxis>,
|
||||||
supported_switch: Option<Switch>,
|
supported_switch: Option<Switch>,
|
||||||
supported_led: Option<Led>,
|
supported_led: Option<Led>,
|
||||||
supported_misc: Option<Misc>,
|
supported_misc: Option<Misc>,
|
||||||
// ff: Option<FixedBitSet>,
|
// ff: Option<ByteBitBox>,
|
||||||
// ff_stat: Option<FFStatus>,
|
// ff_stat: Option<FFStatus>,
|
||||||
// rep: Option<Repeat>,
|
// rep: Option<Repeat>,
|
||||||
supported_snd: Option<Sound>,
|
supported_snd: Option<Sound>,
|
||||||
|
@ -242,17 +244,15 @@ impl std::fmt::Display for Device {
|
||||||
if let (Some(supported_keys), Some(key_vals)) = (&self.supported_keys, &self.state.key_vals)
|
if let (Some(supported_keys), Some(key_vals)) = (&self.supported_keys, &self.state.key_vals)
|
||||||
{
|
{
|
||||||
writeln!(f, " Keys supported:")?;
|
writeln!(f, " Keys supported:")?;
|
||||||
for key_idx in 0..supported_keys.len() {
|
for (key_idx, (key_supported, key_enabled)) in
|
||||||
if supported_keys.contains(key_idx) {
|
supported_keys.iter().zip(key_vals.iter()).enumerate()
|
||||||
|
{
|
||||||
|
if *key_supported {
|
||||||
writeln!(
|
writeln!(
|
||||||
f,
|
f,
|
||||||
" {:?} ({}index {})",
|
" {:?} ({}index {})",
|
||||||
Key::new(key_idx as u32),
|
Key::new(key_idx as u32),
|
||||||
if key_vals.contains(key_idx) {
|
if *key_enabled { "pressed, " } else { "" },
|
||||||
"pressed, "
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
},
|
|
||||||
key_idx
|
key_idx
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
@ -354,8 +354,8 @@ impl Device {
|
||||||
self.driver_version
|
self.driver_version
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn keys_supported(&self) -> &Option<FixedBitSet> {
|
pub fn keys_supported(&self) -> Option<&BitSlice<Lsb0, u8>> {
|
||||||
&self.supported_keys
|
self.supported_keys.as_deref()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn relative_axes_supported(&self) -> Option<RelativeAxis> {
|
pub fn relative_axes_supported(&self) -> Option<RelativeAxis> {
|
||||||
|
@ -441,15 +441,14 @@ impl Device {
|
||||||
let mut state = DeviceState::default();
|
let mut state = DeviceState::default();
|
||||||
|
|
||||||
let supported_keys = if ty.contains(Types::KEY) {
|
let supported_keys = if ty.contains(Types::KEY) {
|
||||||
let mut supported_keys = FixedBitSet::with_capacity(Key::MAX);
|
let mut supported_keys = bitbox![_, _; 0; Key::MAX];
|
||||||
debug_assert!(supported_keys.len() % 8 == 0);
|
debug_assert!(supported_keys.len() % 8 == 0);
|
||||||
let key_slice = supported_keys.as_mut_slice();
|
let key_slice = supported_keys.as_mut_slice();
|
||||||
unsafe {
|
unsafe {
|
||||||
let (_, supported_keys_as_u8_slice, _) = key_slice.align_to_mut();
|
debug_assert!(key_slice.len() == Key::MAX / 8);
|
||||||
debug_assert!(supported_keys_as_u8_slice.len() == Key::MAX / 8);
|
eviocgbit_key(file.as_raw_fd(), key_slice)?;
|
||||||
eviocgbit_key(file.as_raw_fd(), supported_keys_as_u8_slice)?;
|
|
||||||
}
|
}
|
||||||
let key_vals = FixedBitSet::with_capacity(Key::MAX);
|
let key_vals = bitbox![_, _; 0; Key::MAX];
|
||||||
debug_assert!(key_vals.len() % 8 == 0);
|
debug_assert!(key_vals.len() % 8 == 0);
|
||||||
state.key_vals = Some(key_vals);
|
state.key_vals = Some(key_vals);
|
||||||
|
|
||||||
|
@ -478,7 +477,7 @@ impl Device {
|
||||||
let supported_switch = if ty.contains(Types::SWITCH) {
|
let supported_switch = if ty.contains(Types::SWITCH) {
|
||||||
let mut switch = 0;
|
let mut switch = 0;
|
||||||
unsafe { eviocgbit_switch(file.as_raw_fd(), &mut switch)? };
|
unsafe { eviocgbit_switch(file.as_raw_fd(), &mut switch)? };
|
||||||
state.switch_vals = Some(FixedBitSet::with_capacity(0x10));
|
state.switch_vals = Some(bitbox![_, _; 0; Switch::MAX]);
|
||||||
|
|
||||||
Some(Switch::from_bits(switch).expect("evdev: unexpected switch bits! report a bug"))
|
Some(Switch::from_bits(switch).expect("evdev: unexpected switch bits! report a bug"))
|
||||||
} else {
|
} else {
|
||||||
|
@ -488,7 +487,7 @@ impl Device {
|
||||||
let supported_led = if ty.contains(Types::LED) {
|
let supported_led = if ty.contains(Types::LED) {
|
||||||
let mut led = 0;
|
let mut led = 0;
|
||||||
unsafe { eviocgbit_led(file.as_raw_fd(), &mut led)? };
|
unsafe { eviocgbit_led(file.as_raw_fd(), &mut led)? };
|
||||||
let led_vals = FixedBitSet::with_capacity(0x10);
|
let led_vals = bitbox![_, _; 0; Led::MAX];
|
||||||
debug_assert!(led_vals.len() % 8 == 0);
|
debug_assert!(led_vals.len() % 8 == 0);
|
||||||
state.led_vals = Some(led_vals);
|
state.led_vals = Some(led_vals);
|
||||||
|
|
||||||
|
@ -547,11 +546,7 @@ impl Device {
|
||||||
pub fn sync_state(&mut self) -> Result<(), Error> {
|
pub fn sync_state(&mut self) -> Result<(), Error> {
|
||||||
let fd = self.as_raw_fd();
|
let fd = self.as_raw_fd();
|
||||||
if let Some(key_vals) = &mut self.state.key_vals {
|
if let Some(key_vals) = &mut self.state.key_vals {
|
||||||
unsafe {
|
unsafe { eviocgkey(fd, key_vals.as_mut_slice())? };
|
||||||
let key_slice = key_vals.as_mut_slice();
|
|
||||||
let (_, key_vals_as_u8_slice, _) = key_slice.align_to_mut();
|
|
||||||
eviocgkey(fd, key_vals_as_u8_slice)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let (Some(supported_abs), Some(abs_vals)) =
|
if let (Some(supported_abs), Some(abs_vals)) =
|
||||||
|
@ -572,19 +567,11 @@ impl Device {
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(switch_vals) = &mut self.state.switch_vals {
|
if let Some(switch_vals) = &mut self.state.switch_vals {
|
||||||
unsafe {
|
unsafe { eviocgsw(fd, switch_vals.as_mut_slice())? };
|
||||||
let switch_slice = switch_vals.as_mut_slice();
|
|
||||||
let (_, switch_vals_as_u8_slice, _) = switch_slice.align_to_mut();
|
|
||||||
eviocgsw(fd, switch_vals_as_u8_slice)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(led_vals) = &mut self.state.led_vals {
|
if let Some(led_vals) = &mut self.state.led_vals {
|
||||||
unsafe {
|
unsafe { eviocgled(fd, led_vals.as_mut_slice())? };
|
||||||
let led_slice = led_vals.as_mut_slice();
|
|
||||||
let (_, led_vals_as_u8_slice, _) = led_slice.align_to_mut();
|
|
||||||
eviocgled(fd, led_vals_as_u8_slice)?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -627,8 +614,8 @@ impl Device {
|
||||||
|
|
||||||
if let (Some(supported_keys), Some(key_vals)) = (&self.supported_keys, &self.state.key_vals)
|
if let (Some(supported_keys), Some(key_vals)) = (&self.supported_keys, &self.state.key_vals)
|
||||||
{
|
{
|
||||||
for key_idx in 0..supported_keys.len() {
|
for (key_idx, key_supported) in supported_keys.iter().enumerate() {
|
||||||
if supported_keys.contains(key_idx)
|
if *key_supported
|
||||||
&& old_state.key_vals.as_ref().map(|v| v[key_idx]) != Some(key_vals[key_idx])
|
&& old_state.key_vals.as_ref().map(|v| v[key_idx]) != Some(key_vals[key_idx])
|
||||||
{
|
{
|
||||||
self.pending_events.push(raw::input_event {
|
self.pending_events.push(raw::input_event {
|
||||||
|
|
Loading…
Reference in a new issue