Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift rewrite #2

Merged
merged 7 commits into from
Jul 24, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions examples/hello.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,15 +41,15 @@ fn main() {
// Log spam warning: it's commented for a reason
// MouseEvent::CursorMove(x, y) => println!("Cursor moved to ({x}, {y})"),
_ => {}
}
},
EventKind::Keyboard(event) => match event {
KeyboardEvent::KeyPress(keycode) => println!("[{win:?}] Key {keycode:?} pressed"),
KeyboardEvent::KeyRelease(keycode) => {
println!("[{win:?}] Key {keycode:?} released")
}
KeyboardEvent::KeyRepeat(keycode) => println!("[{win:?}] Key {keycode:?} repeated"),
KeyboardEvent::ImeCommit(commit) => println!("[{win:?}] IME commit -> {commit:?}"),
}
},
EventKind::Resized(width, height) => {
println!("[{win:?}] Window resized to ({width}, {height})")
}
Expand All @@ -60,6 +60,11 @@ fn main() {
lok::close_window(win);
println!("[{win:?}] Closed upon request");
}
EventKind::Destroyed => {
println!("[{win:?}] Destroyed")
}
EventKind::FocusIn => println!("[{win:?}] Window focused"),
EventKind::FocusOut => println!("[{win:?}] Window lost focus"),
_ => {}
}
}
Expand Down
44 changes: 0 additions & 44 deletions src/native/macos/ffi_rust.rs
Original file line number Diff line number Diff line change
@@ -1,45 +1 @@
//! FFI functions for Swift to use

use {
super::{
ffi_swift::{SwiftMouseButton, SwiftMouseEvent},
EVENT_QUEUE,
},
crate::{
event::{Event, EventKind},
window::WindowHandle,
},
std::time::Duration,
};

/// Lokinit's mouse event callback
#[no_mangle]
pub extern "C" fn rust_mouse_callback(
window: i32,
mouse_btn: SwiftMouseButton,
mouse_event: SwiftMouseEvent,
x: f64,
y: f64,
) {
EVENT_QUEUE.with(move |queue| {
let mouse_event = mouse_event.into_mouse_event(x, y, mouse_btn);

queue.borrow_mut().push_back(Event {
time: Duration::ZERO,
window: WindowHandle(window as usize),
kind: EventKind::Mouse(mouse_event),
});
});
}

/// Lokinit's window resize callback
#[no_mangle]
pub extern "C" fn rust_window_resize_callback(window: usize, width: u32, height: u32) {
EVENT_QUEUE.with(move |queue| {
queue.borrow_mut().push_back(Event {
time: Duration::ZERO,
window: WindowHandle(window),
kind: EventKind::Resized(width, height),
});
});
}
163 changes: 128 additions & 35 deletions src/native/macos/ffi_swift.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,140 @@
//! Bindings to the external Swift code

use {
crate::event::{MouseButton, MouseEvent},
std::ffi::c_char,
super::keysym,
crate::{
event::{Event, EventKind, KeyboardEvent, MouseButton, MouseEvent},
window::WindowHandle,
},
std::{ffi::c_char, time::Duration},
};

/// The MouseButton enum, exported for Swift
#[repr(i32)]
pub enum SwiftMouseButton {
Left = 0,
Middle = 1,
Right = 2,
}
impl From<SwiftMouseButton> for MouseButton {
fn from(value: SwiftMouseButton) -> Self {
match value {
SwiftMouseButton::Left => MouseButton::Left,
SwiftMouseButton::Right => MouseButton::Right,
SwiftMouseButton::Middle => MouseButton::Middle,
}
}
}
#[allow(dead_code)]
pub enum SwiftEventType {
MouseDownLeft,
MouseDownMiddle,
MouseDownRight,
MouseDownOther,

/// The MouseEvent enum, exported for Swift
#[repr(i32)]
pub enum SwiftMouseEvent {
Pressed = 0,
Released = 1,
Moved = 2,
MouseUpLeft,
MouseUpMiddle,
MouseUpRight,
MouseUpOther,

MouseMoved,
MouseEntered,
MouseExited,
MouseScrolled,

WindowResized,
WindowMoved,
WindowCloseRequested,
WindowDestroyed,
WindowGainedFocus,
WindowLostFocus,

KeyPressed,
KeyReleased,
KeyRepeated,

AppQuit,
}
#[repr(C)]
pub struct SwiftEvent {
pub kind: SwiftEventType,
pub data1: i32,
pub data2: i32,
pub data3: i32,
pub window: usize,
}
impl TryInto<Event> for SwiftEvent {
type Error = ();

impl SwiftMouseEvent {
/// Translates the SwiftMouseEvent enum into Lokinit's MouseEvent enum
pub fn into_mouse_event(self, x: f64, y: f64, button: SwiftMouseButton) -> MouseEvent {
let x = x as i32;
let y = y as i32;
let button = button.into();
fn try_into(self) -> Result<Event, Self::Error> {
let kind = match self.kind {
SwiftEventType::MouseDownLeft => EventKind::Mouse(MouseEvent::ButtonPress(
MouseButton::Left,
self.data1,
self.data2,
)),
SwiftEventType::MouseUpLeft => EventKind::Mouse(MouseEvent::ButtonRelease(
MouseButton::Left,
self.data1,
self.data2,
)),
SwiftEventType::MouseDownRight => EventKind::Mouse(MouseEvent::ButtonPress(
MouseButton::Right,
self.data1,
self.data2,
)),
SwiftEventType::MouseUpMiddle => EventKind::Mouse(MouseEvent::ButtonRelease(
MouseButton::Middle,
self.data1,
self.data2,
)),
SwiftEventType::MouseDownMiddle => EventKind::Mouse(MouseEvent::ButtonPress(
MouseButton::Middle,
self.data1,
self.data2,
)),
SwiftEventType::MouseUpRight => EventKind::Mouse(MouseEvent::ButtonRelease(
MouseButton::Right,
self.data1,
self.data2,
)),
SwiftEventType::MouseDownOther => EventKind::Mouse(MouseEvent::ButtonPress(
MouseButton::Other(self.data3.try_into().unwrap()),
self.data1,
self.data2,
)),
SwiftEventType::MouseUpOther => EventKind::Mouse(MouseEvent::ButtonRelease(
MouseButton::Other(self.data3.try_into().unwrap()),
self.data1,
self.data2,
)),
SwiftEventType::MouseMoved => {
EventKind::Mouse(MouseEvent::CursorMove(self.data1, self.data2))
}
SwiftEventType::WindowResized => {
EventKind::Resized(self.data1 as u32, self.data2 as u32)
}
SwiftEventType::WindowMoved => EventKind::Moved(self.data1, self.data2),
SwiftEventType::WindowDestroyed => EventKind::Destroyed,
SwiftEventType::MouseEntered => {
EventKind::Mouse(MouseEvent::CursorIn(self.data1, self.data2))
}
SwiftEventType::MouseExited => {
EventKind::Mouse(MouseEvent::CursorOut(self.data1, self.data2))
}
SwiftEventType::WindowGainedFocus => EventKind::FocusIn,
SwiftEventType::WindowLostFocus => EventKind::FocusOut,
SwiftEventType::KeyPressed => {
match keysym::to_keycode(self.data1.try_into().unwrap()) {
None => return Err(()),
Some(key) => EventKind::Keyboard(KeyboardEvent::KeyPress(key)),
}
}
SwiftEventType::KeyRepeated => {
match keysym::to_keycode(self.data1.try_into().unwrap()) {
None => return Err(()),
Some(key) => EventKind::Keyboard(KeyboardEvent::KeyRepeat(key)),
}
}
SwiftEventType::KeyReleased => {
match keysym::to_keycode(self.data1.try_into().unwrap()) {
None => return Err(()),
Some(key) => EventKind::Keyboard(KeyboardEvent::KeyRelease(key)),
}
}
_ => return Err(()),
};

match self {
Self::Pressed => MouseEvent::ButtonPress(button, x, y),
Self::Released => MouseEvent::ButtonRelease(button, x, y),
Self::Moved => MouseEvent::CursorMove(x, y),
}
Ok(Event {
time: Duration::ZERO,
window: WindowHandle(self.window),
kind,
})
}
}

Expand All @@ -66,5 +159,5 @@ extern "C" {
/// the event loop. Instead, Lokinit calls this each time `poll_event()`
/// is called, which updates the app state without getting stuck in Apple's
/// run loop.
pub fn update() -> bool;
pub fn update() -> SwiftEvent;
}
137 changes: 137 additions & 0 deletions src/native/macos/keysym.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
use crate::keycode::KeyCode;

pub fn to_keycode(keysym: u32) -> Option<KeyCode> {
Some(match keysym {
// Big thanks to Mozilla:
// https://developer.mozilla.org/en-US/docs/web/api/ui_events/keyboard_event_code_values#code_values_on_mac
// Mozilla's always there for me when the bad fruit company isn't <3
0x00 => KeyCode::A,
0x01 => KeyCode::S,
0x02 => KeyCode::D,
0x03 => KeyCode::F,
0x04 => KeyCode::H,
0x05 => KeyCode::G,
0x06 => KeyCode::Z,
0x07 => KeyCode::X,
0x08 => KeyCode::C,
0x09 => KeyCode::V,
// 0x0A => ISO section?
0x0B => KeyCode::B,
0x0C => KeyCode::Q,
0x0D => KeyCode::W,
0x0E => KeyCode::E,
0x0F => KeyCode::R,
0x10 => KeyCode::Y,
0x11 => KeyCode::T,
0x12 => KeyCode::Key1,
0x13 => KeyCode::Key2,
0x14 => KeyCode::Key3,
0x15 => KeyCode::Key4,
0x16 => KeyCode::Key6,
0x17 => KeyCode::Key5,
0x18 => KeyCode::Equals,
0x19 => KeyCode::Key9,
0x1A => KeyCode::Key7,
0x1B => KeyCode::Minus,
0x1C => KeyCode::Key8,
0x1D => KeyCode::Key0,
0x1E => KeyCode::RBracket,
0x1F => KeyCode::O,
0x20 => KeyCode::U,
0x21 => KeyCode::LBracket,
0x22 => KeyCode::I,
0x23 => KeyCode::P,
0x24 => KeyCode::Enter,
0x25 => KeyCode::L,
0x26 => KeyCode::J,
0x27 => KeyCode::SingleQuote,
0x28 => KeyCode::K,
0x29 => KeyCode::Semicolon,
0x2A => KeyCode::Backslash,
0x2B => KeyCode::Comma,
0x2C => KeyCode::Slash,
0x2D => KeyCode::N,
0x2E => KeyCode::M,
0x2F => KeyCode::Point,
0x30 => KeyCode::Tab,
0x31 => KeyCode::Space,
0x32 => KeyCode::Backtick,
0x33 => KeyCode::Backspace,
// 0x34 => numpad enter on powerbook
0x35 => KeyCode::Escape,
0x36 => KeyCode::RCommand,
0x37 => KeyCode::LCommand,
0x38 => KeyCode::LShift,
0x39 => KeyCode::CapsLock,
0x3A => KeyCode::LAlt,
0x3B => KeyCode::LCtrl,
0x3C => KeyCode::RShift,
0x3D => KeyCode::RAlt,
0x3E => KeyCode::RCtrl,
// 0x3F => nil
// 0x40 => F17
0x41 => KeyCode::NumpadDecimal,
// 0x42 => nil
0x43 => KeyCode::NumpadMultiply,
// 0x44 => nil
0x45 => KeyCode::NumpadAdd,
// 0x46 => nil
0x47 => KeyCode::NumLock,
// 0x48 => volume up
// 0x49 => volume down
// 0x4A => mute volume
0x4B => KeyCode::NumpadDivide,
0x4C => KeyCode::NumpadEnter,
// 0x4D => nil
0x4E => KeyCode::NumpadSubtract,
// 0x4F => F18
// 0x50 => F19
0x51 => KeyCode::NumpadEquals,
0x52 => KeyCode::Numpad0,
0x53 => KeyCode::Numpad1,
0x54 => KeyCode::Numpad2,
0x55 => KeyCode::Numpad3,
0x56 => KeyCode::Numpad4,
0x57 => KeyCode::Numpad5,
0x58 => KeyCode::Numpad6,
0x59 => KeyCode::Numpad7,
// 0x5A => F20
0x5B => KeyCode::Numpad8,
0x5C => KeyCode::Numpad9,
// 0x5D => JIS yen
// 0x5E => JIS underscore
0x5F => KeyCode::NumpadComma,
0x60 => KeyCode::F5,
0x61 => KeyCode::F6,
0x62 => KeyCode::F7,
0x63 => KeyCode::F3,
0x64 => KeyCode::F8,
0x65 => KeyCode::F9,
// 0x66 => JIS eisu
0x67 => KeyCode::F11,
// 0x68 => JIS kana
// 0x69 => F13
// 0x6A => F16
// 0x6B => F14
// 0x6C => nil
0x6D => KeyCode::F10,
// 0x6E => context menu?
0x6F => KeyCode::F12,
// 0x70 => nil
// 0x71 => F15
// 0x72 => help or insert?
0x73 => KeyCode::Home,
0x74 => KeyCode::PageUp,
0x75 => KeyCode::Delete,
0x76 => KeyCode::F4,
0x77 => KeyCode::End,
0x78 => KeyCode::F2,
0x79 => KeyCode::PageDown,
0x7A => KeyCode::F1,
0x7B => KeyCode::ArrowLeft,
0x7C => KeyCode::ArrowRight,
0x7D => KeyCode::ArrowDown,
0x7E => KeyCode::ArrowUp,
_ => return None,
})
}
Loading