From eb09851585f1c96feb39d00497732a9a43634fc1 Mon Sep 17 00:00:00 2001 From: Joshua Simmons Date: Sun, 13 Nov 2022 12:04:52 +0100 Subject: [PATCH] Add basic input events --- ffi/sdl2-sys/src/lib.rs | 321 ++++++++++++++++++++++++++++++++++- narcissus-app/src/button.rs | 8 + narcissus-app/src/key.rs | 197 ++++++++++++++++++++++ narcissus-app/src/lib.rs | 82 ++++++++- narcissus-app/src/sdl.rs | 328 ++++++++++++++++++++++++++++++++++-- narcissus/src/main.rs | 20 ++- 6 files changed, 928 insertions(+), 28 deletions(-) create mode 100644 narcissus-app/src/button.rs create mode 100644 narcissus-app/src/key.rs diff --git a/ffi/sdl2-sys/src/lib.rs b/ffi/sdl2-sys/src/lib.rs index 2e46a15..dddb7e8 100644 --- a/ffi/sdl2-sys/src/lib.rs +++ b/ffi/sdl2-sys/src/lib.rs @@ -10,9 +10,25 @@ pub type JoystickID = i32; pub type TouchID = i64; pub type FingerID = i64; pub type GestureID = i64; -pub type Keycode = i32; -#[repr(C)] +#[repr(u8)] +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum PressedState { + Released = 0, + Pressed = 1, +} + +#[repr(u8)] +#[derive(Clone, Copy, PartialEq, Eq)] +pub enum MouseButton { + Left = 1, + Middle = 2, + Right = 3, + X1 = 4, + X2 = 5, +} + +#[repr(i32)] #[derive(Clone, Copy, PartialEq, Eq)] pub enum Scancode { UNKNOWN = 0, @@ -398,12 +414,303 @@ pub enum Scancode { NUM_SCANCODES = 512, } +const fn keycode_from_scancode(scancode: Scancode) -> i32 { + scancode as i32 | 1 << 30 +} + +#[repr(i32)] +#[derive(Clone, Copy)] +pub enum Keycode { + UNKNOWN = 0, + + RETURN = '\r' as i32, + ESCAPE = '\x1B' as i32, + BACKSPACE = '\x08' as i32, + TAB = '\t' as i32, + SPACE = ' ' as i32, + EXCLAIM = '!' as i32, + QUOTEDBL = '"' as i32, + HASH = '#' as i32, + PERCENT = '%' as i32, + DOLLAR = '$' as i32, + AMPERSAND = '&' as i32, + QUOTE = '\'' as i32, + LEFTPAREN = '(' as i32, + RIGHTPAREN = ')' as i32, + ASTERISK = '*' as i32, + PLUS = '+' as i32, + COMMA = ',' as i32, + MINUS = '-' as i32, + PERIOD = '.' as i32, + SLASH = '/' as i32, + KEY_0 = '0' as i32, + KEY_1 = '1' as i32, + KEY_2 = '2' as i32, + KEY_3 = '3' as i32, + KEY_4 = '4' as i32, + KEY_5 = '5' as i32, + KEY_6 = '6' as i32, + KEY_7 = '7' as i32, + KEY_8 = '8' as i32, + KEY_9 = '9' as i32, + COLON = ':' as i32, + SEMICOLON = ';' as i32, + LESS = '<' as i32, + EQUALS = '=' as i32, + GREATER = '>' as i32, + QUESTION = '?' as i32, + AT = '@' as i32, + + /* + Skip uppercase letters + */ + LEFTBRACKET = '[' as i32, + BACKSLASH = '\\' as i32, + RIGHTBRACKET = ']' as i32, + CARET = '^' as i32, + UNDERSCORE = '_' as i32, + BACKQUOTE = '`' as i32, + a = 'a' as i32, + b = 'b' as i32, + c = 'c' as i32, + d = 'd' as i32, + e = 'e' as i32, + f = 'f' as i32, + g = 'g' as i32, + h = 'h' as i32, + i = 'i' as i32, + j = 'j' as i32, + k = 'k' as i32, + l = 'l' as i32, + m = 'm' as i32, + n = 'n' as i32, + o = 'o' as i32, + p = 'p' as i32, + q = 'q' as i32, + r = 'r' as i32, + s = 's' as i32, + t = 't' as i32, + u = 'u' as i32, + v = 'v' as i32, + w = 'w' as i32, + x = 'x' as i32, + y = 'y' as i32, + z = 'z' as i32, + + CAPSLOCK = keycode_from_scancode(Scancode::CAPSLOCK), + + F1 = keycode_from_scancode(Scancode::F1), + F2 = keycode_from_scancode(Scancode::F2), + F3 = keycode_from_scancode(Scancode::F3), + F4 = keycode_from_scancode(Scancode::F4), + F5 = keycode_from_scancode(Scancode::F5), + F6 = keycode_from_scancode(Scancode::F6), + F7 = keycode_from_scancode(Scancode::F7), + F8 = keycode_from_scancode(Scancode::F8), + F9 = keycode_from_scancode(Scancode::F9), + F10 = keycode_from_scancode(Scancode::F10), + F11 = keycode_from_scancode(Scancode::F11), + F12 = keycode_from_scancode(Scancode::F12), + + PRINTSCREEN = keycode_from_scancode(Scancode::PRINTSCREEN), + SCROLLLOCK = keycode_from_scancode(Scancode::SCROLLLOCK), + PAUSE = keycode_from_scancode(Scancode::PAUSE), + INSERT = keycode_from_scancode(Scancode::INSERT), + HOME = keycode_from_scancode(Scancode::HOME), + PAGEUP = keycode_from_scancode(Scancode::PAGEUP), + DELETE = '\x7F' as i32, + END = keycode_from_scancode(Scancode::END), + PAGEDOWN = keycode_from_scancode(Scancode::PAGEDOWN), + RIGHT = keycode_from_scancode(Scancode::RIGHT), + LEFT = keycode_from_scancode(Scancode::LEFT), + DOWN = keycode_from_scancode(Scancode::DOWN), + UP = keycode_from_scancode(Scancode::UP), + + NUMLOCKCLEAR = keycode_from_scancode(Scancode::NUMLOCKCLEAR), + KP_DIVIDE = keycode_from_scancode(Scancode::KP_DIVIDE), + KP_MULTIPLY = keycode_from_scancode(Scancode::KP_MULTIPLY), + KP_MINUS = keycode_from_scancode(Scancode::KP_MINUS), + KP_PLUS = keycode_from_scancode(Scancode::KP_PLUS), + KP_ENTER = keycode_from_scancode(Scancode::KP_ENTER), + KP_1 = keycode_from_scancode(Scancode::KP_1), + KP_2 = keycode_from_scancode(Scancode::KP_2), + KP_3 = keycode_from_scancode(Scancode::KP_3), + KP_4 = keycode_from_scancode(Scancode::KP_4), + KP_5 = keycode_from_scancode(Scancode::KP_5), + KP_6 = keycode_from_scancode(Scancode::KP_6), + KP_7 = keycode_from_scancode(Scancode::KP_7), + KP_8 = keycode_from_scancode(Scancode::KP_8), + KP_9 = keycode_from_scancode(Scancode::KP_9), + KP_0 = keycode_from_scancode(Scancode::KP_0), + KP_PERIOD = keycode_from_scancode(Scancode::KP_PERIOD), + + APPLICATION = keycode_from_scancode(Scancode::APPLICATION), + POWER = keycode_from_scancode(Scancode::POWER), + KP_EQUALS = keycode_from_scancode(Scancode::KP_EQUALS), + F13 = keycode_from_scancode(Scancode::F13), + F14 = keycode_from_scancode(Scancode::F14), + F15 = keycode_from_scancode(Scancode::F15), + F16 = keycode_from_scancode(Scancode::F16), + F17 = keycode_from_scancode(Scancode::F17), + F18 = keycode_from_scancode(Scancode::F18), + F19 = keycode_from_scancode(Scancode::F19), + F20 = keycode_from_scancode(Scancode::F20), + F21 = keycode_from_scancode(Scancode::F21), + F22 = keycode_from_scancode(Scancode::F22), + F23 = keycode_from_scancode(Scancode::F23), + F24 = keycode_from_scancode(Scancode::F24), + EXECUTE = keycode_from_scancode(Scancode::EXECUTE), + HELP = keycode_from_scancode(Scancode::HELP), + MENU = keycode_from_scancode(Scancode::MENU), + SELECT = keycode_from_scancode(Scancode::SELECT), + STOP = keycode_from_scancode(Scancode::STOP), + AGAIN = keycode_from_scancode(Scancode::AGAIN), + UNDO = keycode_from_scancode(Scancode::UNDO), + CUT = keycode_from_scancode(Scancode::CUT), + COPY = keycode_from_scancode(Scancode::COPY), + PASTE = keycode_from_scancode(Scancode::PASTE), + FIND = keycode_from_scancode(Scancode::FIND), + MUTE = keycode_from_scancode(Scancode::MUTE), + VOLUMEUP = keycode_from_scancode(Scancode::VOLUMEUP), + VOLUMEDOWN = keycode_from_scancode(Scancode::VOLUMEDOWN), + KP_COMMA = keycode_from_scancode(Scancode::KP_COMMA), + KP_EQUALSAS400 = keycode_from_scancode(Scancode::KP_EQUALSAS400), + + ALTERASE = keycode_from_scancode(Scancode::ALTERASE), + SYSREQ = keycode_from_scancode(Scancode::SYSREQ), + CANCEL = keycode_from_scancode(Scancode::CANCEL), + CLEAR = keycode_from_scancode(Scancode::CLEAR), + PRIOR = keycode_from_scancode(Scancode::PRIOR), + RETURN2 = keycode_from_scancode(Scancode::RETURN2), + SEPARATOR = keycode_from_scancode(Scancode::SEPARATOR), + OUT = keycode_from_scancode(Scancode::OUT), + OPER = keycode_from_scancode(Scancode::OPER), + CLEARAGAIN = keycode_from_scancode(Scancode::CLEARAGAIN), + CRSEL = keycode_from_scancode(Scancode::CRSEL), + EXSEL = keycode_from_scancode(Scancode::EXSEL), + + KP_00 = keycode_from_scancode(Scancode::KP_00), + KP_000 = keycode_from_scancode(Scancode::KP_000), + THOUSANDSSEPARATOR = keycode_from_scancode(Scancode::THOUSANDSSEPARATOR), + DECIMALSEPARATOR = keycode_from_scancode(Scancode::DECIMALSEPARATOR), + CURRENCYUNIT = keycode_from_scancode(Scancode::CURRENCYUNIT), + CURRENCYSUBUNIT = keycode_from_scancode(Scancode::CURRENCYSUBUNIT), + KP_LEFTPAREN = keycode_from_scancode(Scancode::KP_LEFTPAREN), + KP_RIGHTPAREN = keycode_from_scancode(Scancode::KP_RIGHTPAREN), + KP_LEFTBRACE = keycode_from_scancode(Scancode::KP_LEFTBRACE), + KP_RIGHTBRACE = keycode_from_scancode(Scancode::KP_RIGHTBRACE), + KP_TAB = keycode_from_scancode(Scancode::KP_TAB), + KP_BACKSPACE = keycode_from_scancode(Scancode::KP_BACKSPACE), + KP_A = keycode_from_scancode(Scancode::KP_A), + KP_B = keycode_from_scancode(Scancode::KP_B), + KP_C = keycode_from_scancode(Scancode::KP_C), + KP_D = keycode_from_scancode(Scancode::KP_D), + KP_E = keycode_from_scancode(Scancode::KP_E), + KP_F = keycode_from_scancode(Scancode::KP_F), + KP_XOR = keycode_from_scancode(Scancode::KP_XOR), + KP_POWER = keycode_from_scancode(Scancode::KP_POWER), + KP_PERCENT = keycode_from_scancode(Scancode::KP_PERCENT), + KP_LESS = keycode_from_scancode(Scancode::KP_LESS), + KP_GREATER = keycode_from_scancode(Scancode::KP_GREATER), + KP_AMPERSAND = keycode_from_scancode(Scancode::KP_AMPERSAND), + KP_DBLAMPERSAND = keycode_from_scancode(Scancode::KP_DBLAMPERSAND), + KP_VERTICALBAR = keycode_from_scancode(Scancode::KP_VERTICALBAR), + KP_DBLVERTICALBAR = keycode_from_scancode(Scancode::KP_DBLVERTICALBAR), + KP_COLON = keycode_from_scancode(Scancode::KP_COLON), + KP_HASH = keycode_from_scancode(Scancode::KP_HASH), + KP_SPACE = keycode_from_scancode(Scancode::KP_SPACE), + KP_AT = keycode_from_scancode(Scancode::KP_AT), + KP_EXCLAM = keycode_from_scancode(Scancode::KP_EXCLAM), + KP_MEMSTORE = keycode_from_scancode(Scancode::KP_MEMSTORE), + KP_MEMRECALL = keycode_from_scancode(Scancode::KP_MEMRECALL), + KP_MEMCLEAR = keycode_from_scancode(Scancode::KP_MEMCLEAR), + KP_MEMADD = keycode_from_scancode(Scancode::KP_MEMADD), + KP_MEMSUBTRACT = keycode_from_scancode(Scancode::KP_MEMSUBTRACT), + KP_MEMMULTIPLY = keycode_from_scancode(Scancode::KP_MEMMULTIPLY), + KP_MEMDIVIDE = keycode_from_scancode(Scancode::KP_MEMDIVIDE), + KP_PLUSMINUS = keycode_from_scancode(Scancode::KP_PLUSMINUS), + KP_CLEAR = keycode_from_scancode(Scancode::KP_CLEAR), + KP_CLEARENTRY = keycode_from_scancode(Scancode::KP_CLEARENTRY), + KP_BINARY = keycode_from_scancode(Scancode::KP_BINARY), + KP_OCTAL = keycode_from_scancode(Scancode::KP_OCTAL), + KP_DECIMAL = keycode_from_scancode(Scancode::KP_DECIMAL), + KP_HEXADECIMAL = keycode_from_scancode(Scancode::KP_HEXADECIMAL), + + LCTRL = keycode_from_scancode(Scancode::LCTRL), + LSHIFT = keycode_from_scancode(Scancode::LSHIFT), + LALT = keycode_from_scancode(Scancode::LALT), + LGUI = keycode_from_scancode(Scancode::LGUI), + RCTRL = keycode_from_scancode(Scancode::RCTRL), + RSHIFT = keycode_from_scancode(Scancode::RSHIFT), + RALT = keycode_from_scancode(Scancode::RALT), + RGUI = keycode_from_scancode(Scancode::RGUI), + + MODE = keycode_from_scancode(Scancode::MODE), + + AUDIONEXT = keycode_from_scancode(Scancode::AUDIONEXT), + AUDIOPREV = keycode_from_scancode(Scancode::AUDIOPREV), + AUDIOSTOP = keycode_from_scancode(Scancode::AUDIOSTOP), + AUDIOPLAY = keycode_from_scancode(Scancode::AUDIOPLAY), + AUDIOMUTE = keycode_from_scancode(Scancode::AUDIOMUTE), + MEDIASELECT = keycode_from_scancode(Scancode::MEDIASELECT), + WWW = keycode_from_scancode(Scancode::WWW), + MAIL = keycode_from_scancode(Scancode::MAIL), + CALCULATOR = keycode_from_scancode(Scancode::CALCULATOR), + COMPUTER = keycode_from_scancode(Scancode::COMPUTER), + AC_SEARCH = keycode_from_scancode(Scancode::AC_SEARCH), + AC_HOME = keycode_from_scancode(Scancode::AC_HOME), + AC_BACK = keycode_from_scancode(Scancode::AC_BACK), + AC_FORWARD = keycode_from_scancode(Scancode::AC_FORWARD), + AC_STOP = keycode_from_scancode(Scancode::AC_STOP), + AC_REFRESH = keycode_from_scancode(Scancode::AC_REFRESH), + AC_BOOKMARKS = keycode_from_scancode(Scancode::AC_BOOKMARKS), + + BRIGHTNESSDOWN = keycode_from_scancode(Scancode::BRIGHTNESSDOWN), + BRIGHTNESSUP = keycode_from_scancode(Scancode::BRIGHTNESSUP), + DISPLAYSWITCH = keycode_from_scancode(Scancode::DISPLAYSWITCH), + KBDILLUMTOGGLE = keycode_from_scancode(Scancode::KBDILLUMTOGGLE), + KBDILLUMDOWN = keycode_from_scancode(Scancode::KBDILLUMDOWN), + KBDILLUMUP = keycode_from_scancode(Scancode::KBDILLUMUP), + EJECT = keycode_from_scancode(Scancode::EJECT), + SLEEP = keycode_from_scancode(Scancode::SLEEP), + APP1 = keycode_from_scancode(Scancode::APP1), + APP2 = keycode_from_scancode(Scancode::APP2), + + AUDIOREWIND = keycode_from_scancode(Scancode::AUDIOREWIND), + AUDIOFASTFORWARD = keycode_from_scancode(Scancode::AUDIOFASTFORWARD), +} + +#[repr(C)] +#[derive(Clone, Copy, PartialEq, Eq)] +pub struct Keymod(pub u16); + +impl Keymod { + pub const NONE: Self = Self(0x0000); + pub const LSHIFT: Self = Self(0x0001); + pub const RSHIFT: Self = Self(0x0002); + pub const LCTRL: Self = Self(0x0040); + pub const RCTRL: Self = Self(0x0080); + pub const LALT: Self = Self(0x0100); + pub const RALT: Self = Self(0x0200); + pub const LGUI: Self = Self(0x0400); + pub const RGUI: Self = Self(0x0800); + pub const NUM: Self = Self(0x1000); + pub const CAPS: Self = Self(0x2000); + pub const MODE: Self = Self(0x4000); + pub const SCROLL: Self = Self(0x8000); + + pub const CTRL: Self = Self(Self::LCTRL.0 | Self::RCTRL.0); + pub const SHIFT: Self = Self(Self::LSHIFT.0 | Self::RSHIFT.0); + pub const ALT: Self = Self(Self::LALT.0 | Self::RALT.0); + pub const GUI: Self = Self(Self::LGUI.0 | Self::RGUI.0); +} + #[repr(C)] #[derive(Clone, Copy)] pub struct Keysym { pub scancode: Scancode, pub sym: Keycode, - pub modifiers: u16, + pub modifiers: Keymod, pub _unused: u32, } @@ -568,7 +875,7 @@ pub struct KeyboardEvent { pub r#type: EventType, pub timestamp: u32, pub window_id: u32, - pub state: u8, + pub state: PressedState, pub repeat: u8, pub _padding2: u8, pub _padding3: u8, @@ -620,8 +927,8 @@ pub struct MouseButtonEvent { pub timestamp: u32, pub window_id: u32, pub which: u32, - pub button: u8, - pub state: u8, + pub button: MouseButton, + pub state: PressedState, pub clicks: u8, pub padding1: u8, pub x: i32, @@ -918,6 +1225,8 @@ extern "C" { pub fn SDL_GetWindowID(window: *mut Window) -> u32; pub fn SDL_GetWindowFromID(id: u32) -> *mut Window; + pub fn SDL_GetKeyFromScancode(scancode: Scancode) -> Keycode; + pub fn SDL_PollEvent(event: *mut Event) -> i32; pub fn SDL_Vulkan_LoadLibrary(path: *const c_char) -> i32; diff --git a/narcissus-app/src/button.rs b/narcissus-app/src/button.rs new file mode 100644 index 0000000..b5e5151 --- /dev/null +++ b/narcissus-app/src/button.rs @@ -0,0 +1,8 @@ +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Button { + Left, + Middle, + Right, + X1, + X2, +} diff --git a/narcissus-app/src/key.rs b/narcissus-app/src/key.rs new file mode 100644 index 0000000..9f01915 --- /dev/null +++ b/narcissus-app/src/key.rs @@ -0,0 +1,197 @@ +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum Key { + Unknown, + + A, + B, + C, + D, + E, + F, + G, + H, + I, + J, + K, + L, + M, + N, + O, + P, + Q, + R, + S, + T, + U, + V, + W, + X, + Y, + Z, + + Key1, + Key2, + Key3, + Key4, + Key5, + Key6, + Key7, + Key8, + Key9, + Key0, + + Return, + Escape, + Backspace, + Delete, + Tab, + Space, + Minus, + Equal, + LeftBrace, + RightBrace, + Backslash, + Semicolon, + Apostrophe, + Grave, + Comma, + Period, + Slash, + CapsLock, + + F1, + F2, + F3, + F4, + F5, + F6, + F7, + F8, + F9, + F10, + F11, + F12, + F13, + F14, + F15, + F16, + F17, + F18, + F19, + F20, + F21, + F22, + F23, + F24, + + ScrollLock, + Insert, + Home, + End, + PageUp, + PageDown, + + Left, + Right, + Up, + Down, + + NumLock, + NumpadDivide, + NumpadMultiply, + NumpadSubtract, + NumpadAdd, + NumpadEnter, + Numpad1, + Numpad2, + Numpad3, + Numpad4, + Numpad5, + Numpad6, + Numpad7, + Numpad8, + Numpad9, + Numpad0, + NumpadPeriod, + NumpadEquals, + NumpadLeftParen, + NumpadRightParen, + NumpadPlusMinus, + NumpadComma, + + Eject, + Stop, + Mute, + VolumeUp, + VolumeDown, + Power, + + Compose, + Sleep, + + LeftShift, + RightShift, + LeftControl, + RightControl, + LeftAlt, + RightAlt, + LeftMeta, + RightMeta, + + Menu, + Pause, + + NonUSBackslash, + SysReq, + Again, + Undo, + Copy, + Paste, + Find, + Cut, + Help, + Calculator, + AltErase, + Cancel, + + BrightnessUp, + BrightnessDown, + + SwitchVideoMode, + + KeyboardIlluminationToggle, + KeyboardIlluminationDown, + KeyboardIlluminationUp, + + App1, + App2, + WWW, + Mail, + Computer, + + ACBookmarks, + ACBack, + ACForward, + ACHome, + ACRefresh, + ACSearch, + + AudioNext, + AudioPlay, + AudioPrev, + AudioStop, + AudioRewind, + AudioFastForward, + + Language1, + Language2, + Language3, + Language4, + Language5, + + International1, + International2, + International3, + International4, + International5, +} diff --git a/narcissus-app/src/lib.rs b/narcissus-app/src/lib.rs index 1810c05..3f971e5 100644 --- a/narcissus-app/src/lib.rs +++ b/narcissus-app/src/lib.rs @@ -1,8 +1,27 @@ +mod button; +mod key; mod sdl; use std::ffi::{c_void, CStr}; -use narcissus_core::Handle; +use narcissus_core::{flags_def, Handle}; + +pub use button::Button; +pub use key::Key; + +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub enum PressedState { + Released, + Pressed, +} + +flags_def!(ModifierFlags); +impl ModifierFlags { + pub const ALT: Self = Self(1 << 0); + pub const CTRL: Self = Self(1 << 1); + pub const SHIFT: Self = Self(1 << 2); + pub const META: Self = Self(1 << 3); +} #[derive(Clone, Copy, PartialEq, Eq, Hash, Default, Debug)] pub struct Window(Handle); @@ -23,7 +42,66 @@ pub struct WindowDesc<'a> { pub enum Event { Unknown, Quit, - WindowClose(Window), + + KeyPress { + window: Window, + key: Key, + pressed: PressedState, + modifiers: ModifierFlags, + }, + + ButtonPress { + window: Window, + button: Button, + pressed: PressedState, + }, + + MouseMotion { + window: Window, + x: i32, + y: i32, + }, + + /// A window has gained mouse focus. + MouseEnter { + window: Window, + x: i32, + y: i32, + }, + + /// A window has lost moust focus. + MouseLeave { + window: Window, + x: i32, + y: i32, + }, + + /// A window has gained keyboard focus. + FocusIn { + window: Window, + }, + + /// A window has lost keyboard focus. + FocusOut { + window: Window, + }, + + /// The window has been resized. + Resize { + window: Window, + width: u32, + height: u32, + }, + + // The close button has been pressed on the window. + Close { + window: Window, + }, + + // The window has been destroyed. + Destroy { + window: Window, + }, } pub trait App { diff --git a/narcissus-app/src/sdl.rs b/narcissus-app/src/sdl.rs index 385d6d2..c35a1dc 100644 --- a/narcissus-app/src/sdl.rs +++ b/narcissus-app/src/sdl.rs @@ -5,7 +5,7 @@ use std::{ os::raw::c_char, }; -use crate::{App, Event, Window}; +use crate::{App, Button, Event, Key, ModifierFlags, PressedState, Window}; use narcissus_core::{Handle, Mutex, Pool}; use sdl2_sys as sdl; @@ -25,6 +25,14 @@ impl SdlApp { window_id_to_handle: Mutex::new(HashMap::new()), }) } + + fn window_from_window_id(&self, window_id: u32) -> Window { + self.window_id_to_handle + .lock() + .get(&window_id) + .copied() + .unwrap_or_else(|| Window(Handle::null())) + } } impl Drop for SdlApp { @@ -131,39 +139,329 @@ impl App for SdlApp { let event = unsafe { event.assume_init() }; let e = match unsafe { event.r#type } { - sdl2_sys::EventType::QUIT => Event::Quit, - sdl2_sys::EventType::WINDOWEVENT => match unsafe { event.window.event } { + sdl::EventType::QUIT => Event::Quit, + sdl::EventType::WINDOWEVENT => match unsafe { event.window.event } { sdl::WindowEventId::None => Event::Unknown, sdl::WindowEventId::Shown => Event::Unknown, sdl::WindowEventId::Hidden => Event::Unknown, sdl::WindowEventId::Exposed => Event::Unknown, sdl::WindowEventId::Moved => Event::Unknown, - sdl::WindowEventId::Resized => Event::Unknown, + sdl::WindowEventId::Resized => { + let handle = self.window_from_window_id(unsafe { event.window.window_id }); + Event::Resize { + window: handle, + width: unsafe { event.window.data1 } as u32, + height: unsafe { event.window.data2 } as u32, + } + } sdl::WindowEventId::SizeChanged => Event::Unknown, sdl::WindowEventId::Minimized => Event::Unknown, sdl::WindowEventId::Maximized => Event::Unknown, sdl::WindowEventId::Restored => Event::Unknown, - sdl::WindowEventId::Enter => Event::Unknown, - sdl::WindowEventId::Leave => Event::Unknown, - sdl::WindowEventId::FocusGained => Event::Unknown, - sdl::WindowEventId::FocusLost => Event::Unknown, + sdl::WindowEventId::Enter => { + let handle = self.window_from_window_id(unsafe { event.window.window_id }); + Event::MouseEnter { + window: handle, + x: unsafe { event.window.data1 }, + y: unsafe { event.window.data2 }, + } + } + sdl::WindowEventId::Leave => { + let handle = self.window_from_window_id(unsafe { event.window.window_id }); + Event::MouseLeave { + window: handle, + x: unsafe { event.window.data1 }, + y: unsafe { event.window.data2 }, + } + } + sdl::WindowEventId::FocusGained => { + let handle = self.window_from_window_id(unsafe { event.window.window_id }); + Event::FocusIn { window: handle } + } + sdl::WindowEventId::FocusLost => { + let handle = self.window_from_window_id(unsafe { event.window.window_id }); + Event::FocusOut { window: handle } + } sdl::WindowEventId::Close => { - let handle = self - .window_id_to_handle - .lock() - .get(&unsafe { event.window.window_id }) - .copied() - .unwrap_or_else(|| Window(Handle::null())); - Event::WindowClose(handle) + let handle = self.window_from_window_id(unsafe { event.window.window_id }); + Event::Close { window: handle } } sdl::WindowEventId::TakeFocus => Event::Unknown, sdl::WindowEventId::HitTest => Event::Unknown, sdl::WindowEventId::IccprofChanged => Event::Unknown, sdl::WindowEventId::DisplayChanged => Event::Unknown, }, + sdl::EventType::KEYUP | sdl::EventType::KEYDOWN => { + let handle = self.window_from_window_id(unsafe { event.key.window_id }); + let scancode = unsafe { event.key.keysym.scancode }; + let modifiers = unsafe { event.key.keysym.modifiers }; + let state = unsafe { event.key.state }; + let key = map_sdl_scancode(scancode); + let modifiers = map_sdl_modifiers(modifiers); + let pressed = map_sdl_pressed_state(state); + Event::KeyPress { + window: handle, + key, + pressed, + modifiers, + } + } + sdl::EventType::MOUSEBUTTONUP | sdl::EventType::MOUSEBUTTONDOWN => { + let handle = self.window_from_window_id(unsafe { event.button.window_id }); + let button = unsafe { event.button.button }; + let state = unsafe { event.button.state }; + let button = map_sdl_button(button); + let pressed = map_sdl_pressed_state(state); + Event::ButtonPress { + window: handle, + button, + pressed, + } + } + sdl::EventType::MOUSEMOTION => { + let handle = self.window_from_window_id(unsafe { event.window.window_id }); + Event::MouseMotion { + window: handle, + x: unsafe { event.window.data1 }, + y: unsafe { event.window.data2 }, + } + } _ => Event::Unknown, }; Some(e) } } + +fn map_sdl_button(button: sdl::MouseButton) -> Button { + match button { + sdl::MouseButton::Left => Button::Left, + sdl::MouseButton::Middle => Button::Middle, + sdl::MouseButton::Right => Button::Right, + sdl::MouseButton::X1 => Button::X1, + sdl::MouseButton::X2 => Button::X2, + } +} + +fn map_sdl_pressed_state(pressed_state: sdl::PressedState) -> PressedState { + match pressed_state { + sdl::PressedState::Released => PressedState::Released, + sdl::PressedState::Pressed => PressedState::Pressed, + } +} + +fn map_sdl_modifiers(modifiers: sdl::Keymod) -> ModifierFlags { + let mut flags = ModifierFlags::default(); + if modifiers.0 & sdl::Keymod::ALT.0 != 0 { + flags &= ModifierFlags::ALT + } + if modifiers.0 & sdl::Keymod::SHIFT.0 != 0 { + flags &= ModifierFlags::SHIFT + } + if modifiers.0 & sdl::Keymod::CTRL.0 != 0 { + flags &= ModifierFlags::CTRL + } + if modifiers.0 & sdl::Keymod::GUI.0 != 0 { + flags &= ModifierFlags::META + } + flags +} + +fn map_sdl_scancode(scancode: sdl::Scancode) -> Key { + match scancode { + sdl::Scancode::A => Key::A, + sdl::Scancode::B => Key::B, + sdl::Scancode::C => Key::C, + sdl::Scancode::D => Key::D, + sdl::Scancode::E => Key::E, + sdl::Scancode::F => Key::F, + sdl::Scancode::G => Key::G, + sdl::Scancode::H => Key::H, + sdl::Scancode::I => Key::I, + sdl::Scancode::J => Key::J, + sdl::Scancode::K => Key::K, + sdl::Scancode::L => Key::L, + sdl::Scancode::M => Key::M, + sdl::Scancode::N => Key::N, + sdl::Scancode::O => Key::O, + sdl::Scancode::P => Key::P, + sdl::Scancode::Q => Key::Q, + sdl::Scancode::R => Key::R, + sdl::Scancode::S => Key::S, + sdl::Scancode::T => Key::T, + sdl::Scancode::U => Key::U, + sdl::Scancode::V => Key::V, + sdl::Scancode::W => Key::W, + sdl::Scancode::X => Key::X, + sdl::Scancode::Y => Key::Y, + sdl::Scancode::Z => Key::Z, + + sdl::Scancode::SCANCODE_1 => Key::Key1, + sdl::Scancode::SCANCODE_2 => Key::Key2, + sdl::Scancode::SCANCODE_3 => Key::Key3, + sdl::Scancode::SCANCODE_4 => Key::Key4, + sdl::Scancode::SCANCODE_5 => Key::Key5, + sdl::Scancode::SCANCODE_6 => Key::Key6, + sdl::Scancode::SCANCODE_7 => Key::Key7, + sdl::Scancode::SCANCODE_8 => Key::Key8, + sdl::Scancode::SCANCODE_9 => Key::Key9, + sdl::Scancode::SCANCODE_0 => Key::Key0, + + sdl::Scancode::RETURN => Key::Return, + sdl::Scancode::ESCAPE => Key::Escape, + sdl::Scancode::BACKSPACE => Key::Backspace, + sdl::Scancode::DELETE => Key::Delete, + sdl::Scancode::TAB => Key::Tab, + sdl::Scancode::SPACE => Key::Space, + sdl::Scancode::MINUS => Key::Minus, + sdl::Scancode::EQUALS => Key::Equal, + sdl::Scancode::LEFTBRACKET => Key::LeftBrace, + sdl::Scancode::RIGHTBRACKET => Key::RightBrace, + sdl::Scancode::BACKSLASH => Key::Backslash, + sdl::Scancode::SEMICOLON => Key::Semicolon, + sdl::Scancode::APOSTROPHE => Key::Apostrophe, + sdl::Scancode::GRAVE => Key::Grave, + sdl::Scancode::COMMA => Key::Comma, + sdl::Scancode::PERIOD => Key::Period, + sdl::Scancode::SLASH => Key::Slash, + sdl::Scancode::CAPSLOCK => Key::CapsLock, + + sdl::Scancode::F1 => Key::F1, + sdl::Scancode::F2 => Key::F2, + sdl::Scancode::F3 => Key::F3, + sdl::Scancode::F4 => Key::F4, + sdl::Scancode::F5 => Key::F5, + sdl::Scancode::F6 => Key::F6, + sdl::Scancode::F7 => Key::F7, + sdl::Scancode::F8 => Key::F8, + sdl::Scancode::F9 => Key::F9, + sdl::Scancode::F10 => Key::F10, + sdl::Scancode::F11 => Key::F11, + sdl::Scancode::F12 => Key::F12, + sdl::Scancode::F13 => Key::F13, + sdl::Scancode::F14 => Key::F14, + sdl::Scancode::F15 => Key::F15, + sdl::Scancode::F16 => Key::F16, + sdl::Scancode::F17 => Key::F17, + sdl::Scancode::F18 => Key::F18, + sdl::Scancode::F19 => Key::F19, + sdl::Scancode::F20 => Key::F20, + sdl::Scancode::F21 => Key::F21, + sdl::Scancode::F22 => Key::F22, + sdl::Scancode::F23 => Key::F23, + sdl::Scancode::F24 => Key::F24, + + sdl::Scancode::SCROLLLOCK => Key::ScrollLock, + sdl::Scancode::INSERT => Key::Insert, + sdl::Scancode::HOME => Key::Home, + sdl::Scancode::END => Key::End, + sdl::Scancode::PAGEUP => Key::PageUp, + sdl::Scancode::PAGEDOWN => Key::PageDown, + + sdl::Scancode::LEFT => Key::Left, + sdl::Scancode::RIGHT => Key::Right, + sdl::Scancode::UP => Key::Up, + sdl::Scancode::DOWN => Key::Down, + + sdl::Scancode::NUMLOCKCLEAR => Key::NumLock, + sdl::Scancode::KP_DIVIDE => Key::NumpadDivide, + sdl::Scancode::KP_MULTIPLY => Key::NumpadMultiply, + sdl::Scancode::KP_MINUS => Key::NumpadSubtract, + sdl::Scancode::KP_PLUS => Key::NumpadAdd, + sdl::Scancode::KP_ENTER => Key::NumpadEnter, + sdl::Scancode::KP_1 => Key::Numpad1, + sdl::Scancode::KP_2 => Key::Numpad2, + sdl::Scancode::KP_3 => Key::Numpad3, + sdl::Scancode::KP_4 => Key::Numpad4, + sdl::Scancode::KP_5 => Key::Numpad5, + sdl::Scancode::KP_6 => Key::Numpad6, + sdl::Scancode::KP_7 => Key::Numpad7, + sdl::Scancode::KP_8 => Key::Numpad8, + sdl::Scancode::KP_9 => Key::Numpad9, + sdl::Scancode::KP_0 => Key::Numpad0, + sdl::Scancode::KP_PERIOD => Key::NumpadPeriod, + sdl::Scancode::KP_EQUALS => Key::NumpadEquals, + sdl::Scancode::KP_LEFTPAREN => Key::NumpadLeftParen, + sdl::Scancode::KP_RIGHTPAREN => Key::NumpadRightParen, + sdl::Scancode::KP_PLUSMINUS => Key::NumpadPlusMinus, + sdl::Scancode::KP_COMMA => Key::NumpadComma, + + sdl::Scancode::EJECT => Key::Eject, + sdl::Scancode::STOP => Key::Stop, + sdl::Scancode::MUTE => Key::Mute, + sdl::Scancode::VOLUMEUP => Key::VolumeUp, + sdl::Scancode::VOLUMEDOWN => Key::VolumeDown, + sdl::Scancode::POWER => Key::Power, + + sdl::Scancode::APPLICATION => Key::Compose, + sdl::Scancode::SLEEP => Key::Sleep, + + sdl::Scancode::LSHIFT => Key::LeftShift, + sdl::Scancode::RSHIFT => Key::RightShift, + sdl::Scancode::LCTRL => Key::LeftControl, + sdl::Scancode::RCTRL => Key::RightControl, + sdl::Scancode::LALT => Key::LeftAlt, + sdl::Scancode::RALT => Key::RightAlt, + sdl::Scancode::LGUI => Key::LeftMeta, + sdl::Scancode::RGUI => Key::RightMeta, + + sdl::Scancode::MENU => Key::Menu, + sdl::Scancode::PAUSE => Key::Pause, + + sdl::Scancode::NONUSBACKSLASH => Key::NonUSBackslash, + sdl::Scancode::SYSREQ => Key::SysReq, + sdl::Scancode::AGAIN => Key::Again, + sdl::Scancode::UNDO => Key::Undo, + sdl::Scancode::COPY => Key::Copy, + sdl::Scancode::PASTE => Key::Paste, + sdl::Scancode::FIND => Key::Find, + sdl::Scancode::CUT => Key::Cut, + sdl::Scancode::HELP => Key::Help, + sdl::Scancode::CALCULATOR => Key::Calculator, + sdl::Scancode::ALTERASE => Key::AltErase, + sdl::Scancode::CANCEL => Key::Cancel, + + sdl::Scancode::BRIGHTNESSUP => Key::BrightnessUp, + sdl::Scancode::BRIGHTNESSDOWN => Key::BrightnessDown, + + sdl::Scancode::DISPLAYSWITCH => Key::SwitchVideoMode, + + sdl::Scancode::KBDILLUMTOGGLE => Key::KeyboardIlluminationToggle, + sdl::Scancode::KBDILLUMDOWN => Key::KeyboardIlluminationDown, + sdl::Scancode::KBDILLUMUP => Key::KeyboardIlluminationUp, + + sdl::Scancode::APP1 => Key::App1, + sdl::Scancode::APP2 => Key::App2, + sdl::Scancode::WWW => Key::WWW, + sdl::Scancode::MAIL => Key::Mail, + sdl::Scancode::COMPUTER => Key::Computer, + + sdl::Scancode::AC_BOOKMARKS => Key::ACBookmarks, + sdl::Scancode::AC_BACK => Key::ACBack, + sdl::Scancode::AC_FORWARD => Key::ACForward, + sdl::Scancode::AC_HOME => Key::ACHome, + sdl::Scancode::AC_REFRESH => Key::ACRefresh, + sdl::Scancode::AC_SEARCH => Key::ACSearch, + + sdl::Scancode::AUDIONEXT => Key::AudioNext, + sdl::Scancode::AUDIOPLAY => Key::AudioPlay, + sdl::Scancode::AUDIOPREV => Key::AudioPrev, + sdl::Scancode::AUDIOSTOP => Key::AudioStop, + sdl::Scancode::AUDIOREWIND => Key::AudioRewind, + sdl::Scancode::AUDIOFASTFORWARD => Key::AudioFastForward, + + sdl::Scancode::LANG1 => Key::Language1, + sdl::Scancode::LANG2 => Key::Language2, + sdl::Scancode::LANG3 => Key::Language3, + sdl::Scancode::LANG4 => Key::Language4, + sdl::Scancode::LANG5 => Key::Language5, + + sdl::Scancode::INTERNATIONAL1 => Key::International1, + sdl::Scancode::INTERNATIONAL2 => Key::International2, + sdl::Scancode::INTERNATIONAL3 => Key::International3, + sdl::Scancode::INTERNATIONAL4 => Key::International4, + sdl::Scancode::INTERNATIONAL5 => Key::International5, + + _ => Key::Unknown, + } +} diff --git a/narcissus/src/main.rs b/narcissus/src/main.rs index 839ada8..a538a33 100644 --- a/narcissus/src/main.rs +++ b/narcissus/src/main.rs @@ -1,6 +1,6 @@ use std::{path::Path, time::Instant}; -use narcissus_app::{create_app, Event, WindowDesc}; +use narcissus_app::{create_app, Event, Key, WindowDesc}; use narcissus_core::{cstr, default, obj, Image}; use narcissus_gpu::{ create_vulkan_device, Bind, BindGroupLayoutDesc, BindGroupLayoutEntryDesc, BindingType, Buffer, @@ -193,7 +193,7 @@ pub fn main() { let (blåhaj_vertices, blåhaj_indices) = load_obj("narcissus/data/blåhaj.obj"); let app = create_app(); - let window = app.create_window(&WindowDesc { + let main_window = app.create_window(&WindowDesc { title: "narcissus", width: 800, height: 600, @@ -279,11 +279,21 @@ pub fn main() { while let Some(event) = app.poll_event() { use Event::*; match event { + KeyPress { + window: _, + key, + pressed: _, + modifiers: _, + } => { + if key == Key::Escape { + break 'main; + } + } Quit => { break 'main; } - WindowClose(w) => { - assert_eq!(window, w); + Close { window } => { + assert_eq!(window, main_window); device.destroy_window(window); break 'main; } @@ -292,7 +302,7 @@ pub fn main() { } let (width, height, swapchain_image) = - device.acquire_swapchain(&frame_token, window, TextureFormat::BGRA8_SRGB); + device.acquire_swapchain(&frame_token, main_window, TextureFormat::BGRA8_SRGB); let frame_start = Instant::now() - start_time; let frame_start = frame_start.as_secs_f32() * 0.5; -- 2.49.0