kobo_core/device/input.rs
1// SPDX-License-Identifier: MIT
2// Copyright (c) 2026 Nayeem Bin Ahsan
3pub const EV_SYN: u16 = 0x00;
4pub const EV_KEY: u16 = 0x01;
5pub const EV_ABS: u16 = 0x03;
6pub const SYN_REPORT: u16 = 0x00;
7pub const ABS_MT_POSITION_X: u16 = 0x35;
8pub const ABS_MT_POSITION_Y: u16 = 0x36;
9pub const BTN_TOUCH_CODE: u16 = 330;
10
11pub const EVIOCGABS_X: libc::c_ulong = 0x80184572;
12pub const EVIOCGABS_Y: libc::c_ulong = 0x80184576;
13
14/// Decode (type, code, value) from a 16-byte arm evdev `input_event`. The first
15/// 8 bytes are the timeval timestamp, ignored. Layout is ARM-32 specific
16/// (timeval=8, type=2, code=2, value=4 = 16 bytes); a 64-bit target has a
17/// 24-byte input_event and this decoder would misread it.
18pub fn decode_input_event(buf: &[u8; 16]) -> (u16, u16, i32) {
19 // Only meaningful on the actual target: `libc::timeval` is 16 bytes on a
20 // 64-bit host (two `i64`s), so this would fire on every `cargo test` run
21 // on a dev machine even though the decoder is never handed a real evdev
22 // buffer there. On 32-bit ARM -- what this device and this decoder's byte
23 // offsets assume -- `timeval` is two `i32`s and the check is exact.
24 #[cfg(target_arch = "arm")]
25 debug_assert_eq!(
26 std::mem::size_of::<libc::timeval>() + 8,
27 16,
28 "input_event layout changed - this decoder assumes 32-bit ARM"
29 );
30 (
31 u16::from_le_bytes([buf[8], buf[9]]),
32 u16::from_le_bytes([buf[10], buf[11]]),
33 i32::from_le_bytes([buf[12], buf[13], buf[14], buf[15]]),
34 )
35}
36
37#[repr(C)]
38#[derive(Default)]
39pub struct InputAbsinfo {
40 pub value: i32,
41 pub minimum: i32,
42 pub maximum: i32,
43 pub fuzz: i32,
44 pub flat: i32,
45 pub resolution: i32,
46}
47
48pub fn query_abs_max(fd: libc::c_int, ioctl: libc::c_ulong) -> i32 {
49 let mut info = InputAbsinfo::default();
50 // SAFETY: ioctl with an EVIOCGABS-class code writes one `struct input_absinfo` into the
51 // supplied &mut. `info` is a valid, initialized, exclusively-borrowed value of exactly
52 // that layout (C-compatible #[repr(C)] struct of 5 i32). fd/ioctl are caller-provided
53 // kernel tokens; a bad fd returns -1 (ignored) and `info` stays default.
54 unsafe {
55 libc::ioctl(fd, ioctl as _, &mut info);
56 }
57 info.maximum
58}