139 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			139 lines
		
	
	
		
			3.5 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
use std::ffi::CString;
 | 
						|
 | 
						|
 | 
						|
/// Gathers stuff defined in C or called by C
 | 
						|
pub mod c {
 | 
						|
    use super::*;
 | 
						|
    
 | 
						|
    use std::ffi::CStr;
 | 
						|
    use std::os::raw::c_char;
 | 
						|
    use std::ptr;
 | 
						|
    
 | 
						|
    // The following defined in C
 | 
						|
    
 | 
						|
    // Legacy; Will never be used in Rust as a bit field
 | 
						|
    enum ModifierMask {
 | 
						|
        Nothing = 0,
 | 
						|
        Shift = 1,
 | 
						|
    }
 | 
						|
    
 | 
						|
    // The following defined in Rust.
 | 
						|
    
 | 
						|
    // TODO: wrap naked pointers to Rust data inside RefCells to prevent multiple writers
 | 
						|
    // Symbols are owned by Rust and will move towards no C manipulation, so it may make sense not to wrap them
 | 
						|
    #[no_mangle]
 | 
						|
    pub extern "C"
 | 
						|
    fn squeek_symbol_get_name(symbol: *const Symbol) -> *const c_char {
 | 
						|
        let symbol = unsafe { &*symbol };
 | 
						|
        match &symbol.action {
 | 
						|
            Action::Submit { text: Some(text), .. } => text.as_ptr(),
 | 
						|
            _ => ptr::null(),
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    #[no_mangle]
 | 
						|
    pub extern "C"
 | 
						|
    fn squeek_symbol_get_label(symbol: *const Symbol) -> *const c_char {
 | 
						|
        let symbol = unsafe { &*symbol };
 | 
						|
        match &symbol.label {
 | 
						|
            Label::Text(text) => text.as_ptr(),
 | 
						|
            // returning static strings to C is a bit cumbersome
 | 
						|
            Label::IconName(_) => unsafe {
 | 
						|
                CStr::from_bytes_with_nul_unchecked(b"icon\0")
 | 
						|
            }.as_ptr(),
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    #[no_mangle]
 | 
						|
    pub extern "C"
 | 
						|
    fn squeek_symbol_get_icon_name(symbol: *const Symbol) -> *const c_char {
 | 
						|
        let symbol = unsafe { &*symbol };
 | 
						|
        match &symbol.label {
 | 
						|
            Label::Text(_) => ptr::null(),
 | 
						|
            Label::IconName(name) => name.as_ptr(),
 | 
						|
        }
 | 
						|
    }
 | 
						|
    
 | 
						|
    // Legacy; throw away
 | 
						|
    #[no_mangle]
 | 
						|
    pub extern "C"
 | 
						|
    fn squeek_symbol_get_modifier_mask(symbol: *const Symbol) -> u32 {
 | 
						|
        let symbol = unsafe { &*symbol };
 | 
						|
        (match &symbol.action {
 | 
						|
            Action::SetLevel(1) => ModifierMask::Shift,
 | 
						|
            _ => ModifierMask::Nothing,
 | 
						|
        }) as u32
 | 
						|
    }
 | 
						|
    
 | 
						|
    #[no_mangle]
 | 
						|
    pub extern "C"
 | 
						|
    fn squeek_symbol_print(symbol: *const Symbol) {
 | 
						|
        let symbol = unsafe { &*symbol };
 | 
						|
        println!("{:?}", symbol);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
/// Just defines some int->identifier mappings for convenience
 | 
						|
#[derive(Debug)]
 | 
						|
pub enum KeySym {
 | 
						|
    Unknown = 0,
 | 
						|
    Shift = 0xffe1,
 | 
						|
}
 | 
						|
 | 
						|
impl KeySym {
 | 
						|
    pub fn from_u32(num: u32) -> KeySym {
 | 
						|
        match num {
 | 
						|
            0xffe1 => KeySym::Shift,
 | 
						|
            _ => KeySym::Unknown,
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
#[derive(Debug)]
 | 
						|
pub struct XKeySym(pub u32);
 | 
						|
 | 
						|
#[derive(Debug)]
 | 
						|
pub enum Label {
 | 
						|
    /// Text used to display the symbol
 | 
						|
    Text(CString),
 | 
						|
    /// Icon name used to render the symbol
 | 
						|
    IconName(CString),
 | 
						|
}
 | 
						|
 | 
						|
/// Use to switch layouts
 | 
						|
type Level = u8;
 | 
						|
 | 
						|
/// Use to send modified keypresses
 | 
						|
#[derive(Debug)]
 | 
						|
pub enum Modifier {
 | 
						|
    Control,
 | 
						|
    Alt,
 | 
						|
}
 | 
						|
 | 
						|
/// Action to perform on the keypress and, in reverse, on keyrelease
 | 
						|
#[derive(Debug)]
 | 
						|
pub enum Action {
 | 
						|
    /// Switch to this level TODO: reverse?
 | 
						|
    SetLevel(Level),
 | 
						|
    /// Set this modifier TODO: release?
 | 
						|
    SetModifier(Modifier),
 | 
						|
    /// Submit some text
 | 
						|
    Submit {
 | 
						|
        /// orig: Canonical name of the symbol
 | 
						|
        text: Option<CString>,
 | 
						|
        /// The key events this symbol submits when submitting text is not possible
 | 
						|
        keys: Vec<XKeySym>,
 | 
						|
    },
 | 
						|
}
 | 
						|
 | 
						|
/// Contains a static description of a particular key's actions
 | 
						|
#[derive(Debug)]
 | 
						|
pub struct Symbol {
 | 
						|
    /// The action that this key performs
 | 
						|
    pub action: Action,
 | 
						|
    /// Label to display to the user
 | 
						|
    pub label: Label,
 | 
						|
    // FIXME: is it used?
 | 
						|
    pub tooltip: Option<CString>,
 | 
						|
}
 |