36

What is the "format" of the character devices located in /dev/input/event*?

In other words, how can I decode the character stream? A Python example would be greatly appreciated.

5 Answers 5

50

A simple and raw reader can be just done using:

#!/usr/bin/python
import struct
import time
import sys

infile_path = "/dev/input/event" + (sys.argv[1] if len(sys.argv) > 1 else "0")

"""
FORMAT represents the format used by linux kernel input event struct
See https://github.com/torvalds/linux/blob/v5.5-rc5/include/uapi/linux/input.h#L28
Stands for: long int, long int, unsigned short, unsigned short, unsigned int
"""
FORMAT = 'llHHI'
EVENT_SIZE = struct.calcsize(FORMAT)

#open file in binary mode
in_file = open(infile_path, "rb")

event = in_file.read(EVENT_SIZE)

while event:
    (tv_sec, tv_usec, type, code, value) = struct.unpack(FORMAT, event)

    if type != 0 or code != 0 or value != 0:
        print("Event type %u, code %u, value %u at %d.%d" % \
            (type, code, value, tv_sec, tv_usec))
    else:
        # Events with code, type and value == 0 are "separator" events
        print("===========================================")

    event = in_file.read(EVENT_SIZE)

in_file.close()
Sign up to request clarification or add additional context in comments.

3 Comments

Any idea what the FORMAT means? When I convert an event to HEX it's a long string. Is there anyway to know what byte is the value?
The comment above the FORMAT line describes what it means. I think the length will depend on the system architecture, but on my Raspberry Pi, long int is 4 bytes, unsigned short is 2 bytes, and unsigned int is 4 bytes. This would make a hex string of 16 characters, the last 4 being the value. Also of note, github.com/torvalds/linux/blob/master/include/uapi/linux/… details the different event types and values.
@etw3 The reply given by Oliver is correct, however I've updated the code to make it clearer.
27

The format is described in the Documentation/input/input.txt file in the Linux source. Basically, you read structs of the following form from the file:

struct input_event {
    struct timeval time;
    unsigned short type;
    unsigned short code;
    unsigned int value;
};

type and code are values defined in linux/input.h. For example, type might be EV_REL for relative moment of a mouse, or EV_KEY for a keypress, and code is the keycode, or REL_X or ABS_X for a mouse.

1 Comment

FYI it corresponds to the FORMAT = 'llHHI' of python struct
11

Right here in the Input.py module. You'll also need the event.py module.

3 Comments

These two modules can't be use standalone...they have other dependencies upon the pycopia stuff.
Nope, but wasn't clear from the answer, I thought -- because the links go directly to the module, rather than to the package itself.
@larsks I also just pointed to it because it embodies some of the hard parts of this interface that might make it easier to "roll your own" if you wanted to do that.
10

The python-evdev package provides bindings to the event device interface. A short usage example would be:

from evdev import InputDevice
from select import select

dev = InputDevice('/dev/input/event1')

while True:
   r,w,x = select([dev], [], [])
   for event in dev.read():
       print(event)

# event at 1337427573.061822, code 01, type 02, val 01
# event at 1337427573.061846, code 00, type 00, val 00

Keep in mind that, unlike the very convenient, purely Pythonic modules mentioned so far, evdev contains C extensions. Building them requires having your Python development and kernel headers installed.

1 Comment

this is great! one can also read from just one device without select function by using dev.read_loop(). I am using this on Raspberry pi Python3.9 or Python 3.11
7

The data is in the form of input_event structures; see http://www.thelinuxdaily.com/2010/05/grab-raw-keyboard-input-from-event-device-node-devinputevent/ for a C example. The struct definition is at (for example) http://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/include/linux/input.h?v=2.6.11.8. Note that you will need to use a bunch of ioctl calls to get information on the device before reading from it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.