Skip to content

Instantly share code, notes, and snippets.

@artizirk
Last active February 14, 2022 11:27
Show Gist options
  • Save artizirk/d08a889164701b1c0e0428e280674429 to your computer and use it in GitHub Desktop.
Save artizirk/d08a889164701b1c0e0428e280674429 to your computer and use it in GitHub Desktop.
Pure python way of getting and setting input_absinfo in linux kernel evdev devices https://python-evdev.readthedocs.io/en/latest/apidoc.html#evdev.device.InputDevice.absinfo
from ctypes import *
from fcntl import ioctl
# See ioctl.h of your architecture for appropriate constants here.
# This has been tested only on x86
_IOC_NRBITS = 8
_IOC_TYPEBITS = 8
_IOC_NRSHIFT = 0
_IOC_TYPESHIFT = _IOC_NRSHIFT + _IOC_NRBITS
_IOC_SIZESHIFT = _IOC_TYPESHIFT + _IOC_TYPEBITS
_IOC_NONE = 0
_IOC_WRITE = 1
_IOC_READ = 2
_IOC_SIZEBITS = 14
_IOC_DIRBITS = 2
_IOC_DIRSHIFT = _IOC_SIZESHIFT + _IOC_SIZEBITS
def _IOC(dir_, type_, nr, size):
return (
c_int32(dir_ << _IOC_DIRSHIFT).value |
c_int32(ord(type_) << _IOC_TYPESHIFT).value |
c_int32(nr << _IOC_NRSHIFT).value |
c_int32(size << _IOC_SIZESHIFT).value)
def _IOC_TYPECHECK(t):
return sizeof(t)
def _IO(type_, nr):
return _IOC(_IOC_NONE, type_, nr, 0)
def _IOW(type_, nr, size):
return _IOC(_IOC_WRITE, type_, nr, _IOC_TYPECHECK(size))
def _IOR(type_, nr, size):
return _IOC(_IOC_READ, type_, nr, _IOC_TYPECHECK(size))
def _IOWR(type_, nr, size):
return _IOC(_IOC_READ | _IOC_WRITE, type_, nr, _IOC_TYPECHECK(size))
# linux/input.h
class input_absinfo(Structure):
_fields_ = [
('value', c_int32),
('minimum', c_int32),
('maximum', c_int32),
('fuzz', c_int32),
('flat', c_int32),
('resolution', c_int32)
]
def __repr__(self):
return "input_absinfo(value={}, minimum={}, maximum={}, fuzz={}, flat={} resolution={}) # object at {}".format(
self.value, self.minimum, self.maximum, self.fuzz, self.flat, self.resolution, hex(id(self))
)
# linux/input.h
def EVIOCGABS(abs):
# EVIOCGABS(abs) _IOR('E', 0x40 + (abs), struct input_absinfo) /* get abs value/limits */
return _IOR("E", 0x40 + abs, input_absinfo)
# linux/input.h
def EVIOCSABS(abs):
# EVIOCSABS(abs) _IOW('E', 0xc0 + (abs), struct input_absinfo) /* set abs value/limits */
return _IOW("E", 0xc0 + abs, input_absinfo)
def get_absinfo(fd, abs):
absinfo = input_absinfo()
r = ioctl(fd, EVIOCGABS(abs), absinfo)
return r, absinfo
def set_absinfo(fd, abs, absinfo):
r = ioctl(fd, EVIOCSABS(abs), absinfo)
return r
if __name__ == '__main__':
f = open("/dev/input/event5", 'rb')
fd = f.fileno()
# set first 4 axes absinfo
for abs in range(4):
r, absinfo = get_absinfo(fd, abs)
if r!=0:
print("error: get_absinfo ret = ", r)
print("cur", absinfo)
absinfo = input_absinfo()
absinfo.minimum = 450
absinfo.maximum = 3650
absinfo.fuzz = 15
absinfo.flat = 255
print("set", absinfo)
r = 0#set_absinfo(fd, abs, absinfo)
if r == 0:
print("OK")
else:
print("error: set_absinfo ret =", r)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment