Added analog stick remapping to keys

This commit is contained in:
cyber-sushi 2024-04-10 09:37:39 +02:00
parent c83b70a91a
commit c838c55af2
2 changed files with 186 additions and 82 deletions

View file

@ -88,23 +88,45 @@ impl Config {
modifiers.axis.insert(modmap, map.clone());
}
let mut pad_horizontal: Vec<Key> = bindings.axis.get("BTN_DPAD_LEFT")
let mut pad_x: Vec<Key> = bindings.axis.get("BTN_DPAD_LEFT")
.unwrap_or(&Vec::new()).clone();
pad_horizontal.extend(bindings.axis.get("BTN_DPAD_RIGHT")
pad_x.extend(bindings.axis.get("BTN_DPAD_RIGHT")
.unwrap_or(&Vec::new()));
let mut pad_vertical: Vec<Key> = bindings.axis.get("BTN_DPAD_UP")
let mut pad_y: Vec<Key> = bindings.axis.get("BTN_DPAD_UP")
.unwrap_or(&Vec::new()).clone();
pad_vertical.extend(bindings.axis.get("BTN_DPAD_DOWN")
pad_y.extend(bindings.axis.get("BTN_DPAD_DOWN")
.unwrap_or(&Vec::new()));
bindings.axis.insert("NONE_X".to_string(), pad_horizontal);
bindings.axis.insert("NONE_Y".to_string(), pad_vertical);
bindings.axis.insert("NONE_X".to_string(), pad_x);
bindings.axis.insert("NONE_Y".to_string(), pad_y);
let mut lstick_x: Vec<Key> = bindings.axis.get("LSTICK_LEFT")
.unwrap_or(&Vec::new()).clone();
lstick_x.extend(bindings.axis.get("LSTICK_RIGHT")
.unwrap_or(&Vec::new()));
let mut lstick_y: Vec<Key> = bindings.axis.get("LSTICK_UP")
.unwrap_or(&Vec::new()).clone();
lstick_y.extend(bindings.axis.get("LSTICK_DOWN")
.unwrap_or(&Vec::new()));
bindings.axis.insert("LSTICK_X".to_string(), lstick_x);
bindings.axis.insert("LSTICK_Y".to_string(), lstick_y);
let mut rstick_x: Vec<Key> = bindings.axis.get("RSTICK_LEFT")
.unwrap_or(&Vec::new()).clone();
rstick_x.extend(bindings.axis.get("RSTICK_RIGHT")
.unwrap_or(&Vec::new()));
let mut rstick_y: Vec<Key> = bindings.axis.get("RSTICK_UP")
.unwrap_or(&Vec::new()).clone();
rstick_y.extend(bindings.axis.get("RSTICK_DOWN")
.unwrap_or(&Vec::new()));
bindings.axis.insert("RSTICK_X".to_string(), rstick_x);
bindings.axis.insert("RSTICK_Y".to_string(), rstick_y);
Self {
name: file_name,
bindings: bindings,
combinations: combinations,
modifiers: modifiers,
settings: settings,
bindings,
combinations,
modifiers,
settings,
}
}
}

View file

@ -6,21 +6,25 @@ use crate::virtual_devices::VirtualDevices;
use crate::Config;
use crate::active_client::*;
struct Settings {
cursor_analog_mode: String,
scroll_analog_mode: String,
cursor_sensitivity: u64,
scroll_sensitivity: u64,
has_signed_axis_value: bool,
struct Stick {
function: String,
sensitivity: u64,
deadzone: i32,
}
struct Settings {
lstick: Stick,
rstick: Stick,
axis_16_bit: bool,
}
pub struct EventReader {
config: HashMap<String, Config>,
stream: Arc<Mutex<EventStream>>,
virt_dev: Arc<Mutex<VirtualDevices>>,
cursor_analog_position: Arc<Mutex<Vec<i32>>>,
scroll_analog_position: Arc<Mutex<Vec<i32>>>,
lstick_position: Arc<Mutex<Vec<i32>>>,
rstick_position: Arc<Mutex<Vec<i32>>>,
modifiers: Arc<Mutex<BTreeMap<Key, i32>>>,
device_is_connected: Arc<Mutex<bool>>,
current_desktop: Option<String>,
@ -36,40 +40,53 @@ impl EventReader {
) -> Self {
let mut position_vector: Vec<i32> = Vec::new();
for i in [0, 0] {position_vector.push(i)};
let cursor_position_vector_mutex = Arc::new(Mutex::new(position_vector.clone()));
let scroll_position_vector_mutex = Arc::new(Mutex::new(position_vector.clone()));
let lstick_position = Arc::new(Mutex::new(position_vector.clone()));
let rstick_position = Arc::new(Mutex::new(position_vector.clone()));
let device_is_connected: Arc<Mutex<bool>> = Arc::new(Mutex::new(true));
let virt_dev = Arc::new(Mutex::new(VirtualDevices::new()));
let cursor_analog_mode: String = config.get(&"default".to_string()).unwrap()
.settings.get("CURSOR_STICK").unwrap_or(&"left".to_string()).to_string();
let scroll_analog_mode: String = config.get(&"default".to_string()).unwrap()
.settings.get("SCROLL_STICK").unwrap_or(&"right".to_string()).to_string();
let cursor_sensitivity: u64 = config.get(&"default".to_string()).unwrap()
.settings.get("CURSOR_SENSITIVITY").unwrap_or(&"0".to_string()).parse::<u64>().expect("Invalid cursor sensitivity.");
let scroll_sensitivity: u64 = config.get(&"default".to_string()).unwrap()
.settings.get("SCROLL_SENSITIVITY").unwrap_or(&"0".to_string()).parse::<u64>().expect("Invalid scroll sensitivity.");
let has_signed_axis_value: bool = config.get(&"default".to_string()).unwrap()
.settings.get("SIGNED_AXIS_VALUE").unwrap_or(&"false".to_string()).parse().expect("SIGNED_AXIS_VALUE can only be true or false.");
let deadzone: i32 = config.get(&"default".to_string()).unwrap()
.settings.get("DEADZONE").unwrap_or(&"5".to_string()).parse::<i32>().expect("Invalid value for DEADZONE, please use an integer between 0 and 128.");
let lstick_function = config.get(&"default".to_string()).unwrap()
.settings.get("LSTICK").unwrap_or(&"cursor".to_string()).to_string();
let lstick_sensitivity: u64 = config.get(&"default".to_string()).unwrap()
.settings.get("LSTICK_SENSITIVITY").unwrap_or(&"0".to_string()).parse::<u64>().expect("Invalid value for LSTICK_SENSITIVITY, please use an integer value >= 0");
let lstick_deadzone: i32 = config.get(&"default".to_string()).unwrap()
.settings.get("LSTICK_DEADZONE").unwrap_or(&"5".to_string()).parse::<i32>().expect("Invalid value for LSTICK_DEADZONE, please use an integer between 0 and 128.");
let lstick = Stick {
function: lstick_function,
sensitivity: lstick_sensitivity,
deadzone: lstick_deadzone,
};
let rstick_function: String = config.get(&"default".to_string()).unwrap()
.settings.get("RSTICK").unwrap_or(&"scroll".to_string()).to_string();
let rstick_sensitivity: u64 = config.get(&"default".to_string()).unwrap()
.settings.get("RSTICK_SENSITIVITY").unwrap_or(&"0".to_string()).parse::<u64>().expect("Invalid value for RSTICK_SENSITIVITY, please use an integer value >= 0");
let rstick_deadzone: i32 = config.get(&"default".to_string()).unwrap()
.settings.get("RSTICK_DEADZONE").unwrap_or(&"5".to_string()).parse::<i32>().expect("Invalid value for RSTICK_DEADZONE, please use an integer between 0 and 128.");
let rstick = Stick {
function: rstick_function,
sensitivity: rstick_sensitivity,
deadzone: rstick_deadzone,
};
let axis_16_bit: bool = config.get(&"default".to_string()).unwrap()
.settings.get("16_BIT_AXIS").unwrap_or(&"false".to_string()).parse().expect("16_BIT_AXIS can only be true or false.");
let settings = Settings {
cursor_analog_mode: cursor_analog_mode,
scroll_analog_mode: scroll_analog_mode,
cursor_sensitivity: cursor_sensitivity,
scroll_sensitivity: scroll_sensitivity,
has_signed_axis_value: has_signed_axis_value,
deadzone: deadzone,
lstick,
rstick,
axis_16_bit,
};
Self {
config: config,
stream: stream,
virt_dev: virt_dev,
cursor_analog_position: cursor_position_vector_mutex,
scroll_analog_position: scroll_position_vector_mutex,
modifiers: modifiers,
device_is_connected: device_is_connected,
current_desktop: current_desktop,
settings: settings,
config,
stream,
virt_dev,
lstick_position,
rstick_position,
modifiers,
device_is_connected,
current_desktop,
settings,
}
}
@ -102,41 +119,79 @@ impl EventReader {
(_, _, AbsoluteAxisType::ABS_HAT0X) => {
let event_string: String = match event.value() {
-1 => "BTN_DPAD_LEFT".to_string(),
0 => "NONE_X".to_string(),
0 => "BTN_DPAD_X".to_string(),
1 => "BTN_DPAD_RIGHT".to_string(),
_ => "NONE_X".to_string(),
_ => "BTN_DPAD_X".to_string(),
};
self.convert_axis_events(event, &event_string, false, false).await;
},
(_, _, AbsoluteAxisType::ABS_HAT0Y) => {
let event_string: String = match event.value() {
-1 => "BTN_DPAD_UP".to_string(),
0 => "NONE_Y".to_string(),
0 => "BTN_DPAD_Y".to_string(),
1 => "BTN_DPAD_DOWN".to_string(),
_ => "NONE_Y".to_string(),
_ => "BTN_DPAD_Y".to_string(),
};
self.convert_axis_events(event, &event_string, false, false).await;
},
(EventType::ABSOLUTE, _, AbsoluteAxisType::ABS_X | AbsoluteAxisType::ABS_Y) => {
if self.settings.cursor_analog_mode == "left".to_string() {
let axis_value = self.get_axis_value(&event).await;
let mut cursor_analog_position = self.cursor_analog_position.lock().await;
cursor_analog_position[event.code() as usize] = axis_value;
} else if self.settings.scroll_analog_mode == "left".to_string() {
let axis_value = self.get_axis_value(&event).await;
let mut scroll_analog_position = self.scroll_analog_position.lock().await;
scroll_analog_position[event.code() as usize] = axis_value;
if ["cursor", "scroll"].contains(&self.settings.lstick.function.as_str()) {
let axis_value = self.get_axis_value(&event, &self.settings.lstick.deadzone).await;
let mut lstick_position = self.lstick_position.lock().await;
lstick_position[event.code() as usize] = axis_value;
} else if self.settings.lstick.function.as_str() == "bind" {
let axis_value = self.get_axis_value(&event, &self.settings.lstick.deadzone).await;
let clamped_value = if axis_value < 0 { -1 }
else if axis_value > 0 { 1 }
else { 0 };
let axis = if AbsoluteAxisType(event.code()) == AbsoluteAxisType::ABS_X { "x" }
else if AbsoluteAxisType(event.code()) == AbsoluteAxisType::ABS_Y { "y" }
else { "none" };
let event_string_option: Option<String> = match clamped_value {
-1 if axis == "x" => Option::Some("LSTICK_LEFT".to_string()),
-1 if axis == "y" => Option::Some("LSTICK_UP".to_string()),
0 if axis == "x" => Option::Some("LSTICK_X".to_string()),
0 if axis == "y" => Option::Some("LSTICK_Y".to_string()),
1 if axis == "x" => Option::Some("LSTICK_RIGHT".to_string()),
1 if axis == "y" => Option::Some("LSTICK_DOWN".to_string()),
_ => Option::None,
};
if let Some(event_string) = event_string_option {
let clamped_event = InputEvent::new_now(event.event_type(), event.code(), clamped_value);
self.convert_axis_events(clamped_event, &event_string, false, false).await;
}
} else {
self.emit_default_event(event).await;
}
},
(EventType::ABSOLUTE, _, AbsoluteAxisType::ABS_RX | AbsoluteAxisType::ABS_RY) => {
if self.settings.cursor_analog_mode == "right".to_string() {
let axis_value = self.get_axis_value(&event).await;
let mut cursor_analog_position = self.cursor_analog_position.lock().await;
cursor_analog_position[event.code() as usize -3] = axis_value;
} else if self.settings.scroll_analog_mode == "right".to_string() {
let axis_value = self.get_axis_value(&event).await;
let mut scroll_analog_position = self.scroll_analog_position.lock().await;
scroll_analog_position[event.code() as usize -3] = axis_value;
if ["cursor", "scroll"].contains(&self.settings.rstick.function.as_str()) {
let axis_value = self.get_axis_value(&event, &self.settings.rstick.deadzone).await;
let mut rstick_position = self.rstick_position.lock().await;
rstick_position[event.code() as usize -3] = axis_value;
} else if self.settings.rstick.function.as_str() == "bind" {
let axis_value = self.get_axis_value(&event, &self.settings.rstick.deadzone).await;
let clamped_value = if axis_value < 0 { -1 }
else if axis_value > 0 { 1 }
else { 0 };
let axis = if AbsoluteAxisType(event.code()) == AbsoluteAxisType::ABS_RX { "x" }
else if AbsoluteAxisType(event.code()) == AbsoluteAxisType::ABS_RY { "y" }
else { "none" };
let event_string_option: Option<String> = match clamped_value {
-1 if axis == "x" => Option::Some("RSTICK_LEFT".to_string()),
-1 if axis == "y" => Option::Some("RSTICK_UP".to_string()),
0 if axis == "x" => Option::Some("RSTICK_X".to_string()),
0 if axis == "y" => Option::Some("RSTICK_Y".to_string()),
1 if axis == "x" => Option::Some("RSTICK_RIGHT".to_string()),
1 if axis == "y" => Option::Some("RSTICK_DOWN".to_string()),
_ => Option::None,
};
if let Some(event_string) = event_string_option {
let clamped_event = InputEvent::new_now(event.event_type(), event.code(), clamped_value);
self.convert_axis_events(clamped_event, &event_string, false, false).await;
}
} else {
self.emit_default_event(event).await;
}
},
(EventType::ABSOLUTE, _, AbsoluteAxisType::ABS_Z) => {
@ -189,6 +244,7 @@ impl EventReader {
}
}
if let Some(event_list) = path.bindings.axis.get(event_string) {
println!("{:?}", event_list);
self.emit_event(event_list, value).await;
if send_zero {
self.emit_event_without_modifiers(event_list, &modifiers, 0).await;
@ -250,12 +306,12 @@ impl EventReader {
}
}
async fn get_axis_value(&self, event: &InputEvent) -> i32 {
let distance_from_center: i32 = match self.settings.has_signed_axis_value {
async fn get_axis_value(&self, event: &InputEvent, deadzone: &i32) -> i32 {
let distance_from_center: i32 = match self.settings.axis_16_bit {
false => (event.value() as i32 - 128) * 200,
_ => event.value() as i32
};
if distance_from_center.abs() <= self.settings.deadzone * 200 {
if distance_from_center.abs() <= deadzone * 200 {
0
} else {
(distance_from_center + 2000 - 1) / 2000
@ -282,19 +338,32 @@ impl EventReader {
}
pub async fn cursor_loop(&self) {
if self.settings.cursor_sensitivity != 0 {
let (cursor, sensitivity) = if self.settings.lstick.function.as_str() == "cursor" {
("left", self.settings.lstick.sensitivity)
} else if self.settings.rstick.function.as_str() == "cursor" {
("right", self.settings.rstick.sensitivity)
} else {
("disabled", 0)
};
if sensitivity != 0 {
while *self.device_is_connected.lock().await {
{
let cursor_analog_position = self.cursor_analog_position.lock().await;
if cursor_analog_position[0] != 0 || cursor_analog_position[1] != 0 {
let virtual_event_x: InputEvent = InputEvent::new_now(EventType::RELATIVE, 0, cursor_analog_position[0]);
let virtual_event_y: InputEvent = InputEvent::new_now(EventType::RELATIVE, 1, cursor_analog_position[1]);
let stick_position = if cursor == "left" {
self.lstick_position.lock().await
} else if cursor == "right" {
self.rstick_position.lock().await
} else {
break
};
if stick_position[0] != 0 || stick_position[1] != 0 {
let virtual_event_x: InputEvent = InputEvent::new_now(EventType::RELATIVE, 0, stick_position[0]);
let virtual_event_y: InputEvent = InputEvent::new_now(EventType::RELATIVE, 1, stick_position[1]);
let mut virt_dev = self.virt_dev.lock().await;
virt_dev.axis.emit(&[virtual_event_x]).unwrap();
virt_dev.axis.emit(&[virtual_event_y]).unwrap();
}
}
tokio::time::sleep(std::time::Duration::from_millis(self.settings.cursor_sensitivity)).await;
tokio::time::sleep(std::time::Duration::from_millis(sensitivity)).await;
}
} else {
return
@ -302,19 +371,32 @@ impl EventReader {
}
pub async fn scroll_loop(&self) {
if self.settings.scroll_sensitivity != 0 {
let (scroll, sensitivity) = if self.settings.lstick.function.as_str() == "scroll" {
("left", self.settings.lstick.sensitivity)
} else if self.settings.rstick.function.as_str() == "scroll" {
("right", self.settings.rstick.sensitivity)
} else {
("disabled", 0)
};
if sensitivity != 0 {
while *self.device_is_connected.lock().await {
{
let scroll_analog_position = self.scroll_analog_position.lock().await;
if scroll_analog_position[0] != 0 || scroll_analog_position[1] != 0 {
let virtual_event_x: InputEvent = InputEvent::new_now(EventType::RELATIVE, 12, scroll_analog_position[0]);
let virtual_event_y: InputEvent = InputEvent::new_now(EventType::RELATIVE, 11, scroll_analog_position[1]);
let stick_position = if scroll == "left" {
self.lstick_position.lock().await
} else if scroll == "right" {
self.rstick_position.lock().await
} else {
break
};
if stick_position[0] != 0 || stick_position[1] != 0 {
let virtual_event_x: InputEvent = InputEvent::new_now(EventType::RELATIVE, 12, stick_position[0]);
let virtual_event_y: InputEvent = InputEvent::new_now(EventType::RELATIVE, 11, stick_position[1]);
let mut virt_dev = self.virt_dev.lock().await;
virt_dev.axis.emit(&[virtual_event_x]).unwrap();
virt_dev.axis.emit(&[virtual_event_y]).unwrap();
}
}
tokio::time::sleep(std::time::Duration::from_millis(self.settings.scroll_sensitivity)).await;
tokio::time::sleep(std::time::Duration::from_millis(sensitivity)).await;
}
} else {
return