162306a36Sopenharmony_ci#!/bin/env python3 262306a36Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0 362306a36Sopenharmony_ci# -*- coding: utf-8 -*- 462306a36Sopenharmony_ci# 562306a36Sopenharmony_ci# Copyright (c) 2021 Benjamin Tissoires <benjamin.tissoires@gmail.com> 662306a36Sopenharmony_ci# Copyright (c) 2021 Red Hat, Inc. 762306a36Sopenharmony_ci# 862306a36Sopenharmony_ci 962306a36Sopenharmony_cifrom . import base 1062306a36Sopenharmony_ciimport copy 1162306a36Sopenharmony_cifrom enum import Enum 1262306a36Sopenharmony_cifrom hidtools.util import BusType 1362306a36Sopenharmony_ciimport libevdev 1462306a36Sopenharmony_ciimport logging 1562306a36Sopenharmony_ciimport pytest 1662306a36Sopenharmony_cifrom typing import Dict, Tuple 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cilogger = logging.getLogger("hidtools.test.tablet") 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ciclass PenState(Enum): 2262306a36Sopenharmony_ci """Pen states according to Microsoft reference: 2362306a36Sopenharmony_ci https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states 2462306a36Sopenharmony_ci """ 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci PEN_IS_OUT_OF_RANGE = (False, None) 2762306a36Sopenharmony_ci PEN_IS_IN_RANGE = (False, libevdev.EV_KEY.BTN_TOOL_PEN) 2862306a36Sopenharmony_ci PEN_IS_IN_CONTACT = (True, libevdev.EV_KEY.BTN_TOOL_PEN) 2962306a36Sopenharmony_ci PEN_IS_IN_RANGE_WITH_ERASING_INTENT = (False, libevdev.EV_KEY.BTN_TOOL_RUBBER) 3062306a36Sopenharmony_ci PEN_IS_ERASING = (True, libevdev.EV_KEY.BTN_TOOL_RUBBER) 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci def __init__(self, touch, tool): 3362306a36Sopenharmony_ci self.touch = touch 3462306a36Sopenharmony_ci self.tool = tool 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci @classmethod 3762306a36Sopenharmony_ci def from_evdev(cls, evdev) -> "PenState": 3862306a36Sopenharmony_ci touch = bool(evdev.value[libevdev.EV_KEY.BTN_TOUCH]) 3962306a36Sopenharmony_ci tool = None 4062306a36Sopenharmony_ci if ( 4162306a36Sopenharmony_ci evdev.value[libevdev.EV_KEY.BTN_TOOL_RUBBER] 4262306a36Sopenharmony_ci and not evdev.value[libevdev.EV_KEY.BTN_TOOL_PEN] 4362306a36Sopenharmony_ci ): 4462306a36Sopenharmony_ci tool = libevdev.EV_KEY.BTN_TOOL_RUBBER 4562306a36Sopenharmony_ci elif ( 4662306a36Sopenharmony_ci evdev.value[libevdev.EV_KEY.BTN_TOOL_PEN] 4762306a36Sopenharmony_ci and not evdev.value[libevdev.EV_KEY.BTN_TOOL_RUBBER] 4862306a36Sopenharmony_ci ): 4962306a36Sopenharmony_ci tool = libevdev.EV_KEY.BTN_TOOL_PEN 5062306a36Sopenharmony_ci elif ( 5162306a36Sopenharmony_ci evdev.value[libevdev.EV_KEY.BTN_TOOL_PEN] 5262306a36Sopenharmony_ci or evdev.value[libevdev.EV_KEY.BTN_TOOL_RUBBER] 5362306a36Sopenharmony_ci ): 5462306a36Sopenharmony_ci raise ValueError("2 tools are not allowed") 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci return cls((touch, tool)) 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci def apply(self, events) -> "PenState": 5962306a36Sopenharmony_ci if libevdev.EV_SYN.SYN_REPORT in events: 6062306a36Sopenharmony_ci raise ValueError("EV_SYN is in the event sequence") 6162306a36Sopenharmony_ci touch = self.touch 6262306a36Sopenharmony_ci touch_found = False 6362306a36Sopenharmony_ci tool = self.tool 6462306a36Sopenharmony_ci tool_found = False 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci for ev in events: 6762306a36Sopenharmony_ci if ev == libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH): 6862306a36Sopenharmony_ci if touch_found: 6962306a36Sopenharmony_ci raise ValueError(f"duplicated BTN_TOUCH in {events}") 7062306a36Sopenharmony_ci touch_found = True 7162306a36Sopenharmony_ci touch = bool(ev.value) 7262306a36Sopenharmony_ci elif ev in ( 7362306a36Sopenharmony_ci libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN), 7462306a36Sopenharmony_ci libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_RUBBER), 7562306a36Sopenharmony_ci ): 7662306a36Sopenharmony_ci if tool_found: 7762306a36Sopenharmony_ci raise ValueError(f"duplicated BTN_TOOL_* in {events}") 7862306a36Sopenharmony_ci tool_found = True 7962306a36Sopenharmony_ci if ev.value: 8062306a36Sopenharmony_ci tool = ev.code 8162306a36Sopenharmony_ci else: 8262306a36Sopenharmony_ci tool = None 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci new_state = PenState((touch, tool)) 8562306a36Sopenharmony_ci assert ( 8662306a36Sopenharmony_ci new_state in self.valid_transitions() 8762306a36Sopenharmony_ci ), f"moving from {self} to {new_state} is forbidden" 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci return new_state 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci def valid_transitions(self) -> Tuple["PenState", ...]: 9262306a36Sopenharmony_ci """Following the state machine in the URL above, with a couple of addition 9362306a36Sopenharmony_ci for skipping the in-range state, due to historical reasons. 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci Note that those transitions are from the evdev point of view, not HID""" 9662306a36Sopenharmony_ci if self == PenState.PEN_IS_OUT_OF_RANGE: 9762306a36Sopenharmony_ci return ( 9862306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 9962306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 10062306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 10162306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 10262306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 10362306a36Sopenharmony_ci ) 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci if self == PenState.PEN_IS_IN_RANGE: 10662306a36Sopenharmony_ci return ( 10762306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 10862306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 10962306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 11062306a36Sopenharmony_ci ) 11162306a36Sopenharmony_ci 11262306a36Sopenharmony_ci if self == PenState.PEN_IS_IN_CONTACT: 11362306a36Sopenharmony_ci return ( 11462306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 11562306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 11662306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 11762306a36Sopenharmony_ci ) 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci if self == PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT: 12062306a36Sopenharmony_ci return ( 12162306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 12262306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 12362306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 12462306a36Sopenharmony_ci ) 12562306a36Sopenharmony_ci 12662306a36Sopenharmony_ci if self == PenState.PEN_IS_ERASING: 12762306a36Sopenharmony_ci return ( 12862306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 12962306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 13062306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 13162306a36Sopenharmony_ci ) 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci return tuple() 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ciclass Data(object): 13762306a36Sopenharmony_ci pass 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ciclass Pen(object): 14162306a36Sopenharmony_ci def __init__(self, x, y): 14262306a36Sopenharmony_ci self.x = x 14362306a36Sopenharmony_ci self.y = y 14462306a36Sopenharmony_ci self.tipswitch = False 14562306a36Sopenharmony_ci self.tippressure = 15 14662306a36Sopenharmony_ci self.azimuth = 0 14762306a36Sopenharmony_ci self.inrange = False 14862306a36Sopenharmony_ci self.width = 10 14962306a36Sopenharmony_ci self.height = 10 15062306a36Sopenharmony_ci self.barrelswitch = False 15162306a36Sopenharmony_ci self.invert = False 15262306a36Sopenharmony_ci self.eraser = False 15362306a36Sopenharmony_ci self.x_tilt = 0 15462306a36Sopenharmony_ci self.y_tilt = 0 15562306a36Sopenharmony_ci self.twist = 0 15662306a36Sopenharmony_ci self._old_values = None 15762306a36Sopenharmony_ci self.current_state = None 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci def _restore(self): 16062306a36Sopenharmony_ci if self._old_values is not None: 16162306a36Sopenharmony_ci for i in [ 16262306a36Sopenharmony_ci "x", 16362306a36Sopenharmony_ci "y", 16462306a36Sopenharmony_ci "tippressure", 16562306a36Sopenharmony_ci "azimuth", 16662306a36Sopenharmony_ci "width", 16762306a36Sopenharmony_ci "height", 16862306a36Sopenharmony_ci "twist", 16962306a36Sopenharmony_ci "x_tilt", 17062306a36Sopenharmony_ci "y_tilt", 17162306a36Sopenharmony_ci ]: 17262306a36Sopenharmony_ci setattr(self, i, getattr(self._old_values, i)) 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci def move_to(self, state): 17562306a36Sopenharmony_ci # fill in the previous values 17662306a36Sopenharmony_ci if self.current_state == PenState.PEN_IS_OUT_OF_RANGE: 17762306a36Sopenharmony_ci self._restore() 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci print(f"\n *** pen is moving to {state} ***") 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci if state == PenState.PEN_IS_OUT_OF_RANGE: 18262306a36Sopenharmony_ci self._old_values = copy.copy(self) 18362306a36Sopenharmony_ci self.x = 0 18462306a36Sopenharmony_ci self.y = 0 18562306a36Sopenharmony_ci self.tipswitch = False 18662306a36Sopenharmony_ci self.tippressure = 0 18762306a36Sopenharmony_ci self.azimuth = 0 18862306a36Sopenharmony_ci self.inrange = False 18962306a36Sopenharmony_ci self.width = 0 19062306a36Sopenharmony_ci self.height = 0 19162306a36Sopenharmony_ci self.invert = False 19262306a36Sopenharmony_ci self.eraser = False 19362306a36Sopenharmony_ci self.x_tilt = 0 19462306a36Sopenharmony_ci self.y_tilt = 0 19562306a36Sopenharmony_ci self.twist = 0 19662306a36Sopenharmony_ci elif state == PenState.PEN_IS_IN_RANGE: 19762306a36Sopenharmony_ci self.tipswitch = False 19862306a36Sopenharmony_ci self.inrange = True 19962306a36Sopenharmony_ci self.invert = False 20062306a36Sopenharmony_ci self.eraser = False 20162306a36Sopenharmony_ci elif state == PenState.PEN_IS_IN_CONTACT: 20262306a36Sopenharmony_ci self.tipswitch = True 20362306a36Sopenharmony_ci self.inrange = True 20462306a36Sopenharmony_ci self.invert = False 20562306a36Sopenharmony_ci self.eraser = False 20662306a36Sopenharmony_ci elif state == PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT: 20762306a36Sopenharmony_ci self.tipswitch = False 20862306a36Sopenharmony_ci self.inrange = True 20962306a36Sopenharmony_ci self.invert = True 21062306a36Sopenharmony_ci self.eraser = False 21162306a36Sopenharmony_ci elif state == PenState.PEN_IS_ERASING: 21262306a36Sopenharmony_ci self.tipswitch = False 21362306a36Sopenharmony_ci self.inrange = True 21462306a36Sopenharmony_ci self.invert = True 21562306a36Sopenharmony_ci self.eraser = True 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci self.current_state = state 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci def __assert_axis(self, evdev, axis, value): 22062306a36Sopenharmony_ci if ( 22162306a36Sopenharmony_ci axis == libevdev.EV_KEY.BTN_TOOL_RUBBER 22262306a36Sopenharmony_ci and evdev.value[libevdev.EV_KEY.BTN_TOOL_RUBBER] is None 22362306a36Sopenharmony_ci ): 22462306a36Sopenharmony_ci return 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci assert ( 22762306a36Sopenharmony_ci evdev.value[axis] == value 22862306a36Sopenharmony_ci ), f"assert evdev.value[{axis}] ({evdev.value[axis]}) != {value}" 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci def assert_expected_input_events(self, evdev): 23162306a36Sopenharmony_ci assert evdev.value[libevdev.EV_ABS.ABS_X] == self.x 23262306a36Sopenharmony_ci assert evdev.value[libevdev.EV_ABS.ABS_Y] == self.y 23362306a36Sopenharmony_ci assert self.current_state == PenState.from_evdev(evdev) 23462306a36Sopenharmony_ci 23562306a36Sopenharmony_ci @staticmethod 23662306a36Sopenharmony_ci def legal_transitions() -> Dict[str, Tuple[PenState, ...]]: 23762306a36Sopenharmony_ci """This is the first half of the Windows Pen Implementation state machine: 23862306a36Sopenharmony_ci we don't have Invert nor Erase bits, so just move in/out-of-range or proximity. 23962306a36Sopenharmony_ci https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states 24062306a36Sopenharmony_ci """ 24162306a36Sopenharmony_ci return { 24262306a36Sopenharmony_ci "in-range": (PenState.PEN_IS_IN_RANGE,), 24362306a36Sopenharmony_ci "in-range -> out-of-range": ( 24462306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 24562306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 24662306a36Sopenharmony_ci ), 24762306a36Sopenharmony_ci "in-range -> touch": (PenState.PEN_IS_IN_RANGE, PenState.PEN_IS_IN_CONTACT), 24862306a36Sopenharmony_ci "in-range -> touch -> release": ( 24962306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 25062306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 25162306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 25262306a36Sopenharmony_ci ), 25362306a36Sopenharmony_ci "in-range -> touch -> release -> out-of-range": ( 25462306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 25562306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 25662306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 25762306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 25862306a36Sopenharmony_ci ), 25962306a36Sopenharmony_ci } 26062306a36Sopenharmony_ci 26162306a36Sopenharmony_ci @staticmethod 26262306a36Sopenharmony_ci def legal_transitions_with_invert() -> Dict[str, Tuple[PenState, ...]]: 26362306a36Sopenharmony_ci """This is the second half of the Windows Pen Implementation state machine: 26462306a36Sopenharmony_ci we now have Invert and Erase bits, so move in/out or proximity with the intend 26562306a36Sopenharmony_ci to erase. 26662306a36Sopenharmony_ci https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states 26762306a36Sopenharmony_ci """ 26862306a36Sopenharmony_ci return { 26962306a36Sopenharmony_ci "hover-erasing": (PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT,), 27062306a36Sopenharmony_ci "hover-erasing -> out-of-range": ( 27162306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 27262306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 27362306a36Sopenharmony_ci ), 27462306a36Sopenharmony_ci "hover-erasing -> erase": ( 27562306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 27662306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 27762306a36Sopenharmony_ci ), 27862306a36Sopenharmony_ci "hover-erasing -> erase -> release": ( 27962306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 28062306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 28162306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 28262306a36Sopenharmony_ci ), 28362306a36Sopenharmony_ci "hover-erasing -> erase -> release -> out-of-range": ( 28462306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 28562306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 28662306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 28762306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 28862306a36Sopenharmony_ci ), 28962306a36Sopenharmony_ci "hover-erasing -> in-range": ( 29062306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 29162306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 29262306a36Sopenharmony_ci ), 29362306a36Sopenharmony_ci "in-range -> hover-erasing": ( 29462306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 29562306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 29662306a36Sopenharmony_ci ), 29762306a36Sopenharmony_ci } 29862306a36Sopenharmony_ci 29962306a36Sopenharmony_ci @staticmethod 30062306a36Sopenharmony_ci def tolerated_transitions() -> Dict[str, Tuple[PenState, ...]]: 30162306a36Sopenharmony_ci """This is not adhering to the Windows Pen Implementation state machine 30262306a36Sopenharmony_ci but we should expect the kernel to behave properly, mostly for historical 30362306a36Sopenharmony_ci reasons.""" 30462306a36Sopenharmony_ci return { 30562306a36Sopenharmony_ci "direct-in-contact": (PenState.PEN_IS_IN_CONTACT,), 30662306a36Sopenharmony_ci "direct-in-contact -> out-of-range": ( 30762306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 30862306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 30962306a36Sopenharmony_ci ), 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci 31262306a36Sopenharmony_ci @staticmethod 31362306a36Sopenharmony_ci def tolerated_transitions_with_invert() -> Dict[str, Tuple[PenState, ...]]: 31462306a36Sopenharmony_ci """This is the second half of the Windows Pen Implementation state machine: 31562306a36Sopenharmony_ci we now have Invert and Erase bits, so move in/out or proximity with the intend 31662306a36Sopenharmony_ci to erase. 31762306a36Sopenharmony_ci https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states 31862306a36Sopenharmony_ci """ 31962306a36Sopenharmony_ci return { 32062306a36Sopenharmony_ci "direct-erase": (PenState.PEN_IS_ERASING,), 32162306a36Sopenharmony_ci "direct-erase -> out-of-range": ( 32262306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 32362306a36Sopenharmony_ci PenState.PEN_IS_OUT_OF_RANGE, 32462306a36Sopenharmony_ci ), 32562306a36Sopenharmony_ci } 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_ci @staticmethod 32862306a36Sopenharmony_ci def broken_transitions() -> Dict[str, Tuple[PenState, ...]]: 32962306a36Sopenharmony_ci """Those tests are definitely not part of the Windows specification. 33062306a36Sopenharmony_ci However, a half broken device might export those transitions. 33162306a36Sopenharmony_ci For example, a pen that has the eraser button might wobble between 33262306a36Sopenharmony_ci touching and erasing if the tablet doesn't enforce the Windows 33362306a36Sopenharmony_ci state machine.""" 33462306a36Sopenharmony_ci return { 33562306a36Sopenharmony_ci "in-range -> touch -> erase -> hover-erase": ( 33662306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 33762306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 33862306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 33962306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 34062306a36Sopenharmony_ci ), 34162306a36Sopenharmony_ci "in-range -> erase -> hover-erase": ( 34262306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 34362306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 34462306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 34562306a36Sopenharmony_ci ), 34662306a36Sopenharmony_ci "hover-erase -> erase -> touch -> in-range": ( 34762306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 34862306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 34962306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 35062306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 35162306a36Sopenharmony_ci ), 35262306a36Sopenharmony_ci "hover-erase -> touch -> in-range": ( 35362306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE_WITH_ERASING_INTENT, 35462306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 35562306a36Sopenharmony_ci PenState.PEN_IS_IN_RANGE, 35662306a36Sopenharmony_ci ), 35762306a36Sopenharmony_ci "touch -> erase -> touch -> erase": ( 35862306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 35962306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 36062306a36Sopenharmony_ci PenState.PEN_IS_IN_CONTACT, 36162306a36Sopenharmony_ci PenState.PEN_IS_ERASING, 36262306a36Sopenharmony_ci ), 36362306a36Sopenharmony_ci } 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ciclass PenDigitizer(base.UHIDTestDevice): 36762306a36Sopenharmony_ci def __init__( 36862306a36Sopenharmony_ci self, 36962306a36Sopenharmony_ci name, 37062306a36Sopenharmony_ci rdesc_str=None, 37162306a36Sopenharmony_ci rdesc=None, 37262306a36Sopenharmony_ci application="Pen", 37362306a36Sopenharmony_ci physical="Stylus", 37462306a36Sopenharmony_ci input_info=(BusType.USB, 1, 2), 37562306a36Sopenharmony_ci evdev_name_suffix=None, 37662306a36Sopenharmony_ci ): 37762306a36Sopenharmony_ci super().__init__(name, application, rdesc_str, rdesc, input_info) 37862306a36Sopenharmony_ci self.physical = physical 37962306a36Sopenharmony_ci self.cur_application = application 38062306a36Sopenharmony_ci if evdev_name_suffix is not None: 38162306a36Sopenharmony_ci self.name += evdev_name_suffix 38262306a36Sopenharmony_ci 38362306a36Sopenharmony_ci self.fields = [] 38462306a36Sopenharmony_ci for r in self.parsed_rdesc.input_reports.values(): 38562306a36Sopenharmony_ci if r.application_name == self.application: 38662306a36Sopenharmony_ci physicals = [f.physical_name for f in r] 38762306a36Sopenharmony_ci if self.physical not in physicals and None not in physicals: 38862306a36Sopenharmony_ci continue 38962306a36Sopenharmony_ci self.fields = [f.usage_name for f in r] 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci def event(self, pen): 39262306a36Sopenharmony_ci rs = [] 39362306a36Sopenharmony_ci r = self.create_report(application=self.cur_application, data=pen) 39462306a36Sopenharmony_ci self.call_input_event(r) 39562306a36Sopenharmony_ci rs.append(r) 39662306a36Sopenharmony_ci return rs 39762306a36Sopenharmony_ci 39862306a36Sopenharmony_ci def get_report(self, req, rnum, rtype): 39962306a36Sopenharmony_ci if rtype != self.UHID_FEATURE_REPORT: 40062306a36Sopenharmony_ci return (1, []) 40162306a36Sopenharmony_ci 40262306a36Sopenharmony_ci rdesc = None 40362306a36Sopenharmony_ci for v in self.parsed_rdesc.feature_reports.values(): 40462306a36Sopenharmony_ci if v.report_ID == rnum: 40562306a36Sopenharmony_ci rdesc = v 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_ci if rdesc is None: 40862306a36Sopenharmony_ci return (1, []) 40962306a36Sopenharmony_ci 41062306a36Sopenharmony_ci return (1, []) 41162306a36Sopenharmony_ci 41262306a36Sopenharmony_ci def set_report(self, req, rnum, rtype, data): 41362306a36Sopenharmony_ci if rtype != self.UHID_FEATURE_REPORT: 41462306a36Sopenharmony_ci return 1 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci rdesc = None 41762306a36Sopenharmony_ci for v in self.parsed_rdesc.feature_reports.values(): 41862306a36Sopenharmony_ci if v.report_ID == rnum: 41962306a36Sopenharmony_ci rdesc = v 42062306a36Sopenharmony_ci 42162306a36Sopenharmony_ci if rdesc is None: 42262306a36Sopenharmony_ci return 1 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci return 1 42562306a36Sopenharmony_ci 42662306a36Sopenharmony_ci 42762306a36Sopenharmony_ciclass BaseTest: 42862306a36Sopenharmony_ci class TestTablet(base.BaseTestCase.TestUhid): 42962306a36Sopenharmony_ci def create_device(self): 43062306a36Sopenharmony_ci raise Exception("please reimplement me in subclasses") 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_ci def post(self, uhdev, pen): 43362306a36Sopenharmony_ci r = uhdev.event(pen) 43462306a36Sopenharmony_ci events = uhdev.next_sync_events() 43562306a36Sopenharmony_ci self.debug_reports(r, uhdev, events) 43662306a36Sopenharmony_ci return events 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci def validate_transitions(self, from_state, pen, evdev, events): 43962306a36Sopenharmony_ci # check that the final state is correct 44062306a36Sopenharmony_ci pen.assert_expected_input_events(evdev) 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci # check that the transitions are valid 44362306a36Sopenharmony_ci sync_events = [] 44462306a36Sopenharmony_ci while libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT) in events: 44562306a36Sopenharmony_ci # split the first EV_SYN from the list 44662306a36Sopenharmony_ci idx = events.index(libevdev.InputEvent(libevdev.EV_SYN.SYN_REPORT)) 44762306a36Sopenharmony_ci sync_events = events[:idx] 44862306a36Sopenharmony_ci events = events[idx + 1 :] 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci # now check for a valid transition 45162306a36Sopenharmony_ci from_state = from_state.apply(sync_events) 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci if events: 45462306a36Sopenharmony_ci from_state = from_state.apply(sync_events) 45562306a36Sopenharmony_ci 45662306a36Sopenharmony_ci def _test_states(self, state_list, scribble): 45762306a36Sopenharmony_ci """Internal method to test against a list of 45862306a36Sopenharmony_ci transition between states. 45962306a36Sopenharmony_ci state_list is a list of PenState objects 46062306a36Sopenharmony_ci scribble is a boolean which tells if we need 46162306a36Sopenharmony_ci to wobble a little the X,Y coordinates of the pen 46262306a36Sopenharmony_ci between each state transition.""" 46362306a36Sopenharmony_ci uhdev = self.uhdev 46462306a36Sopenharmony_ci evdev = uhdev.get_evdev() 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_ci cur_state = PenState.PEN_IS_OUT_OF_RANGE 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci p = Pen(50, 60) 46962306a36Sopenharmony_ci p.move_to(PenState.PEN_IS_OUT_OF_RANGE) 47062306a36Sopenharmony_ci events = self.post(uhdev, p) 47162306a36Sopenharmony_ci self.validate_transitions(cur_state, p, evdev, events) 47262306a36Sopenharmony_ci 47362306a36Sopenharmony_ci cur_state = p.current_state 47462306a36Sopenharmony_ci 47562306a36Sopenharmony_ci for state in state_list: 47662306a36Sopenharmony_ci if scribble and cur_state != PenState.PEN_IS_OUT_OF_RANGE: 47762306a36Sopenharmony_ci p.x += 1 47862306a36Sopenharmony_ci p.y -= 1 47962306a36Sopenharmony_ci events = self.post(uhdev, p) 48062306a36Sopenharmony_ci self.validate_transitions(cur_state, p, evdev, events) 48162306a36Sopenharmony_ci assert len(events) >= 3 # X, Y, SYN 48262306a36Sopenharmony_ci p.move_to(state) 48362306a36Sopenharmony_ci if scribble and state != PenState.PEN_IS_OUT_OF_RANGE: 48462306a36Sopenharmony_ci p.x += 1 48562306a36Sopenharmony_ci p.y -= 1 48662306a36Sopenharmony_ci events = self.post(uhdev, p) 48762306a36Sopenharmony_ci self.validate_transitions(cur_state, p, evdev, events) 48862306a36Sopenharmony_ci cur_state = p.current_state 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci @pytest.mark.parametrize("scribble", [True, False], ids=["scribble", "static"]) 49162306a36Sopenharmony_ci @pytest.mark.parametrize( 49262306a36Sopenharmony_ci "state_list", 49362306a36Sopenharmony_ci [pytest.param(v, id=k) for k, v in Pen.legal_transitions().items()], 49462306a36Sopenharmony_ci ) 49562306a36Sopenharmony_ci def test_valid_pen_states(self, state_list, scribble): 49662306a36Sopenharmony_ci """This is the first half of the Windows Pen Implementation state machine: 49762306a36Sopenharmony_ci we don't have Invert nor Erase bits, so just move in/out-of-range or proximity. 49862306a36Sopenharmony_ci https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states 49962306a36Sopenharmony_ci """ 50062306a36Sopenharmony_ci self._test_states(state_list, scribble) 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_ci @pytest.mark.parametrize("scribble", [True, False], ids=["scribble", "static"]) 50362306a36Sopenharmony_ci @pytest.mark.parametrize( 50462306a36Sopenharmony_ci "state_list", 50562306a36Sopenharmony_ci [pytest.param(v, id=k) for k, v in Pen.tolerated_transitions().items()], 50662306a36Sopenharmony_ci ) 50762306a36Sopenharmony_ci def test_tolerated_pen_states(self, state_list, scribble): 50862306a36Sopenharmony_ci """This is not adhering to the Windows Pen Implementation state machine 50962306a36Sopenharmony_ci but we should expect the kernel to behave properly, mostly for historical 51062306a36Sopenharmony_ci reasons.""" 51162306a36Sopenharmony_ci self._test_states(state_list, scribble) 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci @pytest.mark.skip_if_uhdev( 51462306a36Sopenharmony_ci lambda uhdev: "Invert" not in uhdev.fields, 51562306a36Sopenharmony_ci "Device not compatible, missing Invert usage", 51662306a36Sopenharmony_ci ) 51762306a36Sopenharmony_ci @pytest.mark.parametrize("scribble", [True, False], ids=["scribble", "static"]) 51862306a36Sopenharmony_ci @pytest.mark.parametrize( 51962306a36Sopenharmony_ci "state_list", 52062306a36Sopenharmony_ci [ 52162306a36Sopenharmony_ci pytest.param(v, id=k) 52262306a36Sopenharmony_ci for k, v in Pen.legal_transitions_with_invert().items() 52362306a36Sopenharmony_ci ], 52462306a36Sopenharmony_ci ) 52562306a36Sopenharmony_ci def test_valid_invert_pen_states(self, state_list, scribble): 52662306a36Sopenharmony_ci """This is the second half of the Windows Pen Implementation state machine: 52762306a36Sopenharmony_ci we now have Invert and Erase bits, so move in/out or proximity with the intend 52862306a36Sopenharmony_ci to erase. 52962306a36Sopenharmony_ci https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states 53062306a36Sopenharmony_ci """ 53162306a36Sopenharmony_ci self._test_states(state_list, scribble) 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci @pytest.mark.skip_if_uhdev( 53462306a36Sopenharmony_ci lambda uhdev: "Invert" not in uhdev.fields, 53562306a36Sopenharmony_ci "Device not compatible, missing Invert usage", 53662306a36Sopenharmony_ci ) 53762306a36Sopenharmony_ci @pytest.mark.parametrize("scribble", [True, False], ids=["scribble", "static"]) 53862306a36Sopenharmony_ci @pytest.mark.parametrize( 53962306a36Sopenharmony_ci "state_list", 54062306a36Sopenharmony_ci [ 54162306a36Sopenharmony_ci pytest.param(v, id=k) 54262306a36Sopenharmony_ci for k, v in Pen.tolerated_transitions_with_invert().items() 54362306a36Sopenharmony_ci ], 54462306a36Sopenharmony_ci ) 54562306a36Sopenharmony_ci def test_tolerated_invert_pen_states(self, state_list, scribble): 54662306a36Sopenharmony_ci """This is the second half of the Windows Pen Implementation state machine: 54762306a36Sopenharmony_ci we now have Invert and Erase bits, so move in/out or proximity with the intend 54862306a36Sopenharmony_ci to erase. 54962306a36Sopenharmony_ci https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states 55062306a36Sopenharmony_ci """ 55162306a36Sopenharmony_ci self._test_states(state_list, scribble) 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci @pytest.mark.skip_if_uhdev( 55462306a36Sopenharmony_ci lambda uhdev: "Invert" not in uhdev.fields, 55562306a36Sopenharmony_ci "Device not compatible, missing Invert usage", 55662306a36Sopenharmony_ci ) 55762306a36Sopenharmony_ci @pytest.mark.parametrize("scribble", [True, False], ids=["scribble", "static"]) 55862306a36Sopenharmony_ci @pytest.mark.parametrize( 55962306a36Sopenharmony_ci "state_list", 56062306a36Sopenharmony_ci [pytest.param(v, id=k) for k, v in Pen.broken_transitions().items()], 56162306a36Sopenharmony_ci ) 56262306a36Sopenharmony_ci def test_tolerated_broken_pen_states(self, state_list, scribble): 56362306a36Sopenharmony_ci """Those tests are definitely not part of the Windows specification. 56462306a36Sopenharmony_ci However, a half broken device might export those transitions. 56562306a36Sopenharmony_ci For example, a pen that has the eraser button might wobble between 56662306a36Sopenharmony_ci touching and erasing if the tablet doesn't enforce the Windows 56762306a36Sopenharmony_ci state machine.""" 56862306a36Sopenharmony_ci self._test_states(state_list, scribble) 56962306a36Sopenharmony_ci 57062306a36Sopenharmony_ci @pytest.mark.skip_if_uhdev( 57162306a36Sopenharmony_ci lambda uhdev: "Barrel Switch" not in uhdev.fields, 57262306a36Sopenharmony_ci "Device not compatible, missing Barrel Switch usage", 57362306a36Sopenharmony_ci ) 57462306a36Sopenharmony_ci def test_primary_button(self): 57562306a36Sopenharmony_ci """Primary button (stylus) pressed, reports as pressed even while hovering. 57662306a36Sopenharmony_ci Actual reporting from the device: hid=TIPSWITCH,BARRELSWITCH,INRANGE (code=TOUCH,STYLUS,PEN): 57762306a36Sopenharmony_ci { 0, 0, 1 } <- hover 57862306a36Sopenharmony_ci { 0, 1, 1 } <- primary button pressed 57962306a36Sopenharmony_ci { 0, 1, 1 } <- liftoff 58062306a36Sopenharmony_ci { 0, 0, 0 } <- leaves 58162306a36Sopenharmony_ci """ 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci uhdev = self.uhdev 58462306a36Sopenharmony_ci evdev = uhdev.get_evdev() 58562306a36Sopenharmony_ci 58662306a36Sopenharmony_ci p = Pen(50, 60) 58762306a36Sopenharmony_ci p.inrange = True 58862306a36Sopenharmony_ci events = self.post(uhdev, p) 58962306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1) in events 59062306a36Sopenharmony_ci assert evdev.value[libevdev.EV_ABS.ABS_X] == 50 59162306a36Sopenharmony_ci assert evdev.value[libevdev.EV_ABS.ABS_Y] == 60 59262306a36Sopenharmony_ci assert not evdev.value[libevdev.EV_KEY.BTN_STYLUS] 59362306a36Sopenharmony_ci 59462306a36Sopenharmony_ci p.barrelswitch = True 59562306a36Sopenharmony_ci events = self.post(uhdev, p) 59662306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 1) in events 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_ci p.x += 1 59962306a36Sopenharmony_ci p.y -= 1 60062306a36Sopenharmony_ci events = self.post(uhdev, p) 60162306a36Sopenharmony_ci assert len(events) == 3 # X, Y, SYN 60262306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 51) in events 60362306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 59) in events 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci p.barrelswitch = False 60662306a36Sopenharmony_ci events = self.post(uhdev, p) 60762306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 0) in events 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci p.inrange = False 61062306a36Sopenharmony_ci events = self.post(uhdev, p) 61162306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 0) in events 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci @pytest.mark.skip_if_uhdev( 61462306a36Sopenharmony_ci lambda uhdev: "Barrel Switch" not in uhdev.fields, 61562306a36Sopenharmony_ci "Device not compatible, missing Barrel Switch usage", 61662306a36Sopenharmony_ci ) 61762306a36Sopenharmony_ci def test_contact_primary_button(self): 61862306a36Sopenharmony_ci """Primary button (stylus) pressed, reports as pressed even while hovering. 61962306a36Sopenharmony_ci Actual reporting from the device: hid=TIPSWITCH,BARRELSWITCH,INRANGE (code=TOUCH,STYLUS,PEN): 62062306a36Sopenharmony_ci { 0, 0, 1 } <- hover 62162306a36Sopenharmony_ci { 0, 1, 1 } <- primary button pressed 62262306a36Sopenharmony_ci { 1, 1, 1 } <- touch-down 62362306a36Sopenharmony_ci { 1, 1, 1 } <- still touch, scribble on the screen 62462306a36Sopenharmony_ci { 0, 1, 1 } <- liftoff 62562306a36Sopenharmony_ci { 0, 0, 0 } <- leaves 62662306a36Sopenharmony_ci """ 62762306a36Sopenharmony_ci 62862306a36Sopenharmony_ci uhdev = self.uhdev 62962306a36Sopenharmony_ci evdev = uhdev.get_evdev() 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci p = Pen(50, 60) 63262306a36Sopenharmony_ci p.inrange = True 63362306a36Sopenharmony_ci events = self.post(uhdev, p) 63462306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 1) in events 63562306a36Sopenharmony_ci assert evdev.value[libevdev.EV_ABS.ABS_X] == 50 63662306a36Sopenharmony_ci assert evdev.value[libevdev.EV_ABS.ABS_Y] == 60 63762306a36Sopenharmony_ci assert not evdev.value[libevdev.EV_KEY.BTN_STYLUS] 63862306a36Sopenharmony_ci 63962306a36Sopenharmony_ci p.barrelswitch = True 64062306a36Sopenharmony_ci events = self.post(uhdev, p) 64162306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 1) in events 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci p.tipswitch = True 64462306a36Sopenharmony_ci events = self.post(uhdev, p) 64562306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 1) in events 64662306a36Sopenharmony_ci assert evdev.value[libevdev.EV_KEY.BTN_STYLUS] 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci p.x += 1 64962306a36Sopenharmony_ci p.y -= 1 65062306a36Sopenharmony_ci events = self.post(uhdev, p) 65162306a36Sopenharmony_ci assert len(events) == 3 # X, Y, SYN 65262306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_ABS.ABS_X, 51) in events 65362306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_ABS.ABS_Y, 59) in events 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci p.tipswitch = False 65662306a36Sopenharmony_ci events = self.post(uhdev, p) 65762306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOUCH, 0) in events 65862306a36Sopenharmony_ci 65962306a36Sopenharmony_ci p.barrelswitch = False 66062306a36Sopenharmony_ci p.inrange = False 66162306a36Sopenharmony_ci events = self.post(uhdev, p) 66262306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_TOOL_PEN, 0) in events 66362306a36Sopenharmony_ci assert libevdev.InputEvent(libevdev.EV_KEY.BTN_STYLUS, 0) in events 66462306a36Sopenharmony_ci 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ciclass GXTP_pen(PenDigitizer): 66762306a36Sopenharmony_ci def event(self, pen): 66862306a36Sopenharmony_ci if not hasattr(self, "prev_tip_state"): 66962306a36Sopenharmony_ci self.prev_tip_state = False 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_ci internal_pen = copy.copy(pen) 67262306a36Sopenharmony_ci 67362306a36Sopenharmony_ci # bug in the controller: when the pen touches the 67462306a36Sopenharmony_ci # surface, in-range stays to 1, but when 67562306a36Sopenharmony_ci # the pen moves in-range gets reverted to 0 67662306a36Sopenharmony_ci if pen.tipswitch and self.prev_tip_state: 67762306a36Sopenharmony_ci internal_pen.inrange = False 67862306a36Sopenharmony_ci 67962306a36Sopenharmony_ci self.prev_tip_state = pen.tipswitch 68062306a36Sopenharmony_ci 68162306a36Sopenharmony_ci # another bug in the controller: when the pen is 68262306a36Sopenharmony_ci # inverted, invert is set to 1, but as soon as 68362306a36Sopenharmony_ci # the pen touches the surface, eraser is correctly 68462306a36Sopenharmony_ci # set to 1 but invert is released 68562306a36Sopenharmony_ci if pen.eraser: 68662306a36Sopenharmony_ci internal_pen.invert = False 68762306a36Sopenharmony_ci 68862306a36Sopenharmony_ci return super().event(internal_pen) 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci 69162306a36Sopenharmony_ciclass USIPen(PenDigitizer): 69262306a36Sopenharmony_ci pass 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci 69562306a36Sopenharmony_ci################################################################################ 69662306a36Sopenharmony_ci# 69762306a36Sopenharmony_ci# Windows 7 compatible devices 69862306a36Sopenharmony_ci# 69962306a36Sopenharmony_ci################################################################################ 70062306a36Sopenharmony_ci# class TestEgalax_capacitive_0eef_7224(BaseTest.TestTablet): 70162306a36Sopenharmony_ci# def create_device(self): 70262306a36Sopenharmony_ci# return PenDigitizer('uhid test egalax-capacitive_0eef_7224', 70362306a36Sopenharmony_ci# rdesc='05 0d 09 04 a1 01 85 04 09 22 a1 00 09 42 15 00 25 01 75 01 95 01 81 02 09 32 15 00 25 01 81 02 09 51 75 05 95 01 16 00 00 26 10 00 81 02 09 47 75 01 95 01 15 00 25 01 81 02 05 01 09 30 75 10 95 01 55 0d 65 33 35 00 46 34 49 26 ff 7f 81 02 09 31 75 10 95 01 55 0d 65 33 35 00 46 37 29 26 ff 7f 81 02 05 0d 09 55 25 08 75 08 95 01 b1 02 c0 c0 05 01 09 01 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06 81 01 05 01 09 30 09 31 16 00 00 26 ff 0f 36 00 00 46 ff 0f 66 00 00 75 10 95 02 81 02 c0 c0 06 00 ff 09 01 a1 01 09 01 15 00 26 ff 00 85 03 75 08 95 3f 81 02 06 00 ff 09 01 15 00 26 ff 00 75 08 95 3f 91 02 c0 05 0d 09 04 a1 01 85 02 09 20 a1 00 09 42 09 32 15 00 25 01 95 02 75 01 81 02 95 06 75 01 81 03 05 01 09 30 75 10 95 01 a4 55 0d 65 33 36 00 00 46 34 49 16 00 00 26 ff 0f 81 02 09 31 16 00 00 26 ff 0f 36 00 00 46 37 29 81 02 b4 c0 c0 05 0d 09 0e a1 01 85 05 09 22 a1 00 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0', 70462306a36Sopenharmony_ci# input_info=(BusType.USB, 0x0eef, 0x7224), 70562306a36Sopenharmony_ci# evdev_name_suffix=' Touchscreen') 70662306a36Sopenharmony_ci# 70762306a36Sopenharmony_ci# 70862306a36Sopenharmony_ci# class TestEgalax_capacitive_0eef_72fa(BaseTest.TestTablet): 70962306a36Sopenharmony_ci# def create_device(self): 71062306a36Sopenharmony_ci# return PenDigitizer('uhid test egalax-capacitive_0eef_72fa', 71162306a36Sopenharmony_ci# rdesc='05 0d 09 04 a1 01 85 04 09 22 a1 00 09 42 15 00 25 01 75 01 95 01 81 02 09 32 15 00 25 01 81 02 09 51 75 05 95 01 16 00 00 26 10 00 81 02 09 47 75 01 95 01 15 00 25 01 81 02 05 01 09 30 75 10 95 01 55 0d 65 33 35 00 46 72 22 26 ff 7f 81 02 09 31 75 10 95 01 55 0d 65 33 35 00 46 87 13 26 ff 7f 81 02 05 0d 09 55 25 08 75 08 95 01 b1 02 c0 c0 05 01 09 01 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06 81 01 05 01 09 30 09 31 16 00 00 26 ff 0f 36 00 00 46 ff 0f 66 00 00 75 10 95 02 81 02 c0 c0 06 00 ff 09 01 a1 01 09 01 15 00 26 ff 00 85 03 75 08 95 3f 81 02 06 00 ff 09 01 15 00 26 ff 00 75 08 95 3f 91 02 c0 05 0d 09 04 a1 01 85 02 09 20 a1 00 09 42 09 32 15 00 25 01 95 02 75 01 81 02 95 06 75 01 81 03 05 01 09 30 75 10 95 01 a4 55 0d 65 33 36 00 00 46 72 22 16 00 00 26 ff 0f 81 02 09 31 16 00 00 26 ff 0f 36 00 00 46 87 13 81 02 b4 c0 c0 05 0d 09 0e a1 01 85 05 09 22 a1 00 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0', 71262306a36Sopenharmony_ci# input_info=(BusType.USB, 0x0eef, 0x72fa), 71362306a36Sopenharmony_ci# evdev_name_suffix=' Touchscreen') 71462306a36Sopenharmony_ci# 71562306a36Sopenharmony_ci# 71662306a36Sopenharmony_ci# class TestEgalax_capacitive_0eef_7336(BaseTest.TestTablet): 71762306a36Sopenharmony_ci# def create_device(self): 71862306a36Sopenharmony_ci# return PenDigitizer('uhid test egalax-capacitive_0eef_7336', 71962306a36Sopenharmony_ci# rdesc='05 0d 09 04 a1 01 85 04 09 22 a1 00 09 42 15 00 25 01 75 01 95 01 81 02 09 32 15 00 25 01 81 02 09 51 75 05 95 01 16 00 00 26 10 00 81 02 09 47 75 01 95 01 15 00 25 01 81 02 05 01 09 30 75 10 95 01 55 0d 65 33 35 00 46 c1 20 26 ff 7f 81 02 09 31 75 10 95 01 55 0d 65 33 35 00 46 c2 18 26 ff 7f 81 02 05 0d 09 55 25 08 75 08 95 01 b1 02 c0 c0 05 01 09 01 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06 81 01 05 01 09 30 09 31 16 00 00 26 ff 0f 36 00 00 46 ff 0f 66 00 00 75 10 95 02 81 02 c0 c0 06 00 ff 09 01 a1 01 09 01 15 00 26 ff 00 85 03 75 08 95 3f 81 02 06 00 ff 09 01 15 00 26 ff 00 75 08 95 3f 91 02 c0 05 0d 09 04 a1 01 85 02 09 20 a1 00 09 42 09 32 15 00 25 01 95 02 75 01 81 02 95 06 75 01 81 03 05 01 09 30 75 10 95 01 a4 55 0d 65 33 36 00 00 46 c1 20 16 00 00 26 ff 0f 81 02 09 31 16 00 00 26 ff 0f 36 00 00 46 c2 18 81 02 b4 c0 c0 05 0d 09 0e a1 01 85 05 09 22 a1 00 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0', 72062306a36Sopenharmony_ci# input_info=(BusType.USB, 0x0eef, 0x7336), 72162306a36Sopenharmony_ci# evdev_name_suffix=' Touchscreen') 72262306a36Sopenharmony_ci# 72362306a36Sopenharmony_ci# 72462306a36Sopenharmony_ci# class TestEgalax_capacitive_0eef_7337(BaseTest.TestTablet): 72562306a36Sopenharmony_ci# def create_device(self): 72662306a36Sopenharmony_ci# return PenDigitizer('uhid test egalax-capacitive_0eef_7337', 72762306a36Sopenharmony_ci# rdesc='05 0d 09 04 a1 01 85 04 09 22 a1 00 09 42 15 00 25 01 75 01 95 01 81 02 09 32 15 00 25 01 81 02 09 51 75 05 95 01 16 00 00 26 10 00 81 02 09 47 75 01 95 01 15 00 25 01 81 02 05 01 09 30 75 10 95 01 55 0d 65 33 35 00 46 ae 17 26 ff 7f 81 02 09 31 75 10 95 01 55 0d 65 33 35 00 46 c3 0e 26 ff 7f 81 02 05 0d 09 55 25 08 75 08 95 01 b1 02 c0 c0 05 01 09 01 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06 81 01 05 01 09 30 09 31 16 00 00 26 ff 0f 36 00 00 46 ff 0f 66 00 00 75 10 95 02 81 02 c0 c0 06 00 ff 09 01 a1 01 09 01 15 00 26 ff 00 85 03 75 08 95 3f 81 02 06 00 ff 09 01 15 00 26 ff 00 75 08 95 3f 91 02 c0 05 0d 09 04 a1 01 85 02 09 20 a1 00 09 42 09 32 15 00 25 01 95 02 75 01 81 02 95 06 75 01 81 03 05 01 09 30 75 10 95 01 a4 55 0d 65 33 36 00 00 46 ae 17 16 00 00 26 ff 0f 81 02 09 31 16 00 00 26 ff 0f 36 00 00 46 c3 0e 81 02 b4 c0 c0 05 0d 09 0e a1 01 85 05 09 22 a1 00 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0', 72862306a36Sopenharmony_ci# input_info=(BusType.USB, 0x0eef, 0x7337), 72962306a36Sopenharmony_ci# evdev_name_suffix=' Touchscreen') 73062306a36Sopenharmony_ci# 73162306a36Sopenharmony_ci# 73262306a36Sopenharmony_ci# class TestEgalax_capacitive_0eef_7349(BaseTest.TestTablet): 73362306a36Sopenharmony_ci# def create_device(self): 73462306a36Sopenharmony_ci# return PenDigitizer('uhid test egalax-capacitive_0eef_7349', 73562306a36Sopenharmony_ci# rdesc='05 0d 09 04 a1 01 85 04 09 22 a1 00 09 42 15 00 25 01 75 01 95 01 81 02 09 32 15 00 25 01 81 02 09 51 75 05 95 01 16 00 00 26 10 00 81 02 09 47 75 01 95 01 15 00 25 01 81 02 05 01 09 30 75 10 95 01 55 0d 65 33 35 00 46 34 49 26 ff 7f 81 02 09 31 75 10 95 01 55 0d 65 33 35 00 46 37 29 26 ff 7f 81 02 05 0d 09 55 25 08 75 08 95 01 b1 02 c0 c0 05 01 09 01 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06 81 01 05 01 09 30 09 31 16 00 00 26 ff 0f 36 00 00 46 ff 0f 66 00 00 75 10 95 02 81 02 c0 c0 06 00 ff 09 01 a1 01 09 01 15 00 26 ff 00 85 03 75 08 95 3f 81 02 06 00 ff 09 01 15 00 26 ff 00 75 08 95 3f 91 02 c0 05 0d 09 04 a1 01 85 02 09 20 a1 00 09 42 09 32 15 00 25 01 95 02 75 01 81 02 95 06 75 01 81 03 05 01 09 30 75 10 95 01 a4 55 0d 65 33 36 00 00 46 34 49 16 00 00 26 ff 0f 81 02 09 31 16 00 00 26 ff 0f 36 00 00 46 37 29 81 02 b4 c0 c0 05 0d 09 0e a1 01 85 05 09 22 a1 00 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0', 73662306a36Sopenharmony_ci# input_info=(BusType.USB, 0x0eef, 0x7349), 73762306a36Sopenharmony_ci# evdev_name_suffix=' Touchscreen') 73862306a36Sopenharmony_ci# 73962306a36Sopenharmony_ci# 74062306a36Sopenharmony_ci# class TestEgalax_capacitive_0eef_73f4(BaseTest.TestTablet): 74162306a36Sopenharmony_ci# def create_device(self): 74262306a36Sopenharmony_ci# return PenDigitizer('uhid test egalax-capacitive_0eef_73f4', 74362306a36Sopenharmony_ci# rdesc='05 0d 09 04 a1 01 85 04 09 22 a1 00 09 42 15 00 25 01 75 01 95 01 81 02 09 32 15 00 25 01 81 02 09 51 75 05 95 01 16 00 00 26 10 00 81 02 09 47 75 01 95 01 15 00 25 01 81 02 05 01 09 30 75 10 95 01 55 0d 65 33 35 00 46 96 4e 26 ff 7f 81 02 09 31 75 10 95 01 55 0d 65 33 35 00 46 23 2c 26 ff 7f 81 02 05 0d 09 55 25 08 75 08 95 01 b1 02 c0 c0 05 01 09 01 a1 01 85 01 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 01 75 06 81 01 05 01 09 30 09 31 16 00 00 26 ff 0f 36 00 00 46 ff 0f 66 00 00 75 10 95 02 81 02 c0 c0 06 00 ff 09 01 a1 01 09 01 15 00 26 ff 00 85 03 75 08 95 3f 81 02 06 00 ff 09 01 15 00 26 ff 00 75 08 95 3f 91 02 c0 05 0d 09 04 a1 01 85 02 09 20 a1 00 09 42 09 32 15 00 25 01 95 02 75 01 81 02 95 06 75 01 81 03 05 01 09 30 75 10 95 01 a4 55 0d 65 33 36 00 00 46 96 4e 16 00 00 26 ff 0f 81 02 09 31 16 00 00 26 ff 0f 36 00 00 46 23 2c 81 02 b4 c0 c0 05 0d 09 0e a1 01 85 05 09 22 a1 00 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0', 74462306a36Sopenharmony_ci# input_info=(BusType.USB, 0x0eef, 0x73f4), 74562306a36Sopenharmony_ci# evdev_name_suffix=' Touchscreen') 74662306a36Sopenharmony_ci# 74762306a36Sopenharmony_ci# bogus: BTN_TOOL_PEN is not emitted 74862306a36Sopenharmony_ci# class TestIrtouch_6615_0070(BaseTest.TestTablet): 74962306a36Sopenharmony_ci# def create_device(self): 75062306a36Sopenharmony_ci# return PenDigitizer('uhid test irtouch_6615_0070', 75162306a36Sopenharmony_ci# rdesc='05 01 09 02 a1 01 85 10 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 95 02 75 01 81 02 95 06 81 03 05 01 09 30 09 31 15 00 26 ff 7f 75 10 95 02 81 02 c0 c0 05 0d 09 04 a1 01 85 30 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 09 51 75 08 95 01 81 02 05 01 09 30 26 ff 7f 55 0f 65 11 35 00 46 51 02 75 10 95 01 81 02 09 31 35 00 46 73 01 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 09 51 75 08 95 01 81 02 05 01 09 30 26 ff 7f 55 0f 65 11 35 00 46 51 02 75 10 95 01 81 02 09 31 35 00 46 73 01 81 02 c0 05 0d 09 54 15 00 26 02 00 75 08 95 01 81 02 85 03 09 55 15 00 26 ff 00 75 08 95 01 b1 02 c0 05 0d 09 0e a1 01 85 02 09 52 09 53 15 00 26 ff 00 75 08 95 02 b1 02 c0 05 0d 09 02 a1 01 85 20 09 20 a1 00 09 42 15 00 25 01 75 01 95 01 81 02 95 07 81 03 05 01 09 30 26 ff 7f 55 0f 65 11 35 00 46 51 02 75 10 95 01 81 02 09 31 35 00 46 73 01 81 02 85 01 06 00 ff 09 01 75 08 95 01 b1 02 c0 c0', 75262306a36Sopenharmony_ci# input_info=(BusType.USB, 0x6615, 0x0070)) 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ciclass TestNexio_1870_0100(BaseTest.TestTablet): 75662306a36Sopenharmony_ci def create_device(self): 75762306a36Sopenharmony_ci return PenDigitizer( 75862306a36Sopenharmony_ci "uhid test nexio_1870_0100", 75962306a36Sopenharmony_ci rdesc="05 0d 09 04 a1 01 85 01 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0e 65 11 09 30 35 00 46 1e 19 81 02 26 ff 3f 09 31 35 00 46 be 0f 81 02 26 ff 3f c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0e 65 11 09 30 35 00 46 1e 19 81 02 26 ff 3f 09 31 35 00 46 be 0f 81 02 26 ff 3f c0 05 0d 09 54 95 01 75 08 25 02 81 02 85 02 09 55 25 02 b1 02 c0 09 0e a1 01 85 03 09 23 a1 02 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0 05 01 09 02 a1 01 09 01 a1 00 85 04 05 09 95 03 75 01 19 01 29 03 15 00 25 01 81 02 95 01 75 05 81 01 05 01 75 10 95 02 09 30 09 31 15 00 26 ff 7f 81 02 c0 c0 05 0d 09 02 a1 01 85 05 09 20 a1 00 09 42 09 32 15 00 25 01 75 01 95 02 81 02 95 0e 81 03 05 01 26 ff 3f 75 10 95 01 55 0e 65 11 09 30 35 00 46 1e 19 81 02 26 ff 3f 09 31 35 00 46 be 0f 81 02 26 ff 3f c0 c0 06 00 ff 09 01 a1 01 85 06 19 01 29 40 15 00 26 ff 00 75 08 95 40 81 00 19 01 29 40 91 00 c0", 76062306a36Sopenharmony_ci input_info=(BusType.USB, 0x1870, 0x0100), 76162306a36Sopenharmony_ci ) 76262306a36Sopenharmony_ci 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ciclass TestNexio_1870_010d(BaseTest.TestTablet): 76562306a36Sopenharmony_ci def create_device(self): 76662306a36Sopenharmony_ci return PenDigitizer( 76762306a36Sopenharmony_ci "uhid test nexio_1870_010d", 76862306a36Sopenharmony_ci rdesc="05 0d 09 04 a1 01 85 01 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 05 0d 09 54 95 01 75 08 25 02 81 02 85 02 09 55 25 06 b1 02 c0 09 0e a1 01 85 03 09 23 a1 02 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0 05 01 09 02 a1 01 09 01 a1 00 85 04 05 09 95 03 75 01 19 01 29 03 15 00 25 01 81 02 95 01 75 05 81 01 05 01 75 10 95 02 09 30 09 31 15 00 26 ff 7f 81 02 c0 c0 05 0d 09 02 a1 01 85 05 09 20 a1 00 09 42 09 32 15 00 25 01 75 01 95 02 81 02 95 0e 81 03 05 01 26 ff 3f 75 10 95 01 55 0e 65 11 09 30 35 00 46 1e 19 81 02 26 ff 3f 09 31 35 00 46 be 0f 81 02 26 ff 3f c0 c0 06 00 ff 09 01 a1 01 85 06 19 01 29 40 15 00 26 ff 00 75 08 95 3e 81 00 19 01 29 40 91 00 c0", 76962306a36Sopenharmony_ci input_info=(BusType.USB, 0x1870, 0x010D), 77062306a36Sopenharmony_ci ) 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_ci 77362306a36Sopenharmony_ciclass TestNexio_1870_0119(BaseTest.TestTablet): 77462306a36Sopenharmony_ci def create_device(self): 77562306a36Sopenharmony_ci return PenDigitizer( 77662306a36Sopenharmony_ci "uhid test nexio_1870_0119", 77762306a36Sopenharmony_ci rdesc="05 0d 09 04 a1 01 85 01 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 95 06 81 03 75 08 09 51 95 01 81 02 05 01 26 ff 3f 75 10 55 0d 65 00 09 30 35 00 46 00 00 81 02 26 ff 3f 09 31 35 00 46 00 00 81 02 26 ff 3f 05 0d 09 48 35 00 26 ff 3f 81 02 09 49 35 00 26 ff 3f 81 02 c0 05 0d 09 54 95 01 75 08 25 02 81 02 85 02 09 55 25 06 b1 02 c0 09 0e a1 01 85 03 09 23 a1 02 09 52 09 53 15 00 25 0a 75 08 95 02 b1 02 c0 c0 05 01 09 02 a1 01 09 01 a1 00 85 04 05 09 95 03 75 01 19 01 29 03 15 00 25 01 81 02 95 01 75 05 81 01 05 01 75 10 95 02 09 30 09 31 15 00 26 ff 7f 81 02 c0 c0 05 0d 09 02 a1 01 85 05 09 20 a1 00 09 42 09 32 15 00 25 01 75 01 95 02 81 02 95 0e 81 03 05 01 26 ff 3f 75 10 95 01 55 0e 65 11 09 30 35 00 46 1e 19 81 02 26 ff 3f 09 31 35 00 46 be 0f 81 02 26 ff 3f c0 c0 06 00 ff 09 01 a1 01 85 06 19 01 29 40 15 00 26 ff 00 75 08 95 3e 81 00 19 01 29 40 91 00 c0", 77862306a36Sopenharmony_ci input_info=(BusType.USB, 0x1870, 0x0119), 77962306a36Sopenharmony_ci ) 78062306a36Sopenharmony_ci 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci################################################################################ 78362306a36Sopenharmony_ci# 78462306a36Sopenharmony_ci# Windows 8 compatible devices 78562306a36Sopenharmony_ci# 78662306a36Sopenharmony_ci################################################################################ 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci# bogus: application is 'undefined' 78962306a36Sopenharmony_ci# class Testatmel_03eb_8409(BaseTest.TestTablet): 79062306a36Sopenharmony_ci# def create_device(self): 79162306a36Sopenharmony_ci# return PenDigitizer('uhid test atmel_03eb_8409', rdesc='05 0d 09 04 a1 01 85 01 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 02 46 c8 0a 26 6f 08 09 30 81 02 35 00 35 00 46 18 06 26 77 0f 09 31 81 02 35 00 35 00 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 48 81 02 09 49 81 02 c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 02 46 c8 0a 26 6f 08 09 30 81 02 35 00 35 00 46 18 06 26 77 0f 09 31 81 02 35 00 35 00 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 48 81 02 09 49 81 02 c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 02 46 c8 0a 26 6f 08 09 30 81 02 35 00 35 00 46 18 06 26 77 0f 09 31 81 02 35 00 35 00 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 48 81 02 09 49 81 02 c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 02 46 c8 0a 26 6f 08 09 30 81 02 35 00 35 00 46 18 06 26 77 0f 09 31 81 02 35 00 35 00 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 48 81 02 09 49 81 02 c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 02 46 c8 0a 26 6f 08 09 30 81 02 35 00 35 00 46 18 06 26 77 0f 09 31 81 02 35 00 35 00 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 48 81 02 09 49 81 02 c0 05 0d 27 ff ff 00 00 75 10 95 01 09 56 81 02 15 00 25 1f 75 05 09 54 95 01 81 02 75 03 25 01 95 01 81 03 75 08 85 02 09 55 25 10 b1 02 06 00 ff 85 05 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 00 a1 01 85 03 09 20 a1 00 15 00 25 01 75 01 95 01 09 42 81 02 09 44 81 02 09 45 81 02 81 03 09 32 81 02 95 03 81 03 05 01 55 0e 65 11 35 00 75 10 95 02 46 c8 0a 26 6f 08 09 30 81 02 46 18 06 26 77 0f 09 31 81 02 05 0d 09 30 15 01 26 ff 00 75 08 95 01 81 02 c0 c0') 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci 79462306a36Sopenharmony_ciclass Testatmel_03eb_840b(BaseTest.TestTablet): 79562306a36Sopenharmony_ci def create_device(self): 79662306a36Sopenharmony_ci return PenDigitizer( 79762306a36Sopenharmony_ci "uhid test atmel_03eb_840b", 79862306a36Sopenharmony_ci rdesc="05 0d 09 04 a1 01 85 01 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 01 46 00 0a 26 ff 0f 09 30 81 02 09 00 81 03 46 a0 05 26 ff 0f 09 31 81 02 09 00 81 03 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 00 81 03 09 00 81 03 c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 01 46 00 0a 26 ff 0f 09 30 81 02 09 00 81 03 46 a0 05 26 ff 0f 09 31 81 02 09 00 81 03 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 00 81 03 09 00 81 03 c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 01 46 00 0a 26 ff 0f 09 30 81 02 09 00 81 03 46 a0 05 26 ff 0f 09 31 81 02 09 00 81 03 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 00 81 03 09 00 81 03 c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 01 46 00 0a 26 ff 0f 09 30 81 02 09 00 81 03 46 a0 05 26 ff 0f 09 31 81 02 09 00 81 03 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 00 81 03 09 00 81 03 c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 95 01 81 03 25 1f 75 05 09 51 81 02 05 01 55 0e 65 11 35 00 75 10 95 01 46 00 0a 26 ff 0f 09 30 81 02 09 00 81 03 46 a0 05 26 ff 0f 09 31 81 02 09 00 81 03 05 0d 95 01 75 08 15 00 26 ff 00 46 ff 00 09 00 81 03 09 00 81 03 c0 05 0d 27 ff ff 00 00 75 10 95 01 09 56 81 02 15 00 25 1f 75 05 09 54 95 01 81 02 75 03 25 01 95 01 81 03 75 08 85 02 09 55 25 10 b1 02 06 00 ff 85 05 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 02 a1 01 85 03 09 20 a1 00 15 00 25 01 75 01 95 01 09 42 81 02 09 44 81 02 09 45 81 02 81 03 09 32 81 02 95 03 81 03 05 01 55 0e 65 11 35 00 75 10 95 02 46 00 0a 26 ff 0f 09 30 81 02 46 a0 05 26 ff 0f 09 31 81 02 05 0d 09 30 15 01 26 ff 00 75 08 95 01 81 02 c0 c0", 79962306a36Sopenharmony_ci ) 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci 80262306a36Sopenharmony_ciclass Testn_trig_1b96_0c01(BaseTest.TestTablet): 80362306a36Sopenharmony_ci def create_device(self): 80462306a36Sopenharmony_ci return PenDigitizer( 80562306a36Sopenharmony_ci "uhid test n_trig_1b96_0c01", 80662306a36Sopenharmony_ci rdesc="75 08 15 00 26 ff 00 06 0b ff 09 0b a1 01 95 0f 09 29 85 29 b1 02 95 1f 09 2a 85 2a b1 02 95 3e 09 2b 85 2b b1 02 95 fe 09 2c 85 2c b1 02 96 fe 01 09 2d 85 2d b1 02 95 02 09 48 85 48 b1 02 95 0f 09 2e 85 2e 81 02 95 1f 09 2f 85 2f 81 02 95 3e 09 30 85 30 81 02 95 fe 09 31 85 31 81 02 96 fe 01 09 32 85 32 81 02 75 08 96 fe 0f 09 35 85 35 81 02 c0 05 0d 09 02 a1 01 85 01 09 20 35 00 a1 00 09 32 09 42 09 44 09 3c 09 45 15 00 25 01 75 01 95 05 81 02 95 03 81 03 05 01 09 30 75 10 95 01 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 b4 05 0d 09 30 26 00 01 81 02 06 00 ff 09 01 81 02 c0 85 0c 06 00 ff 09 0c 75 08 95 06 26 ff 00 b1 02 85 0b 09 0b 95 02 b1 02 85 11 09 11 b1 02 85 15 09 15 95 05 b1 02 85 18 09 18 95 0c b1 02 c0 05 0d 09 04 a1 01 85 03 06 00 ff 09 01 75 10 95 01 15 00 27 ff ff 00 00 81 02 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 09 32 81 02 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 54 95 01 75 08 81 02 09 56 75 20 95 01 27 ff ff ff 0f 81 02 85 04 09 55 75 08 95 01 25 0b b1 02 85 0a 06 00 ff 09 03 15 00 b1 02 85 1b 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0", 80762306a36Sopenharmony_ci ) 80862306a36Sopenharmony_ci 80962306a36Sopenharmony_ci 81062306a36Sopenharmony_ciclass Testn_trig_1b96_0c03(BaseTest.TestTablet): 81162306a36Sopenharmony_ci def create_device(self): 81262306a36Sopenharmony_ci return PenDigitizer( 81362306a36Sopenharmony_ci "uhid test n_trig_1b96_0c03", 81462306a36Sopenharmony_ci rdesc="75 08 15 00 26 ff 00 06 0b ff 09 0b a1 01 95 0f 09 29 85 29 b1 02 95 1f 09 2a 85 2a b1 02 95 3e 09 2b 85 2b b1 02 95 fe 09 2c 85 2c b1 02 96 fe 01 09 2d 85 2d b1 02 95 02 09 48 85 48 b1 02 95 0f 09 2e 85 2e 81 02 95 1f 09 2f 85 2f 81 02 95 3e 09 30 85 30 81 02 95 fe 09 31 85 31 81 02 96 fe 01 09 32 85 32 81 02 75 08 96 fe 0f 09 35 85 35 81 02 c0 05 0d 09 02 a1 01 85 01 09 20 35 00 a1 00 09 32 09 42 09 44 09 3c 09 45 15 00 25 01 75 01 95 05 81 02 95 03 81 03 05 01 09 30 75 10 95 01 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 b4 05 0d 09 30 26 00 01 81 02 06 00 ff 09 01 81 02 c0 85 0c 06 00 ff 09 0c 75 08 95 06 26 ff 00 b1 02 85 0b 09 0b 95 02 b1 02 85 11 09 11 b1 02 85 15 09 15 95 05 b1 02 85 18 09 18 95 0c b1 02 c0 05 0d 09 04 a1 01 85 03 06 00 ff 09 01 75 10 95 01 15 00 27 ff ff 00 00 81 02 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 15 0a 26 80 25 81 02 09 31 46 b4 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 54 95 01 75 08 81 02 09 56 75 20 95 01 27 ff ff ff 0f 81 02 85 04 09 55 75 08 95 01 25 0b b1 02 85 0a 06 00 ff 09 03 15 00 b1 02 85 1b 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0", 81562306a36Sopenharmony_ci ) 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ciclass Testn_trig_1b96_0f00(BaseTest.TestTablet): 81962306a36Sopenharmony_ci def create_device(self): 82062306a36Sopenharmony_ci return PenDigitizer( 82162306a36Sopenharmony_ci "uhid test n_trig_1b96_0f00", 82262306a36Sopenharmony_ci rdesc="75 08 15 00 26 ff 00 06 0b ff 09 0b a1 01 95 0f 09 29 85 29 b1 02 95 1f 09 2a 85 2a b1 02 95 3e 09 2b 85 2b b1 02 95 fe 09 2c 85 2c b1 02 96 fe 01 09 2d 85 2d b1 02 95 02 09 48 85 48 b1 02 95 0f 09 2e 85 2e 81 02 95 1f 09 2f 85 2f 81 02 95 3e 09 30 85 30 81 02 95 fe 09 31 85 31 81 02 96 fe 01 09 32 85 32 81 02 75 08 96 fe 0f 09 35 85 35 81 02 c0 05 0d 09 02 a1 01 85 01 09 20 35 00 a1 00 09 32 09 42 09 44 09 3c 09 45 15 00 25 01 75 01 95 05 81 02 95 03 81 03 05 01 09 30 75 10 95 01 a4 55 0e 65 11 46 03 0a 26 80 25 81 02 09 31 46 a1 05 26 20 1c 81 02 b4 05 0d 09 30 26 00 01 81 02 06 00 ff 09 01 81 02 c0 85 0c 06 00 ff 09 0c 75 08 95 06 26 ff 00 b1 02 85 0b 09 0b 95 02 b1 02 85 11 09 11 b1 02 85 15 09 15 95 05 b1 02 85 18 09 18 95 0c b1 02 c0 05 0d 09 04 a1 01 85 03 06 00 ff 09 01 75 10 95 01 15 00 27 ff ff 00 00 81 02 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 03 0a 26 80 25 81 02 09 31 46 a1 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 03 0a 26 80 25 81 02 09 31 46 a1 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 54 95 01 75 08 81 02 09 56 75 20 95 01 27 ff ff ff 0f 81 02 85 04 09 55 75 08 95 01 25 0b b1 02 85 0a 06 00 ff 09 03 15 00 b1 02 85 1b 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0", 82362306a36Sopenharmony_ci ) 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ciclass Testn_trig_1b96_0f04(BaseTest.TestTablet): 82762306a36Sopenharmony_ci def create_device(self): 82862306a36Sopenharmony_ci return PenDigitizer( 82962306a36Sopenharmony_ci "uhid test n_trig_1b96_0f04", 83062306a36Sopenharmony_ci rdesc="75 08 15 00 26 ff 00 06 0b ff 09 0b a1 01 95 0f 09 29 85 29 b1 02 95 1f 09 2a 85 2a b1 02 95 3e 09 2b 85 2b b1 02 95 fe 09 2c 85 2c b1 02 96 fe 01 09 2d 85 2d b1 02 95 02 09 48 85 48 b1 02 95 0f 09 2e 85 2e 81 02 95 1f 09 2f 85 2f 81 02 95 3e 09 30 85 30 81 02 95 fe 09 31 85 31 81 02 96 fe 01 09 32 85 32 81 02 75 08 96 fe 0f 09 35 85 35 81 02 c0 05 0d 09 02 a1 01 85 01 09 20 35 00 a1 00 09 32 09 42 09 44 09 3c 09 45 15 00 25 01 75 01 95 05 81 02 95 03 81 03 05 01 09 30 75 10 95 01 a4 55 0e 65 11 46 7f 0b 26 80 25 81 02 09 31 46 78 06 26 20 1c 81 02 b4 05 0d 09 30 26 00 01 81 02 06 00 ff 09 01 81 02 c0 85 0c 06 00 ff 09 0c 75 08 95 06 26 ff 00 b1 02 85 0b 09 0b 95 02 b1 02 85 11 09 11 b1 02 85 15 09 15 95 05 b1 02 85 18 09 18 95 0c b1 02 c0 05 0d 09 04 a1 01 85 03 06 00 ff 09 01 75 10 95 01 15 00 27 ff ff 00 00 81 02 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 7f 0b 26 80 25 81 02 09 31 46 78 06 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 7f 0b 26 80 25 81 02 09 31 46 78 06 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 54 95 01 75 08 81 02 09 56 75 20 95 01 27 ff ff ff 0f 81 02 85 04 09 55 75 08 95 01 25 0b b1 02 85 0a 06 00 ff 09 03 15 00 b1 02 85 1b 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0", 83162306a36Sopenharmony_ci ) 83262306a36Sopenharmony_ci 83362306a36Sopenharmony_ci 83462306a36Sopenharmony_ciclass Testn_trig_1b96_1000(BaseTest.TestTablet): 83562306a36Sopenharmony_ci def create_device(self): 83662306a36Sopenharmony_ci return PenDigitizer( 83762306a36Sopenharmony_ci "uhid test n_trig_1b96_1000", 83862306a36Sopenharmony_ci rdesc="75 08 15 00 26 ff 00 06 0b ff 09 0b a1 01 95 0f 09 29 85 29 b1 02 95 1f 09 2a 85 2a b1 02 95 3e 09 2b 85 2b b1 02 95 fe 09 2c 85 2c b1 02 96 fe 01 09 2d 85 2d b1 02 95 02 09 48 85 48 b1 02 95 0f 09 2e 85 2e 81 02 95 1f 09 2f 85 2f 81 02 95 3e 09 30 85 30 81 02 95 fe 09 31 85 31 81 02 96 fe 01 09 32 85 32 81 02 75 08 96 fe 0f 09 35 85 35 81 02 c0 05 0d 09 02 a1 01 85 01 09 20 35 00 a1 00 09 32 09 42 09 44 09 3c 09 45 15 00 25 01 75 01 95 05 81 02 95 03 81 03 05 01 09 30 75 10 95 01 a4 55 0e 65 11 46 03 0a 26 80 25 81 02 09 31 46 a1 05 26 20 1c 81 02 b4 05 0d 09 30 26 00 01 81 02 06 00 ff 09 01 81 02 c0 85 0c 06 00 ff 09 0c 75 08 95 06 26 ff 00 b1 02 85 0b 09 0b 95 02 b1 02 85 11 09 11 b1 02 85 15 09 15 95 05 b1 02 85 18 09 18 95 0c b1 02 c0 05 0d 09 04 a1 01 85 03 06 00 ff 09 01 75 10 95 01 15 00 27 ff ff 00 00 81 02 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 03 0a 26 80 25 81 02 09 31 46 a1 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 01 81 03 09 47 81 02 95 05 81 03 75 10 09 51 27 ff ff 00 00 95 01 81 02 05 01 09 30 75 10 95 02 a4 55 0e 65 11 46 03 0a 26 80 25 81 02 09 31 46 a1 05 26 20 1c 81 02 05 0d 09 48 95 01 26 80 25 81 02 09 49 26 20 1c 81 02 b4 06 00 ff 09 02 75 08 95 04 15 00 26 ff 00 81 02 c0 05 0d 09 54 95 01 75 08 81 02 09 56 75 20 95 01 27 ff ff ff 0f 81 02 85 04 09 55 75 08 95 01 25 0b b1 02 85 0a 06 00 ff 09 03 15 00 b1 02 85 1b 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 02 15 00 25 01 75 01 95 02 81 02 95 06 81 03 05 01 09 30 09 31 15 81 25 7f 75 08 95 02 81 06 c0 c0", 83962306a36Sopenharmony_ci ) 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ciclass TestGXTP_27c6_0113(BaseTest.TestTablet): 84362306a36Sopenharmony_ci def create_device(self): 84462306a36Sopenharmony_ci return GXTP_pen( 84562306a36Sopenharmony_ci "uhid test GXTP_27c6_0113", 84662306a36Sopenharmony_ci rdesc="05 0d 09 04 a1 01 85 01 09 22 a1 02 55 0e 65 11 35 00 15 00 09 42 25 01 75 01 95 01 81 02 95 07 81 01 95 01 75 08 09 51 81 02 75 10 05 01 26 00 14 46 1f 07 09 30 81 02 26 80 0c 46 77 04 09 31 81 02 05 0d c0 09 22 a1 02 09 42 25 01 75 01 95 01 81 02 95 07 81 01 95 01 75 08 09 51 81 02 75 10 05 01 26 00 14 46 1f 07 09 30 81 02 26 80 0c 46 77 04 09 31 81 02 05 0d c0 09 22 a1 02 09 42 25 01 75 01 95 01 81 02 95 07 81 01 95 01 75 08 09 51 81 02 75 10 05 01 26 00 14 46 1f 07 09 30 81 02 26 80 0c 46 77 04 09 31 81 02 05 0d c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 07 81 01 75 08 09 51 95 01 81 02 05 01 26 00 14 75 10 55 0e 65 11 09 30 35 00 46 1f 07 81 02 26 80 0c 46 77 04 09 31 81 02 05 0d c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 95 07 81 01 75 08 09 51 95 01 81 02 05 01 26 00 14 75 10 55 0e 65 11 09 30 35 00 46 1f 07 81 02 26 80 0c 46 77 04 09 31 81 02 05 0d c0 09 54 15 00 25 7f 75 08 95 01 81 02 85 02 09 55 95 01 25 0a b1 02 85 03 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 02 a1 01 85 08 09 20 a1 00 09 42 09 44 09 3c 09 45 15 00 25 01 75 01 95 04 81 02 95 01 81 03 09 32 81 02 95 02 81 03 95 01 75 08 09 51 81 02 05 01 09 30 75 10 95 01 a4 55 0e 65 11 35 00 26 00 14 46 1f 07 81 42 09 31 26 80 0c 46 77 04 81 42 b4 05 0d 09 30 26 ff 0f 81 02 09 3d 65 14 55 0e 36 d8 dc 46 28 23 16 d8 dc 26 28 23 81 02 09 3e 81 02 c0 c0 06 f0 ff 09 01 a1 01 85 0e 09 01 15 00 25 ff 75 08 95 40 91 02 09 01 15 00 25 ff 75 08 95 40 81 02 c0 05 01 09 06 a1 01 85 04 05 07 09 e3 15 00 25 01 75 01 95 01 81 02 95 07 81 03 c0", 84762306a36Sopenharmony_ci ) 84862306a36Sopenharmony_ci 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci################################################################################ 85162306a36Sopenharmony_ci# 85262306a36Sopenharmony_ci# Windows 8 compatible devices with USI Pen 85362306a36Sopenharmony_ci# 85462306a36Sopenharmony_ci################################################################################ 85562306a36Sopenharmony_ci 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ciclass TestElan_04f3_2A49(BaseTest.TestTablet): 85862306a36Sopenharmony_ci def create_device(self): 85962306a36Sopenharmony_ci return USIPen( 86062306a36Sopenharmony_ci "uhid test Elan_04f3_2A49", 86162306a36Sopenharmony_ci rdesc="05 0d 09 04 a1 01 85 01 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 75 01 81 03 75 06 09 51 25 3f 81 02 26 ff 00 75 08 55 0f 65 11 35 00 45 ff 09 48 81 02 09 49 81 02 09 30 81 02 95 01 05 01 a4 26 cf 0f 75 10 55 0f 65 11 09 30 35 00 46 26 01 95 01 81 02 26 77 0a 46 a6 00 09 31 81 02 b4 c0 05 0d 09 22 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 75 01 81 03 75 06 09 51 25 3f 81 02 26 ff 00 75 08 55 0f 65 11 35 00 45 ff 09 48 81 02 09 49 81 02 09 30 81 02 95 01 05 01 a4 26 cf 0f 75 10 55 0f 65 11 09 30 35 00 46 26 01 95 01 81 02 26 77 0a 46 a6 00 09 31 81 02 b4 c0 05 0d 09 22 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 75 01 81 03 75 06 09 51 25 3f 81 02 26 ff 00 75 08 55 0f 65 11 35 00 45 ff 09 48 81 02 09 49 81 02 09 30 81 02 95 01 05 01 a4 26 cf 0f 75 10 55 0f 65 11 09 30 35 00 46 26 01 95 01 81 02 26 77 0a 46 a6 00 09 31 81 02 b4 c0 05 0d 09 22 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 75 01 81 03 75 06 09 51 25 3f 81 02 26 ff 00 75 08 55 0f 65 11 35 00 45 ff 09 48 81 02 09 49 81 02 09 30 81 02 95 01 05 01 a4 26 cf 0f 75 10 55 0f 65 11 09 30 35 00 46 26 01 95 01 81 02 26 77 0a 46 a6 00 09 31 81 02 b4 c0 05 0d 09 22 a1 02 05 0d 09 42 15 00 25 01 75 01 95 01 81 02 75 01 81 03 75 06 09 51 25 3f 81 02 26 ff 00 75 08 55 0f 65 11 35 00 45 ff 09 48 81 02 09 49 81 02 09 30 81 02 95 01 05 01 a4 26 cf 0f 75 10 55 0f 65 11 09 30 35 00 46 26 01 95 01 81 02 26 77 0a 46 a6 00 09 31 81 02 b4 c0 05 0d 09 54 25 7f 96 01 00 75 08 81 02 85 0a 09 55 25 0a b1 02 85 44 06 00 ff 09 c5 16 00 00 26 ff 00 75 08 96 00 01 b1 02 c0 06 ff 01 09 01 a1 01 85 02 16 00 00 26 ff 00 75 08 95 40 09 00 81 02 c0 06 00 ff 09 01 a1 01 85 03 75 08 95 20 09 01 91 02 c0 06 00 ff 09 01 a1 01 85 06 09 03 75 08 95 12 91 02 09 04 75 08 95 03 b1 02 c0 06 01 ff 09 01 a1 01 85 04 15 00 26 ff 00 75 08 95 13 09 00 81 02 c0 05 0d 09 02 a1 01 85 07 35 00 09 20 a1 00 09 32 09 42 09 44 09 3c 09 45 15 00 25 01 75 01 95 05 81 02 95 03 81 03 05 01 09 30 75 10 95 01 a4 55 0f 65 11 46 26 01 26 1c 48 81 42 09 31 46 a6 00 26 bc 2f 81 42 b4 05 0d 09 30 26 00 10 81 02 75 08 95 01 09 3b 25 64 81 42 09 38 15 00 25 02 81 02 09 5c 26 ff 00 81 02 09 5e 81 02 09 70 a1 02 15 01 25 06 09 72 09 73 09 74 09 75 09 76 09 77 81 20 09 5b 25 ff 75 40 81 02 c0 06 00 ff 75 08 95 02 09 01 81 02 c0 05 0d 85 60 09 81 a1 02 09 38 75 08 95 01 15 00 25 02 81 02 09 81 15 01 25 04 09 82 09 83 09 84 09 85 81 20 c0 85 61 09 5c a1 02 15 00 26 ff 00 75 08 95 01 09 38 b1 02 09 5c 26 ff 00 b1 02 09 5d 75 01 95 01 25 01 b1 02 95 07 b1 03 c0 85 62 09 5e a1 02 09 38 15 00 25 02 75 08 95 01 b1 02 09 5e 26 ff 00 b1 02 09 5f 75 01 25 01 b1 02 75 07 b1 03 c0 85 63 09 70 a1 02 75 08 95 01 15 00 25 02 09 38 b1 02 09 70 a1 02 25 06 09 72 09 73 09 74 09 75 09 76 09 77 b1 20 c0 09 71 75 01 25 01 b1 02 75 07 b1 03 c0 85 64 09 80 15 00 25 ff 75 40 95 01 b1 02 85 65 09 44 a1 02 09 38 75 08 95 01 25 02 b1 02 15 01 25 03 09 44 a1 02 09 a4 09 44 09 5a 09 45 09 a3 b1 20 c0 09 5a a1 02 09 a4 09 44 09 5a 09 45 09 a3 b1 20 c0 09 45 a1 02 09 a4 09 44 09 5a 09 45 09 a3 b1 20 c0 c0 85 66 75 08 95 01 05 0d 09 90 a1 02 09 38 25 02 b1 02 09 91 75 10 26 ff 0f b1 02 09 92 75 40 25 ff b1 02 05 06 09 2a 75 08 26 ff 00 a1 02 09 2d b1 02 09 2e b1 02 c0 c0 85 67 05 06 09 2b a1 02 05 0d 25 02 09 38 b1 02 05 06 09 2b a1 02 09 2d 26 ff 00 b1 02 09 2e b1 02 c0 c0 85 68 06 00 ff 09 01 a1 02 05 0d 09 38 75 08 95 01 25 02 b1 02 06 00 ff 09 01 75 10 27 ff ff 00 00 b1 02 c0 85 69 05 0d 09 38 75 08 95 01 15 00 25 02 b1 02 c0 06 00 ff 09 81 a1 01 85 17 75 08 95 1f 09 05 81 02 c0", 86262306a36Sopenharmony_ci input_info=(BusType.I2C, 0x04F3, 0x2A49), 86362306a36Sopenharmony_ci ) 86462306a36Sopenharmony_ci 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ciclass TestGoodix_27c6_0e00(BaseTest.TestTablet): 86762306a36Sopenharmony_ci def create_device(self): 86862306a36Sopenharmony_ci return USIPen( 86962306a36Sopenharmony_ci "uhid test Elan_04f3_2A49", 87062306a36Sopenharmony_ci rdesc="05 0d 09 04 a1 01 85 01 09 22 a1 02 55 0e 65 11 35 00 15 00 09 42 25 01 75 01 95 01 81 02 25 7f 09 30 75 07 81 42 95 01 75 08 09 51 81 02 75 10 05 01 26 04 20 46 e6 09 09 30 81 02 26 60 15 46 9a 06 09 31 81 02 05 0d 55 0f 75 08 25 ff 45 ff 09 48 81 42 09 49 81 42 55 0e c0 09 22 a1 02 09 42 25 01 75 01 95 01 81 02 25 7f 09 30 75 07 81 42 95 01 75 08 09 51 81 02 75 10 05 01 26 04 20 46 e6 09 09 30 81 02 26 60 15 46 9a 06 09 31 81 02 05 0d 55 0f 75 08 25 ff 45 ff 09 48 81 42 09 49 81 42 55 0e c0 09 22 a1 02 09 42 25 01 75 01 95 01 81 02 25 7f 09 30 75 07 81 42 95 01 75 08 09 51 81 02 75 10 05 01 26 04 20 46 e6 09 09 30 81 02 26 60 15 46 9a 06 09 31 81 02 05 0d 55 0f 75 08 25 ff 45 ff 09 48 81 42 09 49 81 42 55 0e c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 25 7f 09 30 75 07 81 42 75 08 09 51 95 01 81 02 05 01 26 04 20 75 10 55 0e 65 11 09 30 35 00 46 e6 09 81 02 26 60 15 46 9a 06 09 31 81 02 05 0d 55 0f 75 08 25 ff 45 ff 09 48 81 42 09 49 81 42 55 0e c0 09 22 a1 02 09 42 15 00 25 01 75 01 95 01 81 02 25 7f 09 30 75 07 81 42 75 08 09 51 95 01 81 02 05 01 26 04 20 75 10 55 0e 65 11 09 30 35 00 46 e6 09 81 02 26 60 15 46 9a 06 09 31 81 02 05 0d 55 0f 75 08 25 ff 45 ff 09 48 81 42 09 49 81 42 55 0e c0 09 54 15 00 25 7f 75 08 95 01 81 02 85 02 09 55 95 01 25 0a b1 02 85 03 06 00 ff 09 c5 15 00 26 ff 00 75 08 96 00 01 b1 02 c0 05 0d 09 02 a1 01 09 20 a1 00 85 08 05 01 a4 09 30 35 00 46 e6 09 15 00 26 04 20 55 0d 65 13 75 10 95 01 81 02 09 31 46 9a 06 26 60 15 81 02 b4 05 0d 09 38 95 01 75 08 15 00 25 01 81 02 09 30 75 10 26 ff 0f 81 02 09 31 81 02 09 42 09 44 09 5a 09 3c 09 45 09 32 75 01 95 06 25 01 81 02 95 02 81 03 09 3d 55 0e 65 14 36 d8 dc 46 28 23 16 d8 dc 26 28 23 95 01 75 10 81 02 09 3e 81 02 09 41 15 00 27 a0 8c 00 00 35 00 47 a0 8c 00 00 81 02 05 20 0a 53 04 65 00 16 01 f8 26 ff 07 75 10 95 01 81 02 0a 54 04 81 02 0a 55 04 81 02 0a 57 04 81 02 0a 58 04 81 02 0a 59 04 81 02 0a 72 04 81 02 0a 73 04 81 02 0a 74 04 81 02 05 0d 09 3b 15 00 25 64 75 08 81 02 09 5b 25 ff 75 40 81 02 06 00 ff 09 5b 75 20 81 02 05 0d 09 5c 26 ff 00 75 08 81 02 09 5e 81 02 09 70 a1 02 15 01 25 06 09 72 09 73 09 74 09 75 09 76 09 77 81 20 c0 06 00 ff 09 01 15 00 27 ff ff 00 00 75 10 95 01 81 02 85 09 09 81 a1 02 09 81 15 01 25 04 09 82 09 83 09 84 09 85 81 20 c0 85 10 09 5c a1 02 15 00 25 01 75 08 95 01 09 38 b1 02 09 5c 26 ff 00 b1 02 09 5d 75 01 95 01 25 01 b1 02 95 07 b1 03 c0 85 11 09 5e a1 02 09 38 15 00 25 01 75 08 95 01 b1 02 09 5e 26 ff 00 b1 02 09 5f 75 01 25 01 b1 02 75 07 b1 03 c0 85 12 09 70 a1 02 75 08 95 01 15 00 25 01 09 38 b1 02 09 70 a1 02 25 06 09 72 09 73 09 74 09 75 09 76 09 77 b1 20 c0 09 71 75 01 25 01 b1 02 75 07 b1 03 c0 85 13 09 80 15 00 25 ff 75 40 95 01 b1 02 85 14 09 44 a1 02 09 38 75 08 95 01 25 01 b1 02 15 01 25 03 09 44 a1 02 09 a4 09 44 09 5a 09 45 09 a3 b1 20 c0 09 5a a1 02 09 a4 09 44 09 5a 09 45 09 a3 b1 20 c0 09 45 a1 02 09 a4 09 44 09 5a 09 45 09 a3 b1 20 c0 c0 85 15 75 08 95 01 05 0d 09 90 a1 02 09 38 25 01 b1 02 09 91 75 10 26 ff 0f b1 02 09 92 75 40 25 ff b1 02 05 06 09 2a 75 08 26 ff 00 a1 02 09 2d b1 02 09 2e b1 02 c0 c0 85 16 05 06 09 2b a1 02 05 0d 25 01 09 38 b1 02 05 06 09 2b a1 02 09 2d 26 ff 00 b1 02 09 2e b1 02 c0 c0 85 17 06 00 ff 09 01 a1 02 05 0d 09 38 75 08 95 01 25 01 b1 02 06 00 ff 09 01 75 10 27 ff ff 00 00 b1 02 c0 85 18 05 0d 09 38 75 08 95 01 15 00 25 01 b1 02 c0 c0 06 f0 ff 09 01 a1 01 85 0e 09 01 15 00 25 ff 75 08 95 40 91 02 09 01 15 00 25 ff 75 08 95 40 81 02 c0", 87162306a36Sopenharmony_ci input_info=(BusType.I2C, 0x27C6, 0x0E00), 87262306a36Sopenharmony_ci ) 873