mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 19:31:30 +11:00
Added X11 keyboard support
This commit is contained in:
parent
9c07aaae60
commit
fa8101b885
|
@ -28,6 +28,8 @@ static XContext s_context;
|
|||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
typedef struct WindowInfo {
|
||||
void (*key_callback)(void* user_data, int key, int state);
|
||||
void* rust_data;
|
||||
Window window;
|
||||
XImage* ximage;
|
||||
void* draw_buffer;
|
||||
|
@ -129,6 +131,7 @@ void* mfb_open(const char* title, int width, int height, int scale)
|
|||
sizeHints.min_height = height;
|
||||
sizeHints.max_height = height;
|
||||
|
||||
XSelectInput(s_display, window, KeyPressMask | KeyReleaseMask);
|
||||
XSetWMNormalHints(s_display, window, &sizeHints);
|
||||
XClearWindow(s_display, window);
|
||||
XMapRaised(s_display, window);
|
||||
|
@ -143,6 +146,8 @@ void* mfb_open(const char* title, int width, int height, int scale)
|
|||
}
|
||||
|
||||
window_info = (WindowInfo*)malloc(sizeof(WindowInfo));
|
||||
window_info->key_callback = 0;
|
||||
window_info->rust_data = 0;
|
||||
window_info->window = window;
|
||||
window_info->ximage = image;
|
||||
window_info->scale = scale;
|
||||
|
@ -161,19 +166,36 @@ void* mfb_open(const char* title, int width, int height, int scale)
|
|||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static WindowInfo* find_handle(Window handle)
|
||||
{
|
||||
WindowInfo* info;
|
||||
|
||||
if (XFindContext(s_display, handle, s_context, (XPointer*) &info) != 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void process_event(XEvent* event) {
|
||||
KeySym sym;
|
||||
|
||||
if (event->type != KeyPress)
|
||||
WindowInfo* info = find_handle(event->xany.window);
|
||||
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
sym = XLookupKeysym(&event->xkey, 0);
|
||||
if ((event->type == KeyPress) || (event->type == KeyRelease) && info->key_callback) {
|
||||
int sym = XLookupKeysym(&event->xkey, 0);
|
||||
|
||||
if ((sym >> 8) != KEY_FUNCTION)
|
||||
return;
|
||||
|
||||
if ((sym & 0xFF) == KEY_ESC)
|
||||
return;
|
||||
if (event->type == KeyPress) {
|
||||
info->key_callback(info->rust_data, sym, 1);
|
||||
} else if (event->type == KeyRelease) {
|
||||
info->key_callback(info->rust_data, sym, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -185,6 +207,7 @@ static int process_events()
|
|||
KeySym sym;
|
||||
|
||||
count = XPending(s_display);
|
||||
|
||||
while (count--)
|
||||
{
|
||||
XEvent event;
|
||||
|
@ -230,3 +253,13 @@ void mfb_close(void* window_info)
|
|||
XCloseDisplay(s_display);
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void mfb_set_key_callback(void* window, void* rust_data, void (*key_callback)(void* user_data, int key, int state))
|
||||
{
|
||||
WindowInfo* win = (WindowInfo*)window;
|
||||
win->key_callback = key_callback;
|
||||
win->rust_data = rust_data;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,19 +1,22 @@
|
|||
#![cfg(unix)]
|
||||
|
||||
extern crate x11_dl;
|
||||
|
||||
use {Scale, Key, KeyRepeat};
|
||||
use key_handler::KeyHandler;
|
||||
use self::x11_dl::keysym::*;
|
||||
|
||||
use libc::{c_void, c_char, c_uchar};
|
||||
use std::ffi::{CString};
|
||||
use std::ptr;
|
||||
//use std::mem;
|
||||
use std::mem;
|
||||
|
||||
#[link(name = "X11")]
|
||||
extern {
|
||||
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_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_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;
|
||||
}
|
||||
|
@ -23,6 +26,118 @@ pub struct Window {
|
|||
key_handler: KeyHandler,
|
||||
}
|
||||
|
||||
#[allow(non_upper_case_globals)]
|
||||
unsafe extern "C" fn key_callback(window: *mut c_void, key: i32, s: i32) {
|
||||
let win: *mut Window = mem::transmute(window);
|
||||
|
||||
let state = s == 1;
|
||||
|
||||
match key as u32 {
|
||||
XK_0 => (*win).key_handler.set_key_state(Key::Key0, state),
|
||||
XK_1 => (*win).key_handler.set_key_state(Key::Key1, state),
|
||||
XK_2 => (*win).key_handler.set_key_state(Key::Key2, state),
|
||||
XK_3 => (*win).key_handler.set_key_state(Key::Key3, state),
|
||||
XK_4 => (*win).key_handler.set_key_state(Key::Key4, state),
|
||||
XK_5 => (*win).key_handler.set_key_state(Key::Key5, state),
|
||||
XK_6 => (*win).key_handler.set_key_state(Key::Key6, state),
|
||||
XK_7 => (*win).key_handler.set_key_state(Key::Key7, state),
|
||||
XK_8 => (*win).key_handler.set_key_state(Key::Key8, state),
|
||||
XK_9 => (*win).key_handler.set_key_state(Key::Key9, state),
|
||||
XK_a => (*win).key_handler.set_key_state(Key::A, state),
|
||||
XK_b => (*win).key_handler.set_key_state(Key::B, state),
|
||||
XK_c => (*win).key_handler.set_key_state(Key::C, state),
|
||||
XK_d => (*win).key_handler.set_key_state(Key::D, state),
|
||||
XK_e => (*win).key_handler.set_key_state(Key::E, state),
|
||||
XK_f => (*win).key_handler.set_key_state(Key::F, state),
|
||||
XK_g => (*win).key_handler.set_key_state(Key::G, state),
|
||||
XK_h => (*win).key_handler.set_key_state(Key::H, state),
|
||||
XK_i => (*win).key_handler.set_key_state(Key::I, state),
|
||||
XK_j => (*win).key_handler.set_key_state(Key::J, state),
|
||||
XK_k => (*win).key_handler.set_key_state(Key::K, state),
|
||||
XK_l => (*win).key_handler.set_key_state(Key::L, state),
|
||||
XK_m => (*win).key_handler.set_key_state(Key::M, state),
|
||||
XK_n => (*win).key_handler.set_key_state(Key::N, state),
|
||||
XK_o => (*win).key_handler.set_key_state(Key::O, state),
|
||||
XK_p => (*win).key_handler.set_key_state(Key::P, state),
|
||||
XK_q => (*win).key_handler.set_key_state(Key::Q, state),
|
||||
XK_r => (*win).key_handler.set_key_state(Key::R, state),
|
||||
XK_s => (*win).key_handler.set_key_state(Key::S, state),
|
||||
XK_t => (*win).key_handler.set_key_state(Key::T, state),
|
||||
XK_u => (*win).key_handler.set_key_state(Key::U, state),
|
||||
XK_v => (*win).key_handler.set_key_state(Key::V, state),
|
||||
XK_w => (*win).key_handler.set_key_state(Key::W, state),
|
||||
XK_x => (*win).key_handler.set_key_state(Key::X, state),
|
||||
XK_y => (*win).key_handler.set_key_state(Key::Y, state),
|
||||
XK_z => (*win).key_handler.set_key_state(Key::Z, state),
|
||||
XK_F1 => (*win).key_handler.set_key_state(Key::F1, state),
|
||||
XK_F2 => (*win).key_handler.set_key_state(Key::F2, state),
|
||||
XK_F3 => (*win).key_handler.set_key_state(Key::F3, state),
|
||||
XK_F4 => (*win).key_handler.set_key_state(Key::F4, state),
|
||||
XK_F5 => (*win).key_handler.set_key_state(Key::F5, state),
|
||||
XK_F6 => (*win).key_handler.set_key_state(Key::F6, state),
|
||||
XK_F7 => (*win).key_handler.set_key_state(Key::F7, state),
|
||||
XK_F8 => (*win).key_handler.set_key_state(Key::F8, state),
|
||||
XK_F9 => (*win).key_handler.set_key_state(Key::F9, state),
|
||||
XK_F10 => (*win).key_handler.set_key_state(Key::F10, state),
|
||||
XK_F11 => (*win).key_handler.set_key_state(Key::F11, state),
|
||||
XK_F12 => (*win).key_handler.set_key_state(Key::F12, state),
|
||||
XK_Down => (*win).key_handler.set_key_state(Key::Down, state),
|
||||
XK_Left => (*win).key_handler.set_key_state(Key::Left, state),
|
||||
XK_Right => (*win).key_handler.set_key_state(Key::Right, state),
|
||||
XK_Up => (*win).key_handler.set_key_state(Key::Up, state),
|
||||
XK_apostrophe => (*win).key_handler.set_key_state(Key::Apostrophe, state),
|
||||
XK_grave => (*win).key_handler.set_key_state(Key::Backquote, state),
|
||||
XK_backslash => (*win).key_handler.set_key_state(Key::Backslash, state),
|
||||
XK_comma => (*win).key_handler.set_key_state(Key::Comma, state),
|
||||
XK_equal => (*win).key_handler.set_key_state(Key::Equal, state),
|
||||
XK_bracketleft => (*win).key_handler.set_key_state(Key::LeftBracket, state),
|
||||
XK_minus => (*win).key_handler.set_key_state(Key::Minus, state),
|
||||
//XP_period => (*win).key_handler.set_key_state(Key::Period, state),
|
||||
XK_braceright => (*win).key_handler.set_key_state(Key::RightBracket, state),
|
||||
XK_semicolon => (*win).key_handler.set_key_state(Key::Semicolon, state),
|
||||
XK_slash => (*win).key_handler.set_key_state(Key::Slash, state),
|
||||
//XK_backslash => (*win).key_handler.set_key_state(Key::Backspace, state),
|
||||
XK_Delete => (*win).key_handler.set_key_state(Key::Delete, state),
|
||||
XK_End => (*win).key_handler.set_key_state(Key::End, state),
|
||||
XK_Return => (*win).key_handler.set_key_state(Key::Enter, state),
|
||||
XK_Escape => (*win).key_handler.set_key_state(Key::Escape, state),
|
||||
XK_Home => (*win).key_handler.set_key_state(Key::Home, state),
|
||||
XK_Insert => (*win).key_handler.set_key_state(Key::Insert, state),
|
||||
XK_Menu => (*win).key_handler.set_key_state(Key::Menu, state),
|
||||
XK_Page_Down => (*win).key_handler.set_key_state(Key::PageDown, state),
|
||||
XK_Page_Up => (*win).key_handler.set_key_state(Key::PageUp, state),
|
||||
XK_Pause => (*win).key_handler.set_key_state(Key::Pause, state),
|
||||
XK_space => (*win).key_handler.set_key_state(Key::Space, state),
|
||||
XK_Tab => (*win).key_handler.set_key_state(Key::Tab, state),
|
||||
XK_Num_Lock => (*win).key_handler.set_key_state(Key::NumLock, state),
|
||||
XK_Caps_Lock => (*win).key_handler.set_key_state(Key::CapsLock, state),
|
||||
XK_Scroll_Lock => (*win).key_handler.set_key_state(Key::ScrollLock, state),
|
||||
XK_Shift_L => (*win).key_handler.set_key_state(Key::LeftShift, state),
|
||||
XK_Shift_R => (*win).key_handler.set_key_state(Key::RightShift, state),
|
||||
XK_Control_L => (*win).key_handler.set_key_state(Key::LeftCtrl, state),
|
||||
XK_Control_R => (*win).key_handler.set_key_state(Key::RightCtrl, state),
|
||||
XK_KP_0 => (*win).key_handler.set_key_state(Key::NumPad0, state),
|
||||
XK_KP_1 => (*win).key_handler.set_key_state(Key::NumPad1, state),
|
||||
XK_KP_2 => (*win).key_handler.set_key_state(Key::NumPad2, state),
|
||||
XK_KP_3 => (*win).key_handler.set_key_state(Key::NumPad3, state),
|
||||
XK_KP_4 => (*win).key_handler.set_key_state(Key::NumPad4, state),
|
||||
XK_KP_5 => (*win).key_handler.set_key_state(Key::NumPad5, state),
|
||||
XK_KP_6 => (*win).key_handler.set_key_state(Key::NumPad6, state),
|
||||
XK_KP_7 => (*win).key_handler.set_key_state(Key::NumPad7, state),
|
||||
XK_KP_8 => (*win).key_handler.set_key_state(Key::NumPad8, state),
|
||||
XK_KP_9 => (*win).key_handler.set_key_state(Key::NumPad9, state),
|
||||
XK_KP_Decimal => (*win).key_handler.set_key_state(Key::NumPadDot, state),
|
||||
XK_KP_Divide => (*win).key_handler.set_key_state(Key::NumPadSlash, state),
|
||||
XK_KP_Multiply => (*win).key_handler.set_key_state(Key::NumPadAsterisk, state),
|
||||
XK_KP_Subtract => (*win).key_handler.set_key_state(Key::NumPadMinus, state),
|
||||
XK_KP_Add => (*win).key_handler.set_key_state(Key::NumPadPlus, state),
|
||||
XK_KP_Enter => (*win).key_handler.set_key_state(Key::NumPadEnter, state),
|
||||
XK_Super_L => (*win).key_handler.set_key_state(Key::LeftSuper, state),
|
||||
XK_Super_R => (*win).key_handler.set_key_state(Key::RightSuper, state),
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
|
||||
impl Window {
|
||||
pub fn new(name: &str, width: usize, height: usize, scale: Scale) -> Result<Window, &str> {
|
||||
let n = match CString::new(name) {
|
||||
|
@ -52,7 +167,7 @@ impl Window {
|
|||
|
||||
unsafe {
|
||||
mfb_update(self.window_handle, buffer.as_ptr() as *const u8);
|
||||
//mfb_set_key_callback(self.window_handle, mem::transmute(self), key_callback);
|
||||
mfb_set_key_callback(self.window_handle, mem::transmute(self), key_callback);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue