Something went wrong. Try again.
A hardware-accelerated GPU terminal emulator focusing to run in desktops and browsers.
Something went wrong. Try again.
3.4 kB · 124 lines
Rust
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125//! XKB compose handling.
use std::env;use std::ffi::CString;use std::ops::Deref;use std::os::unix::ffi::OsStringExt;use std::ptr::NonNull;
use super::{XkbContext, XKBCH};use smol_str::SmolStr;use xkbcommon_dl::{ xkb_compose_compile_flags, xkb_compose_feed_result, xkb_compose_state, xkb_compose_state_flags, xkb_compose_status, xkb_compose_table, xkb_keysym_t,};
#[derive(Debug)]pub struct XkbComposeTable { table: NonNull<xkb_compose_table>,}
impl XkbComposeTable { pub fn new(context: &XkbContext) -> Option<Self> { let locale = env::var_os("LC_ALL") .and_then(|v| if v.is_empty() { None } else { Some(v) }) .or_else(|| env::var_os("LC_CTYPE")) .and_then(|v| if v.is_empty() { None } else { Some(v) }) .or_else(|| env::var_os("LANG")) .and_then(|v| if v.is_empty() { None } else { Some(v) }) .unwrap_or_else(|| "C".into()); let locale = CString::new(locale.into_vec()).unwrap();
let table = unsafe { (XKBCH.xkb_compose_table_new_from_locale)( context.as_ptr(), locale.as_ptr(), xkb_compose_compile_flags::XKB_COMPOSE_COMPILE_NO_FLAGS, ) };
let table = NonNull::new(table)?; Some(Self { table }) }
/// Create new state with the given compose table. pub fn new_state(&self) -> Option<XkbComposeState> { let state = unsafe { (XKBCH.xkb_compose_state_new)( self.table.as_ptr(), xkb_compose_state_flags::XKB_COMPOSE_STATE_NO_FLAGS, ) };
let state = NonNull::new(state)?; Some(XkbComposeState { state }) }}
impl Deref for XkbComposeTable { type Target = NonNull<xkb_compose_table>;
fn deref(&self) -> &Self::Target { &self.table }}
impl Drop for XkbComposeTable { fn drop(&mut self) { unsafe { (XKBCH.xkb_compose_table_unref)(self.table.as_ptr()); } }}
#[derive(Debug)]pub struct XkbComposeState { state: NonNull<xkb_compose_state>,}
impl XkbComposeState { pub fn get_string(&mut self, scratch_buffer: &mut Vec<u8>) -> Option<SmolStr> { super::make_string_with(scratch_buffer, |ptr, len| unsafe { (XKBCH.xkb_compose_state_get_utf8)(self.state.as_ptr(), ptr, len) }) }
#[inline] pub fn feed(&mut self, keysym: xkb_keysym_t) -> ComposeStatus { let feed_result = unsafe { (XKBCH.xkb_compose_state_feed)(self.state.as_ptr(), keysym) }; match feed_result { xkb_compose_feed_result::XKB_COMPOSE_FEED_IGNORED => ComposeStatus::Ignored, xkb_compose_feed_result::XKB_COMPOSE_FEED_ACCEPTED => { ComposeStatus::Accepted(self.status()) } } }
#[inline] pub fn reset(&mut self) { unsafe { (XKBCH.xkb_compose_state_reset)(self.state.as_ptr()); } }
#[inline] pub fn status(&mut self) -> xkb_compose_status { unsafe { (XKBCH.xkb_compose_state_get_status)(self.state.as_ptr()) } }}
impl Drop for XkbComposeState { fn drop(&mut self) { unsafe { (XKBCH.xkb_compose_state_unref)(self.state.as_ptr()); }; }}
#[derive(Copy, Clone, Debug)]pub enum ComposeStatus { Accepted(xkb_compose_status), Ignored, None,}