From f5bcfaf73c304bd828d2be5df4812b507cd3ea6e Mon Sep 17 00:00:00 2001 From: kossLAN Date: Fri, 29 May 2026 11:32:34 -0400 Subject: [PATCH] libinput: move bindings into workspace crate --- Cargo.lock | 16 ++ Cargo.toml | 2 + build/enums.rs | 120 ++----------- libinput/Cargo.toml | 20 +++ libinput/build.rs | 175 +++++++++++++++++++ {src/libinput => libinput/src}/consts.rs | 0 {src/libinput => libinput/src}/device.rs | 2 +- {src/libinput => libinput/src}/event.rs | 8 +- libinput/src/lib.rs | 205 +++++++++++++++++++++++ {src/libinput => libinput/src}/sys.rs | 0 src/libinput.rs | 191 +-------------------- src/macros.rs | 19 --- 12 files changed, 442 insertions(+), 316 deletions(-) create mode 100644 libinput/Cargo.toml create mode 100644 libinput/build.rs rename {src/libinput => libinput/src}/consts.rs (100%) rename {src/libinput => libinput/src}/device.rs (99%) rename {src/libinput => libinput/src}/event.rs (98%) create mode 100644 libinput/src/lib.rs rename {src/libinput => libinput/src}/sys.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index c2bb07e6..9424f67f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -712,6 +712,7 @@ dependencies = [ "jay-geometry", "jay-io-uring", "jay-layout-animation", + "jay-libinput", "jay-logger", "jay-pango", "jay-pr-caps", @@ -869,6 +870,21 @@ dependencies = [ "jay-geometry", ] +[[package]] +name = "jay-libinput" +version = "0.1.0" +dependencies = [ + "anyhow", + "bstr", + "isnt 0.2.0", + "jay-utils", + "libloading", + "log", + "repc", + "thiserror", + "uapi", +] + [[package]] name = "jay-logger" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index c3fa822e..a83a58dc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -44,6 +44,7 @@ members = [ "logger", "video-types", "pango", + "libinput", "toml-config", "algorithms", "toml-spec", @@ -89,6 +90,7 @@ jay-bugs = { version = "0.1.0", path = "bugs" } jay-logger = { version = "0.1.0", path = "logger" } jay-video-types = { version = "0.1.0", path = "video-types" } jay-pango = { version = "0.1.0", path = "pango" } +jay-libinput = { version = "0.1.0", path = "libinput" } uapi = "0.2.13" thiserror = "2.0.11" diff --git a/build/enums.rs b/build/enums.rs index 753fcb69..bc13c5df 100644 --- a/build/enums.rs +++ b/build/enums.rs @@ -4,13 +4,25 @@ use { std::{env, io::Write}, }; -#[expect(unused_macros)] -#[macro_use] -#[path = "../src/macros.rs"] -mod macros; +#[allow(unused_macros)] +macro_rules! cenum { + ($name:ident, $uc:ident; $($name2:ident = $val:expr,)*) => { + #[derive(Copy, Clone, Debug, Eq, PartialEq)] + pub struct $name(pub i32); -#[path = "../src/libinput/consts.rs"] -mod libinput; + impl $name { + pub fn raw(self) -> i32 { + self.0 + } + } + + pub const $uc: &[i32] = &[$($val,)*]; + + $( + pub const $name2: $name = $name($val); + )* + } +} #[path = "../src/fontconfig/consts.rs"] mod fontconfig; @@ -46,102 +58,6 @@ fn write_ty(f: &mut W, vals: &[i32], ty: &str) -> anyhow::Result<()> { } pub fn main() -> anyhow::Result<()> { - let mut f = open("libinput_tys.rs")?; - write_ty( - &mut f, - libinput::LIBINPUT_LOG_PRIORITY, - "libinput_log_priority", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_DEVICE_CAPABILITY, - "libinput_device_capability", - )?; - write_ty(&mut f, libinput::LIBINPUT_KEY_STATE, "libinput_key_state")?; - write_ty(&mut f, libinput::LIBINPUT_LED, "libinput_led")?; - write_ty( - &mut f, - libinput::LIBINPUT_BUTTON_STATE, - "libinput_button_state", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_POINTER_AXIS, - "libinput_pointer_axis", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_POINTER_AXIS_SOURCE, - "libinput_pointer_axis_source", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_TABLET_PAD_RING_AXIS_SOURCE, - "libinput_tablet_pad_ring_axis_source", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_TABLET_PAD_STRIP_AXIS_SOURCE, - "libinput_tablet_pad_strip_axis_source", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_TABLET_TOOL_TYPE, - "libinput_tablet_tool_type", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_TABLET_TOOL_PROXIMITY_STATE, - "libinput_tablet_tool_proximity_state", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_TABLET_TOOL_TIP_STATE, - "libinput_tablet_tool_tip_state", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_SWITCH_STATE, - "libinput_switch_state", - )?; - write_ty(&mut f, libinput::LIBINPUT_SWITCH, "libinput_switch")?; - write_ty(&mut f, libinput::LIBINPUT_EVENT_TYPE, "libinput_event_type")?; - write_ty( - &mut f, - libinput::LIBINPUT_CONFIG_STATUS, - "libinput_config_status", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_CONFIG_ACCEL_PROFILE, - "libinput_config_accel_profile", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_CONFIG_TAP_STATE, - "libinput_config_tap_state", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_CONFIG_DRAG_STATE, - "libinput_config_drag_state", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_CONFIG_DRAG_LOCK_STATE, - "libinput_config_drag_lock_state", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_CONFIG_CLICK_METHOD, - "libinput_config_click_method", - )?; - write_ty( - &mut f, - libinput::LIBINPUT_CONFIG_MIDDLE_EMULATION_STATE, - "libinput_config_middle_emulation_state", - )?; - let mut f = open("fontconfig_tys.rs")?; write_ty(&mut f, fontconfig::FC_MATCH_KINDS, "FcMatchKind")?; write_ty(&mut f, fontconfig::FC_RESULTS, "FcResult")?; diff --git a/libinput/Cargo.toml b/libinput/Cargo.toml new file mode 100644 index 00000000..cecf6c74 --- /dev/null +++ b/libinput/Cargo.toml @@ -0,0 +1,20 @@ +[package] +name = "jay-libinput" +version = "0.1.0" +edition = "2024" +license = "GPL-3.0-only" +build = "build.rs" + +[dependencies] +jay-utils = { version = "0.1.0", path = "../utils" } + +bstr = { version = "1.9.0", default-features = false, features = ["std"] } +isnt = "0.2.0" +libloading = "0.9.0" +log = { version = "0.4.20", features = ["std"] } +thiserror = "2.0.11" +uapi = "0.2.13" + +[build-dependencies] +anyhow = "1.0.79" +repc = "0.1.1" diff --git a/libinput/build.rs b/libinput/build.rs new file mode 100644 index 00000000..4f06fd20 --- /dev/null +++ b/libinput/build.rs @@ -0,0 +1,175 @@ +use { + repc::layout::{Type, TypeVariant}, + std::{ + env, + fs::{File, OpenOptions}, + io::{self, BufWriter, Write}, + path::PathBuf, + }, +}; + +#[allow(unused_macros)] +macro_rules! cenum { + ($name:ident, $uc:ident; $($name2:ident = $val:expr,)*) => { + #[derive(Copy, Clone, Debug, Eq, PartialEq)] + pub struct $name(pub i32); + + impl $name { + pub fn raw(self) -> i32 { + self.0 + } + } + + $( + pub const $name2: $name = $name($val); + )* + + pub const $uc: &[i32] = &[$($val,)*]; + }; +} + +#[path = "src/consts.rs"] +mod consts; + +fn open(s: &str) -> io::Result> { + let mut path = PathBuf::from(env::var("OUT_DIR").unwrap()); + path.push(s); + Ok(BufWriter::new( + OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(path)?, + )) +} + +fn get_target() -> repc::Target { + let rustc_target = env::var("TARGET").unwrap(); + repc::TARGET_MAP + .iter() + .cloned() + .find(|t| t.0 == rustc_target) + .unwrap() + .1 +} + +fn get_enum_ty(variants: Vec) -> anyhow::Result { + let target = get_target(); + let ty = Type { + layout: (), + annotations: vec![], + variant: TypeVariant::Enum(variants), + }; + let ty = repc::compute_layout(target, &ty)?; + assert!(ty.layout.pointer_alignment_bits <= ty.layout.size_bits); + Ok(ty.layout.size_bits) +} + +fn write_ty(f: &mut W, vals: &[i32], ty: &str) -> anyhow::Result<()> { + let variants: Vec<_> = vals.iter().cloned().map(|v| v as i128).collect(); + let size = get_enum_ty(variants)?; + writeln!(f, "#[allow(clippy::allow_attributes, dead_code)]")?; + writeln!(f, "pub type {} = i{};", ty, size)?; + Ok(()) +} + +fn main() -> anyhow::Result<()> { + let mut f = open("libinput_tys.rs")?; + write_ty( + &mut f, + consts::LIBINPUT_LOG_PRIORITY, + "libinput_log_priority", + )?; + write_ty( + &mut f, + consts::LIBINPUT_DEVICE_CAPABILITY, + "libinput_device_capability", + )?; + write_ty(&mut f, consts::LIBINPUT_KEY_STATE, "libinput_key_state")?; + write_ty(&mut f, consts::LIBINPUT_LED, "libinput_led")?; + write_ty( + &mut f, + consts::LIBINPUT_BUTTON_STATE, + "libinput_button_state", + )?; + write_ty( + &mut f, + consts::LIBINPUT_POINTER_AXIS, + "libinput_pointer_axis", + )?; + write_ty( + &mut f, + consts::LIBINPUT_POINTER_AXIS_SOURCE, + "libinput_pointer_axis_source", + )?; + write_ty( + &mut f, + consts::LIBINPUT_TABLET_PAD_RING_AXIS_SOURCE, + "libinput_tablet_pad_ring_axis_source", + )?; + write_ty( + &mut f, + consts::LIBINPUT_TABLET_PAD_STRIP_AXIS_SOURCE, + "libinput_tablet_pad_strip_axis_source", + )?; + write_ty( + &mut f, + consts::LIBINPUT_TABLET_TOOL_TYPE, + "libinput_tablet_tool_type", + )?; + write_ty( + &mut f, + consts::LIBINPUT_TABLET_TOOL_PROXIMITY_STATE, + "libinput_tablet_tool_proximity_state", + )?; + write_ty( + &mut f, + consts::LIBINPUT_TABLET_TOOL_TIP_STATE, + "libinput_tablet_tool_tip_state", + )?; + write_ty( + &mut f, + consts::LIBINPUT_SWITCH_STATE, + "libinput_switch_state", + )?; + write_ty(&mut f, consts::LIBINPUT_SWITCH, "libinput_switch")?; + write_ty(&mut f, consts::LIBINPUT_EVENT_TYPE, "libinput_event_type")?; + write_ty( + &mut f, + consts::LIBINPUT_CONFIG_STATUS, + "libinput_config_status", + )?; + write_ty( + &mut f, + consts::LIBINPUT_CONFIG_ACCEL_PROFILE, + "libinput_config_accel_profile", + )?; + write_ty( + &mut f, + consts::LIBINPUT_CONFIG_TAP_STATE, + "libinput_config_tap_state", + )?; + write_ty( + &mut f, + consts::LIBINPUT_CONFIG_DRAG_STATE, + "libinput_config_drag_state", + )?; + write_ty( + &mut f, + consts::LIBINPUT_CONFIG_DRAG_LOCK_STATE, + "libinput_config_drag_lock_state", + )?; + write_ty( + &mut f, + consts::LIBINPUT_CONFIG_CLICK_METHOD, + "libinput_config_click_method", + )?; + write_ty( + &mut f, + consts::LIBINPUT_CONFIG_MIDDLE_EMULATION_STATE, + "libinput_config_middle_emulation_state", + )?; + + println!("cargo:rerun-if-changed=src/consts.rs"); + Ok(()) +} diff --git a/src/libinput/consts.rs b/libinput/src/consts.rs similarity index 100% rename from src/libinput/consts.rs rename to libinput/src/consts.rs diff --git a/src/libinput/device.rs b/libinput/src/device.rs similarity index 99% rename from src/libinput/device.rs rename to libinput/src/device.rs index 9d398880..596c047d 100644 --- a/src/libinput/device.rs +++ b/libinput/src/device.rs @@ -1,5 +1,5 @@ use { - crate::libinput::{ + crate::{ LibInput, consts::{ AccelProfile, ConfigClickMethod, ConfigDragLockState, ConfigDragState, diff --git a/src/libinput/event.rs b/libinput/src/event.rs similarity index 98% rename from src/libinput/event.rs rename to libinput/src/event.rs index c296c56f..7fb16146 100644 --- a/src/libinput/event.rs +++ b/libinput/src/event.rs @@ -1,5 +1,5 @@ use { - crate::libinput::{ + crate::{ consts::{ ButtonState, EventType, KeyState, PointerAxis, Switch, SwitchState, TabletPadRingAxisSource, TabletPadStripAxisSource, TabletToolProximityState, @@ -292,7 +292,7 @@ impl<'a> LibInputEventSwitch<'a> { macro_rules! has_changed { ($name:ident, $f:ident) => { pub fn $name(&self) -> bool { - unsafe { crate::libinput::sys::$f(self.event) != 0 } + unsafe { crate::sys::$f(self.event) != 0 } } }; } @@ -300,7 +300,7 @@ macro_rules! has_changed { macro_rules! get_double { ($name:ident, $f:ident) => { pub fn $name(&self) -> f64 { - unsafe { crate::libinput::sys::$f(self.event) } + unsafe { crate::sys::$f(self.event) } } }; } @@ -308,7 +308,7 @@ macro_rules! get_double { macro_rules! has_capability { ($name:ident, $f:ident) => { pub fn $name(&self) -> bool { - unsafe { crate::libinput::sys::$f(self.tool) != 0 } + unsafe { crate::sys::$f(self.tool) != 0 } } }; } diff --git a/libinput/src/lib.rs b/libinput/src/lib.rs new file mode 100644 index 00000000..421b13cd --- /dev/null +++ b/libinput/src/lib.rs @@ -0,0 +1,205 @@ +#![allow(non_camel_case_types)] + +macro_rules! cenum { + ($name:ident, $uc:ident; $($name2:ident = $val:expr,)*) => { + #[derive(Copy, Clone, Debug, Eq, PartialEq)] + pub struct $name(pub i32); + + impl $name { + #[allow(dead_code)] + pub fn raw(self) -> i32 { + self.0 + } + } + + $( + pub const $name2: $name = $name($val); + )* + + pub const $uc: &[i32] = &[$($val,)*]; + }; +} + +pub mod consts; +pub mod device; +pub mod event; +mod sys; + +use { + crate::{ + consts::{ + LIBINPUT_LOG_PRIORITY_DEBUG, LIBINPUT_LOG_PRIORITY_ERROR, LIBINPUT_LOG_PRIORITY_INFO, + LogPriority, + }, + device::RegisteredDevice, + event::LibInputEvent, + sys::{ + libinput, libinput_device_ref, libinput_dispatch, libinput_get_event, libinput_get_fd, + libinput_interface, libinput_log_priority, libinput_log_set_handler, + libinput_log_set_priority, libinput_path_add_device, libinput_path_create_context, + libinput_unref, + }, + }, + bstr::ByteSlice, + isnt::std_1::primitive::IsntConstPtrExt, + jay_utils::{errorfmt::ErrorFmt, oserror::OsError, ptr_ext::PtrExt}, + std::{ffi::CStr, rc::Rc}, + thiserror::Error, + uapi::{IntoUstr, OwnedFd, c}, +}; + +static INTERFACE: libinput_interface = libinput_interface { + open_restricted, + close_restricted, +}; + +unsafe extern "C" fn open_restricted( + path: *const c::c_char, + _flags: c::c_int, + user_data: *mut c::c_void, +) -> c::c_int { + unsafe { + let ud = (user_data as *const UserData).deref(); + match ud.adapter.open(CStr::from_ptr(path)) { + Ok(f) => f.unwrap(), + Err(e) => { + log::error!("Could not open device for libinput: {}", ErrorFmt(e)); + -1 + } + } + } +} + +unsafe extern "C" fn close_restricted(fd: c::c_int, _user_data: *mut c::c_void) { + drop(OwnedFd::new(fd)); +} + +struct UserData { + adapter: Rc, +} + +pub trait LibInputAdapter { + fn open(&self, path: &CStr) -> Result; +} + +#[derive(Debug, Error)] +pub enum LibInputError { + #[error("Could not create a libinput instance")] + New, + #[error("Could not open a libinput device")] + Open, + #[error("Could not dispatch libinput events")] + Dispatch(#[source] OsError), + #[error("The requested device is not available")] + DeviceUnavailable, + #[error("Dupfd failed")] + DupFd(#[source] OsError), + #[error("Stat failed")] + Stat(#[source] OsError), +} + +pub struct LibInput { + _data: Box, + li: *mut libinput, +} + +unsafe extern "C" { + fn jay_libinput_log_handler_bridge(); +} + +impl LibInput { + pub fn new(adapter: Rc) -> Result { + let mut ud = Box::new(UserData { adapter }); + let li = unsafe { + libinput_path_create_context(&INTERFACE, &mut *ud as *mut _ as *mut c::c_void) + }; + if li.is_null() { + return Err(LibInputError::New); + } + unsafe { + libinput_log_set_handler(li, jay_libinput_log_handler_bridge); + let priority = if log::log_enabled!(log::Level::Debug) { + LIBINPUT_LOG_PRIORITY_DEBUG + } else if log::log_enabled!(log::Level::Info) { + LIBINPUT_LOG_PRIORITY_INFO + } else { + LIBINPUT_LOG_PRIORITY_ERROR + }; + libinput_log_set_priority(li, priority.raw() as _); + } + Ok(Self { _data: ud, li }) + } + + pub fn fd(&self) -> c::c_int { + unsafe { libinput_get_fd(self.li) } + } + + pub fn open<'a>( + self: &Rc, + path: impl IntoUstr<'a>, + ) -> Result { + let path = path.into_ustr(); + let res = unsafe { libinput_path_add_device(self.li, path.as_ptr()) }; + if res.is_null() { + Err(LibInputError::Open) + } else { + unsafe { + libinput_device_ref(res); + } + Ok(RegisteredDevice { + _li: self.clone(), + dev: res, + }) + } + } + + pub fn dispatch(&self) -> Result<(), LibInputError> { + let res = unsafe { libinput_dispatch(self.li) }; + if res < 0 { + Err(LibInputError::Dispatch(OsError(-res))) + } else { + Ok(()) + } + } + + pub fn event(&self) -> Option> { + let res = unsafe { libinput_get_event(self.li) }; + if res.is_null() { + None + } else { + Some(LibInputEvent { + event: res, + _phantom: Default::default(), + }) + } + } +} + +impl Drop for LibInput { + fn drop(&mut self) { + unsafe { + libinput_unref(self.li); + } + } +} + +#[unsafe(no_mangle)] +unsafe extern "C" fn jay_libinput_log_handler( + _libinput: *mut libinput, + priority: libinput_log_priority, + line: *const c::c_char, +) { + assert!(line.is_not_null()); + let str = unsafe { CStr::from_ptr(line) }; + let priority = match LogPriority(priority as _) { + LIBINPUT_LOG_PRIORITY_DEBUG => log::Level::Debug, + LIBINPUT_LOG_PRIORITY_INFO => log::Level::Info, + LIBINPUT_LOG_PRIORITY_ERROR => log::Level::Error, + _ => log::Level::Error, + }; + log::log!( + priority, + "libinput: {}", + str.to_bytes().trim_ascii().as_bstr() + ); +} diff --git a/src/libinput/sys.rs b/libinput/src/sys.rs similarity index 100% rename from src/libinput/sys.rs rename to libinput/src/sys.rs diff --git a/src/libinput.rs b/src/libinput.rs index ecb3ed13..5eaf597a 100644 --- a/src/libinput.rs +++ b/src/libinput.rs @@ -1,190 +1 @@ -#![allow(non_camel_case_types)] - -pub mod consts; -pub mod device; -pub mod event; -mod sys; - -use { - crate::{ - libinput::{ - consts::{ - LIBINPUT_LOG_PRIORITY_DEBUG, LIBINPUT_LOG_PRIORITY_ERROR, - LIBINPUT_LOG_PRIORITY_INFO, LogPriority, - }, - device::RegisteredDevice, - event::LibInputEvent, - sys::{ - libinput, libinput_device_ref, libinput_dispatch, libinput_get_event, - libinput_get_fd, libinput_interface, libinput_log_priority, - libinput_log_set_handler, libinput_log_set_priority, libinput_path_add_device, - libinput_path_create_context, libinput_unref, - }, - }, - udev::UdevError, - utils::{errorfmt::ErrorFmt, oserror::OsError, ptr_ext::PtrExt}, - }, - bstr::ByteSlice, - isnt::std_1::primitive::IsntConstPtrExt, - std::{ffi::CStr, rc::Rc}, - thiserror::Error, - uapi::{IntoUstr, OwnedFd, c}, -}; - -static INTERFACE: libinput_interface = libinput_interface { - open_restricted, - close_restricted, -}; - -unsafe extern "C" fn open_restricted( - path: *const c::c_char, - _flags: c::c_int, - user_data: *mut c::c_void, -) -> c::c_int { - unsafe { - let ud = (user_data as *const UserData).deref(); - match ud.adapter.open(CStr::from_ptr(path)) { - Ok(f) => f.unwrap(), - Err(e) => { - log::error!("Could not open device for libinput: {}", ErrorFmt(e)); - -1 - } - } - } -} - -unsafe extern "C" fn close_restricted(fd: c::c_int, _user_data: *mut c::c_void) { - drop(OwnedFd::new(fd)); -} - -struct UserData { - adapter: Rc, -} - -pub trait LibInputAdapter { - fn open(&self, path: &CStr) -> Result; -} - -#[derive(Debug, Error)] -pub enum LibInputError { - #[error("Could not create a libinput instance")] - New, - #[error("Could not open a libinput device")] - Open, - #[error("Could not dispatch libinput events")] - Dispatch(#[source] OsError), - #[error("The requested device is not available")] - DeviceUnavailable, - #[error("Dupfd failed")] - DupFd(#[source] OsError), - #[error("The udev subsystem produced an error")] - Udev(#[from] UdevError), - #[error("Stat failed")] - Stat(#[source] OsError), -} - -pub struct LibInput { - _data: Box, - li: *mut libinput, -} - -unsafe extern "C" { - fn jay_libinput_log_handler_bridge(); -} - -impl LibInput { - pub fn new(adapter: Rc) -> Result { - let mut ud = Box::new(UserData { adapter }); - let li = unsafe { - libinput_path_create_context(&INTERFACE, &mut *ud as *mut _ as *mut c::c_void) - }; - if li.is_null() { - return Err(LibInputError::New); - } - unsafe { - libinput_log_set_handler(li, jay_libinput_log_handler_bridge); - let priority = if log::log_enabled!(log::Level::Debug) { - LIBINPUT_LOG_PRIORITY_DEBUG - } else if log::log_enabled!(log::Level::Info) { - LIBINPUT_LOG_PRIORITY_INFO - } else { - LIBINPUT_LOG_PRIORITY_ERROR - }; - libinput_log_set_priority(li, priority.raw() as _); - } - Ok(Self { _data: ud, li }) - } - - pub fn fd(&self) -> c::c_int { - unsafe { libinput_get_fd(self.li) } - } - - pub fn open<'a>( - self: &Rc, - path: impl IntoUstr<'a>, - ) -> Result { - let path = path.into_ustr(); - let res = unsafe { libinput_path_add_device(self.li, path.as_ptr()) }; - if res.is_null() { - Err(LibInputError::Open) - } else { - unsafe { - libinput_device_ref(res); - } - Ok(RegisteredDevice { - _li: self.clone(), - dev: res, - }) - } - } - - pub fn dispatch(&self) -> Result<(), LibInputError> { - let res = unsafe { libinput_dispatch(self.li) }; - if res < 0 { - Err(LibInputError::Dispatch(OsError(-res))) - } else { - Ok(()) - } - } - - pub fn event(&self) -> Option> { - let res = unsafe { libinput_get_event(self.li) }; - if res.is_null() { - None - } else { - Some(LibInputEvent { - event: res, - _phantom: Default::default(), - }) - } - } -} - -impl Drop for LibInput { - fn drop(&mut self) { - unsafe { - libinput_unref(self.li); - } - } -} - -#[unsafe(no_mangle)] -unsafe extern "C" fn jay_libinput_log_handler( - _libinput: *mut libinput, - priority: libinput_log_priority, - line: *const c::c_char, -) { - assert!(line.is_not_null()); - let str = unsafe { CStr::from_ptr(line) }; - let priority = match LogPriority(priority as _) { - LIBINPUT_LOG_PRIORITY_DEBUG => log::Level::Debug, - LIBINPUT_LOG_PRIORITY_INFO => log::Level::Info, - LIBINPUT_LOG_PRIORITY_ERROR => log::Level::Error, - _ => log::Level::Error, - }; - log::log!( - priority, - "libinput: {}", - str.to_bytes().trim_ascii().as_bstr() - ); -} +pub use jay_libinput::*; diff --git a/src/macros.rs b/src/macros.rs index 90561b17..356219b5 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -232,25 +232,6 @@ macro_rules! linear_ids { }; } -macro_rules! cenum { - ($name:ident, $uc:ident; $($name2:ident = $val:expr,)*) => { - #[derive(Copy, Clone, Debug, Eq, PartialEq)] - pub struct $name(pub i32); - - impl $name { - pub fn raw(self) -> i32 { - self.0 - } - } - - pub const $uc: &[i32] = &[$($val,)*]; - - $( - pub const $name2: $name = $name($val); - )* - } -} - #[expect(unused_macros)] macro_rules! bitor { ($name:ident) => {