Skip to main content

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}