wacom: add PacketHandlers for handling special commands

For data packets other than basic motion/pressure strokes, add a PacketHandler
that can deal with that particular packet. Those handlers are part of the
class declaration, when we instantiate a protocol we pull them all into a
packet_handlers list and go through them. The first one to return True is
considered the right handler and we expect something has been done with the
packet.

This patch includes the handlers for the end-of-stroke and end-of-sequence
packets, the rest to be added later.
This commit is contained in:
Peter Hutterer 2018-02-16 12:52:41 +10:00
parent 43064b58fc
commit 5692a1f3b2
1 changed files with 57 additions and 7 deletions

View File

@ -15,6 +15,7 @@
import binascii import binascii
import calendar import calendar
import enum import enum
import inspect
import logging import logging
import threading import threading
import time import time
@ -220,6 +221,30 @@ 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 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.
@ -405,6 +430,26 @@ 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
def _on_pen_data_changed(self, name, value): def _on_pen_data_changed(self, name, value):
logger.debug(binascii.hexlify(bytes(value))) logger.debug(binascii.hexlify(bytes(value)))
@ -671,16 +716,17 @@ class WacomProtocolBase(WacomProtocolLowLevelComm):
logger.debug(f'packet: {packet}') logger.debug(f'packet: {packet}')
offset += packet.length 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
if self.parse_next_stroke_prefix(packet.opcode, packet.bytes): if self.parse_next_stroke_prefix(packet.opcode, packet.bytes):
stroke = drawing.new_stroke() stroke = drawing.new_stroke()
continue continue
if bytes(packet.args) == b'\xff\xff\xff\xff\xff\xff\xff\xff':
logger.info(f'end of sequence')
continue
if bytes(packet.args) == b'\x00\x00\xff\xff\xff\xff\xff\xff':
logger.info(f'end of stroke')
stroke.seal()
continue
stroke = drawing.current_stroke stroke = drawing.current_stroke
if stroke is None: if stroke is None:
@ -784,6 +830,8 @@ class WacomProtocolSpark(WacomProtocolBase):
width = 21600 width = 21600
height = 14800 height = 14800
protocol = Protocol.SPARK protocol = Protocol.SPARK
packet_handlers = [WacomPacketHandlerEndOfStroke,
WacomPacketHandlerEndOfSequence]
class WacomProtocolSlate(WacomProtocolSpark): class WacomProtocolSlate(WacomProtocolSpark):
@ -797,6 +845,7 @@ class WacomProtocolSlate(WacomProtocolSpark):
width = 21600 width = 21600
height = 14800 height = 14800
protocol = Protocol.SLATE protocol = Protocol.SLATE
packet_handlers = []
def __init__(self, device, uuid): def __init__(self, device, uuid):
super().__init__(device, uuid) super().__init__(device, uuid)
@ -896,6 +945,7 @@ class WacomProtocolIntuosPro(WacomProtocolSlate):
width = 44800 width = 44800
height = 29600 height = 29600
protocol = Protocol.INTUOS_PRO protocol = Protocol.INTUOS_PRO
packet_handlers = []
def __init__(self, device, uuid): def __init__(self, device, uuid):
super().__init__(device, uuid) super().__init__(device, uuid)