h.n
h.n

Reputation: 153

Is capturing HID keyboard event without root user privilege possible in linux

What I want

Write a script that reads what HID usage ids usb keyboards send without root user right.

The purpose is to map a scancode/HID id and the resulting literal input for writing a keyboard configuration tool; T key press may input a literal Y if the user is using dvorak layout or Z may input a literal ツ.

The code snippet below does a nice job in capturing scancode(usb keyboards send hid usage id, but it still captures scancode), but requires read permission for /dev/input/*, not ideal.

from evdev import *
dev = InputDevice('/dev/input/event5')

print(dev)

for event in dev.read_loop():
    if event.type == ecodes.EV_KEY:
        print(categorize(event))

Is there anyway to do this without special permissions?

Upvotes: 1

Views: 1353

Answers (1)

h.n
h.n

Reputation: 153

Conclusion:

X input extension 2(XI2) provides access to RawEvents; though I could not find what I need in RawKeyPress event: Capture XI2 RawKeyPress event and interpreting it with python

It's half possible to convert X11 keycodes back to scancodes.

Not detailed but my note on them here: How to translate X11 keycode back to scancode or hid usage id reliably

As to capturing keyboard events upstream of /dev/input/event*, it's not possible without some permissions.

XI2 support in python is poor and playing with it seems to require using C library or writing X client library. The latest version of python3-xlib does support it but at least I cannot find documentations and understanding binary data is not easy.

The key event generation chain:

This blog post had some details about keyboard event generation process: https://seasonofcode.com/posts/internal-input-event-handling-in-the-linux-kernel-and-the-android-userspace.html
----os space-------------

  1. A user press a keyboard key
  2. The keyboard sends an hidbp(a packet of a sort) to the usb controller
  3. USB controller receives the packet and make an irq(Interrupt request)
  4. CPU responds to the irq and invokes irq handler which is set by the keyboard driver. ---somewhat uncertain
  5. irq handler stores the packet or event and queues the processing function call for it in the kernel and exits.
  6. The queued function process the event and reports it to various functions in include/linux/input.h and calls input_sync to write the event to a device file such as /dev/input/event1.

---user space----

  1. Be it xwindow server or android InputDeviceReader reads form /dev/input/event*

If what I've read is right and have read it right, anything upstream of the /dev/input/event* happens in the kernel and the task is handled by the device driver.

Upvotes: 4

Related Questions