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