mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2025-01-26 02:36:32 +11:00
Added working keyboard support for Mac
Also moved all code out from windows.rs to a shared key_handler impl
This commit is contained in:
parent
8e9f8d33a1
commit
867daf1ca9
7 changed files with 440 additions and 52 deletions
123
src/key_handler.rs
Normal file
123
src/key_handler.rs
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
extern crate time;
|
||||||
|
|
||||||
|
use std::mem;
|
||||||
|
use {Key, KeyRepeat};
|
||||||
|
|
||||||
|
pub struct KeyHandler {
|
||||||
|
prev_time: f64,
|
||||||
|
delta_time: f32,
|
||||||
|
keys: [bool; 512],
|
||||||
|
keys_down_duration: [f32; 512],
|
||||||
|
key_repeat_delay: f32,
|
||||||
|
key_repeat_rate: f32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl KeyHandler {
|
||||||
|
pub fn new() -> KeyHandler {
|
||||||
|
KeyHandler {
|
||||||
|
keys: [false; 512],
|
||||||
|
keys_down_duration: [-1.0; 512],
|
||||||
|
prev_time: time::precise_time_s(),
|
||||||
|
delta_time: 0.0,
|
||||||
|
key_repeat_delay: 0.250,
|
||||||
|
key_repeat_rate: 0.050,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_key_state(&mut self, key: Key, state: bool) {
|
||||||
|
self.keys[key as usize] = state;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_keys(&self) -> Option<Vec<Key>> {
|
||||||
|
let mut index: u16 = 0;
|
||||||
|
let mut keys: Vec<Key> = Vec::new();
|
||||||
|
|
||||||
|
for i in self.keys.iter() {
|
||||||
|
if *i {
|
||||||
|
unsafe {
|
||||||
|
keys.push(mem::transmute(index as u8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn update(&mut self) {
|
||||||
|
let current_time = time::precise_time_s();
|
||||||
|
let delta_time = (current_time - self.prev_time) as f32;
|
||||||
|
self.prev_time = current_time;
|
||||||
|
self.delta_time = delta_time;
|
||||||
|
|
||||||
|
for i in 0..self.keys.len() {
|
||||||
|
if self.keys[i] {
|
||||||
|
if self.keys_down_duration[i] < 0.0 {
|
||||||
|
self.keys_down_duration[i] = 0.0;
|
||||||
|
} else {
|
||||||
|
self.keys_down_duration[i] += delta_time;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
self.keys_down_duration[i] = -1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_keys_pressed(&self, repeat: KeyRepeat) -> Option<Vec<Key>> {
|
||||||
|
let mut index: u16 = 0;
|
||||||
|
let mut keys: Vec<Key> = Vec::new();
|
||||||
|
|
||||||
|
for i in self.keys.iter() {
|
||||||
|
if *i {
|
||||||
|
unsafe {
|
||||||
|
if Self::key_pressed(self, index as usize, repeat) {
|
||||||
|
keys.push(mem::transmute(index as u8));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
index += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some(keys)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_key_down(&self, key: Key) -> bool {
|
||||||
|
return self.keys[key as usize];
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_key_repeat_delay(&mut self, delay: f32) {
|
||||||
|
self.key_repeat_delay = delay;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn set_key_repeat_rate(&mut self, rate: f32) {
|
||||||
|
self.key_repeat_rate = rate;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn key_pressed(&self, index: usize, repeat: KeyRepeat) -> bool {
|
||||||
|
let t = self.keys_down_duration[index];
|
||||||
|
|
||||||
|
if t == 0.0 {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if repeat == KeyRepeat::Yes && t > self.key_repeat_delay {
|
||||||
|
let delay = self.key_repeat_delay;
|
||||||
|
let rate = self.key_repeat_rate;
|
||||||
|
if ((((t - delay) % rate) > rate * 0.5)) != (((t - delay - self.delta_time) % rate) > rate * 0.5) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn is_key_pressed(&self, key: Key, repeat: KeyRepeat) -> bool {
|
||||||
|
return Self::key_pressed(self, key as usize, repeat);
|
||||||
|
}
|
||||||
|
}
|
14
src/lib.rs
14
src/lib.rs
|
@ -30,6 +30,7 @@ pub enum KeyRepeat {
|
||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq, Clone, Copy)]
|
||||||
pub enum Key {
|
pub enum Key {
|
||||||
Key0 = 0,
|
Key0 = 0,
|
||||||
Key1 = 1,
|
Key1 = 1,
|
||||||
|
@ -144,11 +145,22 @@ pub enum Key {
|
||||||
NumPadPlus,
|
NumPadPlus,
|
||||||
NumPadEnter,
|
NumPadEnter,
|
||||||
|
|
||||||
Count = 103,
|
LeftAlt,
|
||||||
|
RightAlt,
|
||||||
|
|
||||||
|
LeftSuper,
|
||||||
|
RightSuper,
|
||||||
|
|
||||||
|
/// Used when an Unknown key has been pressed
|
||||||
|
Unknown,
|
||||||
|
|
||||||
|
Count = 107,
|
||||||
}
|
}
|
||||||
|
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
|
|
||||||
|
pub mod key_handler;
|
||||||
|
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub mod windows;
|
pub mod windows;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
|
|
209
src/macos.rs
209
src/macos.rs
|
@ -1,20 +1,171 @@
|
||||||
#![cfg(target_os = "macos")]
|
#![cfg(target_os = "macos")]
|
||||||
|
|
||||||
use {Scale, Key, KeyRepeat};
|
use {Scale, Key, KeyRepeat};
|
||||||
|
use key_handler::KeyHandler;
|
||||||
|
|
||||||
use libc::{c_void, c_char, c_uchar};
|
use libc::{c_void, c_char, c_uchar};
|
||||||
use std::ffi::{CString};
|
use std::ffi::{CString};
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
use std::mem;
|
||||||
|
|
||||||
|
// Table taken from GLFW and slightly modified
|
||||||
|
|
||||||
|
static KEY_MAPPINGS: [Key; 128] = [
|
||||||
|
/* 00 */ Key::A,
|
||||||
|
/* 01 */ Key::S,
|
||||||
|
/* 02 */ Key::D,
|
||||||
|
/* 03 */ Key::F,
|
||||||
|
/* 04 */ Key::H,
|
||||||
|
/* 05 */ Key::G,
|
||||||
|
/* 06 */ Key::Z,
|
||||||
|
/* 07 */ Key::X,
|
||||||
|
/* 08 */ Key::C,
|
||||||
|
/* 09 */ Key::V,
|
||||||
|
/* 0a */ Key::Unknown, // GraveAccent
|
||||||
|
/* 0b */ Key::B,
|
||||||
|
/* 0c */ Key::Q,
|
||||||
|
/* 0d */ Key::W,
|
||||||
|
/* 0e */ Key::E,
|
||||||
|
/* 0f */ Key::R,
|
||||||
|
/* 10 */ Key::Y,
|
||||||
|
/* 11 */ Key::T,
|
||||||
|
/* 12 */ Key::Key1,
|
||||||
|
/* 13 */ Key::Key2,
|
||||||
|
/* 14 */ Key::Key3,
|
||||||
|
/* 15 */ Key::Key4,
|
||||||
|
/* 16 */ Key::Key6,
|
||||||
|
/* 17 */ Key::Key5,
|
||||||
|
/* 18 */ Key::Equal,
|
||||||
|
/* 19 */ Key::Key9,
|
||||||
|
/* 1a */ Key::Key7,
|
||||||
|
/* 1b */ Key::Minus,
|
||||||
|
/* 1c */ Key::Key8,
|
||||||
|
/* 1d */ Key::Key0,
|
||||||
|
/* 1e */ Key::RightBracket,
|
||||||
|
/* 1f */ Key::O,
|
||||||
|
/* 20 */ Key::U,
|
||||||
|
/* 21 */ Key::LeftBracket,
|
||||||
|
/* 22 */ Key::I,
|
||||||
|
/* 23 */ Key::P,
|
||||||
|
/* 24 */ Key::Enter,
|
||||||
|
/* 25 */ Key::L,
|
||||||
|
/* 26 */ Key::J,
|
||||||
|
/* 27 */ Key::Apostrophe,
|
||||||
|
/* 28 */ Key::K,
|
||||||
|
/* 29 */ Key::Semicolon,
|
||||||
|
/* 2a */ Key::Backslash,
|
||||||
|
/* 2b */ Key::Comma,
|
||||||
|
/* 2c */ Key::Slash,
|
||||||
|
/* 2d */ Key::N,
|
||||||
|
/* 2e */ Key::M,
|
||||||
|
/* 2f */ Key::Period,
|
||||||
|
/* 30 */ Key::Tab,
|
||||||
|
/* 31 */ Key::Space,
|
||||||
|
/* 32 */ Key::Unknown, // World1
|
||||||
|
/* 33 */ Key::Backspace,
|
||||||
|
/* 34 */ Key::Unknown,
|
||||||
|
/* 35 */ Key::Escape,
|
||||||
|
/* 36 */ Key::RightSuper,
|
||||||
|
/* 37 */ Key::LeftSuper,
|
||||||
|
/* 38 */ Key::LeftShift,
|
||||||
|
/* 39 */ Key::CapsLock,
|
||||||
|
/* 3a */ Key::LeftAlt,
|
||||||
|
/* 3b */ Key::LeftCtrl,
|
||||||
|
/* 3c */ Key::RightShift,
|
||||||
|
/* 3d */ Key::RightAlt,
|
||||||
|
/* 3e */ Key::RightCtrl,
|
||||||
|
/* 3f */ Key::Unknown, // Function
|
||||||
|
/* 40 */ Key::Unknown, // F17
|
||||||
|
/* 41 */ Key::Unknown, // Decimal
|
||||||
|
/* 42 */ Key::Unknown,
|
||||||
|
/* 43 */ Key::Unknown, // Multiply
|
||||||
|
/* 44 */ Key::Unknown,
|
||||||
|
/* 45 */ Key::Unknown, // Add
|
||||||
|
/* 46 */ Key::Unknown,
|
||||||
|
/* 47 */ Key::NumLock, // Really KeypadClear...
|
||||||
|
/* 48 */ Key::Unknown, // VolumeUp
|
||||||
|
/* 49 */ Key::Unknown, // VolumeDown
|
||||||
|
/* 4a */ Key::Unknown, // Mute
|
||||||
|
/* 4b */ Key::Unknown,
|
||||||
|
/* 4c */ Key::Enter,
|
||||||
|
/* 4d */ Key::Unknown,
|
||||||
|
/* 4e */ Key::Unknown, // Subtrackt
|
||||||
|
/* 4f */ Key::Unknown, // F18
|
||||||
|
/* 50 */ Key::Unknown, // F19
|
||||||
|
/* 51 */ Key::Equal,
|
||||||
|
/* 52 */ Key::NumPad0,
|
||||||
|
/* 53 */ Key::NumPad1,
|
||||||
|
/* 54 */ Key::NumPad2,
|
||||||
|
/* 55 */ Key::NumPad3,
|
||||||
|
/* 56 */ Key::NumPad4,
|
||||||
|
/* 57 */ Key::NumPad5,
|
||||||
|
/* 58 */ Key::NumPad6,
|
||||||
|
/* 59 */ Key::NumPad7,
|
||||||
|
/* 5a */ Key::Unknown, // F20
|
||||||
|
/* 5b */ Key::NumPad8,
|
||||||
|
/* 5c */ Key::NumPad9,
|
||||||
|
/* 5d */ Key::Unknown,
|
||||||
|
/* 5e */ Key::Unknown,
|
||||||
|
/* 5f */ Key::Unknown,
|
||||||
|
/* 60 */ Key::F5,
|
||||||
|
/* 61 */ Key::F6,
|
||||||
|
/* 62 */ Key::F7,
|
||||||
|
/* 63 */ Key::F3,
|
||||||
|
/* 64 */ Key::F8,
|
||||||
|
/* 65 */ Key::F9,
|
||||||
|
/* 66 */ Key::Unknown,
|
||||||
|
/* 67 */ Key::F11,
|
||||||
|
/* 68 */ Key::Unknown,
|
||||||
|
/* 69 */ Key::Unknown, // PrintScreen
|
||||||
|
/* 6a */ Key::Unknown, // F16
|
||||||
|
/* 6b */ Key::F14,
|
||||||
|
/* 6c */ Key::Unknown,
|
||||||
|
/* 6d */ Key::F10,
|
||||||
|
/* 6e */ Key::Unknown,
|
||||||
|
/* 6f */ Key::F12,
|
||||||
|
/* 70 */ Key::Unknown,
|
||||||
|
/* 71 */ Key::F15,
|
||||||
|
/* 72 */ Key::Insert, /* Really Help... */
|
||||||
|
/* 73 */ Key::Home,
|
||||||
|
/* 74 */ Key::PageUp,
|
||||||
|
/* 75 */ Key::Delete,
|
||||||
|
/* 76 */ Key::F4,
|
||||||
|
/* 77 */ Key::End,
|
||||||
|
/* 78 */ Key::F2,
|
||||||
|
/* 79 */ Key::PageDown,
|
||||||
|
/* 7a */ Key::F1,
|
||||||
|
/* 7b */ Key::Left,
|
||||||
|
/* 7c */ Key::Right,
|
||||||
|
/* 7d */ Key::Down,
|
||||||
|
/* 7e */ Key::Up,
|
||||||
|
/* 7f */ Key::Unknown,
|
||||||
|
];
|
||||||
|
|
||||||
#[link(name = "Cocoa", kind = "framework")]
|
#[link(name = "Cocoa", kind = "framework")]
|
||||||
extern {
|
extern {
|
||||||
fn mfb_open(name: *const c_char, width: u32, height: u32, scale: i32) -> *mut c_void;
|
fn mfb_open(name: *const c_char, width: u32, height: u32, scale: i32) -> *mut c_void;
|
||||||
fn mfb_close(window: *mut c_void);
|
fn mfb_close(window: *mut c_void);
|
||||||
fn mfb_update(window: *mut c_void, buffer: *const c_uchar);
|
fn mfb_update(window: *mut c_void, buffer: *const c_uchar);
|
||||||
|
fn mfb_set_key_callback(window: *mut c_void, target: *mut c_void, cb: unsafe extern fn(*mut c_void, i32, i32));
|
||||||
|
fn mfb_should_close(window: *mut c_void) -> i32;
|
||||||
|
fn mfb_get_screen_size() -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
window_handle: *mut c_void,
|
window_handle: *mut c_void,
|
||||||
|
key_handler: KeyHandler,
|
||||||
|
}
|
||||||
|
|
||||||
|
unsafe extern "C" fn key_callback(window: *mut c_void, key: i32, state: i32) {
|
||||||
|
let win: *mut Window = mem::transmute(window);
|
||||||
|
|
||||||
|
let s = state == 1;
|
||||||
|
|
||||||
|
if key > 128 {
|
||||||
|
(*win).key_handler.set_key_state(Key::Unknown, s);
|
||||||
|
} else {
|
||||||
|
(*win).key_handler.set_key_state(KEY_MAPPINGS[key as usize], s);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -34,51 +185,58 @@ impl Window {
|
||||||
return Err("Unable to open Window");
|
return Err("Unable to open Window");
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(Window { window_handle: handle })
|
Ok(Window {
|
||||||
|
window_handle: handle,
|
||||||
|
key_handler: KeyHandler::new(),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update(&mut self, buffer: &[u32]) {
|
pub fn update(&mut self, buffer: &[u32]) {
|
||||||
|
self.key_handler.update();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
mfb_update(self.window_handle, buffer.as_ptr() as *const u8);
|
mfb_update(self.window_handle, buffer.as_ptr() as *const u8);
|
||||||
|
mfb_set_key_callback(self.window_handle, mem::transmute(self), key_callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
pub fn get_keys(&self) -> Option<Vec<Key>> {
|
pub fn get_keys(&self) -> Option<Vec<Key>> {
|
||||||
None
|
self.key_handler.get_keys()
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_keys_pressed(&self, _: KeyRepeat) -> Option<Vec<Key>> {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_key_down(&self, _: Key) -> bool {
|
pub fn get_keys_pressed(&self, repeat: KeyRepeat) -> Option<Vec<Key>> {
|
||||||
false
|
self.key_handler.get_keys_pressed(repeat)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_key_repeat_delay(&mut self, _: f32) {
|
pub fn is_key_down(&self, key: Key) -> bool {
|
||||||
|
self.key_handler.is_key_down(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn set_key_repeat_rate(&mut self, _: f32) {
|
pub fn set_key_repeat_delay(&mut self, delay: f32) {
|
||||||
|
self.key_handler.set_key_repeat_delay(delay)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn key_pressed(&self, _: usize, _: KeyRepeat) -> bool {
|
#[inline]
|
||||||
false
|
pub fn set_key_repeat_rate(&mut self, rate: f32) {
|
||||||
|
self.key_handler.set_key_repeat_rate(rate)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_key_pressed(&self, _: Key, _: KeyRepeat) -> bool {
|
#[inline]
|
||||||
false
|
pub fn is_key_pressed(&self, key: Key, repeat: KeyRepeat) -> bool {
|
||||||
|
self.key_handler.is_key_pressed(key, repeat)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_open(&self) -> bool {
|
pub fn is_open(&self) -> bool {
|
||||||
true
|
unsafe { mfb_should_close(self.window_handle) == 0 }
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn get_scale_factor(_: usize, _: usize, scale: Scale) -> i32 {
|
unsafe fn get_scale_factor(width: usize, height: usize, scale: Scale) -> i32 {
|
||||||
let factor: i32 = match scale {
|
let factor: i32 = match scale {
|
||||||
Scale::X1 => 1,
|
Scale::X1 => 1,
|
||||||
Scale::X2 => 2,
|
Scale::X2 => 2,
|
||||||
|
@ -87,7 +245,24 @@ impl Window {
|
||||||
Scale::X16 => 16,
|
Scale::X16 => 16,
|
||||||
Scale::X32 => 32,
|
Scale::X32 => 32,
|
||||||
Scale::FitScreen => {
|
Scale::FitScreen => {
|
||||||
1
|
let wh: u32 = mfb_get_screen_size();
|
||||||
|
let screen_x = (wh >> 16) as i32;
|
||||||
|
let screen_y = (wh & 0xffff) as i32;
|
||||||
|
|
||||||
|
let mut scale = 1i32;
|
||||||
|
|
||||||
|
loop {
|
||||||
|
let w = width as i32 * (scale + 1);
|
||||||
|
let h = height as i32 * (scale + 1);
|
||||||
|
|
||||||
|
if w > screen_x || h > screen_y {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
scale *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
scale
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
static bool s_init = false;
|
static bool s_init = false;
|
||||||
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void* mfb_open(const char* name, int width, int height, int scale)
|
void* mfb_open(const char* name, int width, int height, int scale)
|
||||||
|
@ -25,6 +26,12 @@ void* mfb_open(const char* name, int width, int height, int scale)
|
||||||
if (!window)
|
if (!window)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
NSRect e = [[NSScreen mainScreen] frame];
|
||||||
|
int H = (int)e.size.height;
|
||||||
|
int W = (int)e.size.width;
|
||||||
|
|
||||||
|
printf("H %d W %d\n", W, H);
|
||||||
|
|
||||||
window->draw_buffer = malloc(width * height * 4);
|
window->draw_buffer = malloc(width * height * 4);
|
||||||
|
|
||||||
if (!window->draw_buffer)
|
if (!window->draw_buffer)
|
||||||
|
@ -33,6 +40,7 @@ void* mfb_open(const char* name, int width, int height, int scale)
|
||||||
window->width = width;
|
window->width = width;
|
||||||
window->height = height;
|
window->height = height;
|
||||||
window->scale = scale;
|
window->scale = scale;
|
||||||
|
window->key_callback = 0;
|
||||||
|
|
||||||
[window updateSize];
|
[window updateSize];
|
||||||
|
|
||||||
|
@ -88,3 +96,31 @@ int mfb_update(void* window, void* buffer)
|
||||||
[[win contentView] setNeedsDisplay:YES];
|
[[win contentView] setNeedsDisplay:YES];
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
int mfb_should_close(void* window)
|
||||||
|
{
|
||||||
|
OSXWindow* win = (OSXWindow*)window;
|
||||||
|
return win->should_close;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
uint32_t mfb_get_screen_size()
|
||||||
|
{
|
||||||
|
NSRect e = [[NSScreen mainScreen] frame];
|
||||||
|
uint32_t w = (uint32_t)e.size.width;
|
||||||
|
uint32_t h = (uint32_t)e.size.height;
|
||||||
|
return (w << 16) | h;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void mfb_set_key_callback(void* window, void* rust_data, void (*key_callback)(void* user_data, int key, int state))
|
||||||
|
{
|
||||||
|
OSXWindow* win = (OSXWindow*)window;
|
||||||
|
win->key_callback = key_callback;
|
||||||
|
win->rust_data = rust_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,13 @@
|
||||||
@interface OSXWindow : NSWindow
|
@interface OSXWindow : NSWindow
|
||||||
{
|
{
|
||||||
NSView* childContentView;
|
NSView* childContentView;
|
||||||
|
@public void (*key_callback)(void* user_data, int key, int state);
|
||||||
@public int width;
|
@public int width;
|
||||||
@public int height;
|
@public int height;
|
||||||
@public int scale;
|
@public int scale;
|
||||||
@public void* draw_buffer;
|
@public void* draw_buffer;
|
||||||
|
@public void* rust_data;
|
||||||
|
@public bool should_close;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -58,19 +58,87 @@
|
||||||
newFrameSize.width += sizeDelta.width;
|
newFrameSize.width += sizeDelta.width;
|
||||||
newFrameSize.height += sizeDelta.height;
|
newFrameSize.height += sizeDelta.height;
|
||||||
|
|
||||||
printf("conten size\n");
|
|
||||||
|
|
||||||
[super setContentSize:newFrameSize];
|
[super setContentSize:newFrameSize];
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
-(void)flagsChanged:(NSEvent *)event
|
||||||
|
{
|
||||||
|
const uint32_t flags = [event modifierFlags];
|
||||||
|
|
||||||
|
// Left Shift
|
||||||
|
key_callback(rust_data, 0x38, flags == 0x20102 ? 1 : 0);
|
||||||
|
|
||||||
|
// RightShift
|
||||||
|
key_callback(rust_data, 0x3c, flags == 0x20104 ? 1 : 0);
|
||||||
|
|
||||||
|
// Left Ctrl
|
||||||
|
key_callback(rust_data, 0x3b, flags == 0x40101 ? 1 : 0);
|
||||||
|
|
||||||
|
// Right Ctrl
|
||||||
|
key_callback(rust_data, 0x3b, flags == 0x42101 ? 1 : 0);
|
||||||
|
|
||||||
|
// Left Alt
|
||||||
|
key_callback(rust_data, 0x3a, flags == 0x80120 ? 1 : 0);
|
||||||
|
|
||||||
|
// Right Super
|
||||||
|
key_callback(rust_data, 0x3d, flags == 0x80140 ? 1 : 0);
|
||||||
|
|
||||||
|
// Left Super
|
||||||
|
key_callback(rust_data, 0x37, flags == 0x100108 ? 1 : 0);
|
||||||
|
|
||||||
|
// Right Super
|
||||||
|
key_callback(rust_data, 0x36, flags == 0x100110 ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (void)keyDown:(NSEvent *)event
|
||||||
|
{
|
||||||
|
// Cmd+Q always closes app
|
||||||
|
if ([event.characters.uppercaseString isEqualToString:@"Q"] && ([event modifierFlags] & NSCommandKeyMask)) {
|
||||||
|
[self performClose:self];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key_callback) {
|
||||||
|
key_callback(rust_data, [event keyCode], 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (void)keyUp:(NSEvent *)event
|
||||||
|
{
|
||||||
|
if (key_callback) {
|
||||||
|
key_callback(rust_data, [event keyCode], 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
- (void)mainWindowChanged:(NSNotification *)aNotification
|
- (void)mainWindowChanged:(NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (void)windowWillClose:(NSNotification *)notification
|
||||||
|
{
|
||||||
|
should_close = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
- (BOOL)windowShouldClose:(id)sender
|
||||||
|
{
|
||||||
|
should_close = true;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
- (void)setContentView:(NSView *)aView
|
- (void)setContentView:(NSView *)aView
|
||||||
{
|
{
|
||||||
if ([childContentView isEqualTo:aView])
|
if ([childContentView isEqualTo:aView])
|
||||||
|
|
|
@ -6,9 +6,7 @@ extern crate winapi;
|
||||||
extern crate gdi32;
|
extern crate gdi32;
|
||||||
extern crate time;
|
extern crate time;
|
||||||
|
|
||||||
use Scale;
|
use {Scale, Key, KeyRepeat, KeyHandler};
|
||||||
use Key;
|
|
||||||
use KeyRepeat;
|
|
||||||
|
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
use std::os::windows::ffi::OsStrExt;
|
use std::os::windows::ffi::OsStrExt;
|
||||||
|
@ -217,17 +215,12 @@ fn to_wstring(str: &str) -> Vec<u16> {
|
||||||
pub struct Window {
|
pub struct Window {
|
||||||
dc: Option<HDC>,
|
dc: Option<HDC>,
|
||||||
window: Option<HWND>,
|
window: Option<HWND>,
|
||||||
keys: [bool; 512],
|
|
||||||
keys_down_duration: [f32; 512],
|
|
||||||
buffer: Vec<u32>,
|
buffer: Vec<u32>,
|
||||||
is_open : bool,
|
is_open : bool,
|
||||||
scale_factor: i32,
|
scale_factor: i32,
|
||||||
width: i32,
|
width: i32,
|
||||||
height: i32,
|
height: i32,
|
||||||
prev_time: f64,
|
key_handler: KeyHandler,
|
||||||
delta_time: f32,
|
|
||||||
key_repeat_delay: f32,
|
|
||||||
key_repeat_rate: f32,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Window {
|
impl Window {
|
||||||
|
@ -316,13 +309,8 @@ impl Window {
|
||||||
let window = Window {
|
let window = Window {
|
||||||
dc: Some(user32::GetDC(handle.unwrap())),
|
dc: Some(user32::GetDC(handle.unwrap())),
|
||||||
window: Some(handle.unwrap()),
|
window: Some(handle.unwrap()),
|
||||||
keys: [false; 512],
|
|
||||||
keys_down_duration: [-1.0; 512],
|
|
||||||
prev_time: time::precise_time_s(),
|
|
||||||
delta_time: 0.0,
|
|
||||||
key_repeat_delay: 0.250,
|
|
||||||
key_repeat_rate: 0.050,
|
|
||||||
buffer: Vec::new(),
|
buffer: Vec::new(),
|
||||||
|
key_handler: KeyHandler::new(),
|
||||||
is_open: true,
|
is_open: true,
|
||||||
scale_factor: scale_factor,
|
scale_factor: scale_factor,
|
||||||
width: width as i32,
|
width: width as i32,
|
||||||
|
@ -415,23 +403,6 @@ impl Window {
|
||||||
let mut msg = mem::uninitialized();
|
let mut msg = mem::uninitialized();
|
||||||
let window = self.window.unwrap();
|
let window = self.window.unwrap();
|
||||||
|
|
||||||
let current_time = time::precise_time_s();
|
|
||||||
let delta_time = (current_time - self.prev_time) as f32;
|
|
||||||
self.prev_time = current_time;
|
|
||||||
self.delta_time = delta_time;
|
|
||||||
|
|
||||||
for i in 0..self.keys.len() {
|
|
||||||
if self.keys[i] {
|
|
||||||
if self.keys_down_duration[i] < 0.0 {
|
|
||||||
self.keys_down_duration[i] = 0.0;
|
|
||||||
} else {
|
|
||||||
self.keys_down_duration[i] += delta_time;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.keys_down_duration[i] = -1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Optimize
|
// TODO: Optimize
|
||||||
|
|
||||||
self.buffer = buffer.iter().cloned().collect();
|
self.buffer = buffer.iter().cloned().collect();
|
||||||
|
|
Loading…
Add table
Reference in a new issue