mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-24 03:41:29 +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 {
|
typedef struct WindowInfo {
|
||||||
|
void (*key_callback)(void* user_data, int key, int state);
|
||||||
|
void* rust_data;
|
||||||
Window window;
|
Window window;
|
||||||
XImage* ximage;
|
XImage* ximage;
|
||||||
void* draw_buffer;
|
void* draw_buffer;
|
||||||
|
@ -129,6 +131,7 @@ void* mfb_open(const char* title, int width, int height, int scale)
|
||||||
sizeHints.min_height = height;
|
sizeHints.min_height = height;
|
||||||
sizeHints.max_height = height;
|
sizeHints.max_height = height;
|
||||||
|
|
||||||
|
XSelectInput(s_display, window, KeyPressMask | KeyReleaseMask);
|
||||||
XSetWMNormalHints(s_display, window, &sizeHints);
|
XSetWMNormalHints(s_display, window, &sizeHints);
|
||||||
XClearWindow(s_display, window);
|
XClearWindow(s_display, window);
|
||||||
XMapRaised(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 = (WindowInfo*)malloc(sizeof(WindowInfo));
|
||||||
|
window_info->key_callback = 0;
|
||||||
|
window_info->rust_data = 0;
|
||||||
window_info->window = window;
|
window_info->window = window;
|
||||||
window_info->ximage = image;
|
window_info->ximage = image;
|
||||||
window_info->scale = scale;
|
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) {
|
static void process_event(XEvent* event) {
|
||||||
KeySym sym;
|
KeySym sym;
|
||||||
|
|
||||||
if (event->type != KeyPress)
|
WindowInfo* info = find_handle(event->xany.window);
|
||||||
|
|
||||||
|
if (!info)
|
||||||
return;
|
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)
|
if (event->type == KeyPress) {
|
||||||
return;
|
info->key_callback(info->rust_data, sym, 1);
|
||||||
|
} else if (event->type == KeyRelease) {
|
||||||
if ((sym & 0xFF) == KEY_ESC)
|
info->key_callback(info->rust_data, sym, 0);
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -185,6 +207,7 @@ static int process_events()
|
||||||
KeySym sym;
|
KeySym sym;
|
||||||
|
|
||||||
count = XPending(s_display);
|
count = XPending(s_display);
|
||||||
|
|
||||||
while (count--)
|
while (count--)
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
|
@ -230,3 +253,13 @@ void mfb_close(void* window_info)
|
||||||
XCloseDisplay(s_display);
|
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)]
|
#![cfg(unix)]
|
||||||
|
|
||||||
|
extern crate x11_dl;
|
||||||
|
|
||||||
use {Scale, Key, KeyRepeat};
|
use {Scale, Key, KeyRepeat};
|
||||||
use key_handler::KeyHandler;
|
use key_handler::KeyHandler;
|
||||||
|
use self::x11_dl::keysym::*;
|
||||||
|
|
||||||
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;
|
use std::mem;
|
||||||
|
|
||||||
#[link(name = "X11")]
|
#[link(name = "X11")]
|
||||||
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_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_should_close(window: *mut c_void) -> i32;
|
||||||
//fn mfb_get_screen_size() -> u32;
|
//fn mfb_get_screen_size() -> u32;
|
||||||
}
|
}
|
||||||
|
@ -23,6 +26,118 @@ pub struct Window {
|
||||||
key_handler: KeyHandler,
|
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 {
|
impl Window {
|
||||||
pub fn new(name: &str, width: usize, height: usize, scale: Scale) -> Result<Window, &str> {
|
pub fn new(name: &str, width: usize, height: usize, scale: Scale) -> Result<Window, &str> {
|
||||||
let n = match CString::new(name) {
|
let n = match CString::new(name) {
|
||||||
|
@ -52,7 +167,7 @@ impl Window {
|
||||||
|
|
||||||
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);
|
mfb_set_key_callback(self.window_handle, mem::transmute(self), key_callback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue