wacom: switch to the new protocol stroke parsers
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
parent
a24c54a570
commit
fa888b742f
160
tuhi/wacom.py
160
tuhi/wacom.py
|
@ -14,7 +14,6 @@
|
||||||
|
|
||||||
import binascii
|
import binascii
|
||||||
import enum
|
import enum
|
||||||
import inspect
|
|
||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import time
|
import time
|
||||||
|
@ -25,7 +24,7 @@ from gi.repository import GObject
|
||||||
from .drawing import Drawing
|
from .drawing import Drawing
|
||||||
from .uhid import UHIDDevice
|
from .uhid import UHIDDevice
|
||||||
import tuhi.protocol
|
import tuhi.protocol
|
||||||
from tuhi.protocol import NordicData, Interactions, Mode, ProtocolVersion
|
from tuhi.protocol import NordicData, Interactions, Mode, ProtocolVersion, StrokeFile
|
||||||
from .util import list2hex, flatten
|
from .util import list2hex, flatten
|
||||||
|
|
||||||
logger = logging.getLogger('tuhi.wacom')
|
logger = logging.getLogger('tuhi.wacom')
|
||||||
|
@ -348,80 +347,6 @@ class WacomPacket(GObject.Object):
|
||||||
return " ".join(debug_data)
|
return " ".join(debug_data)
|
||||||
|
|
||||||
|
|
||||||
class WacomPacketHandler(GObject.Object):
|
|
||||||
def process(self, packet, drawing):
|
|
||||||
raise NotImplementedError('This method must be implemented in the subclass')
|
|
||||||
|
|
||||||
|
|
||||||
class WacomPacketHandlerEndOfSequence(WacomPacketHandler):
|
|
||||||
def process(self, packet, drawing):
|
|
||||||
if bytes(packet.args) != b'\xff\xff\xff\xff\xff\xff\xff\xff':
|
|
||||||
return False
|
|
||||||
|
|
||||||
logger.info(f'end of sequence')
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class WacomPacketHandlerEndOfStroke(WacomPacketHandler):
|
|
||||||
def process(self, packet, drawing):
|
|
||||||
if bytes(packet.args) != b'\x00\x00\xff\xff\xff\xff\xff\xff':
|
|
||||||
return False
|
|
||||||
|
|
||||||
logger.info(f'end of stroke')
|
|
||||||
drawing.current_stroke.seal()
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class WacomPacketHandlerStrokePrefixSlate(WacomPacketHandler):
|
|
||||||
def process(self, packet, drawing):
|
|
||||||
if packet.opcode != 0xeeff:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# some sort of headers
|
|
||||||
time_offset = int.from_bytes(packet.bytes[4:], byteorder='little')
|
|
||||||
logger.info(f'time offset since boot: {time_offset * 0.005} secs')
|
|
||||||
drawing.new_stroke()
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class WacomPacketHandlerStrokePrefixIntuosPro(WacomPacketHandler):
|
|
||||||
def process(self, packet, drawing):
|
|
||||||
if packet.opcode != 0x03fa:
|
|
||||||
return False
|
|
||||||
|
|
||||||
t = WacomProtocolIntuosPro.time_from_bytes(packet.bytes[2:])
|
|
||||||
t = time.strftime("%y%m%d%H%M%S", t)
|
|
||||||
logger.info(f'stroke time: {t}')
|
|
||||||
drawing.new_stroke()
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class WacomPacketHandlerStrokeTimestampIntuosPro(WacomPacketHandler):
|
|
||||||
def process(self, packet, drawing):
|
|
||||||
if packet.opcode != 0xc3fa:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# First stroke timestamp, note this is less than the drawing's
|
|
||||||
# timestamp
|
|
||||||
# ff fa c3 <6-byte-timestamp>
|
|
||||||
t = WacomProtocolIntuosPro.time_from_bytes(packet.bytes[2:])
|
|
||||||
t = time.strftime("%y%m%d%H%M%S", t)
|
|
||||||
logger.info(f'stroke time: {t}')
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class WacomPacketHandlerUnknownFixedStrokeDataIntuosPro(WacomPacketHandler):
|
|
||||||
def process(self, packet, drawing):
|
|
||||||
if packet.opcode != 0x870a:
|
|
||||||
return False
|
|
||||||
|
|
||||||
# Unclear what this header is
|
|
||||||
expected_bytes = b'\xff\x0a\x87\x75\x80\x28\x42\x00\x10'
|
|
||||||
if bytes(packet.bytes) != expected_bytes:
|
|
||||||
logger.debug(f'Missing header, got {packet.bytes}')
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class WacomProtocolLowLevelComm(GObject.Object):
|
class WacomProtocolLowLevelComm(GObject.Object):
|
||||||
'''
|
'''
|
||||||
Internal class to handle the communication with the Wacom device.
|
Internal class to handle the communication with the Wacom device.
|
||||||
|
@ -589,26 +514,6 @@ class WacomProtocolBase(WacomProtocolLowLevelComm):
|
||||||
device.connect_gatt_value(WACOM_OFFLINE_CHRC_PEN_DATA_UUID,
|
device.connect_gatt_value(WACOM_OFFLINE_CHRC_PEN_DATA_UUID,
|
||||||
self._on_pen_data_received)
|
self._on_pen_data_received)
|
||||||
|
|
||||||
# Instantiate all packet_handlers from our current object and its
|
|
||||||
# parent classes
|
|
||||||
self.packet_handlers = []
|
|
||||||
parents = inspect.getmro(self.__class__)
|
|
||||||
child = None
|
|
||||||
for cls in parents:
|
|
||||||
if cls.__name__ == 'WacomProtocolBase':
|
|
||||||
break
|
|
||||||
|
|
||||||
if (child is not None and
|
|
||||||
child.packet_handlers and
|
|
||||||
child.packet_handlers == cls.packet_handlers):
|
|
||||||
raise NotImplementedError(f'Subclass {child} must override packet_handlers')
|
|
||||||
|
|
||||||
for handler in cls.packet_handlers:
|
|
||||||
h = handler()
|
|
||||||
self.packet_handlers.append(h)
|
|
||||||
|
|
||||||
child = cls
|
|
||||||
|
|
||||||
@GObject.property
|
@GObject.property
|
||||||
def dimensions(self):
|
def dimensions(self):
|
||||||
return (self.width, self.height)
|
return (self.width, self.height)
|
||||||
|
@ -820,59 +725,20 @@ class WacomProtocolBase(WacomProtocolLowLevelComm):
|
||||||
'''
|
'''
|
||||||
:param timestamp: seconds since UNIX epoch
|
:param timestamp: seconds since UNIX epoch
|
||||||
'''
|
'''
|
||||||
x, y, p = 0, 0, 0
|
|
||||||
dx, dy, dp = 0, 0, 0
|
|
||||||
|
|
||||||
stroke = None
|
|
||||||
|
|
||||||
success, offset = self.parse_pen_data_prefix(data)
|
|
||||||
if not success:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
f = StrokeFile(data)
|
||||||
drawing = Drawing(self.device.name, (self.width, self.height), timestamp)
|
drawing = Drawing(self.device.name, (self.width, self.height), timestamp)
|
||||||
ps = self.point_size
|
ps = self.point_size
|
||||||
|
|
||||||
while offset < len(data):
|
def normalize(p):
|
||||||
packet = WacomPacket(data[offset:])
|
NORMALIZED_RANGE = 0x10000
|
||||||
logger.debug(f'packet: {packet}')
|
return NORMALIZED_RANGE * p / self.pressure
|
||||||
offset += packet.length
|
|
||||||
|
|
||||||
has_handler = False
|
|
||||||
for handler in self.packet_handlers:
|
|
||||||
if handler.process(packet, drawing):
|
|
||||||
has_handler = True
|
|
||||||
break
|
|
||||||
if has_handler:
|
|
||||||
continue
|
|
||||||
|
|
||||||
stroke = drawing.current_stroke
|
|
||||||
if stroke is None:
|
|
||||||
stroke = drawing.new_stroke()
|
|
||||||
|
|
||||||
# data is in device units
|
|
||||||
x, dx, xrel = self.get_coordinate(packet.bitmask, 0, packet.args, x, dx)
|
|
||||||
y, dy, yrel = self.get_coordinate(packet.bitmask, 1, packet.args, y, dy)
|
|
||||||
p, dp, prel = self.get_coordinate(packet.bitmask, 2, packet.args, p, dp)
|
|
||||||
|
|
||||||
x += dx
|
|
||||||
y += dy
|
|
||||||
p += dp
|
|
||||||
|
|
||||||
xr = '*' if xrel else ''
|
|
||||||
yr = '*' if yrel else ''
|
|
||||||
pr = '*' if prel else ''
|
|
||||||
logger.info(f'point at {x},{y} ({dx:+}{xr}, {dy:+}{yr}) with pressure {p} ({dp:+}{pr})')
|
|
||||||
|
|
||||||
if packet.bitmask & 0b00111100 == 0:
|
|
||||||
continue
|
|
||||||
|
|
||||||
def normalize(p):
|
|
||||||
NORMALIZED_RANGE = 0x10000
|
|
||||||
return NORMALIZED_RANGE * p / self.pressure
|
|
||||||
|
|
||||||
# now convert to actual µm
|
|
||||||
stroke.new_abs((x * ps, y * ps), normalize(p))
|
|
||||||
|
|
||||||
|
for s in f.strokes:
|
||||||
|
stroke = drawing.new_stroke()
|
||||||
|
for p in s.points:
|
||||||
|
stroke.new_abs((p.x * ps, p.y * ps), normalize(p.p))
|
||||||
|
stroke.seal()
|
||||||
drawing.seal()
|
drawing.seal()
|
||||||
return drawing
|
return drawing
|
||||||
|
|
||||||
|
@ -933,8 +799,6 @@ class WacomProtocolSpark(WacomProtocolBase):
|
||||||
|
|
||||||
pressure = 1023
|
pressure = 1023
|
||||||
protocol = ProtocolVersion.SPARK
|
protocol = ProtocolVersion.SPARK
|
||||||
packet_handlers = [WacomPacketHandlerEndOfStroke,
|
|
||||||
WacomPacketHandlerEndOfSequence]
|
|
||||||
|
|
||||||
orientation = 'portrait'
|
orientation = 'portrait'
|
||||||
|
|
||||||
|
@ -961,7 +825,6 @@ class WacomProtocolSlate(WacomProtocolSpark):
|
||||||
|
|
||||||
pressure = 2047
|
pressure = 2047
|
||||||
protocol = ProtocolVersion.SLATE
|
protocol = ProtocolVersion.SLATE
|
||||||
packet_handlers = [WacomPacketHandlerStrokePrefixSlate]
|
|
||||||
|
|
||||||
orientation = 'portrait'
|
orientation = 'portrait'
|
||||||
|
|
||||||
|
@ -1044,9 +907,6 @@ class WacomProtocolIntuosPro(WacomProtocolSlate):
|
||||||
|
|
||||||
pressure = 8192
|
pressure = 8192
|
||||||
protocol = ProtocolVersion.INTUOS_PRO
|
protocol = ProtocolVersion.INTUOS_PRO
|
||||||
packet_handlers = [WacomPacketHandlerStrokePrefixIntuosPro,
|
|
||||||
WacomPacketHandlerStrokeTimestampIntuosPro,
|
|
||||||
WacomPacketHandlerUnknownFixedStrokeDataIntuosPro]
|
|
||||||
|
|
||||||
orientation = 'landscape'
|
orientation = 'landscape'
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue