Simulate graphics tablet using libevent
I would like to simulate a graphics tablet (like wacom's ones) from a script. The "good" way to proceed seems to use libevent that is an abstract layer above uinput. So I tried to write a script that sends some event like EV_ABS.ABS_X or EV_ABS.ABS_PRESSURE, using the python library of libevent. Unfortunately, when I use Krita/Gimp/... to test it, the line that it draws does not change it's shape depending on the pressure, and xinput test-xi2 does not display any pressure event. Any idea why?
Thanks!
Steps to reproduce
Execute the code below:
sudo pip3 install libevdev
chmod +x ./simulate_graphics_tablet.py
sudo ./simulate_graphics_tablet.py
Then you have 30 seconds to:
- either run
xinput listand thenxinput test-xi2 <number of Tablet alone>
- or open Gimp, go to 'Edit/Input device' and configure the device 'Tablet alone' to 'Screen', save and close the pop up,create a new file (Ctrl-N), Zoom and press 'tab' to have a drawing surface covering most of the screen. Switch to brush using 'p' key, by making sure the brush is set to
Pressure size.
What I get: a uniform line, and on xinput I don't have any reference to pressure and I just have things like:
EVENT type 17 (RawMotion)
device: 11 (11)
detail: 0
flags:
valuators:
0: 29897.54 (29897.54)
1: 29897.54 (29897.54)
What I expect: a line whose size is not constatn (the script increase the pressure linearly), or to see some pressure-related events on xinput.
#!/usr/bin/env python3
import sys
import libevdev
import time
def main(args):
dev = libevdev.Device()
dev.name = "Tablet alone"
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.KEY_P)
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.
print("Waiting 30s to let you:")
print("1) open Gimp")
print("2) Go to 'Edit/Input device' and configure the device 'Tablet alone' to 'Screen'.")
print("3) Save and close the pop up")
print("4) Create a new file (Ctrl-N)")
print("5) Zoom and press 'tab' to have a drawing surface coverint most of the screen.")
print("6) Switch to brush using 'p' key.")
time.sleep(30)
pc = 0
direc = +1
already_pressed_one = False
# uinput.send_events([
# libevdev.InputEvent(libevdev.EV_KEY.KEY_P, 1),
# libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
# ])
# time.sleep(0.1)
# uinput.send_events([
# libevdev.InputEvent(libevdev.EV_KEY.KEY_P, 0),
# libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
# ])
for i in range(250):
pc_ = pc/100
val_x = int(pc_*10000 + (1-pc_)*17767)
val_y = int(pc_*5000 + (1-pc_)*22767)
val_pres = int(pc_*10 + (1-pc_)*6000)
print("Will send: x={}, y={}, press={} (pc={})".format(
val_x,
val_y,
val_pres,
pc))
uinput.send_events([
libevdev.InputEvent(libevdev.EV_ABS.ABS_PRESSURE, val_pres),
libevdev.InputEvent(libevdev.EV_ABS.ABS_X, val_y),
libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, val_y),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
pc += direc
if not already_pressed_one:
print("Press!")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
already_pressed_one = True
if pc >= 100 or pc <=0 :
print("Release click.")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 0),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
if pc >= 100:
pc = 100
direc = -1
if pc <= 0:
pc = 0
direc = +1
time.sleep(10)
print("Press!")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
already_pressed_one = True
time.sleep(0.1)
except KeyboardInterrupt:
pass
except OSError as e:
print(e)
if __name__ == "__main__":
if len(sys.argv) > 2:
print("Usage: {}")
sys.exit(1)
main(sys.argv)
EDIT:
I tried to play with ABS_KEY.BTN_TOOL_PEN as explained here, but I don't know why the second I enable it it stops being detected by xinput list:
dev.enable(libevdev.EV_KEY.BTN_TOOL_PEN)
keyboard tablet
add a comment |
I would like to simulate a graphics tablet (like wacom's ones) from a script. The "good" way to proceed seems to use libevent that is an abstract layer above uinput. So I tried to write a script that sends some event like EV_ABS.ABS_X or EV_ABS.ABS_PRESSURE, using the python library of libevent. Unfortunately, when I use Krita/Gimp/... to test it, the line that it draws does not change it's shape depending on the pressure, and xinput test-xi2 does not display any pressure event. Any idea why?
Thanks!
Steps to reproduce
Execute the code below:
sudo pip3 install libevdev
chmod +x ./simulate_graphics_tablet.py
sudo ./simulate_graphics_tablet.py
Then you have 30 seconds to:
- either run
xinput listand thenxinput test-xi2 <number of Tablet alone>
- or open Gimp, go to 'Edit/Input device' and configure the device 'Tablet alone' to 'Screen', save and close the pop up,create a new file (Ctrl-N), Zoom and press 'tab' to have a drawing surface covering most of the screen. Switch to brush using 'p' key, by making sure the brush is set to
Pressure size.
What I get: a uniform line, and on xinput I don't have any reference to pressure and I just have things like:
EVENT type 17 (RawMotion)
device: 11 (11)
detail: 0
flags:
valuators:
0: 29897.54 (29897.54)
1: 29897.54 (29897.54)
What I expect: a line whose size is not constatn (the script increase the pressure linearly), or to see some pressure-related events on xinput.
#!/usr/bin/env python3
import sys
import libevdev
import time
def main(args):
dev = libevdev.Device()
dev.name = "Tablet alone"
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.KEY_P)
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.
print("Waiting 30s to let you:")
print("1) open Gimp")
print("2) Go to 'Edit/Input device' and configure the device 'Tablet alone' to 'Screen'.")
print("3) Save and close the pop up")
print("4) Create a new file (Ctrl-N)")
print("5) Zoom and press 'tab' to have a drawing surface coverint most of the screen.")
print("6) Switch to brush using 'p' key.")
time.sleep(30)
pc = 0
direc = +1
already_pressed_one = False
# uinput.send_events([
# libevdev.InputEvent(libevdev.EV_KEY.KEY_P, 1),
# libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
# ])
# time.sleep(0.1)
# uinput.send_events([
# libevdev.InputEvent(libevdev.EV_KEY.KEY_P, 0),
# libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
# ])
for i in range(250):
pc_ = pc/100
val_x = int(pc_*10000 + (1-pc_)*17767)
val_y = int(pc_*5000 + (1-pc_)*22767)
val_pres = int(pc_*10 + (1-pc_)*6000)
print("Will send: x={}, y={}, press={} (pc={})".format(
val_x,
val_y,
val_pres,
pc))
uinput.send_events([
libevdev.InputEvent(libevdev.EV_ABS.ABS_PRESSURE, val_pres),
libevdev.InputEvent(libevdev.EV_ABS.ABS_X, val_y),
libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, val_y),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
pc += direc
if not already_pressed_one:
print("Press!")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
already_pressed_one = True
if pc >= 100 or pc <=0 :
print("Release click.")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 0),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
if pc >= 100:
pc = 100
direc = -1
if pc <= 0:
pc = 0
direc = +1
time.sleep(10)
print("Press!")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
already_pressed_one = True
time.sleep(0.1)
except KeyboardInterrupt:
pass
except OSError as e:
print(e)
if __name__ == "__main__":
if len(sys.argv) > 2:
print("Usage: {}")
sys.exit(1)
main(sys.argv)
EDIT:
I tried to play with ABS_KEY.BTN_TOOL_PEN as explained here, but I don't know why the second I enable it it stops being detected by xinput list:
dev.enable(libevdev.EV_KEY.BTN_TOOL_PEN)
keyboard tablet
add a comment |
I would like to simulate a graphics tablet (like wacom's ones) from a script. The "good" way to proceed seems to use libevent that is an abstract layer above uinput. So I tried to write a script that sends some event like EV_ABS.ABS_X or EV_ABS.ABS_PRESSURE, using the python library of libevent. Unfortunately, when I use Krita/Gimp/... to test it, the line that it draws does not change it's shape depending on the pressure, and xinput test-xi2 does not display any pressure event. Any idea why?
Thanks!
Steps to reproduce
Execute the code below:
sudo pip3 install libevdev
chmod +x ./simulate_graphics_tablet.py
sudo ./simulate_graphics_tablet.py
Then you have 30 seconds to:
- either run
xinput listand thenxinput test-xi2 <number of Tablet alone>
- or open Gimp, go to 'Edit/Input device' and configure the device 'Tablet alone' to 'Screen', save and close the pop up,create a new file (Ctrl-N), Zoom and press 'tab' to have a drawing surface covering most of the screen. Switch to brush using 'p' key, by making sure the brush is set to
Pressure size.
What I get: a uniform line, and on xinput I don't have any reference to pressure and I just have things like:
EVENT type 17 (RawMotion)
device: 11 (11)
detail: 0
flags:
valuators:
0: 29897.54 (29897.54)
1: 29897.54 (29897.54)
What I expect: a line whose size is not constatn (the script increase the pressure linearly), or to see some pressure-related events on xinput.
#!/usr/bin/env python3
import sys
import libevdev
import time
def main(args):
dev = libevdev.Device()
dev.name = "Tablet alone"
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.KEY_P)
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.
print("Waiting 30s to let you:")
print("1) open Gimp")
print("2) Go to 'Edit/Input device' and configure the device 'Tablet alone' to 'Screen'.")
print("3) Save and close the pop up")
print("4) Create a new file (Ctrl-N)")
print("5) Zoom and press 'tab' to have a drawing surface coverint most of the screen.")
print("6) Switch to brush using 'p' key.")
time.sleep(30)
pc = 0
direc = +1
already_pressed_one = False
# uinput.send_events([
# libevdev.InputEvent(libevdev.EV_KEY.KEY_P, 1),
# libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
# ])
# time.sleep(0.1)
# uinput.send_events([
# libevdev.InputEvent(libevdev.EV_KEY.KEY_P, 0),
# libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
# ])
for i in range(250):
pc_ = pc/100
val_x = int(pc_*10000 + (1-pc_)*17767)
val_y = int(pc_*5000 + (1-pc_)*22767)
val_pres = int(pc_*10 + (1-pc_)*6000)
print("Will send: x={}, y={}, press={} (pc={})".format(
val_x,
val_y,
val_pres,
pc))
uinput.send_events([
libevdev.InputEvent(libevdev.EV_ABS.ABS_PRESSURE, val_pres),
libevdev.InputEvent(libevdev.EV_ABS.ABS_X, val_y),
libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, val_y),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
pc += direc
if not already_pressed_one:
print("Press!")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
already_pressed_one = True
if pc >= 100 or pc <=0 :
print("Release click.")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 0),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
if pc >= 100:
pc = 100
direc = -1
if pc <= 0:
pc = 0
direc = +1
time.sleep(10)
print("Press!")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
already_pressed_one = True
time.sleep(0.1)
except KeyboardInterrupt:
pass
except OSError as e:
print(e)
if __name__ == "__main__":
if len(sys.argv) > 2:
print("Usage: {}")
sys.exit(1)
main(sys.argv)
EDIT:
I tried to play with ABS_KEY.BTN_TOOL_PEN as explained here, but I don't know why the second I enable it it stops being detected by xinput list:
dev.enable(libevdev.EV_KEY.BTN_TOOL_PEN)
keyboard tablet
I would like to simulate a graphics tablet (like wacom's ones) from a script. The "good" way to proceed seems to use libevent that is an abstract layer above uinput. So I tried to write a script that sends some event like EV_ABS.ABS_X or EV_ABS.ABS_PRESSURE, using the python library of libevent. Unfortunately, when I use Krita/Gimp/... to test it, the line that it draws does not change it's shape depending on the pressure, and xinput test-xi2 does not display any pressure event. Any idea why?
Thanks!
Steps to reproduce
Execute the code below:
sudo pip3 install libevdev
chmod +x ./simulate_graphics_tablet.py
sudo ./simulate_graphics_tablet.py
Then you have 30 seconds to:
- either run
xinput listand thenxinput test-xi2 <number of Tablet alone>
- or open Gimp, go to 'Edit/Input device' and configure the device 'Tablet alone' to 'Screen', save and close the pop up,create a new file (Ctrl-N), Zoom and press 'tab' to have a drawing surface covering most of the screen. Switch to brush using 'p' key, by making sure the brush is set to
Pressure size.
What I get: a uniform line, and on xinput I don't have any reference to pressure and I just have things like:
EVENT type 17 (RawMotion)
device: 11 (11)
detail: 0
flags:
valuators:
0: 29897.54 (29897.54)
1: 29897.54 (29897.54)
What I expect: a line whose size is not constatn (the script increase the pressure linearly), or to see some pressure-related events on xinput.
#!/usr/bin/env python3
import sys
import libevdev
import time
def main(args):
dev = libevdev.Device()
dev.name = "Tablet alone"
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.KEY_P)
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.
print("Waiting 30s to let you:")
print("1) open Gimp")
print("2) Go to 'Edit/Input device' and configure the device 'Tablet alone' to 'Screen'.")
print("3) Save and close the pop up")
print("4) Create a new file (Ctrl-N)")
print("5) Zoom and press 'tab' to have a drawing surface coverint most of the screen.")
print("6) Switch to brush using 'p' key.")
time.sleep(30)
pc = 0
direc = +1
already_pressed_one = False
# uinput.send_events([
# libevdev.InputEvent(libevdev.EV_KEY.KEY_P, 1),
# libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
# ])
# time.sleep(0.1)
# uinput.send_events([
# libevdev.InputEvent(libevdev.EV_KEY.KEY_P, 0),
# libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
# ])
for i in range(250):
pc_ = pc/100
val_x = int(pc_*10000 + (1-pc_)*17767)
val_y = int(pc_*5000 + (1-pc_)*22767)
val_pres = int(pc_*10 + (1-pc_)*6000)
print("Will send: x={}, y={}, press={} (pc={})".format(
val_x,
val_y,
val_pres,
pc))
uinput.send_events([
libevdev.InputEvent(libevdev.EV_ABS.ABS_PRESSURE, val_pres),
libevdev.InputEvent(libevdev.EV_ABS.ABS_X, val_y),
libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, val_y),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
pc += direc
if not already_pressed_one:
print("Press!")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
already_pressed_one = True
if pc >= 100 or pc <=0 :
print("Release click.")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 0),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
if pc >= 100:
pc = 100
direc = -1
if pc <= 0:
pc = 0
direc = +1
time.sleep(10)
print("Press!")
uinput.send_events([
libevdev.InputEvent(libevdev.EV_KEY.BTN_LEFT, 1),
libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT, 0),
])
already_pressed_one = True
time.sleep(0.1)
except KeyboardInterrupt:
pass
except OSError as e:
print(e)
if __name__ == "__main__":
if len(sys.argv) > 2:
print("Usage: {}")
sys.exit(1)
main(sys.argv)
EDIT:
I tried to play with ABS_KEY.BTN_TOOL_PEN as explained here, but I don't know why the second I enable it it stops being detected by xinput list:
dev.enable(libevdev.EV_KEY.BTN_TOOL_PEN)
keyboard tablet
keyboard tablet
edited 1 hour ago
tobiasBora
asked 1 hour ago
tobiasBoratobiasBora
264312
264312
add a comment |
add a comment |
0
active
oldest
votes
Your Answer
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "106"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f508612%2fsimulate-graphics-tablet-using-libevent%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
0
active
oldest
votes
0
active
oldest
votes
active
oldest
votes
active
oldest
votes
Thanks for contributing an answer to Unix & Linux Stack Exchange!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f508612%2fsimulate-graphics-tablet-using-libevent%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown