indianakernick / The-Fat-Controller

A library for simulating mouse and keyboard events
Apache License 2.0
38 stars 13 forks source link

linux_wayland (uinput) doesn't work on 32-bit linux systems #12

Open BrianHoldsworth opened 5 months ago

BrianHoldsworth commented 5 months ago

Hi. I've only tested on ARMv7, but I'd assume the problem exists with any 32-bit linux. On 32-bit linux, the timeval struct, which is part of the input_event struct, uses 32-bit longs. However, the struct is hard-coded for 64-bit longs.

I fixed this for ARMv7 with the following change:

diff --git a/src/linux_wayland/ffi/input.rs b/src/linux_wayland/ffi/input.rs
index a8c6b08..3447684 100644
--- a/src/linux_wayland/ffi/input.rs
+++ b/src/linux_wayland/ffi/input.rs
@@ -1,11 +1,13 @@
 // https://github.com/torvalds/linux/blob/master/include/uapi/linux/input.h

+use std::ffi::c_long;
+
 #[repr(C)]
 #[allow(non_camel_case_types)]
 pub struct timeval {
     // Not quite sure if these should be 32 or 64
-    pub tv_sec: i64,
-    pub tv_usec: i64,
+    pub tv_sec: c_long,
+    pub tv_usec: c_long,
 }

 #[repr(C)]
indianakernick commented 5 months ago

Digging through the headers, it kind of seems like timeval could be using 64-bit integers even on a 32-bit system. If the intent is 32-bit int on 32-bit system and 64-bit int on 64-bit system then isize is another option. I'm not 100% convinced that this is correct but I don't know how to do it better. It almost seems like it needs to be another feature flag.

indianakernick commented 5 months ago

I thought about it and realised that I was probably over-analysing the problem. I pushed up a fix.

BrianHoldsworth commented 5 months ago

I see. Unfortunately, using isize in place of c_long doesn't work with my Raspberry Pi target.

The target description (taken from the output of the linux file command) is ELF 32-bit LSB pie executable, ARM, EABI5 version 1 (SYSV)

indianakernick commented 5 months ago

So isize is 64 bits on a 32-bit target? That's unexpected! I switched it to c_long.

BrianHoldsworth commented 5 months ago

It seems like isize is about the architecture's maximum address range. Whereas the c types are data range. But I'm also not sure and it is hard to know without testing on more archs.