#![allow(dead_code, non_camel_case_types)]
#![cfg_attr(rustfmt, rustfmt_skip)]
extern crate dlib;
extern crate bitflags;
extern crate xkeysym;
#[doc(inline)]
pub use xkeysym::key as keysyms;
use std::os::raw::{c_char, c_int, c_uint, c_void};
use bitflags::bitflags;
use dlib::dlopen_external_library;
use log::info;
use once_cell::sync::OnceCell;
#[cfg(feature = "x11")]
pub mod x11;
pub const XKB_MOD_NAME_SHIFT: &[u8] = b"Shift\0";
pub const XKB_MOD_NAME_CAPS: &[u8] = b"Lock\0";
pub const XKB_MOD_NAME_CTRL: &[u8] = b"Control\0";
pub const XKB_MOD_NAME_ALT: &[u8] = b"Mod1\0";
pub const XKB_MOD_NAME_NUM: &[u8] = b"Mod2\0";
pub const XKB_MOD_NAME_LOGO: &[u8] = b"Mod4\0";
pub const XKB_LED_NAME_CAPS: &[u8] = b"Caps Lock\0";
pub const XKB_LED_NAME_NUM: &[u8] = b"Num Lock\0";
pub const XKB_LED_NAME_SCROLL: &[u8] = b"Scroll Lock\0";
pub struct xkb_context;
pub struct xkb_keymap;
pub struct xkb_state;
pub struct xkb_compose_table;
pub struct xkb_compose_state;
pub type xkb_keycode_t = u32;
pub type xkb_keysym_t = u32;
pub type xkb_layout_index_t = u32;
pub type xkb_layout_mask_t = u32;
pub type xkb_level_index_t = u32;
pub type xkb_mod_index_t = u32;
pub type xkb_mod_mask_t = u32;
pub type xkb_led_index_t = u32;
pub type xkb_led_mask_t = u32;
pub type xkb_keymap_key_iter_t = Option<extern "C" fn(*mut xkb_keymap, xkb_keycode_t, *mut c_void)>;
pub const XKB_KEYCODE_INVALID: u32 = 0xffffffff;
pub const XKB_LAYOUT_INVALID: u32 = 0xffffffff;
pub const XKB_LEVEL_INVALID: u32 = 0xffffffff;
pub const XKB_MOD_INVALID: u32 = 0xffffffff;
pub const XKB_LED_INVALID: u32 = 0xffffffff;
pub const XKB_KEYCODE_MAX: u32 = 0xffffffff - 1;
#[repr(C)]
pub struct xkb_rule_names {
pub rules: *const c_char,
pub model: *const c_char,
pub layout: *const c_char,
pub variant: *const c_char,
pub options: *const c_char,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_keysym_flags {
XKB_KEYSYM_NO_FLAGS = 0,
XKB_KEYSYM_CASE_INSENSITIVE = (1 << 0),
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_context_flags {
XKB_CONTEXT_NO_FLAGS = 0,
XKB_CONTEXT_NO_DEFAULT_INCLUDES = (1 << 0),
XKB_CONTEXT_NO_ENVIRONMENT_NAMES = (1 << 1),
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_log_level {
XKB_LOG_LEVEL_CRITICAL = 10,
XKB_LOG_LEVEL_ERROR = 20,
XKB_LOG_LEVEL_WARNING = 30,
XKB_LOG_LEVEL_INFO = 40,
XKB_LOG_LEVEL_DEBUG = 50,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_keymap_compile_flags {
XKB_KEYMAP_COMPILE_NO_FLAGS = 0,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_keymap_format {
XKB_KEYMAP_USE_ORIGINAL_FORMAT = 0,
XKB_KEYMAP_FORMAT_TEXT_V1 = 1,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_key_direction {
XKB_KEY_UP,
XKB_KEY_DOWN,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_compose_compile_flags {
XKB_COMPOSE_COMPILE_NO_FLAGS = 0,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_compose_format {
XKB_COMPOSE_FORMAT_TEXT_V1 = 1,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_compose_state_flags {
XKB_COMPOSE_STATE_NO_FLAGS = 0,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_compose_status {
XKB_COMPOSE_NOTHING,
XKB_COMPOSE_COMPOSING,
XKB_COMPOSE_COMPOSED,
XKB_COMPOSE_CANCELLED,
}
#[repr(C)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum xkb_compose_feed_result {
XKB_COMPOSE_FEED_IGNORED,
XKB_COMPOSE_FEED_ACCEPTED,
}
bitflags!(
pub struct xkb_state_component: u32 {
const XKB_STATE_MODS_DEPRESSED = (1 << 0);
const XKB_STATE_MODS_LATCHED = (1 << 1);
const XKB_STATE_MODS_LOCKED = (1 << 2);
const XKB_STATE_MODS_EFFECTIVE = (1 << 3);
const XKB_STATE_LAYOUT_DEPRESSED = (1 << 4);
const XKB_STATE_LAYOUT_LATCHED = (1 << 5);
const XKB_STATE_LAYOUT_LOCKED = (1 << 6);
const XKB_STATE_LAYOUT_EFFECTIVE = (1 << 7);
const XKB_STATE_LEDS = (1 << 8);
}
);
dlopen_external_library!(XkbCommon,
functions:
fn xkb_keysym_get_name(xkb_keysym_t, *mut c_char, usize) -> c_int,
fn xkb_keysym_from_name(*const c_char, xkb_keysym_flags) -> xkb_keysym_t,
fn xkb_keysym_to_utf8(xkb_keysym_t, *mut c_char, usize) -> c_int,
fn xkb_keysym_to_utf32(xkb_keysym_t) -> u32,
fn xkb_context_new(xkb_context_flags) -> *mut xkb_context,
fn xkb_context_ref(*mut xkb_context) -> *mut xkb_context,
fn xkb_context_unref(*mut xkb_context) -> (),
fn xkb_context_set_user_data(*mut xkb_context, *mut c_void) -> (),
fn xkb_context_get_user_data(*mut xkb_context) -> *mut c_void,
fn xkb_context_include_path_append(*mut xkb_context, *const c_char) -> c_int,
fn xkb_context_include_path_append_default(*mut xkb_context) -> c_int,
fn xkb_context_include_path_reset_defaults(*mut xkb_context) -> c_int,
fn xkb_context_include_path_clear(*mut xkb_context) -> (),
fn xkb_context_num_include_paths(*mut xkb_context) -> c_uint,
fn xkb_context_include_path_get(*mut xkb_context, c_uint) -> *const c_char,
fn xkb_context_set_log_level(*mut xkb_context, xkb_log_level) -> (),
fn xkb_context_get_log_level(*mut xkb_context) -> xkb_log_level,
fn xkb_context_set_log_verbosity(*mut xkb_context, c_int) -> (),
fn xkb_context_get_log_verbosity(*mut xkb_context) -> c_int,
fn xkb_keymap_new_from_names(
*mut xkb_context,
*const xkb_rule_names,
xkb_keymap_compile_flags
) -> *mut xkb_keymap,
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_new_from_buffer(
*mut xkb_context,
*const c_char,
usize,
xkb_keymap_format,
xkb_keymap_compile_flags
) -> *mut xkb_keymap,
fn xkb_keymap_ref(*mut xkb_keymap) -> *mut xkb_keymap,
fn xkb_keymap_unref(*mut xkb_keymap) -> (),
fn xkb_keymap_get_as_string(*mut xkb_keymap, xkb_keymap_format) -> *const c_char,
fn xkb_keymap_key_get_syms_by_level(*mut xkb_keymap, xkb_keycode_t, xkb_layout_index_t, xkb_level_index_t, *mut *const xkb_keysym_t) -> c_int,
fn xkb_keymap_key_repeats(*mut xkb_keymap, xkb_keycode_t) -> c_int,
fn xkb_keymap_min_keycode(*mut xkb_keymap) -> xkb_keycode_t,
fn xkb_keymap_max_keycode(*mut xkb_keymap) -> xkb_keycode_t,
fn xkb_keymap_key_for_each(*mut xkb_keymap, xkb_keymap_key_iter_t, *mut c_void) -> (),
fn xkb_keymap_num_layouts(*mut xkb_keymap) -> xkb_layout_index_t,
fn xkb_keymap_num_layouts_for_key(*mut xkb_keymap, xkb_keycode_t) -> xkb_layout_index_t,
fn xkb_keymap_num_levels_for_key(*mut xkb_keymap, xkb_keycode_t, xkb_layout_index_t) -> xkb_level_index_t,
fn xkb_keymap_mod_get_name(*mut xkb_keymap, xkb_mod_index_t) -> *const c_char,
fn xkb_keymap_mod_get_index(*mut xkb_keymap, *const c_char) -> xkb_mod_index_t,
fn xkb_state_new(*mut xkb_keymap) -> *mut xkb_state,
fn xkb_state_ref(*mut xkb_state) -> *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,
fn xkb_state_update_key(
*mut xkb_state,
xkb_keycode_t,
xkb_key_direction
) -> xkb_state_component,
fn xkb_state_key_get_syms(
*mut xkb_state,
xkb_keycode_t,
*const *mut xkb_keysym_t
) -> c_int,
fn xkb_state_key_get_utf8(
*mut xkb_state,
xkb_keycode_t,
*mut c_char,
usize
) -> c_int,
fn xkb_state_key_get_utf32(*mut xkb_state, xkb_keycode_t) -> u32,
fn xkb_state_key_get_one_sym(*mut xkb_state, xkb_keycode_t) -> xkb_keysym_t,
fn xkb_state_key_get_layout(*mut xkb_state, xkb_keycode_t) -> xkb_layout_index_t,
fn xkb_state_key_get_level(*mut xkb_state, xkb_keycode_t, xkb_layout_index_t) -> xkb_level_index_t,
fn xkb_state_mod_name_is_active(*mut xkb_state, *const c_char, xkb_state_component) -> c_int,
fn xkb_state_mod_index_is_active(*mut xkb_state, xkb_mod_index_t, xkb_state_component) -> c_int,
fn xkb_state_serialize_mods(*mut xkb_state, xkb_state_component) -> xkb_mod_mask_t,
fn xkb_state_serialize_layout(*mut xkb_state, xkb_state_component) -> xkb_layout_index_t,
);
dlopen_external_library!(XkbCommonCompose,
functions:
fn xkb_compose_table_new_from_locale(
*mut xkb_context,
*const c_char,
xkb_compose_compile_flags
) -> *mut xkb_compose_table,
fn xkb_compose_table_unref(*mut xkb_compose_table) -> (),
fn xkb_compose_state_new(
*mut xkb_compose_table,
xkb_compose_state_flags
) -> *mut xkb_compose_state,
fn xkb_compose_state_unref(*mut xkb_compose_state) -> (),
fn xkb_compose_state_feed(*mut xkb_compose_state, xkb_keysym_t) -> xkb_compose_feed_result,
fn xkb_compose_state_reset(*mut xkb_compose_state) -> (),
fn xkb_compose_state_get_status(*mut xkb_compose_state) -> xkb_compose_status,
fn xkb_compose_state_get_utf8(*mut xkb_compose_state, *mut c_char, usize) -> c_int,
fn xkb_compose_state_get_one_sym(*mut xkb_compose_state) -> xkb_keysym_t,
);
pub fn xkbcommon_handle() -> &'static XkbCommon {
xkbcommon_option().expect("Library libxkbcommon.so could not be loaded.")
}
pub fn xkbcommon_option() -> Option<&'static XkbCommon> {
static XKBCOMMON_OPTION: OnceCell<Option<XkbCommon>> = OnceCell::new();
XKBCOMMON_OPTION
.get_or_init(|| {
open_with_sonames(
&["libxkbcommon.so.0", "libxkbcommon.so"],
None,
|name| unsafe { XkbCommon::open(name) },
)
})
.as_ref()
}
pub fn xkbcommon_compose_handle() -> &'static XkbCommonCompose {
xkbcommon_compose_option().expect("Could not load compose module from libxkbcommon.so.")
}
pub fn xkbcommon_compose_option() -> Option<&'static XkbCommonCompose> {
static XKBCOMMON_COMPOSE_OPTION: OnceCell<Option<XkbCommonCompose>> = OnceCell::new();
XKBCOMMON_COMPOSE_OPTION
.get_or_init(|| {
open_with_sonames(
&["libxkbcommon.so.0", "libxkbcommon.so"],
Some("compose"),
|name| unsafe { XkbCommonCompose::open(name) },
)
})
.as_ref()
}
fn open_with_sonames<T, F>(names: &[&str], module: Option<&str>, open: F) -> Option<T>
where
F: Fn(&str) -> Result<T, dlib::DlError>,
{
for name in names {
match open(name) {
Ok(l) => return Some(l),
Err(e) => {
if let Some(module) = module {
info!(
"Failed loading {} module from `{}`. Error: {:?}",
module, name, e
)
} else {
info!("Failed loading `{}`. Error: {:?}", name, e)
}
}
}
}
None
}