Ajout du GUI
This commit is contained in:
254
kivy/lib/mtdev.py
Normal file
254
kivy/lib/mtdev.py
Normal file
@@ -0,0 +1,254 @@
|
||||
'''
|
||||
Python mtdev
|
||||
============
|
||||
|
||||
The mtdev module provides Python bindings to the `Kernel multi-touch
|
||||
transformation library <https://launchpad.net/mtdev>`_, also known as mtdev
|
||||
(MIT license).
|
||||
|
||||
The mtdev library transforms all variants of kernel MT events to the
|
||||
slotted type B protocol. The events put into mtdev may be from any MT
|
||||
device, specifically type A without contact tracking, type A with
|
||||
contact tracking, or type B with contact tracking. See the kernel
|
||||
documentation for further details.
|
||||
|
||||
.. warning::
|
||||
|
||||
This is an external library and Kivy does not provide any support for it.
|
||||
It might change in the future and we advise you don't rely on it in your
|
||||
code.
|
||||
'''
|
||||
# flake8: noqa
|
||||
|
||||
import os
|
||||
import time
|
||||
from ctypes import cdll, Structure, c_ulong, c_int, c_ushort, \
|
||||
c_void_p, pointer, POINTER, byref
|
||||
|
||||
# load library
|
||||
if 'KIVY_DOC' not in os.environ:
|
||||
libmtdev = cdll.LoadLibrary('libmtdev.so.1')
|
||||
|
||||
# from linux/input.h
|
||||
MTDEV_CODE_SLOT = 0x2f # MT slot being modified
|
||||
MTDEV_CODE_TOUCH_MAJOR = 0x30 # Major axis of touching ellipse
|
||||
MTDEV_CODE_TOUCH_MINOR = 0x31 # Minor axis (omit if circular)
|
||||
MTDEV_CODE_WIDTH_MAJOR = 0x32 # Major axis of approaching ellipse
|
||||
MTDEV_CODE_WIDTH_MINOR = 0x33 # Minor axis (omit if circular)
|
||||
MTDEV_CODE_ORIENTATION = 0x34 # Ellipse orientation
|
||||
MTDEV_CODE_POSITION_X = 0x35 # Center X ellipse position
|
||||
MTDEV_CODE_POSITION_Y = 0x36 # Center Y ellipse position
|
||||
MTDEV_CODE_TOOL_TYPE = 0x37 # Type of touching device
|
||||
MTDEV_CODE_BLOB_ID = 0x38 # Group a set of packets as a blob
|
||||
MTDEV_CODE_TRACKING_ID = 0x39 # Unique ID of initiated contact
|
||||
MTDEV_CODE_PRESSURE = 0x3a # Pressure on contact area
|
||||
MTDEV_CODE_ABS_X = 0x00
|
||||
MTDEV_CODE_ABS_Y = 0x01
|
||||
MTDEV_CODE_ABS_Z = 0x02
|
||||
MTDEV_CODE_BTN_DIGI = 0x140
|
||||
MTDEV_CODE_BTN_TOOL_PEN = 0x140
|
||||
MTDEV_CODE_BTN_TOOL_RUBBER = 0x141
|
||||
MTDEV_CODE_BTN_TOOL_BRUSH = 0x142
|
||||
MTDEV_CODE_BTN_TOOL_PENCIL = 0x143
|
||||
MTDEV_CODE_BTN_TOOL_AIRBRUSH = 0x144
|
||||
MTDEV_CODE_BTN_TOOL_FINGER = 0x145
|
||||
MTDEV_CODE_BTN_TOOL_MOUSE = 0x146
|
||||
MTDEV_CODE_BTN_TOOL_LENS = 0x147
|
||||
MTDEV_CODE_BTN_TOUCH = 0x14a
|
||||
MTDEV_CODE_BTN_STYLUS = 0x14b
|
||||
MTDEV_CODE_BTN_STYLUS2 = 0x14c
|
||||
MTDEV_CODE_BTN_TOOL_DOUBLETAP = 0x14d
|
||||
MTDEV_CODE_BTN_TOOL_TRIPLETAP = 0x14e
|
||||
MTDEV_CODE_BTN_TOOL_QUADTAP = 0x14f # Four fingers on trackpad
|
||||
|
||||
MTDEV_TYPE_EV_ABS = 0x03
|
||||
MTDEV_TYPE_EV_SYN = 0x00
|
||||
MTDEV_TYPE_EV_KEY = 0x01
|
||||
MTDEV_TYPE_EV_REL = 0x02
|
||||
MTDEV_TYPE_EV_ABS = 0x03
|
||||
MTDEV_TYPE_EV_MSC = 0x04
|
||||
MTDEV_TYPE_EV_SW = 0x05
|
||||
MTDEV_TYPE_EV_LED = 0x11
|
||||
MTDEV_TYPE_EV_SND = 0x12
|
||||
MTDEV_TYPE_EV_REP = 0x14
|
||||
MTDEV_TYPE_EV_FF = 0x15
|
||||
MTDEV_TYPE_EV_PWR = 0x16
|
||||
MTDEV_TYPE_EV_FF_STATUS = 0x17
|
||||
|
||||
MTDEV_ABS_TRACKING_ID = 9
|
||||
MTDEV_ABS_POSITION_X = 5
|
||||
MTDEV_ABS_POSITION_Y = 6
|
||||
MTDEV_ABS_TOUCH_MAJOR = 0
|
||||
MTDEV_ABS_TOUCH_MINOR = 1
|
||||
MTDEV_ABS_WIDTH_MAJOR = 2
|
||||
MTDEV_ABS_WIDTH_MINOR = 3
|
||||
MTDEV_ABS_ORIENTATION = 4
|
||||
MTDEV_ABS_SIZE = 11
|
||||
|
||||
class timeval(Structure):
|
||||
_fields_ = [
|
||||
('tv_sec', c_ulong),
|
||||
('tv_usec', c_ulong)
|
||||
]
|
||||
|
||||
class input_event(Structure):
|
||||
_fields_ = [
|
||||
('time', timeval),
|
||||
('type', c_ushort),
|
||||
('code', c_ushort),
|
||||
('value', c_int)
|
||||
]
|
||||
|
||||
class input_absinfo(Structure):
|
||||
_fields_ = [
|
||||
('value', c_int),
|
||||
('minimum', c_int),
|
||||
('maximum', c_int),
|
||||
('fuzz', c_int),
|
||||
('flat', c_int),
|
||||
('resolution', c_int)
|
||||
]
|
||||
|
||||
class mtdev_caps(Structure):
|
||||
_fields_ = [
|
||||
('has_mtdata', c_int),
|
||||
('has_slot', c_int),
|
||||
('has_abs', c_int * MTDEV_ABS_SIZE),
|
||||
('slot', input_absinfo),
|
||||
('abs', input_absinfo * MTDEV_ABS_SIZE)
|
||||
]
|
||||
|
||||
class mtdev(Structure):
|
||||
_fields_ = [
|
||||
('caps', mtdev_caps),
|
||||
('state', c_void_p)
|
||||
]
|
||||
|
||||
# binding
|
||||
if 'KIVY_DOC' not in os.environ:
|
||||
mtdev_open = libmtdev.mtdev_open
|
||||
mtdev_open.argtypes = [POINTER(mtdev), c_int]
|
||||
mtdev_get = libmtdev.mtdev_get
|
||||
mtdev_get.argtypes = [POINTER(mtdev), c_int, POINTER(input_event), c_int]
|
||||
mtdev_idle = libmtdev.mtdev_idle
|
||||
mtdev_idle.argtypes = [POINTER(mtdev), c_int, c_int]
|
||||
mtdev_close = libmtdev.mtdev_close
|
||||
mtdev_close.argtypes = [POINTER(mtdev)]
|
||||
|
||||
|
||||
class Device:
|
||||
def __init__(self, filename):
|
||||
self._filename = filename
|
||||
self._fd = -1
|
||||
self._device = mtdev()
|
||||
|
||||
# Linux kernel creates input devices then hands permission changes
|
||||
# off to udev. This results in a period of time when the device is
|
||||
# readable only by root. Device reconnects can be processed by
|
||||
# MTDMotionEventProvider faster than udev can get a chance to run,
|
||||
# so we spin for a period of time to allow udev to fix permissions.
|
||||
# We limit the loop time in case the system is misconfigured and
|
||||
# the user really does not (and will not) have permission to access
|
||||
# the device.
|
||||
# Note: udev takes about 0.6 s on a Raspberry Pi 4
|
||||
permission_wait_until = time.time() + 3.0
|
||||
while self._fd == -1:
|
||||
try:
|
||||
self._fd = os.open(filename, os.O_NONBLOCK | os.O_RDONLY)
|
||||
except PermissionError:
|
||||
if time.time() > permission_wait_until:
|
||||
raise
|
||||
ret = mtdev_open(pointer(self._device), self._fd)
|
||||
if ret != 0:
|
||||
os.close(self._fd)
|
||||
self._fd = -1
|
||||
raise Exception('Unable to open device')
|
||||
|
||||
def close(self):
|
||||
'''Close the mtdev converter
|
||||
'''
|
||||
if self._fd == -1:
|
||||
return
|
||||
mtdev_close(pointer(self._device))
|
||||
os.close(self._fd)
|
||||
self._fd = -1
|
||||
|
||||
def idle(self, ms):
|
||||
'''Check state of kernel device
|
||||
|
||||
:Parameters:
|
||||
`ms`: int
|
||||
Number of milliseconds to wait for activity
|
||||
|
||||
:Return:
|
||||
Return True if the device is idle, i.e, there are no fetched events
|
||||
in the pipe and there is nothing to fetch from the device.
|
||||
'''
|
||||
if self._fd == -1:
|
||||
raise Exception('Device closed')
|
||||
return bool(mtdev_idle(pointer(self._device), self._fd, ms))
|
||||
|
||||
|
||||
def get(self):
|
||||
if self._fd == -1:
|
||||
raise Exception('Device closed')
|
||||
ev = input_event()
|
||||
if mtdev_get(pointer(self._device), self._fd, byref(ev), 1) <= 0:
|
||||
return None
|
||||
return ev
|
||||
|
||||
def has_mtdata(self):
|
||||
'''Return True if the device has multitouch data.
|
||||
'''
|
||||
if self._fd == -1:
|
||||
raise Exception('Device closed')
|
||||
return bool(self._device.caps.has_mtdata)
|
||||
|
||||
def has_slot(self):
|
||||
'''Return True if the device has slot information.
|
||||
'''
|
||||
if self._fd == -1:
|
||||
raise Exception('Device closed')
|
||||
return bool(self._device.caps.has_slot)
|
||||
|
||||
def has_abs(self, index):
|
||||
'''Return True if the device has abs data.
|
||||
|
||||
:Parameters:
|
||||
`index`: int
|
||||
One of const starting with a name ABS_MT_
|
||||
'''
|
||||
if self._fd == -1:
|
||||
raise Exception('Device closed')
|
||||
if index < 0 or index >= MTDEV_ABS_SIZE:
|
||||
raise IndexError('Invalid index')
|
||||
return bool(self._device.caps.has_abs[index])
|
||||
|
||||
def get_max_abs(self):
|
||||
'''Return the maximum number of abs information available.
|
||||
'''
|
||||
return MTDEV_ABS_SIZE
|
||||
|
||||
def get_slot(self):
|
||||
'''Return the slot data.
|
||||
'''
|
||||
if self._fd == -1:
|
||||
raise Exception('Device closed')
|
||||
if self._device.caps.has_slot == 0:
|
||||
return
|
||||
return self._device.caps.slot
|
||||
|
||||
def get_abs(self, index):
|
||||
'''Return the abs data.
|
||||
|
||||
:Parameters:
|
||||
`index`: int
|
||||
One of const starting with a name ABS_MT_
|
||||
'''
|
||||
if self._fd == -1:
|
||||
raise Exception('Device closed')
|
||||
if index < 0 or index >= MTDEV_ABS_SIZE:
|
||||
raise IndexError('Invalid index')
|
||||
return self._device.caps.abs[index]
|
||||
|
||||
|
||||
Reference in New Issue
Block a user