You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

115 lines
3.3 KiB
Python

import logging
import struct
logging.basicConfig(format='%(message)s')
log = logging.getLogger(__name__)
# evtype_sync = 0
# evtype_key = 1
e_type_abs = 3
# evcode_stylus_distance = 25
# evcode_stylus_xtilt = 26
# evcode_stylus_ytilt = 27
e_code_stylus_xpos = 1
e_code_stylus_ypos = 0
e_code_stylus_pressure = 24
# evcode_finger_xpos = 53
# evcode_finger_ypos = 54
# evcode_finger_pressure = 58
# wacom digitizer dimensions
wacom_width = 15725
wacom_height = 20967
# touchscreen dimensions
# finger_width = 767
# finger_height = 1023
# remap wacom coordinates in various orientations
def remap(x, y, wacom_width, wacom_height, monitor_width, monitor_height, mode, orientation=None):
if orientation == 'bottom':
y = wacom_height - y
elif orientation == 'right':
x, y = wacom_height - y, wacom_width - x
wacom_width, wacom_height = wacom_height, wacom_width
elif orientation == 'left':
x, y = y, x
wacom_width, wacom_height = wacom_height, wacom_width
elif orientation == 'top':
x = wacom_width - x
ratio_width, ratio_height = monitor.width / wacom_width, monitor.height / wacom_height
if mode == 'fill':
scaling = max(ratio_width, ratio_height)
else:
scaling = min(ratio_width, ratio_height)
return (
scaling * (x - (wacom_width - monitor.width / scaling) / 2),
scaling * (y - (wacom_height - monitor.height / scaling) / 2)
)
def read_tablet(args, remote_device):
"""Loop forever and map evdev events to mouse"""
from screeninfo import get_monitors
from pynput.mouse import Button, Controller
lifted = True
new_x = new_y = False
mouse = Controller()
monitor = get_monitors()[args.monitor]
log.debug('Chose monitor: {}'.format(monitor))
while True:
_, _, e_type, e_code, e_value = struct.unpack('2IHHi', remote_device.read(16))
if e_type == e_type_abs:
# handle x direction
if e_code == e_code_stylus_xpos:
log.debug(e_value)
x = e_value
new_x = True
# handle y direction
if e_code == e_code_stylus_ypos:
log.debug('\t{}'.format(e_value))
y = e_value
new_y = True
# handle draw
if e_code == e_code_stylus_pressure:
log.debug('\t\t{}'.format(e_value))
if e_value > args.threshold:
if lifted:
log.debug('PRESS')
lifted = False
mouse.press(Button.left)
else:
if not lifted:
log.debug('RELEASE')
lifted = True
mouse.release(Button.left)
# only move when x and y are updated for smoother mouse
if new_x and new_y:
mapped_x, mapped_y = remap(
x, y,
wacom_width, wacom_height,
monitor, args.orientation,
args.mode
)
mouse.move(
monitor.x + mapped_x - mouse.position[0],
monitor.y + mapped_y - mouse.position[1]
)
new_x = new_y = False