tests_kernel.test_tablet module — hid-tools documentation

# tests_kernel.test_tablet module

class BaseTest

  Bases: `object`

  class TestTablet

    Bases: `TestUhid`

    create_device()
    post(uhdev, pen, test_button)
    test_tolerated_broken_pen_states(state_list, scribble)

      Those tests are definitely not part of the Windows specification. However, a half broken device might export those transitions. For example, a pen that has the eraser button might wobble between touching and erasing if the tablet doesn’t enforce the Windows state machine.

    test_tolerated_invert_pen_states(state_list, scribble)

      This is the second half of the Windows Pen Implementation state machine: we now have Invert and Erase bits, so move in/out or proximity with the intend to erase. https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states

    test_tolerated_pen_states(state_list, scribble)

      This is not adhering to the Windows Pen Implementation state machine but we should expect the kernel to behave properly, mostly for historical reasons.

    test_valid_invert_pen_states(state_list, scribble)

      This is the second half of the Windows Pen Implementation state machine: we now have Invert and Erase bits, so move in/out or proximity with the intend to erase. https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states

    test_valid_pen_states(state_list, scribble)

      This is the first half of the Windows Pen Implementation state machine: we don’t have Invert nor Erase bits, so just move in/out-of-range or proximity. https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states

    test_valid_primary_button_pen_states(state_list, scribble)

      Rework the transition state machine by adding the primary button.

    test_valid_secondary_button_pen_states(state_list, scribble)

      Rework the transition state machine by adding the secondary button.

    test_valid_third_button_pen_states(state_list, scribble)

      Rework the transition state machine by adding the secondary button.

    validate_transitions(from_state, pen, evdev, events, allow_intermediate_states, button)

class BtnPressed(*values)

  Bases: `Enum`

  Represents whether a button is pressed on the stylus

  PRIMARY_PRESSED = BTN_STYLUS:331
  SECONDARY_PRESSED = BTN_STYLUS2:332
  THIRD_PRESSED = BTN_STYLUS3:329

class BtnTouch(*values)

  Bases: `Enum`

  Represents whether the BTN_TOUCH event is set to True or False

  DOWN = True
  UP = False

class GXTP_pen(name, rdesc_str=None, rdesc=None, application='Pen', physical='Stylus', input_info=(BusType.USB, 1, 2), evdev_name_suffix=None)

  Bases: `PenDigitizer`

  event(pen, test_button)

class Huion_Kamvas_Pro_19_256c_006b(name, rdesc_str=None, rdesc=None, application='Stylus', physical=None, input_info=(BusType.USB, 9580, 107), evdev_name_suffix=None)

  Bases: `PenDigitizer`

  Pen that reports secondary barrel switch through secondary TipSwtich and 3rd button through Invert

  call_input_event(report)

    Send an input event from this device.

    Parameters:

      data (list) – a list of 8-bit integers representing the HID report for this input event

  event(pen, button)
  move_to(pen, state, button, debug=True)
  send_intermediate_state(pen, state, test_button)

class Pen(x, y)

  Bases: `object`

  assert_expected_input_events(evdev, button)
  backup()
  restore()

class PenDigitizer(name, rdesc_str=None, rdesc=None, application='Pen', physical='Stylus', input_info=(BusType.USB, 1, 2), evdev_name_suffix=None)

  Bases: `UHIDTestDevice`

  event(pen, button)
  get_report(req, rnum, rtype)

    Callback invoked when a process calls SetReport on this UHID device.

    Return `(0, [data bytes])` on success or `(errno, [])` on failure.

    The default method always returns `(EIO, [])` for a failure. Override this in your device if you want GetReport to succeed.

    Parameters:

      - req – the request identifier

      - rnum –

        ???

      - rtype – one of `UHID_FEATURE_REPORT`, `UHID_INPUT_REPORT`, or `UHID_OUTPUT_REPORT`

  move_to(pen, state, button)
  set_report(req, rnum, rtype, data)

    Callback invoked when a process calls SetReport on this UHID device.

    Return `0` on success or an errno on failure.

    The default method always returns `EIO` for a failure. Override this in your device if you want SetReport to succeed.

    Parameters:

      - req – the request identifier

      - rnum –

        ???

      - rtype – one of `UHID_FEATURE_REPORT`, `UHID_INPUT_REPORT`, or `UHID_OUTPUT_REPORT`

      - data (list) – a byte string with the data

class PenState(*values)

  Bases: `Enum`

  Pen states according to Microsoft reference: https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states

  We extend it with the various buttons when we need to check them.

  PEN_IS_ERASING = (BtnTouch.DOWN, ToolType.RUBBER, False)
  PEN_IS_ERASING_WITH_BUTTON = (BtnTouch.DOWN, ToolType.RUBBER, True)
  PEN_IS_IN_CONTACT = (BtnTouch.DOWN, ToolType.PEN, False)
  PEN_IS_IN_CONTACT_WITH_BUTTON = (BtnTouch.DOWN, ToolType.PEN, True)
  PEN_IS_IN_RANGE = (BtnTouch.UP, ToolType.PEN, False)
  PEN_IS_IN_RANGE_WITH_BUTTON = (BtnTouch.UP, ToolType.PEN, True)
  PEN_IS_IN_RANGE_WITH_ERASING_INTENT = (BtnTouch.UP, ToolType.RUBBER, False)
  PEN_IS_IN_RANGE_WITH_ERASING_INTENT_WITH_BUTTON = (BtnTouch.UP, ToolType.RUBBER, True)
  PEN_IS_OUT_OF_RANGE = (BtnTouch.UP, None, False)
  apply(events: list[InputEvent], strict: bool, test_button: BtnPressed) → PenState
  static broken_transitions() → dict[str, Tuple[PenState, ...]]

    Those tests are definitely not part of the Windows specification. However, a half broken device might export those transitions. For example, a pen that has the eraser button might wobble between touching and erasing if the tablet doesn’t enforce the Windows state machine.

  classmethod from_evdev(evdev, test_button) → PenState
  historically_tolerated_transitions() → Tuple[PenState, ...]

    Following the state machine in the URL above, with a couple of addition for skipping the in-range state, due to historical reasons.

    Note that those transitions are from the evdev point of view, not HID

  static legal_transitions() → dict[str, Tuple[PenState, ...]]

    This is the first half of the Windows Pen Implementation state machine: we don’t have Invert nor Erase bits, so just move in/out-of-range or proximity. https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states

  static legal_transitions_with_button() → dict[str, Tuple[PenState, ...]]

    We revisit the Windows Pen Implementation state machine: we now have a button.

  static legal_transitions_with_invert() → dict[str, Tuple[PenState, ...]]

    This is the second half of the Windows Pen Implementation state machine: we now have Invert and Erase bits, so move in/out or proximity with the intend to erase. https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states

  static tolerated_transitions() → dict[str, Tuple[PenState, ...]]

    This is not adhering to the Windows Pen Implementation state machine but we should expect the kernel to behave properly, mostly for historical reasons.

  static tolerated_transitions_with_invert() → dict[str, Tuple[PenState, ...]]

    This is the second half of the Windows Pen Implementation state machine: we now have Invert and Erase bits, so move in/out or proximity with the intend to erase. https://docs.microsoft.com/en-us/windows-hardware/design/component-guidelines/windows-pen-states

  valid_transitions() → Tuple[PenState, ...]

    Following the state machine in the URL above.

    Note that those transitions are from the evdev point of view, not HID

class TestElan_04f3_2A49

  Bases: `TestTablet`

  create_device()

class TestGXTP_27c6_0113

  Bases: `TestTablet`

  create_device()

class TestGoodix_27c6_0e00

  Bases: `TestTablet`

  create_device()

class TestHuion_Kamvas_Pro_19_256c_006b

  Bases: `TestTablet`

  create_device()
  hid_bpfs: list[HidBpf] = [HidBpf(object_name='Huion__Kamvas-Pro-19.bpf.o', has_rdesc_fixup=True)]

class TestNexio_1870_0100

  Bases: `TestTablet`

  create_device()

class TestNexio_1870_010d

  Bases: `TestTablet`

  create_device()

class TestNexio_1870_0119

  Bases: `TestTablet`

  create_device()

class TestXPPen_Artist24_28bd_093a

  Bases: `TestTablet`

  create_device()
  hid_bpfs: list[HidBpf] = [HidBpf(object_name='XPPen__Artist24.bpf.o', has_rdesc_fixup=True)]

class TestXPPen_ArtistPro16Gen2_28bd_095b

  Bases: `TestTablet`

  create_device()
  hid_bpfs: list[HidBpf] = [HidBpf(object_name='XPPen__ArtistPro16Gen2.bpf.o', has_rdesc_fixup=True)]

class Testatmel_03eb_840b

  Bases: `TestTablet`

  create_device()

class Testn_trig_1b96_0c01

  Bases: `TestTablet`

  create_device()

class Testn_trig_1b96_0c03

  Bases: `TestTablet`

  create_device()

class Testn_trig_1b96_0f00

  Bases: `TestTablet`

  create_device()

class Testn_trig_1b96_0f04

  Bases: `TestTablet`

  create_device()

class Testn_trig_1b96_1000

  Bases: `TestTablet`

  create_device()

class ToolType(*values)

  Bases: `Enum`

  PEN = BTN_TOOL_PEN:320
  RUBBER = BTN_TOOL_RUBBER:321

class USIPen(name, rdesc_str=None, rdesc=None, application='Pen', physical='Stylus', input_info=(BusType.USB, 1, 2), evdev_name_suffix=None)

  Bases: `PenDigitizer`

class XPPen_Artist24_28bd_093a(name, rdesc_str=None, rdesc=None, application='Pen', physical='Stylus', input_info=(BusType.USB, 10429, 2362), evdev_name_suffix=None)

  Bases: `PenDigitizer`

  Pen that reports secondary barrel switch through eraser

  event(pen, button)
  move_to(pen, state, button, debug=True)
  send_intermediate_state(pen, state, button)

class XPPen_ArtistPro16Gen2_28bd_095b(name, rdesc_str=None, rdesc=None, application='Pen', physical='Stylus', input_info=(BusType.USB, 10429, 2395), evdev_name_suffix=None)

  Bases: `PenDigitizer`

  Pen with two buttons and a rubber end, but which reports the second button as an eraser

  event(pen, test_button)
  move_to(pen, state, button)