Properly understand keys pressed and unpressed
This commit is contained in:
@@ -60,7 +60,7 @@ impl WlClient {
|
|||||||
|
|
||||||
let mut keymap_fd = self.keymap_fd.lock().unwrap();
|
let mut keymap_fd = self.keymap_fd.lock().unwrap();
|
||||||
*keymap_fd = Some(shm::ShmPool::from_fd(fd, size as usize)?);
|
*keymap_fd = Some(shm::ShmPool::from_fd(fd, size as usize)?);
|
||||||
let mut keymap = self.keymap.lock().unwrap();
|
let mut keymap = self.keymap.write().unwrap();
|
||||||
*keymap = xkb::gen_id_keysym_mapping(keymap_fd.as_ref().unwrap());
|
*keymap = xkb::gen_id_keysym_mapping(keymap_fd.as_ref().unwrap());
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -73,12 +73,12 @@ impl WlClient {
|
|||||||
let key = event.read_u32(&mut offset);
|
let key = event.read_u32(&mut offset);
|
||||||
let state = event.read_u32(&mut offset);
|
let state = event.read_u32(&mut offset);
|
||||||
|
|
||||||
if let Some(keymap) = &*self.keymap.lock().unwrap() {
|
if let Some(keymap) = &*self.keymap.read().unwrap() {
|
||||||
if let Some(keysym) = keymap.get(&(key + 8)) {
|
if let Some(keysym) = keymap.get(&(key + 8)) {
|
||||||
if keysym == "ESC" && state == 0 {
|
if keysym[0] == "Escape" && state == 0 {
|
||||||
self.exit();
|
self.exit();
|
||||||
}
|
}
|
||||||
println!("Received key:\n\t{} {}", keysym, if state == 0 {'↑'} else {'↓'});
|
println!("Received key:\n\t{} {}", keysym[0], if state == 0 {'↑'} else {'↓'});
|
||||||
} else {
|
} else {
|
||||||
eprintln!("Unrecognized key!");
|
eprintln!("Unrecognized key!");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use std::{collections::HashMap, env::var, error::Error, fmt::Debug, io::{IoSliceMut, Write}, os::unix::net::{AncillaryData, SocketAncillary, UnixStream}, sync::{atomic::{AtomicU32, AtomicBool, Ordering}, mpsc, Arc, Mutex}, thread::{self}, time::Duration, u32};
|
use std::{collections::HashMap, env::var, error::Error, fmt::Debug, io::{IoSliceMut, Write}, os::unix::net::{AncillaryData, SocketAncillary, UnixStream}, sync::{atomic::{AtomicBool, AtomicU32, Ordering}, mpsc, Arc, Mutex, RwLock}, thread::{self}, time::Duration, u32};
|
||||||
|
|
||||||
use crate::wayland::{shm, vec_utils::WlMessage};
|
use crate::wayland::{shm, vec_utils::WlMessage};
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ pub struct WlClient {
|
|||||||
pub seat_id: AtomicU32,
|
pub seat_id: AtomicU32,
|
||||||
pub keyboard_id: AtomicU32,
|
pub keyboard_id: AtomicU32,
|
||||||
pub keymap_fd: Mutex<Option<shm::ShmPool>>,
|
pub keymap_fd: Mutex<Option<shm::ShmPool>>,
|
||||||
pub keymap: Mutex<Option<HashMap<u32, String>>>
|
pub keymap: RwLock<Option<HashMap<u32, Vec<String>>>>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WlClient {
|
impl WlClient {
|
||||||
@@ -62,7 +62,7 @@ impl WlClient {
|
|||||||
layer_surface_id: AtomicU32::from(0),
|
layer_surface_id: AtomicU32::from(0),
|
||||||
seat_id: AtomicU32::from(0),
|
seat_id: AtomicU32::from(0),
|
||||||
keyboard_id: AtomicU32::from(0),
|
keyboard_id: AtomicU32::from(0),
|
||||||
keymap: Mutex::new(None),
|
keymap: RwLock::new(None),
|
||||||
keymap_fd: Mutex::new(None),
|
keymap_fd: Mutex::new(None),
|
||||||
});
|
});
|
||||||
arc_wl_client.wl_display_get_registry();
|
arc_wl_client.wl_display_get_registry();
|
||||||
|
|||||||
@@ -16,11 +16,11 @@ impl WlClient {
|
|||||||
let current_id = self.current_id.fetch_add(1, Ordering::Relaxed) + 1;
|
let current_id = self.current_id.fetch_add(1, Ordering::Relaxed) + 1;
|
||||||
self.shmpool_id.store(current_id, Ordering::Relaxed);
|
self.shmpool_id.store(current_id, Ordering::Relaxed);
|
||||||
|
|
||||||
shm_pool.write(&vec![0xffff0000; width * height], 0);
|
// shm_pool.write(&vec![0xffff0000; width * height], 0);
|
||||||
let rect = Rectangle::new(100, 100, 200, 50, 25, 0xffffff);
|
let rect = Rectangle::new(100, 100, 200, 50, 20, 0xffffff);
|
||||||
rect.draw(&mut shm_pool);
|
rect.draw(&mut shm_pool);
|
||||||
let circle = Circle::new(250, 150, 20, 0xff00ffff);
|
// let circle = Circle::new(250, 150, 20, 0xff00ffff);
|
||||||
circle.draw(&mut shm_pool);
|
// circle.draw(&mut shm_pool);
|
||||||
|
|
||||||
let object = self.shm_id.load(Ordering::Relaxed);
|
let object = self.shm_id.load(Ordering::Relaxed);
|
||||||
if object == 0 {
|
if object == 0 {
|
||||||
|
|||||||
@@ -1,115 +1,167 @@
|
|||||||
use core::str;
|
use core::str;
|
||||||
use std::{collections::HashMap, string};
|
use std::{collections::HashMap, fmt::{Debug, Display}, string::{self, ParseError}};
|
||||||
|
|
||||||
use super::shm::ShmPool;
|
use super::shm::ShmPool;
|
||||||
|
|
||||||
#[derive(Debug)]
|
enum Data<'a> {
|
||||||
enum ParseMode {
|
Block(&'a str, Vec<Data<'a>>),
|
||||||
Default,
|
Statement(&'a str),
|
||||||
Outer,
|
|
||||||
Inner,
|
|
||||||
Min,
|
|
||||||
Max,
|
|
||||||
Keysym,
|
|
||||||
Keycode,
|
|
||||||
}
|
}
|
||||||
use ParseMode::*;
|
impl Debug for Data<'_> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
Block(header, data) => write!(f, "Block({}, {:#?})", header, data),
|
||||||
|
Statement(str) => write!(f, "Statement({})", str),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
use Data::*;
|
||||||
|
|
||||||
pub fn gen_id_keysym_mapping(xkb_map: &ShmPool) -> Option<HashMap<u32, String>> {
|
fn parse_block(map: &str) -> Vec<Data> {
|
||||||
let mut word = String::new();
|
let mut begin = 0;
|
||||||
let mut keycodes: bool = false;
|
let mut stack = 0;
|
||||||
|
let mut is_statement = true;
|
||||||
let mut parse_mode = ParseMode::Default;
|
let mut datas = Vec::new();
|
||||||
|
for (i, byte) in map.bytes().enumerate() {
|
||||||
let mut max = 0;
|
if stack == 0 {
|
||||||
let mut min = 0;
|
if byte == '{' as u8 {
|
||||||
|
datas.push(Block(
|
||||||
let mut keycode: String = String::new();
|
map.get(begin..i).unwrap(),
|
||||||
let mut keysym: String = String::new();
|
parse_block(map.get(i+1..).unwrap())
|
||||||
|
));
|
||||||
let mut res: HashMap<u32, String> = HashMap::new();
|
is_statement = false;
|
||||||
|
}
|
||||||
// TODO: Make this not a nightmare if else tree
|
else if byte == '}' as u8 {
|
||||||
for ch in unsafe {str::from_raw_parts(xkb_map.addr as *mut u8, xkb_map.size)}.chars() {
|
return datas;
|
||||||
match parse_mode {
|
}
|
||||||
Default => {
|
else if byte == ';' as u8 || byte == ',' as u8 || byte == ']' as u8 {
|
||||||
if ch.is_whitespace() {
|
if is_statement {
|
||||||
word.clear();
|
datas.push(Statement(map.get(begin..i).unwrap()));
|
||||||
} else {
|
} else {
|
||||||
word.push(ch);
|
is_statement = true;
|
||||||
}
|
|
||||||
if word == "xkb_keycodes" {
|
|
||||||
parse_mode = Outer;
|
|
||||||
}
|
}
|
||||||
|
begin = i+1;
|
||||||
}
|
}
|
||||||
Outer => {
|
else if byte == '[' as u8 {
|
||||||
if ch == '{' {
|
begin = i+1;
|
||||||
parse_mode = Inner;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Inner => {
|
}
|
||||||
if ch.is_whitespace() {
|
|
||||||
word.clear();
|
|
||||||
} else {
|
|
||||||
word.push(ch);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ch == '}' {
|
if byte == '{' as u8 {
|
||||||
break;
|
stack += 1;
|
||||||
} else if ch == '<' {
|
}
|
||||||
parse_mode = Keysym;
|
else if byte == '}' as u8 {
|
||||||
} else if ch == '=' {
|
stack -= 1;
|
||||||
parse_mode = Keycode;
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
if word == "minimum" {
|
datas
|
||||||
parse_mode = Min;
|
}
|
||||||
}
|
|
||||||
else if word == "maximum" {
|
fn xkb_symbols(xkb_map: &Data) -> Result<HashMap<String, Vec<String>>, ()> {
|
||||||
parse_mode = Max;
|
let mut map_symbols: Option<&Vec<Data>> = None;
|
||||||
}
|
if let Block(header, subdata) = xkb_map {
|
||||||
}
|
if header.find("xkb_keymap").is_some() {
|
||||||
Min => {
|
for subdata in subdata {
|
||||||
if ch == ';' {
|
if let Block(header, subdata) = subdata {
|
||||||
min = u32::from_str_radix(keycode.as_str(), 10).unwrap();
|
if header.find("xkb_symbols").is_some() {
|
||||||
keycode.clear();
|
map_symbols = Some(&subdata);
|
||||||
parse_mode = Inner;
|
|
||||||
} else if ch.is_digit(10) {
|
|
||||||
keycode.push(ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Max => {
|
|
||||||
if ch == ';' {
|
|
||||||
max = u32::from_str_radix(keycode.as_str(), 10).unwrap();
|
|
||||||
keycode.clear();
|
|
||||||
parse_mode = Inner;
|
|
||||||
} else if ch.is_digit(10) {
|
|
||||||
keycode.push(ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Keysym => {
|
|
||||||
if ch == '>' {
|
|
||||||
parse_mode = Inner;
|
|
||||||
} else {
|
|
||||||
keysym.push(ch);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Keycode => {
|
|
||||||
if ch == ';' {
|
|
||||||
let code = u32::from_str_radix(keycode.as_str(), 10).unwrap();
|
|
||||||
res.insert(code, keysym.clone());
|
|
||||||
if u32::from_str_radix(keycode.as_str(), 10).unwrap() >= max {
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
keycode.clear();
|
|
||||||
keysym.clear();
|
|
||||||
parse_mode = Inner;
|
|
||||||
} else if ch.is_digit(10) {
|
|
||||||
keycode.push(ch);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let map_symbols: &Vec<Data> = map_symbols.ok_or(())?;
|
||||||
|
let mut res = HashMap::new();
|
||||||
|
for map_symbols in map_symbols {
|
||||||
|
if let Block(header, map_symbols) = map_symbols {
|
||||||
|
if header.find("key").is_some() {
|
||||||
|
let keysym = header.get(
|
||||||
|
header.find('<').ok_or(())?+1..
|
||||||
|
header.find('>').ok_or(())?
|
||||||
|
).ok_or(())?.to_string();
|
||||||
|
let mut symbols = Vec::new();
|
||||||
|
for map_symbol in map_symbols {
|
||||||
|
if let Statement(map_symbol) = &map_symbol {
|
||||||
|
let mut symbol = String::new();
|
||||||
|
for ch in map_symbol.chars() {
|
||||||
|
if !ch.is_whitespace() {
|
||||||
|
symbol.push(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
symbols.push(symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.insert(keysym, symbols);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn first_non_whitespace(s: &str) -> Option<char> {
|
||||||
|
for ch in s.chars() {
|
||||||
|
if !ch.is_whitespace() {
|
||||||
|
return Some(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn xkb_keycodes(xkb_map: &Data) -> Result<HashMap<u32, String>, ()> {
|
||||||
|
let mut keycodes: Option<&Vec<Data>> = None;
|
||||||
|
if let Block(header, subdata) = xkb_map {
|
||||||
|
if header.find("xkb_keymap").is_some() {
|
||||||
|
for subdata in subdata {
|
||||||
|
if let Block(header, subdata) = subdata {
|
||||||
|
if header.find("xkb_keycodes").is_some() {
|
||||||
|
keycodes = Some(&subdata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut res = HashMap::new();
|
||||||
|
let keycodes = keycodes.ok_or(())?;
|
||||||
|
for map_keycode in keycodes {
|
||||||
|
if let Statement(map_keycode) = map_keycode {
|
||||||
|
if Some('<') != first_non_whitespace(map_keycode) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let keysym = map_keycode.get(
|
||||||
|
map_keycode.find('<').ok_or(())?+1..
|
||||||
|
map_keycode.find('>').ok_or(())?
|
||||||
|
).ok_or(())?;
|
||||||
|
let mut keycode = String::new();
|
||||||
|
for ch in map_keycode.get(map_keycode.find('=').ok_or(())?..).ok_or(())?.chars() {
|
||||||
|
if ch.is_digit(10) {
|
||||||
|
keycode.push(ch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let keycode: u32 = keycode.parse().or(Err(()))?;
|
||||||
|
res.insert(keycode, keysym.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gen_id_keysym_mapping(xkb_map: &ShmPool) -> Option<HashMap<u32, Vec<String>>> {
|
||||||
|
let xkb_map = unsafe {str::from_raw_parts(xkb_map.addr as *const u8, xkb_map.size)};
|
||||||
|
let mut res = HashMap::new();
|
||||||
|
let data = parse_block(xkb_map);
|
||||||
|
let mut symbols = xkb_symbols(&data[0]).ok()?;
|
||||||
|
let keycodes = xkb_keycodes(&data[0]).ok()?;
|
||||||
|
for keycode in keycodes {
|
||||||
|
let symbol = symbols.remove(&keycode.1);
|
||||||
|
if let Some(symbol) = symbol {
|
||||||
|
res.insert(keycode.0, symbol);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Some(res)
|
Some(res)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user