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,
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,
}
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,
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,
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;
--- /dev/null
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum Button {
+ Left,
+ Middle,
+ Right,
+ X1,
+ X2,
+}
--- /dev/null
+#[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,
+}
+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);
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 {
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;
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 {
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,
+ }
+}
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,
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,
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;
}
}
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;