방금 그래픽 태블릿 VEIKK A30을 구입했습니다. 마우스를 직접 식별하십시오. 안타깝게도 Linux에서 압력 감지를 활성화하는 방법을 찾을 수 없습니다. 한 사람이 몇 가지 조정을 통해 작동할 수 있었지만 이에 대한 참조를 찾을 수 없다고 보고하는 것을 보았습니다.
편집: 이것은 dmesg의 출력입니다.
[mars19 01:15] usb 2-1: new full-speed USB device number 10 using xhci_hcd
[ +0,153026] usb 2-1: New USB device found, idVendor=2feb, idProduct=0002, bcdDevice= 0.00
[ +0,000006] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ +0,000004] usb 2-1: Product: A30
[ +0,000003] usb 2-1: Manufacturer: VEIKK.INC
[ +0,000004] usb 2-1: SerialNumber: 0000001
[ +0,003052] input: VEIKK.INC A30 Mouse as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/0003:2FEB:0002.000C/input/input64
[ +0,064250] input: VEIKK.INC A30 as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.0/0003:2FEB:0002.000C/input/input65
[ +0,000429] hid-generic 0003:2FEB:0002.000C: input,hidraw0: USB HID v1.00 Mouse [VEIKK.INC A30] on usb-0000:00:14.0-1/input0
[ +0,001079] input: VEIKK.INC A30 as /devices/pci0000:00/0000:00:14.0/usb2/2-1/2-1:1.1/0003:2FEB:0002.000D/input/input66
[ +0,062599] hid-generic 0003:2FEB:0002.000D: input,hidraw1: USB HID v1.00 Keyboard [VEIKK.INC A30] on usb-0000:00:14.0-1/input1
[ +0,001208] hid-generic 0003:2FEB:0002.000E: hiddev0,hidraw2: USB HID v1.00 Device [VEIKK.INC A30] on usb-0000:00:14.0-1/input2
sudo cat /dev/hidraw0
편집 2: 음, 압력을 가하는 장치에 따라 패턴이 다르기 때문에 압력을 보내는 장치를 읽을 수 있는 것 같습니다 . 이 바이너리를 어떻게 읽는지 모르겠습니다 ^^ 가능하다면 사용할 수 있을 것 같습니다.입력새 장치에 매핑하시겠습니까? ^^ /dev/input
mouseX, eventY, mouse1이 포함된 파일은 태블릿 관련 파일이지만 스트레스 관련 파일은 아니며, 이 폴더에서 태블릿과 연결된 많은 정보를 보여주는 파일은 /dev/input/by-id/usb-VEIKK.INC_A30_0000001-event-mouse
. 그러나 이러한 패턴이 스트레스와 일치하는지 여부는 확실하지 않습니다. 여기에 너무 많은 정보가 전송됩니다. 구문 분석 방법을 알고 계시다면 알려주세요!
Edit3: 아직 드라이버가 없지만 적어도 장치 원시 통신의 입력을 쉽게 읽을 수 있을 것 같습니다. 나는 개념 증명으로 이 Python 스크립트를 만들었습니다.
#!/usr/bin/env python3
import struct
PRINT_TIMESTAMP = True
# Open the file in the read-binary mode
f = open("/dev/input/by-id/usb-VEIKK.INC_A30_0000001-event-mouse", "rb" )
while 1:
data = f.read(24)
# print struct.unpack('4IHHI',data)
###### FORMAT = ( Time Stamp_INT , 0 , Time Stamp_DEC , 0 ,
###### type , code ( key pressed ) , value (press/release) )
time_int, _, time_dec, _, ev_type, ev_code, ev_val = struct.unpack('4IHHI',data)
t = (ev_type, ev_code)
if ((t == (0,0) and ev_val == 0)
or (t == (4, 4) and ev_val >= 589825 and ev_val <= 589827)):
# Redundant as it's for normal/bottom/top clicks
# (same code for press/release), or just garbage 0,0,0
continue
if PRINT_TIMESTAMP:
print("[{:.2f}] ".format(time_int + time_dec/1e6),
end="", flush=True)
if t == (3,0):
print("Pos x: {} ({:.2f}%)".format(ev_val, 100*ev_val/32767), flush=True)
elif t == (3,1):
print("Pos y: {} ({:.2f}%)".format(ev_val, 100*ev_val/32767), flush=True)
elif t == (3,24):
print("Pression: {} ({:.2f}%)".format(ev_val, 100*ev_val/8191), flush=True)
elif t == (1,272):
print("Normal click ({})".format("press" if ev_val else "release"), flush=True)
elif t == (1,273):
print("click button 2 (bottom) ({})".format("press" if ev_val else "release"), flush=True)
elif t == (1,274):
print("click button 3 (top) ({})".format("press" if ev_val else "release"), flush=True)
else:
print("Unknow: type={}, code={}, value={}".format(ev_type, ev_code, ev_val), flush=True)
데모:
[1553182025.55] Pos y: 11458 (34.97%)
[1553182025.55] Pos x: 14310 (43.67%)
[1553182025.56] Pos x: 14314 (43.68%)
[1553182025.56] Pos x: 14318 (43.70%)
[1553182025.57] Pos x: 14321 (43.71%)
[1553182025.57] Normal click (press)
[1553182025.57] Pos x: 14323 (43.71%)
[1553182025.57] Pression: 1122 (13.70%)
[1553182025.57] Pos x: 14326 (43.72%)
[1553182025.57] Pos y: 11466 (34.99%)
[1553182025.57] Pression: 1260 (15.38%)
[1553182025.58] Pos x: 14329 (43.73%)
[1553182025.58] Pression: 1337 (16.32%)
[1553182025.58] Pos x: 14330 (43.73%)
[1553182025.58] Pos y: 11494 (35.08%)
[1553182025.58] Pression: 1515 (18.50%)
[1553182025.59] Pos y: 11506 (35.11%)
[1553182025.59] Pression: 1687 (20.60%)
[1553182025.59] Pos y: 11517 (35.15%)
[1553182025.59] Pression: 1689 (20.62%)
[1553182025.59] Pos y: 11529 (35.18%)
[1553182025.59] Pression: 1789 (21.84%)
[1553182025.60] Pos y: 11536 (35.21%)
[1553182025.60] Pression: 1829 (22.33%)
[1553182025.60] Pos y: 11542 (35.22%)
[1553182025.60] Pression: 1907 (23.28%)
[1553182025.61] Pression: 2031 (24.80%)
[1553182025.61] Pos y: 11549 (35.25%)
[1553182025.61] Pression: 2140 (26.13%)
편집 4: 놀라운 페이지:https://digimend.github.io/support/howto/trbl/ located_failure/그러나 여기서는 모든 것이 잘 작동합니다. 테스트하려는 마지막 단계를 제외하고 말이죠. MyPaint로 테스트를 시도했지만 압력이 감지되지 않았습니다.
또한 기본적으로 이벤트 파일의 입력을 새 장치에 복사하는 코드를 직접 작성해 보았습니다. 다음과 같습니다.
#!/usr/bin/env python3
import sys
import libevdev
import time
def print_capabilities(l):
v = l.driver_version
print("Input driver version is {}.{}.{}".format(v >> 16, (v >> 8) & 0xff, v & 0xff))
id = l.id
print("Input device ID: bus {:#x} vendor {:#x} product {:#x} version {:#x}".format(
id["bustype"],
id["vendor"],
id["product"],
id["version"],
))
print("Input device name: {}".format(l.name))
print("Supported events:")
for t, cs in l.evbits.items():
print(" Event type {} ({})".format(t.value, t.name))
for c in cs:
if t in [libevdev.EV_LED, libevdev.EV_SND, libevdev.EV_SW]:
v = l.value[c]
print(" Event code {} ({}) state {}".format(c.value, c.name, v))
else:
print(" Event code {} ({})".format(c.value, c.name))
if t == libevdev.EV_ABS:
a = l.absinfo[c]
print(" {:10s} {:6d}".format('Value', a.value))
print(" {:10s} {:6d}".format('Minimum', a.minimum))
print(" {:10s} {:6d}".format('Maximum', a.maximum))
print(" {:10s} {:6d}".format('Fuzz', a.fuzz))
print(" {:10s} {:6d}".format('Flat', a.flat))
print(" {:10s} {:6d}".format('Resolution', a.resolution))
print("Properties:")
for p in l.properties:
print(" Property type {} ({})".format(p.value, p.name))
def print_event(e):
print("Event: time {}.{:06d}, ".format(e.sec, e.usec), end='')
if e.matches(libevdev.EV_SYN):
if e.matches(libevdev.EV_SYN.SYN_MT_REPORT):
print("++++++++++++++ {} ++++++++++++".format(e.code.name))
elif e.matches(libevdev.EV_SYN.SYN_DROPPED):
print(">>>>>>>>>>>>>> {} >>>>>>>>>>>>".format(e.code.name))
else:
print("-------------- {} ------------".format(e.code.name))
else:
print("type {:02x} {} code {:03x} {:20s} value {:4d}".format(e.type.value, e.type.name, e.code.value, e.code.name, e.value))
def main(args):
path = args[1]
dev = libevdev.Device()
dev.name = "Combined Both Devices"
dev.enable(libevdev.EV_ABS.ABS_X,
libevdev.InputAbsInfo(minimum=0, maximum=32767))
dev.enable(libevdev.EV_ABS.ABS_Y,
libevdev.InputAbsInfo(minimum=0, maximum=32767))
dev.enable(libevdev.EV_ABS.ABS_Z,
libevdev.InputAbsInfo(minimum=0, maximum=8191))
dev.enable(libevdev.EV_ABS.ABS_0B,
libevdev.InputAbsInfo(minimum=0, maximum=8191))
dev.enable(libevdev.EV_ABS.ABS_DISTANCE,
libevdev.InputAbsInfo(minimum=0, maximum=8191))
dev.enable(libevdev.EV_ABS.ABS_PRESSURE,
libevdev.InputAbsInfo(minimum=0, maximum=8191))
dev.enable(libevdev.EV_MSC.MSC_SCAN)
dev.enable(libevdev.EV_KEY.BTN_LEFT)
dev.enable(libevdev.EV_KEY.BTN_RIGHT)
dev.enable(libevdev.EV_KEY.BTN_MIDDLE)
dev.enable(libevdev.EV_KEY.BTN_TOUCH)
dev.enable(libevdev.EV_SYN.SYN_REPORT)
dev.enable(libevdev.EV_SYN.SYN_CONFIG)
dev.enable(libevdev.EV_SYN.SYN_MT_REPORT)
dev.enable(libevdev.EV_SYN.SYN_DROPPED)
dev.enable(libevdev.EV_SYN.SYN_04)
dev.enable(libevdev.EV_SYN.SYN_05)
dev.enable(libevdev.EV_SYN.SYN_06)
dev.enable(libevdev.EV_SYN.SYN_07)
dev.enable(libevdev.EV_SYN.SYN_08)
dev.enable(libevdev.EV_SYN.SYN_09)
dev.enable(libevdev.EV_SYN.SYN_0A)
dev.enable(libevdev.EV_SYN.SYN_0B)
dev.enable(libevdev.EV_SYN.SYN_0C)
dev.enable(libevdev.EV_SYN.SYN_0D)
dev.enable(libevdev.EV_SYN.SYN_0E)
dev.enable(libevdev.EV_SYN.SYN_MAX)
try:
uinput = dev.create_uinput_device()
print("New device at {} ({})".format(uinput.devnode, uinput.syspath))
# Sleep for a bit so udev, libinput, Xorg, Wayland, ...
# all have had a chance to see the device and initialize
# it. Otherwise the event will be sent by the kernel but
# nothing is ready to listen to the device yet.
time.sleep(1)
with open(path, "rb") as fd:
l = libevdev.Device(fd)
print_capabilities(l)
print("################################\n"
"# Waiting for events #\n"
"################################")
while True:
try:
ev = l.events()
for e in ev:
uinput.send_events([e])
print_event(e)
if e.matches(libevdev.EV_ABS.ABS_PRESSURE):
print("Pressure! Will send another packeton Z axis!")
uinput.send_events([libevdev.InputEvent(libevdev.EV_ABS.ABS_Z, e.value)])
uinput.send_events([libevdev.InputEvent(libevdev.EV_ABS.ABS_0B, e.value)])
uinput.send_events([libevdev.InputEvent(libevdev.EV_ABS.ABS_DISTANCE, e.value)])
except libevdev.EventsDroppedException:
for e in l.sync():
print_event(e)
uinput.send_events([e])
except KeyboardInterrupt:
pass
except IOError as e:
import errno
if e.errno == errno.EACCES:
print("Insufficient permissions to access {}".format(path))
elif e.errno == errno.ENOENT:
print("Device {} does not exist".format(path))
else:
raise e
except OSError as e:
print(e)
if __name__ == "__main__":
if len(sys.argv) < 2:
print("Usage: {} /dev/input/eventX".format(sys.argv[0]))
sys.exit(1)
main(sys.argv)
나는 그것이 Veikk 마우스와 거의 동일하고 더 좋지 않다는 것을 깨달았습니다.
답변1
당신! ! ! 새로운 가상 장치의 스트레스를 완화하는 Python 스크립트를 만들었습니다. :-D 이제 Gimp/Krita/와 함께 사용할 수 있습니다... 남은 유일한 부분은 적절한 C 드라이버를 작성하고 직접 로드하는 것입니다. 커널...아이디어가 있으면 알려주세요!
입증하다:
따라서 스크립트의 아이디어는 그래픽 태블릿의 이벤트 파일에서 입력을 읽은 다음 생성하는 것입니다.좋아요이벤트(더 이상은 아니지만 BTN_LEFT
... BTN_TOUCH
내 다른 질문/답변 참조)여기자세한 내용은).
스크립트를 실행하려면(아래 참조) 아래에 저장하고 combine_both.py
실행 가능/설치 deps로 만듭니다.
$ chmod +x combine_both.py
$ sudo pip3 install libevdev
그런 다음 사용 가능한 입력 장치를 확인하세요.
$ xinput list
이렇게 하면 몇 가지 항목이 제공되며 그 중 하나는 다음과 같습니다.
VEIKK.INC A30 Mouse id=12 [slave pointer (2)]
ID( <id veikk>
나중에 참고)와 가상 코어 포인터의 ID를 기록해 두세요 <id core>
.
Virtual core pointer id=2 [master pointer (3)]
/dev/input/eventX
그런 다음 어떤 파일을 선택할지 알아야 합니다 . 가장 간단한 방법은 sudo evtest
다음 VEIKK.INC A30 Mouse
과 같은 매개변수에서 이 파일을 사용하여 스크립트를 실행하는 것입니다.
sudo ./combine_both.py /dev/input/event7
이 스크립트는 장치를 클릭/이동하려고 할 때 콘텐츠를 출력해야 합니다. 또한 xinput list
장치의 이름 Tablet alone Pen (0)
과 ID 가 나열되어야 <id fake tablet>
하며 xinput test <id fake tablet>
다음과 같은 내용을 제공해야 합니다(x/y/압력에 대한 3개 열 참고).
$ xinput test 21
[...]
motion a[0]=4151295 a[1]=4151295 a[2]=241
motion a[0]=4060671 a[1]=4060671 a[2]=226
motion a[0]=3969535 a[1]=3969535 a[2]=211
motion a[0]=3878399 a[1]=3878399 a[2]=196
motion a[0]=3787775 a[1]=3787775 a[2]=181
motion a[0]=3696639 a[1]=3696639 a[2]=166
motion a[0]=3605503 a[1]=3605503 a[2]=151
motion a[0]=3514879 a[1]=3514879 a[2]=137
motion a[0]=3423743 a[1]=3423743 a[2]=122
motion a[0]=3332607 a[1]=3332607 a[2]=107
motion a[0]=3241983 a[1]=3241983 a[2]=92
motion a[0]=3150847 a[1]=3150847 a[2]=77
motion a[0]=3059711 a[1]=3059711 a[2]=62
motion a[0]=2969087 a[1]=2969087 a[2]=47
motion a[0]=2877951 a[1]=2877951 a[2]=32
motion a[0]=2650623 a[1]=2650623 a[2]=17
button release 1
이제 Gimp/Krita에서 작동하게 하려면 실제 마우스를 비활성화해야 합니다(그렇지 않으면 실제 태블릿과 가짜 태블릿 간에 충돌이 발생합니다).
xinput float <id veikk>
완료되면 다음 명령을 사용하여 실제 장치에 다시 연결할 수 있습니다.
xinput reattach <id veikk> <id core>
김프에서는 설정에서 사용 Tablet alone Pen (0)
하고 실제 태블릿을 비활성화하는 것을 mode=screen
잊지 마십시오. 마지막으로 나는 좋은 역동성을 골랐고 그것을 시험해 보고 싶습니다!Edit/input devices
VEIKK.INC A30 Mouse
Pencil Generic
즐기다! (언젠가 C 드라이버를 작성하면 알려드리겠습니다)
스크립트:
#!/usr/bin/env python3
import sys
import libevdev
import datetime
import time
def print_capabilities(l):
v = l.driver_version
print("Input driver version is {}.{}.{}".format(v >> 16, (v >> 8) & 0xff, v & 0xff))
id = l.id
print("Input device ID: bus {:#x} vendor {:#x} product {:#x} version {:#x}".format(
id["bustype"],
id["vendor"],
id["product"],
id["version"],
))
print("Input device name: {}".format(l.name))
print("Supported events:")
for t, cs in l.evbits.items():
print(" Event type {} ({})".format(t.value, t.name))
for c in cs:
if t in [libevdev.EV_LED, libevdev.EV_SND, libevdev.EV_SW]:
v = l.value[c]
print(" Event code {} ({}) state {}".format(c.value, c.name, v))
else:
print(" Event code {} ({})".format(c.value, c.name))
if t == libevdev.EV_ABS:
a = l.absinfo[c]
print(" {:10s} {:6d}".format('Value', a.value))
print(" {:10s} {:6d}".format('Minimum', a.minimum))
print(" {:10s} {:6d}".format('Maximum', a.maximum))
print(" {:10s} {:6d}".format('Fuzz', a.fuzz))
print(" {:10s} {:6d}".format('Flat', a.flat))
print(" {:10s} {:6d}".format('Resolution', a.resolution))
print("Properties:")
for p in l.properties:
print(" Property type {} ({})".format(p.value, p.name))
def print_event(e):
print("Event: time {}.{:06d}, ".format(e.sec, e.usec), end='')
if e.matches(libevdev.EV_SYN):
if e.matches(libevdev.EV_SYN.SYN_MT_REPORT):
print("++++++++++++++ {} ++++++++++++".format(e.code.name))
elif e.matches(libevdev.EV_SYN.SYN_DROPPED):
print(">>>>>>>>>>>>>> {} >>>>>>>>>>>>".format(e.code.name))
else:
print("-------------- {} ------------".format(e.code.name))
else:
print("type {:02x} {} code {:03x} {:20s} value {:4d}".format(e.type.value, e.type.name, e.code.value, e.code.name, e.value))
class Tablet():
def __init__(self, tablet_name):
self.tablet_name = tablet_name
def __enter__(self):
self.dev = libevdev.Device()
self.dev.name = "Tablet alone"
### NB: all the following information needs to be enabled
### in order to recognize the device as a tablet.
# Say that the device will send "absolute" values
self.dev.enable(libevdev.INPUT_PROP_DIRECT)
# Say that we are using the pen (not the erasor), and should be set to 1 when we are at proximity to the device.
# See http://www.infradead.org/~mchehab/kernel_docs_pdf/linux-input.pdf page 9 (=13) and guidelines page 12 (=16), or the https://github.com/linuxwacom/input-wacom/blob/master/4.5/wacom_w8001.c (rdy=proximity)
self.dev.enable(libevdev.EV_KEY.BTN_TOOL_PEN)
self.dev.enable(libevdev.EV_KEY.BTN_TOOL_RUBBER)
# Click
self.dev.enable(libevdev.EV_KEY.BTN_TOUCH)
# Press button 1 on pen
self.dev.enable(libevdev.EV_KEY.BTN_STYLUS)
# Press button 2 on pen, see great doc
self.dev.enable(libevdev.EV_KEY.BTN_STYLUS2)
# Send absolute X coordinate
self.dev.enable(libevdev.EV_ABS.ABS_X,
libevdev.InputAbsInfo(minimum=0, maximum=32767, resolution=100))
# Send absolute Y coordinate
self.dev.enable(libevdev.EV_ABS.ABS_Y,
libevdev.InputAbsInfo(minimum=0, maximum=32767, resolution=100))
# Send absolute pressure
self.dev.enable(libevdev.EV_ABS.ABS_PRESSURE,
libevdev.InputAbsInfo(minimum=0, maximum=8191))
# Use to confirm that we finished to send the informations
# (to be sent after every burst of information, otherwise
# the kernel does not proceed the information)
self.dev.enable(libevdev.EV_SYN.SYN_REPORT)
# Report buffer overflow
self.dev.enable(libevdev.EV_SYN.SYN_DROPPED)
self.uinput = self.dev.create_uinput_device()
print("New device at {} ({})".format(self.uinput.devnode, self.uinput.syspath))
# Sleep for a bit so udev, libinput, Xorg, Wayland, ...
# all have had a chance to see the device and initialize
# it. Otherwise the event will be sent by the kernel but
# nothing is ready to listen to the device yet. And it
# will never be detected in the futur ;-)
time.sleep(1)
# self.simulate_first_click()
self.reset_state()
return self
def __exit__(self, type, value, traceback):
pass
def reset_state(self):
self.is_away = True
self.is_touching = False
self.pressed_button_1 = False
self.pressed_button_2 = False
self.lastmodif = datetime.datetime.now()
def send_events(self, events, is_away=False):
self.lastmodif = datetime.datetime.now()
self.is_away = is_away
self.uinput.send_events(events)
def simulate_first_click(self):
"""Useful only the first time to make sure
xinput detected the input"""
# Reports that the PEN is close to the surface
# Important to make sure xinput can detect (and list)
# the pen. Otherwise, it won't write anything in gimp.
self.uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
value=0),
libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
value=1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
value=0),
])
# Says that the pen it out of range of the tablet. Useful
# to make sure you can move your mouse, and to avoid
# strange things during the first draw.
self.uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
value=0),
libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
value=0),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
value=0),
])
def send_state_no_pos(self, is_away=False):
self.lastmodif = datetime.datetime.now()
self.is_away = is_away
print("Away: {}, Touching: {}".format(self.is_away, self.is_touching))
self.uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH,
value=1 if self.is_touching else 0),
libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN,
value=1 if not self.is_away else 0),
libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS,
value=1 if self.pressed_button_1 else 0),
libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS2,
value=1 if self.pressed_button_2 else 0),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
value=0),
])
def touch_press(self):
self.is_touching = True
self.send_state_no_pos()
def touch_release(self):
self.is_touching = False
self.send_state_no_pos()
def button_1_press(self):
self.pressed_button_1 = True
self.send_state_no_pos()
def button_1_release(self):
self.pressed_button_1 = False
self.send_state_no_pos()
def button_2_press(self):
self.pressed_button_2 = True
self.send_state_no_pos()
def button_2_release(self):
self.pressed_button_2 = False
self.send_state_no_pos()
def move_x(self, abs_x):
self.send_events([
libevdev.InputEvent(libevdev.EV_ABS.ABS_X,
value=abs_x),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
value=0),
])
def move_y(self, abs_y):
self.send_events([
libevdev.InputEvent(libevdev.EV_ABS.ABS_Y,
value=abs_y),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
value=0),
])
def change_pressure(self, pressure):
self.send_events([
libevdev.InputEvent(libevdev.EV_ABS.ABS_PRESSURE,
value=pressure),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT,
value=0),
])
def handle_event(self, e):
if e.matches(libevdev.EV_ABS.ABS_PRESSURE):
self.change_pressure(e.value)
elif e.matches(libevdev.EV_ABS.ABS_X):
self.move_x(e.value)
elif e.matches(libevdev.EV_ABS.ABS_Y):
self.move_y(e.value)
elif e.matches(libevdev.EV_KEY.BTN_LEFT):
if e.value == 1:
self.touch_press()
else:
self.touch_release()
elif e.matches(libevdev.EV_SYN.SYN_REPORT):
pass
else:
print("Unkown event:")
print_event(e)
def main(args):
path = args[1]
try:
with Tablet("Tablet alone") as tablet:
### Read the events from real graphics tablet
with open(path, "rb") as fd:
l = libevdev.Device(fd)
print_capabilities(l)
print("################################\n"
"# Waiting for events #\n"
"################################")
while True:
try:
ev = l.events()
for e in ev:
print_event(e)
tablet.handle_event(e)
except libevdev.EventsDroppedException:
for e in l.sync():
print_event(e)
tablet.handle_event(e)
except KeyboardInterrupt:
pass
except IOError as e:
import errno
if e.errno == errno.EACCES:
print("Insufficient permissions to access {}".format(path))
elif e.errno == errno.ENOENT:
print("Device {} does not exist".format(path))
else:
raise e
except OSError as e:
print(e)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: sudo {} /dev/input/eventX".format(sys.argv[0]))
print(" $ sudo evtest")
print("can help you to know which file to use.")
sys.exit(1)
main(sys.argv)