Reading input events

The driver for the touch screen that I have been using registers itself as an input event handler. If it is the only input device on the system, it will be mapped to /dev/input/event0. If there is also an USB mouse, for example, it will be mapped to /dev/input/event1. You can get an idea of what is mapped to what by listing the contents of directory /dev/input/by-path. With only the display, my system reads:

$ ls -l /dev/input/by-path/*
/dev/input/by-path/platform-fe204000.spi-event -> ../event0

The “spi-event” mapped to event0 belongs to the display, which uses the SPI protocol for communication. With this information all you need to do is read the byte stream from /dev/input/event0 and interpret the contents. Information is sent in packets and on the Raspberry Pi the packet is 16-bytes long (on 64-bits Linux systems the size may differ, but I have not tried that). The packet structure is as following (again referencing this good article):

  • timestamp: 8 bytes encoding the event time as a struct timeval, a standard way of measuring time on Linux systems;
  • type: 2 bytes (Little Endian 16-bits integer), the event type;
  • code: 2 bytes (Little Endian 16-bits integer), the code identifying the device;
  • value: 4 bytes (Little Endian 32-bits integer), the event value.

The constants for event type and code are defined in the system header /usr/include/linux/input-event-codes.h. I have observed that my display sends only these events:

#define EV_SYN 0x00
#define EV_KEY 0x01
#define EV_ABS 0x03

EV_KEY is sent when the pen touches the screen and also when the pen is raised from the screen. In these two cases code is always 0x14A which, according to input-event-codes.h, is BTN_TOUCH. Value is 1 on touch and 0 on release.

EV_ABS is sent when the pen is dragged over the screen. Code is 0x00 for the horizontal coordinate (X), 0x01 for the vertical coordinate (Y) and 0x18 for the pressure applied by the pen on the screen:

#define ABS_X 0x00
#define ABS_Y 0x01
#define ABS_PRESSURE 0x18

The X and Y values encode the absolute coordinates. I have noticed that the value ranges from 0x100 to around 0xF00 (different displays may give different values). To convert these values to screen coordinates you must map the 0x100->0xF00 range to 0->320 or 0->480. I am not interpreting the pressure value yet, but it may be useful in the future.

EV_SYN is sent to signal the end of the “logical event”. Touching the display sends EV_KEY(BTN_TOUCH), EV_ABS(ABS_X) EV_ABS(ABS_Y), EV_ABS(ABS_PRESSURE) and EV_SYN. Releasing the pen sends EV_KEY(BTN_TOUCH) and EV_SYN. Dragging the pen sends EV_ABS(ABS_X) EV_ABS(ABS_Y), EV_ABS(ABS_PRESSURE) and EV_SYN. Sometimes I have seen move events with just the X or Y coordinate. I am assuming this means that the missing coordinate have not changed since the last event. An this is all you need to interpret input events directly from this type of display, without relying on X.org for example.

One thought on “Reading input events

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s