mirror of
https://github.com/italicsjenga/rust_minifb.git
synced 2024-12-23 11:21:30 +11:00
Reduce wayland dependencies (#293)
This change removes dependency on the `xkb` and `xkbcommon-sys` crates (and this indirectly, `bindgen` and everything below it) by using our own ffi wrapper, based on sctk's. A new feature `dlopen`, enabled by default, is added that causes xkbcommon to be loaded at runtime instead of linked at build-time.
This commit is contained in:
parent
7019ba41ea
commit
e96380375c
22
Cargo.toml
22
Cargo.toml
|
@ -31,15 +31,17 @@ version = "0.3"
|
|||
features = ["winuser", "wingdi", "libloaderapi", "errhandlingapi", "fileapi"]
|
||||
|
||||
[features]
|
||||
default = ["wayland", "x11"]
|
||||
x11 = ["x11-dl", "xkb", "libc"]
|
||||
default = ["wayland", "x11", "dlopen"]
|
||||
dlopen = ["wayland-client/dlopen"]
|
||||
x11 = ["x11-dl", "libc"]
|
||||
wayland = [
|
||||
"wayland-client",
|
||||
"wayland-protocols",
|
||||
"wayland-cursor",
|
||||
"tempfile",
|
||||
"xkb",
|
||||
"xkbcommon-sys",
|
||||
"dlib",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"tempfile",
|
||||
"wayland-client",
|
||||
"wayland-cursor",
|
||||
"wayland-protocols",
|
||||
]
|
||||
web = [
|
||||
"wasm-bindgen",
|
||||
|
@ -56,10 +58,10 @@ wayland-protocols = { version = "0.29", features = [
|
|||
], optional = true }
|
||||
wayland-cursor = { version = "0.29", optional = true }
|
||||
tempfile = { version = "3.3", optional = true }
|
||||
xkb = { version = "0.2.1", optional = true }
|
||||
xkbcommon-sys = { version = "0.7.5", optional = true }
|
||||
x11-dl = { version = "2.19.1", optional = true }
|
||||
libc = { version = "0.2.107", optional = true }
|
||||
dlib = { version = "0.5", optional = true }
|
||||
lazy_static = { version = "1.0", optional = true }
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -5,6 +5,11 @@
|
|||
//!
|
||||
#![deny(missing_debug_implementations)]
|
||||
|
||||
#[cfg(not(any(target_os = "macos", target_os = "redox", windows)))]
|
||||
#[cfg(feature = "wayland")]
|
||||
#[macro_use]
|
||||
extern crate dlib;
|
||||
|
||||
use std::fmt;
|
||||
use std::os::raw;
|
||||
|
||||
|
|
|
@ -13,6 +13,10 @@ mod common;
|
|||
mod wayland;
|
||||
#[cfg(feature = "x11")]
|
||||
mod x11;
|
||||
#[cfg(feature = "wayland")]
|
||||
mod xkb_ffi;
|
||||
#[cfg(feature = "wayland")]
|
||||
mod xkb_keysyms;
|
||||
|
||||
use crate::icon::Icon;
|
||||
use crate::Result;
|
||||
|
|
|
@ -9,6 +9,11 @@ use crate::{
|
|||
};
|
||||
|
||||
use super::common::Menu;
|
||||
use super::xkb_ffi;
|
||||
#[cfg(feature = "dlopen")]
|
||||
use super::xkb_ffi::XKBCOMMON_HANDLE as XKBH;
|
||||
#[cfg(not(feature = "dlopen"))]
|
||||
use super::xkb_ffi::*;
|
||||
|
||||
use wayland_client::protocol::wl_buffer::WlBuffer;
|
||||
use wayland_client::protocol::wl_compositor::WlCompositor;
|
||||
|
@ -25,8 +30,6 @@ use wayland_protocols::unstable::xdg_decoration::v1::client::zxdg_decoration_man
|
|||
use wayland_protocols::xdg_shell::client::xdg_surface::XdgSurface;
|
||||
use wayland_protocols::xdg_shell::client::xdg_toplevel::XdgToplevel;
|
||||
use wayland_protocols::xdg_shell::client::xdg_wm_base::XdgWmBase;
|
||||
use xkb::keymap::Keymap;
|
||||
use xkb::state::State;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::ffi::c_void;
|
||||
|
@ -34,6 +37,7 @@ use std::fs::File;
|
|||
use std::io::{self, Seek, SeekFrom, Write};
|
||||
use std::mem;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::ptr;
|
||||
use std::rc::Rc;
|
||||
use std::slice;
|
||||
use std::sync::mpsc;
|
||||
|
@ -488,9 +492,11 @@ pub struct Window {
|
|||
active: bool,
|
||||
|
||||
key_handler: KeyHandler,
|
||||
// Option because MaybeUninit's get_ref() is nightly-only
|
||||
keymap: Option<Keymap>,
|
||||
keymap_state: Option<State>,
|
||||
|
||||
xkb_context: *mut xkb_ffi::xkb_context,
|
||||
xkb_keymap: *mut xkb_ffi::xkb_keymap,
|
||||
xkb_state: *mut xkb_ffi::xkb_state,
|
||||
|
||||
update_rate: UpdateRate,
|
||||
menu_counter: MenuHandle,
|
||||
menus: Vec<UnixMenu>,
|
||||
|
@ -533,6 +539,27 @@ impl Window {
|
|||
|
||||
let (resolution, closed) = display.get_toplevel_info();
|
||||
|
||||
#[cfg(feature = "dlopen")]
|
||||
{
|
||||
if xkb_ffi::XKBCOMMON_OPTION.as_ref().is_none() {
|
||||
return Err(Error::WindowCreate(
|
||||
"Could not load xkbcommon shared library.".to_owned(),
|
||||
));
|
||||
}
|
||||
}
|
||||
let context = unsafe {
|
||||
ffi_dispatch!(
|
||||
XKBH,
|
||||
xkb_context_new,
|
||||
xkb_ffi::xkb_context_flags::XKB_CONTEXT_NO_FLAGS
|
||||
)
|
||||
};
|
||||
if context.is_null() {
|
||||
return Err(Error::WindowCreate(
|
||||
"Could not create xkb context.".to_owned(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
display,
|
||||
|
||||
|
@ -554,8 +581,11 @@ impl Window {
|
|||
active: false,
|
||||
|
||||
key_handler: KeyHandler::new(),
|
||||
keymap: None,
|
||||
keymap_state: None,
|
||||
|
||||
xkb_context: context,
|
||||
xkb_keymap: ptr::null_mut(),
|
||||
xkb_state: ptr::null_mut(),
|
||||
|
||||
update_rate: UpdateRate::new(),
|
||||
menu_counter: MenuHandle(0),
|
||||
menus: Vec::new(),
|
||||
|
@ -764,9 +794,9 @@ impl Window {
|
|||
|
||||
match event {
|
||||
Event::Keymap { format, fd, size } => {
|
||||
let keymap = Self::handle_keymap(format, fd, size).unwrap();
|
||||
self.keymap_state = Some(keymap.state());
|
||||
self.keymap = Some(keymap);
|
||||
let keymap = Self::handle_keymap(self.xkb_context, format, fd, size).unwrap();
|
||||
self.xkb_keymap = keymap;
|
||||
self.xkb_state = unsafe { ffi_dispatch!(XKBH, xkb_state_new, keymap) };
|
||||
}
|
||||
Event::Enter { .. } => {
|
||||
self.active = true;
|
||||
|
@ -775,9 +805,9 @@ impl Window {
|
|||
self.active = false;
|
||||
}
|
||||
Event::Key { key, state, .. } => {
|
||||
if let Some(ref keymap_state) = self.keymap_state {
|
||||
if !self.xkb_state.is_null() {
|
||||
Self::handle_key(
|
||||
keymap_state,
|
||||
self.xkb_state,
|
||||
key + KEY_XKB_OFFSET,
|
||||
state,
|
||||
&mut self.key_handler,
|
||||
|
@ -791,9 +821,20 @@ impl Window {
|
|||
group,
|
||||
..
|
||||
} => {
|
||||
if let Some(ref mut state) = self.keymap_state {
|
||||
let mut update = state.update();
|
||||
update.mask(mods_depressed, mods_latched, mods_locked, 0, 0, group);
|
||||
if !self.xkb_state.is_null() {
|
||||
unsafe {
|
||||
ffi_dispatch!(
|
||||
XKBH,
|
||||
xkb_state_update_mask,
|
||||
self.xkb_state,
|
||||
mods_depressed,
|
||||
mods_latched,
|
||||
mods_locked,
|
||||
0,
|
||||
0,
|
||||
group
|
||||
)
|
||||
};
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -928,20 +969,19 @@ impl Window {
|
|||
}
|
||||
|
||||
fn handle_key(
|
||||
keymap_state: &State,
|
||||
keymap_state: *mut xkb_ffi::xkb_state,
|
||||
key: u32,
|
||||
state: wl_keyboard::KeyState,
|
||||
key_handler: &mut KeyHandler,
|
||||
) {
|
||||
let is_down = state == wl_keyboard::KeyState::Pressed;
|
||||
let key_xkb = keymap_state.key(key);
|
||||
|
||||
if let Some(keysym) = key_xkb.sym() {
|
||||
use xkb::key;
|
||||
let key_xkb = unsafe { ffi_dispatch!(XKBH, xkb_state_key_get_one_sym, keymap_state, key) };
|
||||
if key_xkb != 0 {
|
||||
use super::xkb_keysyms as key;
|
||||
|
||||
if state == wl_keyboard::KeyState::Pressed {
|
||||
// Taken from GLFW
|
||||
let code_point = keysym.utf32();
|
||||
let code_point = unsafe { ffi_dispatch!(XKBH, xkb_keysym_to_utf32, key_xkb) };
|
||||
if !(code_point < 32 || (code_point > 126 && code_point < 160)) {
|
||||
if let Some(ref mut callback) = key_handler.key_callback {
|
||||
callback.add_char(code_point);
|
||||
|
@ -949,115 +989,115 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
let key_i = match keysym {
|
||||
key::_0 => Key::Key0,
|
||||
key::_1 => Key::Key1,
|
||||
key::_2 => Key::Key2,
|
||||
key::_3 => Key::Key3,
|
||||
key::_4 => Key::Key4,
|
||||
key::_5 => Key::Key5,
|
||||
key::_6 => Key::Key6,
|
||||
key::_7 => Key::Key7,
|
||||
key::_8 => Key::Key8,
|
||||
key::_9 => Key::Key9,
|
||||
let key_i = match key_xkb {
|
||||
key::XKB_KEY_0 => Key::Key0,
|
||||
key::XKB_KEY_1 => Key::Key1,
|
||||
key::XKB_KEY_2 => Key::Key2,
|
||||
key::XKB_KEY_3 => Key::Key3,
|
||||
key::XKB_KEY_4 => Key::Key4,
|
||||
key::XKB_KEY_5 => Key::Key5,
|
||||
key::XKB_KEY_6 => Key::Key6,
|
||||
key::XKB_KEY_7 => Key::Key7,
|
||||
key::XKB_KEY_8 => Key::Key8,
|
||||
key::XKB_KEY_9 => Key::Key9,
|
||||
|
||||
key::a => Key::A,
|
||||
key::b => Key::B,
|
||||
key::c => Key::C,
|
||||
key::d => Key::D,
|
||||
key::e => Key::E,
|
||||
key::f => Key::F,
|
||||
key::g => Key::G,
|
||||
key::h => Key::H,
|
||||
key::i => Key::I,
|
||||
key::j => Key::J,
|
||||
key::k => Key::K,
|
||||
key::l => Key::L,
|
||||
key::m => Key::M,
|
||||
key::n => Key::N,
|
||||
key::o => Key::O,
|
||||
key::p => Key::P,
|
||||
key::q => Key::Q,
|
||||
key::r => Key::R,
|
||||
key::s => Key::S,
|
||||
key::t => Key::T,
|
||||
key::u => Key::U,
|
||||
key::v => Key::V,
|
||||
key::w => Key::W,
|
||||
key::x => Key::X,
|
||||
key::y => Key::Y,
|
||||
key::z => Key::Z,
|
||||
key::XKB_KEY_a => Key::A,
|
||||
key::XKB_KEY_b => Key::B,
|
||||
key::XKB_KEY_c => Key::C,
|
||||
key::XKB_KEY_d => Key::D,
|
||||
key::XKB_KEY_e => Key::E,
|
||||
key::XKB_KEY_f => Key::F,
|
||||
key::XKB_KEY_g => Key::G,
|
||||
key::XKB_KEY_h => Key::H,
|
||||
key::XKB_KEY_i => Key::I,
|
||||
key::XKB_KEY_j => Key::J,
|
||||
key::XKB_KEY_k => Key::K,
|
||||
key::XKB_KEY_l => Key::L,
|
||||
key::XKB_KEY_m => Key::M,
|
||||
key::XKB_KEY_n => Key::N,
|
||||
key::XKB_KEY_o => Key::O,
|
||||
key::XKB_KEY_p => Key::P,
|
||||
key::XKB_KEY_q => Key::Q,
|
||||
key::XKB_KEY_r => Key::R,
|
||||
key::XKB_KEY_s => Key::S,
|
||||
key::XKB_KEY_t => Key::T,
|
||||
key::XKB_KEY_u => Key::U,
|
||||
key::XKB_KEY_v => Key::V,
|
||||
key::XKB_KEY_w => Key::W,
|
||||
key::XKB_KEY_x => Key::X,
|
||||
key::XKB_KEY_y => Key::Y,
|
||||
key::XKB_KEY_z => Key::Z,
|
||||
|
||||
key::apostrophe => Key::Apostrophe,
|
||||
key::grave => Key::Backquote,
|
||||
key::backslash => Key::Backslash,
|
||||
key::comma => Key::Comma,
|
||||
key::equal => Key::Equal,
|
||||
key::bracketleft => Key::LeftBracket,
|
||||
key::bracketright => Key::RightBracket,
|
||||
key::minus => Key::Minus,
|
||||
key::period => Key::Period,
|
||||
key::semicolon => Key::Semicolon,
|
||||
key::slash => Key::Slash,
|
||||
key::space => Key::Space,
|
||||
key::XKB_KEY_apostrophe => Key::Apostrophe,
|
||||
key::XKB_KEY_grave => Key::Backquote,
|
||||
key::XKB_KEY_backslash => Key::Backslash,
|
||||
key::XKB_KEY_comma => Key::Comma,
|
||||
key::XKB_KEY_equal => Key::Equal,
|
||||
key::XKB_KEY_bracketleft => Key::LeftBracket,
|
||||
key::XKB_KEY_bracketright => Key::RightBracket,
|
||||
key::XKB_KEY_minus => Key::Minus,
|
||||
key::XKB_KEY_period => Key::Period,
|
||||
key::XKB_KEY_semicolon => Key::Semicolon,
|
||||
key::XKB_KEY_slash => Key::Slash,
|
||||
key::XKB_KEY_space => Key::Space,
|
||||
|
||||
key::F1 => Key::F1,
|
||||
key::F2 => Key::F2,
|
||||
key::F3 => Key::F3,
|
||||
key::F4 => Key::F4,
|
||||
key::F5 => Key::F5,
|
||||
key::F6 => Key::F6,
|
||||
key::F7 => Key::F7,
|
||||
key::F8 => Key::F8,
|
||||
key::F9 => Key::F9,
|
||||
key::F10 => Key::F10,
|
||||
key::F11 => Key::F11,
|
||||
key::F12 => Key::F12,
|
||||
key::XKB_KEY_F1 => Key::F1,
|
||||
key::XKB_KEY_F2 => Key::F2,
|
||||
key::XKB_KEY_F3 => Key::F3,
|
||||
key::XKB_KEY_F4 => Key::F4,
|
||||
key::XKB_KEY_F5 => Key::F5,
|
||||
key::XKB_KEY_F6 => Key::F6,
|
||||
key::XKB_KEY_F7 => Key::F7,
|
||||
key::XKB_KEY_F8 => Key::F8,
|
||||
key::XKB_KEY_F9 => Key::F9,
|
||||
key::XKB_KEY_F10 => Key::F10,
|
||||
key::XKB_KEY_F11 => Key::F11,
|
||||
key::XKB_KEY_F12 => Key::F12,
|
||||
|
||||
key::Down => Key::Down,
|
||||
key::Left => Key::Left,
|
||||
key::Right => Key::Right,
|
||||
key::Up => Key::Up,
|
||||
key::Escape => Key::Escape,
|
||||
key::BackSpace => Key::Backspace,
|
||||
key::Delete => Key::Delete,
|
||||
key::End => Key::End,
|
||||
key::Return => Key::Enter,
|
||||
key::Home => Key::Home,
|
||||
key::Insert => Key::Insert,
|
||||
key::Menu => Key::Menu,
|
||||
key::Page_Down => Key::PageDown,
|
||||
key::Page_Up => Key::PageUp,
|
||||
key::Pause => Key::Pause,
|
||||
key::Tab => Key::Tab,
|
||||
key::Num_Lock => Key::NumLock,
|
||||
key::Caps_Lock => Key::CapsLock,
|
||||
key::Scroll_Lock => Key::ScrollLock,
|
||||
key::Shift_L => Key::LeftShift,
|
||||
key::Shift_R => Key::RightShift,
|
||||
key::Alt_L => Key::LeftAlt,
|
||||
key::Alt_R => Key::RightAlt,
|
||||
key::Control_L => Key::LeftCtrl,
|
||||
key::Control_R => Key::RightCtrl,
|
||||
key::Super_L => Key::LeftSuper,
|
||||
key::Super_R => Key::RightSuper,
|
||||
key::XKB_KEY_Down => Key::Down,
|
||||
key::XKB_KEY_Left => Key::Left,
|
||||
key::XKB_KEY_Right => Key::Right,
|
||||
key::XKB_KEY_Up => Key::Up,
|
||||
key::XKB_KEY_Escape => Key::Escape,
|
||||
key::XKB_KEY_BackSpace => Key::Backspace,
|
||||
key::XKB_KEY_Delete => Key::Delete,
|
||||
key::XKB_KEY_End => Key::End,
|
||||
key::XKB_KEY_Return => Key::Enter,
|
||||
key::XKB_KEY_Home => Key::Home,
|
||||
key::XKB_KEY_Insert => Key::Insert,
|
||||
key::XKB_KEY_Menu => Key::Menu,
|
||||
key::XKB_KEY_Page_Down => Key::PageDown,
|
||||
key::XKB_KEY_Page_Up => Key::PageUp,
|
||||
key::XKB_KEY_Pause => Key::Pause,
|
||||
key::XKB_KEY_Tab => Key::Tab,
|
||||
key::XKB_KEY_Num_Lock => Key::NumLock,
|
||||
key::XKB_KEY_Caps_Lock => Key::CapsLock,
|
||||
key::XKB_KEY_Scroll_Lock => Key::ScrollLock,
|
||||
key::XKB_KEY_Shift_L => Key::LeftShift,
|
||||
key::XKB_KEY_Shift_R => Key::RightShift,
|
||||
key::XKB_KEY_Alt_L => Key::LeftAlt,
|
||||
key::XKB_KEY_Alt_R => Key::RightAlt,
|
||||
key::XKB_KEY_Control_L => Key::LeftCtrl,
|
||||
key::XKB_KEY_Control_R => Key::RightCtrl,
|
||||
key::XKB_KEY_Super_L => Key::LeftSuper,
|
||||
key::XKB_KEY_Super_R => Key::RightSuper,
|
||||
|
||||
key::KP_Insert => Key::NumPad0,
|
||||
key::KP_End => Key::NumPad1,
|
||||
key::KP_Down => Key::NumPad2,
|
||||
key::KP_Next => Key::NumPad3,
|
||||
key::KP_Left => Key::NumPad4,
|
||||
key::KP_Begin => Key::NumPad5,
|
||||
key::KP_Right => Key::NumPad6,
|
||||
key::KP_Home => Key::NumPad7,
|
||||
key::KP_Up => Key::NumPad8,
|
||||
key::KP_Prior => Key::NumPad9,
|
||||
key::KP_Decimal => Key::NumPadDot,
|
||||
key::KP_Divide => Key::NumPadSlash,
|
||||
key::KP_Multiply => Key::NumPadAsterisk,
|
||||
key::KP_Subtract => Key::NumPadMinus,
|
||||
key::KP_Add => Key::NumPadPlus,
|
||||
key::KP_Enter => Key::NumPadEnter,
|
||||
key::XKB_KEY_KP_Insert => Key::NumPad0,
|
||||
key::XKB_KEY_KP_End => Key::NumPad1,
|
||||
key::XKB_KEY_KP_Down => Key::NumPad2,
|
||||
key::XKB_KEY_KP_Next => Key::NumPad3,
|
||||
key::XKB_KEY_KP_Left => Key::NumPad4,
|
||||
key::XKB_KEY_KP_Begin => Key::NumPad5,
|
||||
key::XKB_KEY_KP_Right => Key::NumPad6,
|
||||
key::XKB_KEY_KP_Home => Key::NumPad7,
|
||||
key::XKB_KEY_KP_Up => Key::NumPad8,
|
||||
key::XKB_KEY_KP_Prior => Key::NumPad9,
|
||||
key::XKB_KEY_KP_Decimal => Key::NumPadDot,
|
||||
key::XKB_KEY_KP_Divide => Key::NumPadSlash,
|
||||
key::XKB_KEY_KP_Multiply => Key::NumPadAsterisk,
|
||||
key::XKB_KEY_KP_Subtract => Key::NumPadMinus,
|
||||
key::XKB_KEY_KP_Add => Key::NumPadPlus,
|
||||
key::XKB_KEY_KP_Enter => Key::NumPadEnter,
|
||||
|
||||
_ => {
|
||||
// Ignore other keys
|
||||
|
@ -1069,7 +1109,12 @@ impl Window {
|
|||
}
|
||||
}
|
||||
|
||||
fn handle_keymap(keymap: KeymapFormat, fd: RawFd, len: u32) -> std::io::Result<Keymap> {
|
||||
fn handle_keymap(
|
||||
context: *mut xkb_ffi::xkb_context,
|
||||
keymap: KeymapFormat,
|
||||
fd: RawFd,
|
||||
len: u32,
|
||||
) -> Result<*mut xkb_ffi::xkb_keymap> {
|
||||
match keymap {
|
||||
KeymapFormat::XkbV1 => {
|
||||
unsafe {
|
||||
|
@ -1083,21 +1128,30 @@ impl Window {
|
|||
0,
|
||||
);
|
||||
if addr == libc::MAP_FAILED {
|
||||
return Err(std::io::Error::last_os_error());
|
||||
return Err(Error::WindowCreate(format!(
|
||||
"Could not mmap keymap from compositor ({})",
|
||||
std::io::Error::last_os_error()
|
||||
)));
|
||||
}
|
||||
|
||||
let ctx = xkbcommon_sys::xkb_context_new(0);
|
||||
let kb_map_ptr = xkbcommon_sys::xkb_keymap_new_from_string(
|
||||
ctx,
|
||||
addr as _,
|
||||
xkbcommon_sys::xkb_keymap_format::XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
0,
|
||||
let keymap = ffi_dispatch!(
|
||||
XKBH,
|
||||
xkb_keymap_new_from_string,
|
||||
context,
|
||||
addr as *const _,
|
||||
xkb_ffi::xkb_keymap_format::XKB_KEYMAP_FORMAT_TEXT_V1,
|
||||
xkb_ffi::xkb_keymap_compile_flags::XKB_KEYMAP_COMPILE_NO_FLAGS
|
||||
);
|
||||
|
||||
libc::munmap(addr, len as usize);
|
||||
|
||||
// Wrap keymap
|
||||
Ok(Keymap::from_ptr(kb_map_ptr as *mut _ as *mut c_void))
|
||||
if keymap.is_null() {
|
||||
Err(Error::WindowCreate(
|
||||
"Received invalid keymap from compositor.".to_owned(),
|
||||
))
|
||||
} else {
|
||||
Ok(keymap)
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => unimplemented!("Only XKB keymaps are supported"),
|
||||
|
@ -1224,3 +1278,13 @@ unsafe impl raw_window_handle::HasRawWindowHandle for Window {
|
|||
raw_window_handle::RawWindowHandle::Wayland(handle)
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for Window {
|
||||
fn drop(&mut self) {
|
||||
unsafe {
|
||||
ffi_dispatch!(XKBH, xkb_state_unref, self.xkb_state);
|
||||
ffi_dispatch!(XKBH, xkb_keymap_unref, self.xkb_keymap);
|
||||
ffi_dispatch!(XKBH, xkb_context_unref, self.xkb_context);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
80
src/os/posix/xkb_ffi.rs
Normal file
80
src/os/posix/xkb_ffi.rs
Normal file
|
@ -0,0 +1,80 @@
|
|||
#![allow(non_camel_case_types, clippy::identity_op)]
|
||||
/** Minimal xkb_common ffi wrapper, based on sctk's. */
|
||||
use std::os::raw::c_char;
|
||||
|
||||
#[repr(C)]
|
||||
pub struct xkb_context {
|
||||
_private: [u8; 0],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct xkb_keymap {
|
||||
_private: [u8; 0],
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct xkb_state {
|
||||
_private: [u8; 0],
|
||||
}
|
||||
|
||||
pub type xkb_keycode_t = u32;
|
||||
pub type xkb_keysym_t = u32;
|
||||
pub type xkb_layout_index_t = u32;
|
||||
pub type xkb_mod_mask_t = u32;
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum xkb_context_flags {
|
||||
/** Do not apply any context flags. */
|
||||
XKB_CONTEXT_NO_FLAGS = 0,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum xkb_keymap_compile_flags {
|
||||
/** Do not apply any flags. */
|
||||
XKB_KEYMAP_COMPILE_NO_FLAGS = 0,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Copy, Clone, Debug, PartialEq)]
|
||||
pub enum xkb_keymap_format {
|
||||
/** The current/classic XKB text format, as generated by xkbcomp -xkb. */
|
||||
XKB_KEYMAP_FORMAT_TEXT_V1 = 1,
|
||||
}
|
||||
|
||||
pub type xkb_state_component = u32;
|
||||
|
||||
external_library!(XkbCommon, "xkbcommon",
|
||||
functions:
|
||||
fn xkb_keysym_to_utf32(xkb_keysym_t) -> u32,
|
||||
fn xkb_context_new(xkb_context_flags) -> *mut xkb_context,
|
||||
fn xkb_context_unref(*mut xkb_context) -> (),
|
||||
fn xkb_keymap_new_from_string(*mut xkb_context,
|
||||
*const c_char,
|
||||
xkb_keymap_format,
|
||||
xkb_keymap_compile_flags
|
||||
) -> *mut xkb_keymap,
|
||||
fn xkb_keymap_unref(*mut xkb_keymap) -> (),
|
||||
fn xkb_state_key_get_one_sym(*mut xkb_state, xkb_keycode_t) -> xkb_keysym_t,
|
||||
fn xkb_state_new(*mut xkb_keymap) -> *mut xkb_state,
|
||||
fn xkb_state_unref(*mut xkb_state) -> (),
|
||||
fn xkb_state_update_mask(*mut xkb_state,
|
||||
xkb_mod_mask_t,
|
||||
xkb_mod_mask_t,
|
||||
xkb_mod_mask_t,
|
||||
xkb_layout_index_t,
|
||||
xkb_layout_index_t,
|
||||
xkb_layout_index_t
|
||||
) -> xkb_state_component,
|
||||
);
|
||||
|
||||
#[cfg(feature = "dlopen")]
|
||||
lazy_static::lazy_static!(
|
||||
pub static ref XKBCOMMON_OPTION: Option<XkbCommon> = unsafe {
|
||||
XkbCommon::open("libxkbcommon.so.0")
|
||||
.or_else(|_| XkbCommon::open("libxkbcommon.so"))
|
||||
.ok()
|
||||
};
|
||||
pub static ref XKBCOMMON_HANDLE: &'static XkbCommon = {
|
||||
XKBCOMMON_OPTION.as_ref().expect("Library libxkbcommon.so could not be loaded.")
|
||||
};
|
||||
);
|
106
src/os/posix/xkb_keysyms.rs
Normal file
106
src/os/posix/xkb_keysyms.rs
Normal file
|
@ -0,0 +1,106 @@
|
|||
#![allow(missing_docs, non_upper_case_globals, unused_parens, clippy::all)]
|
||||
/** The subset of XKB_* key symbols that are used in minifb. */
|
||||
|
||||
pub const XKB_KEY_0: u32 = 0x0030;
|
||||
pub const XKB_KEY_1: u32 = 0x0031;
|
||||
pub const XKB_KEY_2: u32 = 0x0032;
|
||||
pub const XKB_KEY_3: u32 = 0x0033;
|
||||
pub const XKB_KEY_4: u32 = 0x0034;
|
||||
pub const XKB_KEY_5: u32 = 0x0035;
|
||||
pub const XKB_KEY_6: u32 = 0x0036;
|
||||
pub const XKB_KEY_7: u32 = 0x0037;
|
||||
pub const XKB_KEY_8: u32 = 0x0038;
|
||||
pub const XKB_KEY_9: u32 = 0x0039;
|
||||
pub const XKB_KEY_a: u32 = 0x0061;
|
||||
pub const XKB_KEY_b: u32 = 0x0062;
|
||||
pub const XKB_KEY_c: u32 = 0x0063;
|
||||
pub const XKB_KEY_d: u32 = 0x0064;
|
||||
pub const XKB_KEY_e: u32 = 0x0065;
|
||||
pub const XKB_KEY_f: u32 = 0x0066;
|
||||
pub const XKB_KEY_g: u32 = 0x0067;
|
||||
pub const XKB_KEY_h: u32 = 0x0068;
|
||||
pub const XKB_KEY_i: u32 = 0x0069;
|
||||
pub const XKB_KEY_j: u32 = 0x006a;
|
||||
pub const XKB_KEY_k: u32 = 0x006b;
|
||||
pub const XKB_KEY_l: u32 = 0x006c;
|
||||
pub const XKB_KEY_m: u32 = 0x006d;
|
||||
pub const XKB_KEY_n: u32 = 0x006e;
|
||||
pub const XKB_KEY_o: u32 = 0x006f;
|
||||
pub const XKB_KEY_p: u32 = 0x0070;
|
||||
pub const XKB_KEY_q: u32 = 0x0071;
|
||||
pub const XKB_KEY_r: u32 = 0x0072;
|
||||
pub const XKB_KEY_s: u32 = 0x0073;
|
||||
pub const XKB_KEY_t: u32 = 0x0074;
|
||||
pub const XKB_KEY_u: u32 = 0x0075;
|
||||
pub const XKB_KEY_v: u32 = 0x0076;
|
||||
pub const XKB_KEY_w: u32 = 0x0077;
|
||||
pub const XKB_KEY_x: u32 = 0x0078;
|
||||
pub const XKB_KEY_y: u32 = 0x0079;
|
||||
pub const XKB_KEY_z: u32 = 0x007a;
|
||||
pub const XKB_KEY_apostrophe: u32 = 0x0027;
|
||||
pub const XKB_KEY_grave: u32 = 0x0060;
|
||||
pub const XKB_KEY_backslash: u32 = 0x005c;
|
||||
pub const XKB_KEY_comma: u32 = 0x002c;
|
||||
pub const XKB_KEY_equal: u32 = 0x003d;
|
||||
pub const XKB_KEY_bracketleft: u32 = 0x005b;
|
||||
pub const XKB_KEY_bracketright: u32 = 0x005d;
|
||||
pub const XKB_KEY_minus: u32 = 0x002d;
|
||||
pub const XKB_KEY_period: u32 = 0x002e;
|
||||
pub const XKB_KEY_semicolon: u32 = 0x003b;
|
||||
pub const XKB_KEY_slash: u32 = 0x002f;
|
||||
pub const XKB_KEY_space: u32 = 0x0020;
|
||||
pub const XKB_KEY_F1: u32 = 0xffbe;
|
||||
pub const XKB_KEY_F2: u32 = 0xffbf;
|
||||
pub const XKB_KEY_F3: u32 = 0xffc0;
|
||||
pub const XKB_KEY_F4: u32 = 0xffc1;
|
||||
pub const XKB_KEY_F5: u32 = 0xffc2;
|
||||
pub const XKB_KEY_F6: u32 = 0xffc3;
|
||||
pub const XKB_KEY_F7: u32 = 0xffc4;
|
||||
pub const XKB_KEY_F8: u32 = 0xffc5;
|
||||
pub const XKB_KEY_F9: u32 = 0xffc6;
|
||||
pub const XKB_KEY_F10: u32 = 0xffc7;
|
||||
pub const XKB_KEY_F11: u32 = 0xffc8;
|
||||
pub const XKB_KEY_F12: u32 = 0xffc9;
|
||||
pub const XKB_KEY_Down: u32 = 0xff54;
|
||||
pub const XKB_KEY_Left: u32 = 0xff51;
|
||||
pub const XKB_KEY_Right: u32 = 0xff53;
|
||||
pub const XKB_KEY_Up: u32 = 0xff52;
|
||||
pub const XKB_KEY_Escape: u32 = 0xff1b;
|
||||
pub const XKB_KEY_BackSpace: u32 = 0xff08;
|
||||
pub const XKB_KEY_Delete: u32 = 0xffff;
|
||||
pub const XKB_KEY_End: u32 = 0xff57;
|
||||
pub const XKB_KEY_Return: u32 = 0xff0d;
|
||||
pub const XKB_KEY_Home: u32 = 0xff50;
|
||||
pub const XKB_KEY_Insert: u32 = 0xff63;
|
||||
pub const XKB_KEY_Menu: u32 = 0xff67;
|
||||
pub const XKB_KEY_Page_Down: u32 = 0xff56;
|
||||
pub const XKB_KEY_Page_Up: u32 = 0xff55;
|
||||
pub const XKB_KEY_Pause: u32 = 0xff13;
|
||||
pub const XKB_KEY_Tab: u32 = 0xff09;
|
||||
pub const XKB_KEY_Num_Lock: u32 = 0xff7f;
|
||||
pub const XKB_KEY_Caps_Lock: u32 = 0xffe5;
|
||||
pub const XKB_KEY_Scroll_Lock: u32 = 0xff14;
|
||||
pub const XKB_KEY_Shift_L: u32 = 0xffe1;
|
||||
pub const XKB_KEY_Shift_R: u32 = 0xffe2;
|
||||
pub const XKB_KEY_Alt_L: u32 = 0xffe9;
|
||||
pub const XKB_KEY_Alt_R: u32 = 0xffea;
|
||||
pub const XKB_KEY_Control_L: u32 = 0xffe3;
|
||||
pub const XKB_KEY_Control_R: u32 = 0xffe4;
|
||||
pub const XKB_KEY_Super_L: u32 = 0xffeb;
|
||||
pub const XKB_KEY_Super_R: u32 = 0xffec;
|
||||
pub const XKB_KEY_KP_Insert: u32 = 0xff9e;
|
||||
pub const XKB_KEY_KP_End: u32 = 0xff9c;
|
||||
pub const XKB_KEY_KP_Down: u32 = 0xff99;
|
||||
pub const XKB_KEY_KP_Next: u32 = 0xff9b;
|
||||
pub const XKB_KEY_KP_Left: u32 = 0xff96;
|
||||
pub const XKB_KEY_KP_Begin: u32 = 0xff9d;
|
||||
pub const XKB_KEY_KP_Right: u32 = 0xff98;
|
||||
pub const XKB_KEY_KP_Home: u32 = 0xff95;
|
||||
pub const XKB_KEY_KP_Up: u32 = 0xff97;
|
||||
pub const XKB_KEY_KP_Prior: u32 = 0xff9a;
|
||||
pub const XKB_KEY_KP_Decimal: u32 = 0xffae;
|
||||
pub const XKB_KEY_KP_Divide: u32 = 0xffaf;
|
||||
pub const XKB_KEY_KP_Multiply: u32 = 0xffaa;
|
||||
pub const XKB_KEY_KP_Subtract: u32 = 0xffad;
|
||||
pub const XKB_KEY_KP_Add: u32 = 0xffab;
|
||||
pub const XKB_KEY_KP_Enter: u32 = 0xff8d;
|
Loading…
Reference in a new issue