Open richardanaya opened 4 years ago
I'm working on a little micro library to suss out the input devices using sysfs https://github.com/richardanaya/sysfs_input
i'd be curious what your raspberry pi says with
cargo run --example scan
Besides input file path, the one thing I had to adapt on my rpi running Raspbian, is that the timeval of the input event was given on 8 bytes instead of 16. Here I abstracted this in a struct with impl for reading the events. This should probably be turned unto a trait with impl for 8- or 16-bytes timeval. I assume the difference comes from that Raspbian is a 32bit system, but I haven't found details on 32/64bits difference in the behaviour of input event. Properly implementing input events (spec here) certainly deserves to be delegated to a crate on its own. The only relevant rate I found so far is input-event-codes which only contains constants.
Here is the scan on my rpi, the touchscreen is input0:
Ok(
[
Input(
InputDevice {
name: "MX Keys Consumer Control",
file_name: "input3",
capabilities: [
InputCapability {
name: "rel",
raw_value: "40",
},
InputCapability {
name: "abs",
raw_value: "1 0",
},
InputCapability {
name: "ff",
raw_value: "0",
},
InputCapability {
name: "led",
raw_value: "0",
},
InputCapability {
name: "sw",
raw_value: "0",
},
InputCapability {
name: "key",
raw_value: "300ff 0 0 0 0 483ffff 17aff32d bf544446 0 0 1 130ff3 8b17c000 677bfa d9415fed 9ed680 4400 0 10000002",
},
InputCapability {
name: "msc",
raw_value: "10",
},
InputCapability {
name: "snd",
raw_value: "0",
},
InputCapability {
name: "ev",
raw_value: "1f",
},
],
properties: "0",
},
),
Event(
EventDevice {
file_name: "event3",
device_name: "input3",
},
),
Input(
InputDevice {
name: "MX Keys Keyboard",
file_name: "input1",
capabilities: [
InputCapability {
name: "rel",
raw_value: "0",
},
InputCapability {
name: "abs",
raw_value: "0",
},
InputCapability {
name: "ff",
raw_value: "0",
},
InputCapability {
name: "led",
raw_value: "1f",
},
InputCapability {
name: "sw",
raw_value: "0",
},
InputCapability {
name: "key",
raw_value: "10000 7 ff800000 7ff febeffdf ffefffff ffffffff fffffffe",
},
InputCapability {
name: "msc",
raw_value: "10",
},
InputCapability {
name: "snd",
raw_value: "0",
},
InputCapability {
name: "ev",
raw_value: "120013",
},
],
properties: "0",
},
),
Event(
EventDevice {
file_name: "event1",
device_name: "input1",
},
),
Event(
EventDevice {
file_name: "event4",
device_name: "input5",
},
),
Input(
InputDevice {
name: "MX Keys Mouse",
file_name: "input2",
capabilities: [
InputCapability {
name: "rel",
raw_value: "143",
},
InputCapability {
name: "abs",
raw_value: "0",
},
InputCapability {
name: "ff",
raw_value: "0",
},
InputCapability {
name: "led",
raw_value: "0",
},
InputCapability {
name: "sw",
raw_value: "0",
},
InputCapability {
name: "key",
raw_value: "ffff0000 0 0 0 0 0 0 0 0",
},
InputCapability {
name: "msc",
raw_value: "10",
},
InputCapability {
name: "snd",
raw_value: "0",
},
InputCapability {
name: "ev",
raw_value: "17",
},
],
properties: "0",
},
),
Event(
EventDevice {
file_name: "event2",
device_name: "input2",
},
),
Input(
InputDevice {
name: "FT5406 memory based driver",
file_name: "input0",
capabilities: [
InputCapability {
name: "rel",
raw_value: "0",
},
InputCapability {
name: "abs",
raw_value: "2608000 3",
},
InputCapability {
name: "ff",
raw_value: "0",
},
InputCapability {
name: "led",
raw_value: "0",
},
InputCapability {
name: "sw",
raw_value: "0",
},
InputCapability {
name: "key",
raw_value: "400 0 0 0 0 0 0 0 0 0 0",
},
InputCapability {
name: "msc",
raw_value: "0",
},
InputCapability {
name: "snd",
raw_value: "0",
},
InputCapability {
name: "ev",
raw_value: "b",
},
],
properties: "2",
},
),
Event(
EventDevice {
file_name: "event0",
device_name: "input0",
},
),
Input(
InputDevice {
name: "MX Ergo Mouse",
file_name: "input5",
capabilities: [
InputCapability {
name: "rel",
raw_value: "143",
},
InputCapability {
name: "abs",
raw_value: "0",
},
InputCapability {
name: "ff",
raw_value: "0",
},
InputCapability {
name: "led",
raw_value: "0",
},
InputCapability {
name: "sw",
raw_value: "0",
},
InputCapability {
name: "key",
raw_value: "ffff0000 0 0 0 0 0 0 0 0",
},
InputCapability {
name: "msc",
raw_value: "10",
},
InputCapability {
name: "snd",
raw_value: "0",
},
InputCapability {
name: "ev",
raw_value: "17",
},
],
properties: "0",
},
),
],
)
I really like they direction you are going with having a stateful struct that holds the configuration of the target file and other params. Ideally we could auto detect all this stuff, but it would be an improvement I think even having your ability to manually put it together. :)
What do you think about renaming Config to Device? Since it probably will contain both config info for input as well as frame buffer ( maybe other device buttons some day? like volume buttons?)
I noticed that your touchscreen appears to be
name: "FT5406 memory based driver", file_name: "input0"
I'm noticing that it's the only device that has a non-trivial "abs" value, i'm wondering if we could use that as some kind of ability to detect the device. I'd really love to figure out how to decode those magical values in "abs". I need to research that a bit.
I'm noticing that it's the only device that has a non-trivial "abs" value, i'm wondering if we could use that as some kind of ability to detect the device. I'd really love to figure out how to decode those magical values in "abs". I need to research that a bit.
It's actually all in the document I mentioned that I've begun reading, here. Actually no you are specifically mentioning the content of /sys/class/input/event*/device/capabilities/. I believe this is an array listing what kind of events are supported by the device (briefly mentioned here but I need to find better reference.
As for the document I previously linked, it gives a few ways to identify a touchscreen from the events, I don't know how reliable it is as it seems conventional. ABS describes absolute coordinates, while REL describes movement relative to the last known position. So ABS seems to be characteristic of touch devices, while REL is more apt to describe mouse movement.
All this seems to be a fragment of evdev for which there is already a few crates.
‘evdev’ looks like it has what we need. The api is a little esoteric, going to look at it a bit. I wonder if it handles time stamp differences.
@nbrr checkout the new example I added in conifer
https://github.com/richardanaya/conifer/blob/master/examples/scan.rs :)
cargo run --example scan
‘evdev’ looks like it has what we need. The api is a little esoteric, going to look at it a bit. I wonder if it handles time stamp differences.
It seems to be doing fine, I guess it is because it uses libc FFI which certainly knows about it. I rewrote lib using the evdev
crate, it is a bit cleaner since it doesn't need to read bytes. evdev
doesn't seem to give higher level interpretation of the event bits.
@nbrr checkout the new example I added in
conifer
https://github.com/richardanaya/conifer/blob/master/examples/scan.rs :)cargo run --example scan
Looks good!
name: FT5406 memory based driver
file: File {
fd: 8,
path: "/dev/input/event0",
read: true,
write: true,
}
abs: input_absinfo {
value: 722,
minimum: 0,
maximum: 800,
fuzz: 0,
flat: 0,
resolution: 0,
}
@nbrr did you want to try to add in auto detect to your config struct? Or if you want I could do it, we could PR your stuff into mainline conifer. I liked the direction you were going with Config
For now I PR'd that Config
. I did not include changes I made not to color 2 pixels per touch as it's clumsy and I'd like to make it nice.
What behaviour did you have in mind in case there are several available devices? How about the framebuffer? And input width/height are in a way dependent on the hardware capacity but also depend on what surface the user actually wants to use.
I think for basic auto detect v1, using fb0 makes sense, and we could use the first device that has touch events and absolute events flag capability. Just even something basic that makes running conifer on PinePhone or RP effortlessly would be awesome.
For auto detect v2, since we are in console, if we truly do see multiple options we can’t decide between we could make a simple text entry “choose what frame buffer you want to use?” Perhaps.
I think the only thing really remaining in this issue is updating examples when we are ready, and coming up with some common way to exit for our demos.
Also need to make sure that 32/64bits timeval is properly dealt with.
@nbrr
Could you describe for me again what issues remain with timeval now on your machine?
The way we are building things up looks fairly generic.
for ev in self.input_device.events_no_sync().unwrap() {
let e = match (ev._type, ev.code, ev.value, ev.time) {
(EV_ABS, ABS_X, x, time) => {
InputEvent::PartialX(x as isize, Timeval::from_timeval(time))
@nbrr
I'd love for us to figure out some generic way we can understand the touch screen capabilities of our respective devices in an hardware agnostic manner.
I think the secrets exist somewhere in
/sys/class/input/event*
I'm wondering if we can scan over the event drivers and figure out which device is a touch screen and their min max details.