Linux input
+Some notes on using /dev/input/*
device driver files.
mouseX / mice
+These device files are created by the [mousedev] driver.
+-
+
/dev/input/mouseX
represents the input stream for a SINGLE mouse device.
+/dev/input/mice
represents the merged input stream for ALL mouse devices.
+
The data stream consists of 3 bytes
per event
. An event is encoded as (BTN, X, Y)
.
-
+
BTN
button pressed
+X
movement in x-direction-1 -> left
and1 -> right
+Y
movement in y-direction-1 -> down
and1 -> up
+
The raw data stream can be inspected as follows.
+sudo cat /dev/input/mice | od -tx1 -w3 -v
+
+eventX
+These device files are created by the [evdev] driver.
+-
+
/dev/input/eventX
represents the generic input event interface a SINGLE input deivece.
+
Input events are encoded as given by the input_event
struct below. Reading
+from the eventX
device file will always yield whole number of input events.
struct input_event {
+ struct timeval time;
+ unsigned short type;
+ unsigned short code;
+ unsigned int value;
+};
+
+On most 64bit machines the raw data stream can be inspected as follows.
+sudo cat /dev/input/event4 | od -tx1 -w24 -v
+
+Identifyin device files.
+To find out which device file is assigned to which input device the following
+file /proc/bus/input/devices
in the proc filesystem can be consulted.
This yields entries as follows and shows which Handlers
are assigned to which
+Name
.
I: Bus=0018 Vendor=04f3 Product=0033 Version=0000
+N: Name="Elan Touchpad"
+...
+H: Handlers=event15 mouse0
+...
+
+Example: Toying with /dev/input/eventX
+Once compiled, the example should be run as sudo ./event /dev/input/eventX
.
#include <stdio.h>
+#include <fcntl.h>
+#include <assert.h>
+#include <unistd.h>
+#include <time.h>
+
+#include <sys/time.h>
+#include <linux/input-event-codes.h>
+
+struct input_event {
+ struct timeval time;
+ unsigned short type;
+ unsigned short code;
+ unsigned int value;
+};
+
+const char* type(unsigned short t) {
+ static char buf[32];
+ const char* fmt = "0x%x";
+ switch (t) {
+#define FMT(TYPE) case TYPE: fmt = #TYPE"(0x%x)"; break
+ FMT(EV_SYN);
+ FMT(EV_KEY);
+ FMT(EV_REL);
+ FMT(EV_ABS);
+#undef FMT
+ }
+ snprintf(buf, sizeof(buf), fmt, t);
+ return buf;
+}
+
+const char* code(unsigned short c) {
+ static char buf[32];
+ const char* fmt = "0x%x";
+ switch (c) {
+#define FMT(CODE) case CODE: fmt = #CODE"(0x%x)"; break
+ FMT(BTN_LEFT);
+ FMT(BTN_RIGHT);
+ FMT(BTN_MIDDLE);
+ FMT(REL_X);
+ FMT(REL_Y);
+#undef FMT
+ }
+ snprintf(buf, sizeof(buf), fmt, c);
+ return buf;
+}
+
+const char* timefmt(const struct timeval* t) {
+ assert(t);
+ struct tm* lt = localtime(&t->tv_sec); // Returns pointer to static tm object.
+ static char buf[64];
+ strftime(buf, sizeof(buf), "%H:%M:%S", lt);
+ return buf;
+}
+
+int main(int argc, char* argv[]) {
+ assert(argc == 2);
+
+ int fd = open(argv[1], O_RDONLY);
+ assert(fd != -1);
+
+ struct input_event inp;
+ while (1) {
+ int ret = read(fd, &inp, sizeof(inp));
+ assert(ret == sizeof(inp));
+ printf("time: %s type: %s code: %s value: 0x%x\n",
+ timefmt(&inp.time), type(inp.type), code(inp.code), inp.value);
+ }
+}
+
+[mousedev]: TODO /home/johannst/dev/linux/drivers/input/mousedev.c +[evdev]: TODO /home/johannst/dev/linux/drivers/input/evdev.c
+ +