Get keyboard events from window manager IPC instead of syscalls, fix ipc
read memory leak, remove debug prints in request_window, add kill syscall, update SHM base, add window title arg
This commit is contained in:
parent
7f9192f4e8
commit
04e87c6099
6 changed files with 85 additions and 286 deletions
|
|
@ -9,7 +9,7 @@ typedef struct Window {
|
|||
uint64_t shm_id;
|
||||
} Window;
|
||||
|
||||
Window request_window(size_t width, size_t height);
|
||||
Window request_window(size_t width, size_t height, const char* title);
|
||||
|
||||
int draw_buffer_to_window(
|
||||
const uint32_t* buffer,
|
||||
|
|
|
|||
286
src/io/input.rs
286
src/io/input.rs
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{
|
||||
print,
|
||||
syscall::{INPUT_READ, syscall2},
|
||||
};
|
||||
use alloc::{format, vec::Vec};
|
||||
|
||||
use crate::{getpid, io::ipc::read_port_rust};
|
||||
|
||||
pub const KEY_RESERVED: u8 = 0;
|
||||
pub const KEY_ESC: u8 = 1;
|
||||
|
|
@ -93,175 +92,6 @@ pub const KEY_LEFT: u8 = 105;
|
|||
pub const KEY_RIGHT: u8 = 106;
|
||||
pub const KEY_DOWN: u8 = 108;
|
||||
|
||||
pub struct Mouse {
|
||||
pub left_button_pressed: bool,
|
||||
pub right_button_pressed: bool,
|
||||
pub middle_button_pressed: bool,
|
||||
pub x_delta: i16,
|
||||
pub y_delta: i16,
|
||||
}
|
||||
|
||||
impl Mouse {
|
||||
const fn new() -> Mouse {
|
||||
Mouse {
|
||||
left_button_pressed: false,
|
||||
right_button_pressed: false,
|
||||
middle_button_pressed: false,
|
||||
x_delta: 0,
|
||||
y_delta: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn button_state(&self) -> (bool, bool, bool) {
|
||||
(
|
||||
self.left_button_pressed,
|
||||
self.right_button_pressed,
|
||||
self.middle_button_pressed,
|
||||
)
|
||||
}
|
||||
pub fn take_motion(&mut self) -> (i16, i16) {
|
||||
let old_x_delta = self.x_delta.clone();
|
||||
let old_y_delta = self.y_delta.clone();
|
||||
self.x_delta = 0;
|
||||
self.y_delta = 0;
|
||||
(old_x_delta, old_y_delta)
|
||||
}
|
||||
}
|
||||
|
||||
pub const KEY_TO_CHAR: [Option<(char, char)>; 84] = [
|
||||
None, // 0 KEY_RESERVED
|
||||
Some(('\x1b', '\x1b')), // 1 KEY_ESC
|
||||
Some(('1', '!')), // 2 KEY_1
|
||||
Some(('2', '@')), // 3 KEY_2
|
||||
Some(('3', '#')), // 4 KEY_3
|
||||
Some(('4', '$')), // 5 KEY_4
|
||||
Some(('5', '%')), // 6 KEY_5
|
||||
Some(('6', '^')), // 7 KEY_6
|
||||
Some(('7', '&')), // 8 KEY_7
|
||||
Some(('8', '*')), // 9 KEY_8
|
||||
Some(('9', '(')), // 10 KEY_9
|
||||
Some(('0', ')')), // 11 KEY_0
|
||||
Some(('-', '_')), // 12 KEY_MINUS
|
||||
Some(('=', '+')), // 13 KEY_EQUAL
|
||||
Some(('\x08', '\x08')), // 14 KEY_BACKSPACE
|
||||
Some(('\t', '\t')), // 15 KEY_TAB
|
||||
Some(('q', 'Q')), // 16 KEY_Q
|
||||
Some(('w', 'W')), // 17 KEY_W
|
||||
Some(('e', 'E')), // 18 KEY_E
|
||||
Some(('r', 'R')), // 19 KEY_R
|
||||
Some(('t', 'T')), // 20 KEY_T
|
||||
Some(('y', 'Y')), // 21 KEY_Y
|
||||
Some(('u', 'U')), // 22 KEY_U
|
||||
Some(('i', 'I')), // 23 KEY_I
|
||||
Some(('o', 'O')), // 24 KEY_O
|
||||
Some(('p', 'P')), // 25 KEY_P
|
||||
Some(('[', '{')), // 26 KEY_LEFTBRACE
|
||||
Some((']', '}')), // 27 KEY_RIGHTBRACE
|
||||
Some(('\n', '\n')), // 28 KEY_ENTER
|
||||
None, // 29 KEY_LEFTCTRL
|
||||
Some(('a', 'A')), // 30 KEY_A
|
||||
Some(('s', 'S')), // 31 KEY_S
|
||||
Some(('d', 'D')), // 32 KEY_D
|
||||
Some(('f', 'F')), // 33 KEY_F
|
||||
Some(('g', 'G')), // 34 KEY_G
|
||||
Some(('h', 'H')), // 35 KEY_H
|
||||
Some(('j', 'J')), // 36 KEY_J
|
||||
Some(('k', 'K')), // 37 KEY_K
|
||||
Some(('l', 'L')), // 38 KEY_L
|
||||
Some((';', ':')), // 39 KEY_SEMICOLON
|
||||
Some(('\'', '"')), // 40 KEY_APOSTROPHE
|
||||
Some(('`', '~')), // 41 KEY_GRAVE
|
||||
None, // 42 KEY_LEFTSHIFT
|
||||
Some(('\\', '|')), // 43 KEY_BACKSLASH
|
||||
Some(('z', 'Z')), // 44 KEY_Z
|
||||
Some(('x', 'X')), // 45 KEY_X
|
||||
Some(('c', 'C')), // 46 KEY_C
|
||||
Some(('v', 'V')), // 47 KEY_V
|
||||
Some(('b', 'B')), // 48 KEY_B
|
||||
Some(('n', 'N')), // 49 KEY_N
|
||||
Some(('m', 'M')), // 50 KEY_M
|
||||
Some((',', '<')), // 51 KEY_COMMA
|
||||
Some(('.', '>')), // 52 KEY_DOT
|
||||
Some(('/', '?')), // 53 KEY_SLASH
|
||||
None, // 54 KEY_RIGHTSHIFT
|
||||
Some(('*', '*')), // 55 KEY_KPASTERISK
|
||||
None, // 56 KEY_LEFTALT
|
||||
Some((' ', ' ')), // 57 KEY_SPACE
|
||||
None, // 58 KEY_CAPSLOCK
|
||||
None, // 59 KEY_F1
|
||||
None, // 60 KEY_F2
|
||||
None, // 61 KEY_F3
|
||||
None, // 62 KEY_F4
|
||||
None, // 63 KEY_F5
|
||||
None, // 64 KEY_F6
|
||||
None, // 65 KEY_F7
|
||||
None, // 66 KEY_F8
|
||||
None, // 67 KEY_F9
|
||||
None, // 68 KEY_F10
|
||||
None, // 69 KEY_NUMLOCK
|
||||
None, // 70 KEY_SCROLLLOCK
|
||||
Some(('7', '7')), // 71 KEY_KP7
|
||||
Some(('8', '8')), // 72 KEY_KP8
|
||||
Some(('9', '9')), // 73 KEY_KP9
|
||||
Some(('-', '-')), // 74 KEY_KPMINUS
|
||||
Some(('4', '4')), // 75 KEY_KP4
|
||||
Some(('5', '5')), // 76 KEY_KP5
|
||||
Some(('6', '6')), // 77 KEY_KP6
|
||||
Some((('+'), '+')), // 78 KEY_KPPLUS
|
||||
Some(('1', '1')), // 79 KEY_KP1
|
||||
Some(('2', '2')), // 80 KEY_KP2
|
||||
Some(('3', '3')), // 81 KEY_KP3
|
||||
Some(('0', '0')), // 82 KEY_KP0
|
||||
Some(('.', '.')), // 83 KEY_KPDOT
|
||||
];
|
||||
|
||||
pub struct ModState {
|
||||
shift: bool,
|
||||
caps_lock: bool,
|
||||
ctrl: bool,
|
||||
alt: bool,
|
||||
}
|
||||
|
||||
impl ModState {
|
||||
pub const fn new() -> Self {
|
||||
Self {
|
||||
shift: false,
|
||||
caps_lock: false,
|
||||
ctrl: false,
|
||||
alt: false,
|
||||
}
|
||||
}
|
||||
pub fn update(&mut self, code: u8, value: u32) {
|
||||
match code {
|
||||
KEY_LEFTSHIFT | KEY_RIGHTSHIFT => self.shift = value != 0,
|
||||
KEY_LEFTCTRL => self.ctrl = value != 0,
|
||||
KEY_CAPSLOCK => self.caps_lock = value != 0,
|
||||
KEY_LEFTALT => self.alt = value != 0,
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn effective_shift(&self) -> bool {
|
||||
self.shift ^ self.caps_lock
|
||||
}
|
||||
}
|
||||
|
||||
pub fn keycode_to_char(keycode: u8, shift: bool) -> Option<char> {
|
||||
let entry = KEY_TO_CHAR.get(keycode as usize)?.as_ref()?;
|
||||
Some(if shift { entry.1 } else { entry.0 })
|
||||
}
|
||||
|
||||
pub static mut MODIFIERS: ModState = ModState::new();
|
||||
pub static mut MOUSE: Mouse = Mouse::new();
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct InputEvent {
|
||||
pub event_type: u16,
|
||||
pub code: u16,
|
||||
pub value: u32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Debug, Copy, Default)]
|
||||
pub struct KeyboardEvent {
|
||||
|
|
@ -273,93 +103,49 @@ pub struct KeyboardEvent {
|
|||
pub unicode: u32,
|
||||
}
|
||||
|
||||
pub const EVENT_KEY: u16 = 0x01;
|
||||
pub const EVENT_REL: u16 = 0x02;
|
||||
pub fn input_read(kbd_buf: *mut KeyboardEvent, _n: u8) -> usize {
|
||||
let mut event_n = 0;
|
||||
|
||||
pub const BTN_LEFT: u16 = 0x110;
|
||||
pub const BTN_RIGHT: u16 = 0x111;
|
||||
pub const BTN_MIDDLE: u16 = 0x112;
|
||||
if let Some((_, message)) = read_port_rust(format!("wm_priv_{}", getpid()), 1) {
|
||||
let args: Vec<&str> = message.split_whitespace().collect();
|
||||
let mut args_n = 0;
|
||||
|
||||
pub const REL_X: u16 = 0x00;
|
||||
pub const REL_Y: u16 = 0x01;
|
||||
pub const REL_WHEEL: u16 = 0x08;
|
||||
while args_n < args.len() {
|
||||
match args[args_n] {
|
||||
"kbd" => {
|
||||
if args_n + 4 < args.len() {
|
||||
let key = args[args_n + 1].parse::<u16>().unwrap_or(0);
|
||||
let mods = args[args_n + 2].parse::<u16>().unwrap_or(0);
|
||||
let state = args[args_n + 3].parse::<u8>().unwrap_or(0);
|
||||
let unicode = args[args_n + 4].parse::<u32>().unwrap_or(0);
|
||||
|
||||
#[allow(static_mut_refs)]
|
||||
pub fn handle_event(event: &InputEvent) -> Option<KeyboardEvent> {
|
||||
if event.event_type == 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
match event.event_type {
|
||||
EVENT_KEY => {
|
||||
unsafe { MODIFIERS.update(event.code as u8, event.value) };
|
||||
match event.code {
|
||||
BTN_LEFT => {
|
||||
unsafe { MOUSE.left_button_pressed = event.value == 1 };
|
||||
None
|
||||
unsafe {
|
||||
*kbd_buf.add(event_n) = KeyboardEvent {
|
||||
state,
|
||||
_pad1: 0,
|
||||
key,
|
||||
mods,
|
||||
_pad2: 0,
|
||||
unicode,
|
||||
};
|
||||
event_n += 1;
|
||||
}
|
||||
args_n += 5;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
BTN_RIGHT => {
|
||||
unsafe { MOUSE.right_button_pressed = event.value == 1 };
|
||||
None
|
||||
"mouse" => {
|
||||
args_n += 6;
|
||||
}
|
||||
BTN_MIDDLE => {
|
||||
unsafe { MOUSE.middle_button_pressed = event.value == 1 };
|
||||
None
|
||||
_ => {
|
||||
args_n += 1;
|
||||
}
|
||||
_ => Some(KeyboardEvent {
|
||||
state: event.value as u8,
|
||||
_pad1: 0,
|
||||
key: event.code as u16,
|
||||
mods: 0,
|
||||
_pad2: 0,
|
||||
unicode: keycode_to_char(event.code as u8, unsafe {
|
||||
MODIFIERS.effective_shift()
|
||||
})
|
||||
.unwrap_or('\0') as u32,
|
||||
}),
|
||||
}
|
||||
}
|
||||
EVENT_REL => match event.code {
|
||||
REL_X => {
|
||||
unsafe { MOUSE.x_delta += event.value as i32 as i16 };
|
||||
None
|
||||
}
|
||||
REL_Y => {
|
||||
unsafe { MOUSE.y_delta += event.value as i32 as i16 };
|
||||
None
|
||||
}
|
||||
REL_WHEEL => None,
|
||||
_ => None,
|
||||
},
|
||||
_ => {
|
||||
print("Could not recognize virtio input event from interrupt\n");
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn input_read(kbd_buf: *mut KeyboardEvent, n: u8) -> usize {
|
||||
let mut input_buf = [InputEvent {
|
||||
event_type: 0,
|
||||
code: 0,
|
||||
value: 0,
|
||||
}; 32];
|
||||
let n = n.min(32);
|
||||
let len = unsafe { syscall2(INPUT_READ, input_buf.as_mut_ptr() as isize, n as isize) };
|
||||
let mut current_event_n = 0;
|
||||
|
||||
for i in 0..len {
|
||||
unsafe {
|
||||
let event = *((input_buf.as_mut_ptr()).add(i as usize));
|
||||
|
||||
if let Some(keyboard_event) = handle_event(&event) {
|
||||
*(kbd_buf.add(current_event_n)) = keyboard_event;
|
||||
current_event_n += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return current_event_n;
|
||||
return event_n;
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
use core::ffi::c_char;
|
||||
use core::ffi::{CStr, c_char};
|
||||
|
||||
use alloc::{ffi::CString, string::String};
|
||||
use alloc::{
|
||||
ffi::CString,
|
||||
string::{String, ToString},
|
||||
vec,
|
||||
};
|
||||
use bitflags::bitflags;
|
||||
|
||||
use crate::{
|
||||
mem::malloc,
|
||||
syscall::{IPC_CREATE, IPC_MANAGE, IPC_READ, IPC_WRITE, syscall2, syscall3},
|
||||
};
|
||||
use crate::syscall::{IPC_CREATE, IPC_MANAGE, IPC_READ, IPC_WRITE, syscall2, syscall3};
|
||||
|
||||
bitflags! {
|
||||
#[derive(Debug)]
|
||||
|
|
@ -58,22 +59,18 @@ pub extern "C" fn read_port(name_ptr: *const u8, output_ptr: *mut u8, from: i64)
|
|||
}
|
||||
|
||||
pub fn read_port_rust(name: String, from: i64) -> Option<(u64, String)> {
|
||||
let name_cstring_opt = CString::new(name);
|
||||
if let Ok(name_cstring) = name_cstring_opt {
|
||||
let output_ptr = malloc(256);
|
||||
return match read_port(name_cstring.as_ptr() as *const u8, output_ptr, from) {
|
||||
-1 => None,
|
||||
sender if sender > 0 => {
|
||||
match unsafe { CString::from_raw(output_ptr as *mut c_char) }.into_string() {
|
||||
Ok(rust_string) => Some((sender as u64, rust_string)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
_ => None,
|
||||
};
|
||||
} else {
|
||||
let name_cstring = CString::new(name).ok()?;
|
||||
|
||||
let mut buf = vec![0u8; 256];
|
||||
let sender = read_port(name_cstring.as_ptr() as *const u8, buf.as_mut_ptr(), from);
|
||||
|
||||
if sender <= 0 {
|
||||
return None;
|
||||
}
|
||||
|
||||
let cstr = unsafe { CStr::from_ptr(buf.as_ptr() as *const c_char) };
|
||||
let msg = cstr.to_str().ok()?.to_string();
|
||||
Some((sender as u64, msg))
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
|
|
|||
|
|
@ -1,4 +1,7 @@
|
|||
use core::ffi::c_char;
|
||||
|
||||
use alloc::{
|
||||
ffi::CString,
|
||||
format,
|
||||
string::{String, ToString},
|
||||
vec::Vec,
|
||||
|
|
@ -10,7 +13,6 @@ use crate::{
|
|||
ipc::{read_port_rust, write_port_rust},
|
||||
time::sleep_ms,
|
||||
},
|
||||
println,
|
||||
shm::{SHM_SLOT_SIZE, USER_SHM_BASE, shm_open_rust},
|
||||
};
|
||||
|
||||
|
|
@ -26,18 +28,16 @@ pub struct Window {
|
|||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn request_window(width: usize, height: usize) -> Window {
|
||||
pub unsafe extern "C" fn request_window(width: usize, height: usize, title: *mut c_char) -> Window {
|
||||
let title = unsafe { CString::from_raw(title) };
|
||||
|
||||
write_port_rust("window_manager".to_string(), "request_priv_ipc".to_string());
|
||||
let pid = getpid();
|
||||
let priv_ipc_name = loop {
|
||||
if let Some((sender, msg)) = read_port_rust(format!("wm_priv_{}", getpid()), -1) {
|
||||
println!("{}: {}", sender, msg);
|
||||
|
||||
if let Some((_, msg)) = read_port_rust(format!("wm_priv_{}", getpid()), -1) {
|
||||
if msg.starts_with("ack_request_priv_ipc") {
|
||||
let parts = msg.split_whitespace().collect::<Vec<&str>>();
|
||||
|
||||
println!("{}", parts[1].trim().parse::<isize>().unwrap_or(-1) == pid);
|
||||
|
||||
if parts[1].trim().parse::<isize>().unwrap_or(-1) == pid {
|
||||
break parts[2].to_string();
|
||||
}
|
||||
|
|
@ -47,15 +47,18 @@ pub unsafe extern "C" fn request_window(width: usize, height: usize) -> Window {
|
|||
unsafe { sleep_ms(1) };
|
||||
};
|
||||
|
||||
println!("Private IPC Name: {}", priv_ipc_name);
|
||||
|
||||
unsafe {
|
||||
PRIV_IPC_NAME = Some(priv_ipc_name.clone());
|
||||
}
|
||||
|
||||
write_port_rust(
|
||||
priv_ipc_name.clone(),
|
||||
format!("request_window_buf {} {}", width, height),
|
||||
format!(
|
||||
"request_window_buf {} {} {}",
|
||||
title.to_str().unwrap_or("noname"),
|
||||
width,
|
||||
height
|
||||
),
|
||||
);
|
||||
|
||||
let (width, height, x, y, shm_name, shm_id) = loop {
|
||||
|
|
@ -87,6 +90,14 @@ pub unsafe extern "C" fn request_window(width: usize, height: usize) -> Window {
|
|||
}
|
||||
}
|
||||
|
||||
pub unsafe fn request_window_rust(width: usize, height: usize, title: String) -> Window {
|
||||
if let Ok(c_string) = CString::new(title) {
|
||||
unsafe { request_window(width, height, c_string.as_ptr() as *mut c_char) }
|
||||
} else {
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn draw_buffer_to_window(
|
||||
buffer: *const u32,
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ use core::{
|
|||
use crate::{
|
||||
heap::init_heap,
|
||||
mem::{malloc, memcpy},
|
||||
syscall::{EXIT, GETPID, WRITE, syscall0, syscall3},
|
||||
syscall::{EXIT, GETPID, KILL, WRITE, syscall0, syscall1, syscall3},
|
||||
};
|
||||
|
||||
pub mod graphics;
|
||||
|
|
@ -691,6 +691,11 @@ pub unsafe extern "C" fn sscanf(str: *mut u8, fmt: *const u8, args: ...) -> i32
|
|||
0
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn kill(pid: isize) -> isize {
|
||||
unsafe { syscall1(KILL, pid) }
|
||||
}
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
pub unsafe extern "C" fn __errno_location() -> *mut core::ffi::c_int {
|
||||
addr_of_mut!(ERRNO)
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use alloc::{ffi::CString, string::String};
|
|||
|
||||
use crate::syscall::{SHM_OPEN, syscall2};
|
||||
|
||||
pub const USER_SHM_BASE: u64 = 0x0000_7000_0000_0000;
|
||||
pub const USER_SHM_BASE: u64 = 0x0000_4000_0000_0000;
|
||||
pub const SHM_SLOT_SIZE: u64 = 64 * 1024 * 1024;
|
||||
|
||||
#[unsafe(no_mangle)]
|
||||
|
|
|
|||
Loading…
Reference in a new issue