extern crate swayipc;
use std::ffi::{CString, CStr};
use std::os::raw::c_char;
use swayipc::{Connection, Input};
fn get_keyboard(conn: &mut Connection) -> Input {
let all_inputs = conn.get_inputs().unwrap();
let keyboard_iter = all_inputs.iter().position(|input_device| input_device.input_type == "keyboard").unwrap();
return all_inputs[keyboard_iter].clone();
}
fn get_cur_layout(conn: &mut Connection) -> String {
return get_keyboard(conn).xkb_active_layout_name.unwrap();
}
fn switch_layout(conn: &mut Connection, layout: &String) {
let keyboard = get_keyboard(conn);
match keyboard.xkb_layout_names.iter().position(|x| x == layout) {
Some(layout_index) => conn.run_command(format!("input {} xkb_switch_layout {}", keyboard.identifier, layout_index)),
None => panic!("There is no required layout for keyboard")
};
}
#[no_mangle]
pub extern "C" fn Xkb_Switch_getXkbLayout() -> *const c_char {
match Connection::new() {
Ok(mut conn) => CString::new(get_cur_layout(&mut conn)).unwrap().into_raw() as *const c_char,
Err(_) => 0 as *const c_char
}
}
#[no_mangle]
pub extern "C" fn Xkb_Switch_setXkbLayout(layout_ptr: *const c_char) {
match Connection::new() {
Ok(mut conn) => unsafe {
let layout = CStr::from_ptr(layout_ptr).to_string_lossy().to_string();
switch_layout(&mut conn, &layout);
},
Err(_) => ()
};
}