210 lines
5.9 KiB
Rust
210 lines
5.9 KiB
Rust
use std::{env, path::PathBuf};
|
|
|
|
use bindgen::callbacks::{EnumVariantValue, ParseCallbacks};
|
|
use convert_case::{Case, Casing};
|
|
|
|
#[derive(Debug)]
|
|
struct RemovePrefixesCallback {}
|
|
|
|
impl RemovePrefixesCallback {
|
|
fn new() -> Self {
|
|
Self {}
|
|
}
|
|
|
|
fn boxed() -> Box<dyn ParseCallbacks> {
|
|
Box::new(Self::new())
|
|
}
|
|
}
|
|
|
|
impl ParseCallbacks for RemovePrefixesCallback {
|
|
fn item_name(&self, original_item_name: &str) -> Option<String> {
|
|
const PREFIXES: &[&str] = &["XKB_", "xkb_"];
|
|
let mut ret = None;
|
|
for prefix in PREFIXES {
|
|
if let Some(name) = original_item_name.strip_prefix(prefix) {
|
|
ret = Some(name.to_owned());
|
|
break;
|
|
}
|
|
}
|
|
ret
|
|
}
|
|
|
|
fn enum_variant_name(
|
|
&self,
|
|
enum_name: Option<&str>,
|
|
original_variant_name: &str,
|
|
_variant_value: EnumVariantValue,
|
|
) -> Option<String> {
|
|
if enum_name.is_none() {
|
|
return self.item_name(original_variant_name);
|
|
}
|
|
// let original_variant_name = self
|
|
// .item_name(original_variant_name)
|
|
// .unwrap_or(original_variant_name.to_owned());
|
|
let enum_name = enum_name.unwrap();
|
|
let enum_name = enum_name.strip_prefix("enum ").unwrap_or(enum_name);
|
|
let enum_lower = original_variant_name.to_lowercase();
|
|
let diff_index = enum_lower
|
|
.chars()
|
|
.zip(enum_name.chars())
|
|
.enumerate()
|
|
.find(|(_i, (v, e))| v != e)
|
|
.map(|it| it.0)
|
|
.unwrap_or(enum_name.len());
|
|
let name = original_variant_name[diff_index..]
|
|
.trim_start_matches('_')
|
|
.to_case(Case::Pascal);
|
|
|
|
Some(name)
|
|
}
|
|
}
|
|
|
|
#[derive(Debug)]
|
|
struct TypedefCallback {}
|
|
|
|
impl TypedefCallback {
|
|
fn new() -> Self {
|
|
Self {}
|
|
}
|
|
|
|
fn boxed() -> Box<dyn ParseCallbacks> {
|
|
Box::new(Self::new())
|
|
}
|
|
}
|
|
|
|
impl ParseCallbacks for TypedefCallback {
|
|
fn item_name(&self, original_item_name: &str) -> Option<String> {
|
|
if original_item_name == "xkb_keysym_t" {
|
|
Some(String::from("Keysym"))
|
|
} else {
|
|
None
|
|
}
|
|
}
|
|
|
|
// fn int_macro(&self, name: &str, _value: i64) -> Option<IntKind> {
|
|
// if name.starts_with("XKB_KEY_") {
|
|
// Some(IntKind::Custom {
|
|
// name: "Keysym",
|
|
// is_signed: false,
|
|
// })
|
|
// } else {
|
|
// None
|
|
// }
|
|
// }
|
|
|
|
// fn add_derives(&self, info: &DeriveInfo<'_>) -> Vec<String> {
|
|
// if (info.name.contains("keysym") && !info.name.contains("flags"))
|
|
// || info.name == "Keysym"
|
|
// || info.name == "xkb_keysym_t"
|
|
// || info.name == "keysym_t"
|
|
// {
|
|
// panic!("{info:?}");
|
|
// vec![
|
|
// "PartialEq".to_string(),
|
|
// "PartialOrd".to_string(),
|
|
// "Ord".to_string(),
|
|
// "Eq".to_string(),
|
|
// ]
|
|
// } else {
|
|
// vec![]
|
|
// }
|
|
// }
|
|
}
|
|
|
|
// #[derive(Debug)]
|
|
// struct VariadicsCallback {}
|
|
//
|
|
// impl VariadicsCallback {
|
|
// fn new() -> Self {
|
|
// Self {}
|
|
// }
|
|
// fn boxed() -> Box<dyn ParseCallbacks> {
|
|
// Box::new(Self::new())
|
|
// }
|
|
// }
|
|
//
|
|
// impl ParseCallbacks for VariadicsCallback {
|
|
// fn wrap_as_variadic_fn(&self, name: &str) -> Option<String> {
|
|
// panic!("mdr {name}");
|
|
// Some(format!("{name}_var"))
|
|
// }
|
|
// }
|
|
|
|
fn build_xkb_keysyms() -> anyhow::Result<()> {
|
|
let common_bindings = bindgen::builder()
|
|
.header("/usr/include/xkbcommon/xkbcommon-keysyms.h")
|
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
|
.parse_callbacks(RemovePrefixesCallback::boxed())
|
|
.parse_callbacks(TypedefCallback::boxed())
|
|
.allowlist_var("XKB_.*")
|
|
.generate()?;
|
|
|
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
let out_file = out_path.join("libxkbcommon-keysyms.rs");
|
|
common_bindings
|
|
.write_to_file(out_file)
|
|
.expect("Couldn't write bindings!");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn build_xkbcommon() -> anyhow::Result<()> {
|
|
let common_bindings = bindgen::builder()
|
|
.header("ffi/logger.h")
|
|
.header("/usr/include/xkbcommon/xkbcommon.h")
|
|
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
|
.parse_callbacks(RemovePrefixesCallback::boxed())
|
|
.parse_callbacks(TypedefCallback::boxed())
|
|
// .parse_callbacks(VariadicsCallback::boxed())
|
|
.allowlist_item("xkb_.*")
|
|
.allowlist_item("log_.*") // Log wrapper
|
|
// .allowlist_item("XKB_.*")
|
|
.new_type_alias_deref("Keysym")
|
|
.no_debug("xkb_keysym_t")
|
|
.allowlist_var("XKB_KEYCODE_INVALID")
|
|
.allowlist_var("XKB_LAYOUT_INVALID")
|
|
.allowlist_var("XKB_LEVEL_INVALID")
|
|
.allowlist_var("XKB_MOD_INVALID")
|
|
.allowlist_var("XKB_LED_INVALID")
|
|
.allowlist_var("XKB_KEYCODE_MAX")
|
|
.allowlist_var("XKB_KEYSYM_MAX")
|
|
.default_enum_style(bindgen::EnumVariation::NewType {
|
|
is_bitfield: false,
|
|
is_global: false,
|
|
})
|
|
.derive_eq(true)
|
|
.derive_partialeq(true)
|
|
.derive_ord(true)
|
|
.derive_partialord(true)
|
|
.derive_hash(true)
|
|
.generate()?;
|
|
|
|
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
|
let out_file = out_path.join("libxkbcommon.rs");
|
|
common_bindings
|
|
.write_to_file(out_file)
|
|
.expect("Couldn't write bindings!");
|
|
|
|
println!("cargo:rustc-link-lib=xkbcommon");
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn build_logger() -> anyhow::Result<()> {
|
|
cc::Build::new()
|
|
.file("ffi/logger.c")
|
|
.std("c17")
|
|
.warnings(true)
|
|
.warnings_into_errors(true)
|
|
.extra_warnings(true)
|
|
.compile("logger");
|
|
Ok(())
|
|
}
|
|
|
|
fn main() -> anyhow::Result<()> {
|
|
build_xkbcommon()?;
|
|
build_xkb_keysyms()?;
|
|
build_logger()?;
|
|
Ok(())
|
|
}
|