1*b2c4944eSBenjamin Tissoires#!/bin/env python3 2*b2c4944eSBenjamin Tissoires# SPDX-License-Identifier: GPL-2.0 3*b2c4944eSBenjamin Tissoires# -*- coding: utf-8 -*- 4*b2c4944eSBenjamin Tissoires# 5*b2c4944eSBenjamin Tissoires# Copyright (c) 2018 Benjamin Tissoires <benjamin.tissoires@gmail.com> 6*b2c4944eSBenjamin Tissoires# Copyright (c) 2018 Red Hat, Inc. 7*b2c4944eSBenjamin Tissoires# 8*b2c4944eSBenjamin Tissoires 9*b2c4944eSBenjamin Tissoiresfrom . import base 10*b2c4944eSBenjamin Tissoiresimport hidtools.hid 11*b2c4944eSBenjamin Tissoiresimport libevdev 12*b2c4944eSBenjamin Tissoiresimport logging 13*b2c4944eSBenjamin Tissoires 14*b2c4944eSBenjamin Tissoireslogger = logging.getLogger("hidtools.test.keyboard") 15*b2c4944eSBenjamin Tissoires 16*b2c4944eSBenjamin Tissoires 17*b2c4944eSBenjamin Tissoiresclass InvalidHIDCommunication(Exception): 18*b2c4944eSBenjamin Tissoires pass 19*b2c4944eSBenjamin Tissoires 20*b2c4944eSBenjamin Tissoires 21*b2c4944eSBenjamin Tissoiresclass KeyboardData(object): 22*b2c4944eSBenjamin Tissoires pass 23*b2c4944eSBenjamin Tissoires 24*b2c4944eSBenjamin Tissoires 25*b2c4944eSBenjamin Tissoiresclass BaseKeyboard(base.UHIDTestDevice): 26*b2c4944eSBenjamin Tissoires def __init__(self, rdesc, name=None, input_info=None): 27*b2c4944eSBenjamin Tissoires assert rdesc is not None 28*b2c4944eSBenjamin Tissoires super().__init__(name, "Key", input_info=input_info, rdesc=rdesc) 29*b2c4944eSBenjamin Tissoires self.keystates = {} 30*b2c4944eSBenjamin Tissoires 31*b2c4944eSBenjamin Tissoires def _update_key_state(self, keys): 32*b2c4944eSBenjamin Tissoires """ 33*b2c4944eSBenjamin Tissoires Update the internal state of keys with the new state given. 34*b2c4944eSBenjamin Tissoires 35*b2c4944eSBenjamin Tissoires :param key: a tuple of chars for the currently pressed keys. 36*b2c4944eSBenjamin Tissoires """ 37*b2c4944eSBenjamin Tissoires # First remove the already released keys 38*b2c4944eSBenjamin Tissoires unused_keys = [k for k, v in self.keystates.items() if not v] 39*b2c4944eSBenjamin Tissoires for key in unused_keys: 40*b2c4944eSBenjamin Tissoires del self.keystates[key] 41*b2c4944eSBenjamin Tissoires 42*b2c4944eSBenjamin Tissoires # self.keystates contains now the list of currently pressed keys, 43*b2c4944eSBenjamin Tissoires # release them... 44*b2c4944eSBenjamin Tissoires for key in self.keystates.keys(): 45*b2c4944eSBenjamin Tissoires self.keystates[key] = False 46*b2c4944eSBenjamin Tissoires 47*b2c4944eSBenjamin Tissoires # ...and press those that are in parameter 48*b2c4944eSBenjamin Tissoires for key in keys: 49*b2c4944eSBenjamin Tissoires self.keystates[key] = True 50*b2c4944eSBenjamin Tissoires 51*b2c4944eSBenjamin Tissoires def _create_report_data(self): 52*b2c4944eSBenjamin Tissoires keyboard = KeyboardData() 53*b2c4944eSBenjamin Tissoires for key, value in self.keystates.items(): 54*b2c4944eSBenjamin Tissoires key = key.replace(" ", "").lower() 55*b2c4944eSBenjamin Tissoires setattr(keyboard, key, value) 56*b2c4944eSBenjamin Tissoires return keyboard 57*b2c4944eSBenjamin Tissoires 58*b2c4944eSBenjamin Tissoires def create_array_report(self, keys, reportID=None, application=None): 59*b2c4944eSBenjamin Tissoires """ 60*b2c4944eSBenjamin Tissoires Return an input report for this device. 61*b2c4944eSBenjamin Tissoires 62*b2c4944eSBenjamin Tissoires :param keys: a tuple of chars for the pressed keys. The class maintains 63*b2c4944eSBenjamin Tissoires the list of currently pressed keys, so to release a key, the caller 64*b2c4944eSBenjamin Tissoires needs to call again this function without the key in this tuple. 65*b2c4944eSBenjamin Tissoires :param reportID: the numeric report ID for this report, if needed 66*b2c4944eSBenjamin Tissoires """ 67*b2c4944eSBenjamin Tissoires self._update_key_state(keys) 68*b2c4944eSBenjamin Tissoires reportID = reportID or self.default_reportID 69*b2c4944eSBenjamin Tissoires 70*b2c4944eSBenjamin Tissoires keyboard = self._create_report_data() 71*b2c4944eSBenjamin Tissoires return self.create_report(keyboard, reportID=reportID, application=application) 72*b2c4944eSBenjamin Tissoires 73*b2c4944eSBenjamin Tissoires def event(self, keys, reportID=None, application=None): 74*b2c4944eSBenjamin Tissoires """ 75*b2c4944eSBenjamin Tissoires Send an input event on the default report ID. 76*b2c4944eSBenjamin Tissoires 77*b2c4944eSBenjamin Tissoires :param keys: a tuple of chars for the pressed keys. The class maintains 78*b2c4944eSBenjamin Tissoires the list of currently pressed keys, so to release a key, the caller 79*b2c4944eSBenjamin Tissoires needs to call again this function without the key in this tuple. 80*b2c4944eSBenjamin Tissoires """ 81*b2c4944eSBenjamin Tissoires r = self.create_array_report(keys, reportID, application) 82*b2c4944eSBenjamin Tissoires self.call_input_event(r) 83*b2c4944eSBenjamin Tissoires return [r] 84*b2c4944eSBenjamin Tissoires 85*b2c4944eSBenjamin Tissoires 86*b2c4944eSBenjamin Tissoiresclass PlainKeyboard(BaseKeyboard): 87*b2c4944eSBenjamin Tissoires # fmt: off 88*b2c4944eSBenjamin Tissoires report_descriptor = [ 89*b2c4944eSBenjamin Tissoires 0x05, 0x01, # Usage Page (Generic Desktop) 90*b2c4944eSBenjamin Tissoires 0x09, 0x06, # Usage (Keyboard) 91*b2c4944eSBenjamin Tissoires 0xa1, 0x01, # Collection (Application) 92*b2c4944eSBenjamin Tissoires 0x85, 0x01, # .Report ID (1) 93*b2c4944eSBenjamin Tissoires 0x05, 0x07, # .Usage Page (Keyboard) 94*b2c4944eSBenjamin Tissoires 0x19, 0xe0, # .Usage Minimum (224) 95*b2c4944eSBenjamin Tissoires 0x29, 0xe7, # .Usage Maximum (231) 96*b2c4944eSBenjamin Tissoires 0x15, 0x00, # .Logical Minimum (0) 97*b2c4944eSBenjamin Tissoires 0x25, 0x01, # .Logical Maximum (1) 98*b2c4944eSBenjamin Tissoires 0x75, 0x01, # .Report Size (1) 99*b2c4944eSBenjamin Tissoires 0x95, 0x08, # .Report Count (8) 100*b2c4944eSBenjamin Tissoires 0x81, 0x02, # .Input (Data,Var,Abs) 101*b2c4944eSBenjamin Tissoires 0x19, 0x00, # .Usage Minimum (0) 102*b2c4944eSBenjamin Tissoires 0x29, 0x97, # .Usage Maximum (151) 103*b2c4944eSBenjamin Tissoires 0x15, 0x00, # .Logical Minimum (0) 104*b2c4944eSBenjamin Tissoires 0x25, 0x01, # .Logical Maximum (1) 105*b2c4944eSBenjamin Tissoires 0x75, 0x01, # .Report Size (1) 106*b2c4944eSBenjamin Tissoires 0x95, 0x98, # .Report Count (152) 107*b2c4944eSBenjamin Tissoires 0x81, 0x02, # .Input (Data,Var,Abs) 108*b2c4944eSBenjamin Tissoires 0xc0, # End Collection 109*b2c4944eSBenjamin Tissoires ] 110*b2c4944eSBenjamin Tissoires # fmt: on 111*b2c4944eSBenjamin Tissoires 112*b2c4944eSBenjamin Tissoires def __init__(self, rdesc=report_descriptor, name=None, input_info=None): 113*b2c4944eSBenjamin Tissoires super().__init__(rdesc, name, input_info) 114*b2c4944eSBenjamin Tissoires self.default_reportID = 1 115*b2c4944eSBenjamin Tissoires 116*b2c4944eSBenjamin Tissoires 117*b2c4944eSBenjamin Tissoiresclass ArrayKeyboard(BaseKeyboard): 118*b2c4944eSBenjamin Tissoires # fmt: off 119*b2c4944eSBenjamin Tissoires report_descriptor = [ 120*b2c4944eSBenjamin Tissoires 0x05, 0x01, # Usage Page (Generic Desktop) 121*b2c4944eSBenjamin Tissoires 0x09, 0x06, # Usage (Keyboard) 122*b2c4944eSBenjamin Tissoires 0xa1, 0x01, # Collection (Application) 123*b2c4944eSBenjamin Tissoires 0x05, 0x07, # .Usage Page (Keyboard) 124*b2c4944eSBenjamin Tissoires 0x19, 0xe0, # .Usage Minimum (224) 125*b2c4944eSBenjamin Tissoires 0x29, 0xe7, # .Usage Maximum (231) 126*b2c4944eSBenjamin Tissoires 0x15, 0x00, # .Logical Minimum (0) 127*b2c4944eSBenjamin Tissoires 0x25, 0x01, # .Logical Maximum (1) 128*b2c4944eSBenjamin Tissoires 0x75, 0x01, # .Report Size (1) 129*b2c4944eSBenjamin Tissoires 0x95, 0x08, # .Report Count (8) 130*b2c4944eSBenjamin Tissoires 0x81, 0x02, # .Input (Data,Var,Abs) 131*b2c4944eSBenjamin Tissoires 0x95, 0x06, # .Report Count (6) 132*b2c4944eSBenjamin Tissoires 0x75, 0x08, # .Report Size (8) 133*b2c4944eSBenjamin Tissoires 0x15, 0x00, # .Logical Minimum (0) 134*b2c4944eSBenjamin Tissoires 0x26, 0xa4, 0x00, # .Logical Maximum (164) 135*b2c4944eSBenjamin Tissoires 0x05, 0x07, # .Usage Page (Keyboard) 136*b2c4944eSBenjamin Tissoires 0x19, 0x00, # .Usage Minimum (0) 137*b2c4944eSBenjamin Tissoires 0x29, 0xa4, # .Usage Maximum (164) 138*b2c4944eSBenjamin Tissoires 0x81, 0x00, # .Input (Data,Arr,Abs) 139*b2c4944eSBenjamin Tissoires 0xc0, # End Collection 140*b2c4944eSBenjamin Tissoires ] 141*b2c4944eSBenjamin Tissoires # fmt: on 142*b2c4944eSBenjamin Tissoires 143*b2c4944eSBenjamin Tissoires def __init__(self, rdesc=report_descriptor, name=None, input_info=None): 144*b2c4944eSBenjamin Tissoires super().__init__(rdesc, name, input_info) 145*b2c4944eSBenjamin Tissoires 146*b2c4944eSBenjamin Tissoires def _create_report_data(self): 147*b2c4944eSBenjamin Tissoires data = KeyboardData() 148*b2c4944eSBenjamin Tissoires array = [] 149*b2c4944eSBenjamin Tissoires 150*b2c4944eSBenjamin Tissoires hut = hidtools.hut.HUT 151*b2c4944eSBenjamin Tissoires 152*b2c4944eSBenjamin Tissoires # strip modifiers from the array 153*b2c4944eSBenjamin Tissoires for k, v in self.keystates.items(): 154*b2c4944eSBenjamin Tissoires # we ignore depressed keys 155*b2c4944eSBenjamin Tissoires if not v: 156*b2c4944eSBenjamin Tissoires continue 157*b2c4944eSBenjamin Tissoires 158*b2c4944eSBenjamin Tissoires usage = hut[0x07].from_name[k].usage 159*b2c4944eSBenjamin Tissoires if usage >= 224 and usage <= 231: 160*b2c4944eSBenjamin Tissoires # modifier 161*b2c4944eSBenjamin Tissoires setattr(data, k.lower(), 1) 162*b2c4944eSBenjamin Tissoires else: 163*b2c4944eSBenjamin Tissoires array.append(k) 164*b2c4944eSBenjamin Tissoires 165*b2c4944eSBenjamin Tissoires # if array length is bigger than 6, report ErrorRollOver 166*b2c4944eSBenjamin Tissoires if len(array) > 6: 167*b2c4944eSBenjamin Tissoires array = ["ErrorRollOver"] * 6 168*b2c4944eSBenjamin Tissoires 169*b2c4944eSBenjamin Tissoires data.keyboard = array 170*b2c4944eSBenjamin Tissoires return data 171*b2c4944eSBenjamin Tissoires 172*b2c4944eSBenjamin Tissoires 173*b2c4944eSBenjamin Tissoiresclass LEDKeyboard(ArrayKeyboard): 174*b2c4944eSBenjamin Tissoires # fmt: off 175*b2c4944eSBenjamin Tissoires report_descriptor = [ 176*b2c4944eSBenjamin Tissoires 0x05, 0x01, # Usage Page (Generic Desktop) 177*b2c4944eSBenjamin Tissoires 0x09, 0x06, # Usage (Keyboard) 178*b2c4944eSBenjamin Tissoires 0xa1, 0x01, # Collection (Application) 179*b2c4944eSBenjamin Tissoires 0x05, 0x07, # .Usage Page (Keyboard) 180*b2c4944eSBenjamin Tissoires 0x19, 0xe0, # .Usage Minimum (224) 181*b2c4944eSBenjamin Tissoires 0x29, 0xe7, # .Usage Maximum (231) 182*b2c4944eSBenjamin Tissoires 0x15, 0x00, # .Logical Minimum (0) 183*b2c4944eSBenjamin Tissoires 0x25, 0x01, # .Logical Maximum (1) 184*b2c4944eSBenjamin Tissoires 0x75, 0x01, # .Report Size (1) 185*b2c4944eSBenjamin Tissoires 0x95, 0x08, # .Report Count (8) 186*b2c4944eSBenjamin Tissoires 0x81, 0x02, # .Input (Data,Var,Abs) 187*b2c4944eSBenjamin Tissoires 0x95, 0x01, # .Report Count (1) 188*b2c4944eSBenjamin Tissoires 0x75, 0x08, # .Report Size (8) 189*b2c4944eSBenjamin Tissoires 0x81, 0x01, # .Input (Cnst,Arr,Abs) 190*b2c4944eSBenjamin Tissoires 0x95, 0x05, # .Report Count (5) 191*b2c4944eSBenjamin Tissoires 0x75, 0x01, # .Report Size (1) 192*b2c4944eSBenjamin Tissoires 0x05, 0x08, # .Usage Page (LEDs) 193*b2c4944eSBenjamin Tissoires 0x19, 0x01, # .Usage Minimum (1) 194*b2c4944eSBenjamin Tissoires 0x29, 0x05, # .Usage Maximum (5) 195*b2c4944eSBenjamin Tissoires 0x91, 0x02, # .Output (Data,Var,Abs) 196*b2c4944eSBenjamin Tissoires 0x95, 0x01, # .Report Count (1) 197*b2c4944eSBenjamin Tissoires 0x75, 0x03, # .Report Size (3) 198*b2c4944eSBenjamin Tissoires 0x91, 0x01, # .Output (Cnst,Arr,Abs) 199*b2c4944eSBenjamin Tissoires 0x95, 0x06, # .Report Count (6) 200*b2c4944eSBenjamin Tissoires 0x75, 0x08, # .Report Size (8) 201*b2c4944eSBenjamin Tissoires 0x15, 0x00, # .Logical Minimum (0) 202*b2c4944eSBenjamin Tissoires 0x26, 0xa4, 0x00, # .Logical Maximum (164) 203*b2c4944eSBenjamin Tissoires 0x05, 0x07, # .Usage Page (Keyboard) 204*b2c4944eSBenjamin Tissoires 0x19, 0x00, # .Usage Minimum (0) 205*b2c4944eSBenjamin Tissoires 0x29, 0xa4, # .Usage Maximum (164) 206*b2c4944eSBenjamin Tissoires 0x81, 0x00, # .Input (Data,Arr,Abs) 207*b2c4944eSBenjamin Tissoires 0xc0, # End Collection 208*b2c4944eSBenjamin Tissoires ] 209*b2c4944eSBenjamin Tissoires # fmt: on 210*b2c4944eSBenjamin Tissoires 211*b2c4944eSBenjamin Tissoires def __init__(self, rdesc=report_descriptor, name=None, input_info=None): 212*b2c4944eSBenjamin Tissoires super().__init__(rdesc, name, input_info) 213*b2c4944eSBenjamin Tissoires 214*b2c4944eSBenjamin Tissoires 215*b2c4944eSBenjamin Tissoires# Some Primax manufactured keyboards set the Usage Page after having defined 216*b2c4944eSBenjamin Tissoires# some local Usages. It relies on the fact that the specification states that 217*b2c4944eSBenjamin Tissoires# Usages are to be concatenated with Usage Pages upon finding a Main item (see 218*b2c4944eSBenjamin Tissoires# 6.2.2.8). This test covers this case. 219*b2c4944eSBenjamin Tissoiresclass PrimaxKeyboard(ArrayKeyboard): 220*b2c4944eSBenjamin Tissoires # fmt: off 221*b2c4944eSBenjamin Tissoires report_descriptor = [ 222*b2c4944eSBenjamin Tissoires 0x05, 0x01, # Usage Page (Generic Desktop) 223*b2c4944eSBenjamin Tissoires 0x09, 0x06, # Usage (Keyboard) 224*b2c4944eSBenjamin Tissoires 0xA1, 0x01, # Collection (Application) 225*b2c4944eSBenjamin Tissoires 0x05, 0x07, # .Usage Page (Keyboard) 226*b2c4944eSBenjamin Tissoires 0x19, 0xE0, # .Usage Minimum (224) 227*b2c4944eSBenjamin Tissoires 0x29, 0xE7, # .Usage Maximum (231) 228*b2c4944eSBenjamin Tissoires 0x15, 0x00, # .Logical Minimum (0) 229*b2c4944eSBenjamin Tissoires 0x25, 0x01, # .Logical Maximum (1) 230*b2c4944eSBenjamin Tissoires 0x75, 0x01, # .Report Size (1) 231*b2c4944eSBenjamin Tissoires 0x95, 0x08, # .Report Count (8) 232*b2c4944eSBenjamin Tissoires 0x81, 0x02, # .Input (Data,Var,Abs) 233*b2c4944eSBenjamin Tissoires 0x75, 0x08, # .Report Size (8) 234*b2c4944eSBenjamin Tissoires 0x95, 0x01, # .Report Count (1) 235*b2c4944eSBenjamin Tissoires 0x81, 0x01, # .Input (Data,Var,Abs) 236*b2c4944eSBenjamin Tissoires 0x05, 0x08, # .Usage Page (LEDs) 237*b2c4944eSBenjamin Tissoires 0x19, 0x01, # .Usage Minimum (1) 238*b2c4944eSBenjamin Tissoires 0x29, 0x03, # .Usage Maximum (3) 239*b2c4944eSBenjamin Tissoires 0x75, 0x01, # .Report Size (1) 240*b2c4944eSBenjamin Tissoires 0x95, 0x03, # .Report Count (3) 241*b2c4944eSBenjamin Tissoires 0x91, 0x02, # .Output (Data,Var,Abs) 242*b2c4944eSBenjamin Tissoires 0x95, 0x01, # .Report Count (1) 243*b2c4944eSBenjamin Tissoires 0x75, 0x05, # .Report Size (5) 244*b2c4944eSBenjamin Tissoires 0x91, 0x01, # .Output (Constant) 245*b2c4944eSBenjamin Tissoires 0x15, 0x00, # .Logical Minimum (0) 246*b2c4944eSBenjamin Tissoires 0x26, 0xFF, 0x00, # .Logical Maximum (255) 247*b2c4944eSBenjamin Tissoires 0x19, 0x00, # .Usage Minimum (0) 248*b2c4944eSBenjamin Tissoires 0x2A, 0xFF, 0x00, # .Usage Maximum (255) 249*b2c4944eSBenjamin Tissoires 0x05, 0x07, # .Usage Page (Keyboard) 250*b2c4944eSBenjamin Tissoires 0x75, 0x08, # .Report Size (8) 251*b2c4944eSBenjamin Tissoires 0x95, 0x06, # .Report Count (6) 252*b2c4944eSBenjamin Tissoires 0x81, 0x00, # .Input (Data,Arr,Abs) 253*b2c4944eSBenjamin Tissoires 0xC0, # End Collection 254*b2c4944eSBenjamin Tissoires ] 255*b2c4944eSBenjamin Tissoires # fmt: on 256*b2c4944eSBenjamin Tissoires 257*b2c4944eSBenjamin Tissoires def __init__(self, rdesc=report_descriptor, name=None, input_info=None): 258*b2c4944eSBenjamin Tissoires super().__init__(rdesc, name, input_info) 259*b2c4944eSBenjamin Tissoires 260*b2c4944eSBenjamin Tissoires 261*b2c4944eSBenjamin Tissoiresclass BaseTest: 262*b2c4944eSBenjamin Tissoires class TestKeyboard(base.BaseTestCase.TestUhid): 263*b2c4944eSBenjamin Tissoires def test_single_key(self): 264*b2c4944eSBenjamin Tissoires """check for key reliability.""" 265*b2c4944eSBenjamin Tissoires uhdev = self.uhdev 266*b2c4944eSBenjamin Tissoires evdev = uhdev.get_evdev() 267*b2c4944eSBenjamin Tissoires syn_event = self.syn_event 268*b2c4944eSBenjamin Tissoires 269*b2c4944eSBenjamin Tissoires r = uhdev.event(["a and A"]) 270*b2c4944eSBenjamin Tissoires expected = [syn_event] 271*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_A, 1)) 272*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 273*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 274*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 275*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_A] == 1 276*b2c4944eSBenjamin Tissoires 277*b2c4944eSBenjamin Tissoires r = uhdev.event([]) 278*b2c4944eSBenjamin Tissoires expected = [syn_event] 279*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_A, 0)) 280*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 281*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 282*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 283*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_A] == 0 284*b2c4944eSBenjamin Tissoires 285*b2c4944eSBenjamin Tissoires def test_two_keys(self): 286*b2c4944eSBenjamin Tissoires uhdev = self.uhdev 287*b2c4944eSBenjamin Tissoires evdev = uhdev.get_evdev() 288*b2c4944eSBenjamin Tissoires syn_event = self.syn_event 289*b2c4944eSBenjamin Tissoires 290*b2c4944eSBenjamin Tissoires r = uhdev.event(["a and A", "q and Q"]) 291*b2c4944eSBenjamin Tissoires expected = [syn_event] 292*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_A, 1)) 293*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_Q, 1)) 294*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 295*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 296*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 297*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_A] == 1 298*b2c4944eSBenjamin Tissoires 299*b2c4944eSBenjamin Tissoires r = uhdev.event([]) 300*b2c4944eSBenjamin Tissoires expected = [syn_event] 301*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_A, 0)) 302*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_Q, 0)) 303*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 304*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 305*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 306*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_A] == 0 307*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_Q] == 0 308*b2c4944eSBenjamin Tissoires 309*b2c4944eSBenjamin Tissoires r = uhdev.event(["c and C"]) 310*b2c4944eSBenjamin Tissoires expected = [syn_event] 311*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_C, 1)) 312*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 313*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 314*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 315*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_C] == 1 316*b2c4944eSBenjamin Tissoires 317*b2c4944eSBenjamin Tissoires r = uhdev.event(["c and C", "Spacebar"]) 318*b2c4944eSBenjamin Tissoires expected = [syn_event] 319*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_SPACE, 1)) 320*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 321*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 322*b2c4944eSBenjamin Tissoires assert libevdev.InputEvent(libevdev.EV_KEY.KEY_C) not in events 323*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 324*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_C] == 1 325*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_SPACE] == 1 326*b2c4944eSBenjamin Tissoires 327*b2c4944eSBenjamin Tissoires r = uhdev.event(["Spacebar"]) 328*b2c4944eSBenjamin Tissoires expected = [syn_event] 329*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_C, 0)) 330*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 331*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 332*b2c4944eSBenjamin Tissoires assert libevdev.InputEvent(libevdev.EV_KEY.KEY_SPACE) not in events 333*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 334*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_C] == 0 335*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_SPACE] == 1 336*b2c4944eSBenjamin Tissoires 337*b2c4944eSBenjamin Tissoires r = uhdev.event([]) 338*b2c4944eSBenjamin Tissoires expected = [syn_event] 339*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_SPACE, 0)) 340*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 341*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 342*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 343*b2c4944eSBenjamin Tissoires assert evdev.value[libevdev.EV_KEY.KEY_SPACE] == 0 344*b2c4944eSBenjamin Tissoires 345*b2c4944eSBenjamin Tissoires def test_modifiers(self): 346*b2c4944eSBenjamin Tissoires # ctrl-alt-del would be very nice :) 347*b2c4944eSBenjamin Tissoires uhdev = self.uhdev 348*b2c4944eSBenjamin Tissoires syn_event = self.syn_event 349*b2c4944eSBenjamin Tissoires 350*b2c4944eSBenjamin Tissoires r = uhdev.event(["LeftControl", "LeftShift", "= and +"]) 351*b2c4944eSBenjamin Tissoires expected = [syn_event] 352*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_LEFTCTRL, 1)) 353*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_LEFTSHIFT, 1)) 354*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_EQUAL, 1)) 355*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 356*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 357*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 358*b2c4944eSBenjamin Tissoires 359*b2c4944eSBenjamin Tissoires 360*b2c4944eSBenjamin Tissoiresclass TestPlainKeyboard(BaseTest.TestKeyboard): 361*b2c4944eSBenjamin Tissoires def create_device(self): 362*b2c4944eSBenjamin Tissoires return PlainKeyboard() 363*b2c4944eSBenjamin Tissoires 364*b2c4944eSBenjamin Tissoires def test_10_keys(self): 365*b2c4944eSBenjamin Tissoires uhdev = self.uhdev 366*b2c4944eSBenjamin Tissoires syn_event = self.syn_event 367*b2c4944eSBenjamin Tissoires 368*b2c4944eSBenjamin Tissoires r = uhdev.event( 369*b2c4944eSBenjamin Tissoires [ 370*b2c4944eSBenjamin Tissoires "1 and !", 371*b2c4944eSBenjamin Tissoires "2 and @", 372*b2c4944eSBenjamin Tissoires "3 and #", 373*b2c4944eSBenjamin Tissoires "4 and $", 374*b2c4944eSBenjamin Tissoires "5 and %", 375*b2c4944eSBenjamin Tissoires "6 and ^", 376*b2c4944eSBenjamin Tissoires "7 and &", 377*b2c4944eSBenjamin Tissoires "8 and *", 378*b2c4944eSBenjamin Tissoires "9 and (", 379*b2c4944eSBenjamin Tissoires "0 and )", 380*b2c4944eSBenjamin Tissoires ] 381*b2c4944eSBenjamin Tissoires ) 382*b2c4944eSBenjamin Tissoires expected = [syn_event] 383*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_0, 1)) 384*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_1, 1)) 385*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_2, 1)) 386*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_3, 1)) 387*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_4, 1)) 388*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_5, 1)) 389*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_6, 1)) 390*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_7, 1)) 391*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_8, 1)) 392*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_9, 1)) 393*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 394*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 395*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 396*b2c4944eSBenjamin Tissoires 397*b2c4944eSBenjamin Tissoires r = uhdev.event([]) 398*b2c4944eSBenjamin Tissoires expected = [syn_event] 399*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_0, 0)) 400*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_1, 0)) 401*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_2, 0)) 402*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_3, 0)) 403*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_4, 0)) 404*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_5, 0)) 405*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_6, 0)) 406*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_7, 0)) 407*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_8, 0)) 408*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_9, 0)) 409*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 410*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 411*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 412*b2c4944eSBenjamin Tissoires 413*b2c4944eSBenjamin Tissoires 414*b2c4944eSBenjamin Tissoiresclass TestArrayKeyboard(BaseTest.TestKeyboard): 415*b2c4944eSBenjamin Tissoires def create_device(self): 416*b2c4944eSBenjamin Tissoires return ArrayKeyboard() 417*b2c4944eSBenjamin Tissoires 418*b2c4944eSBenjamin Tissoires def test_10_keys(self): 419*b2c4944eSBenjamin Tissoires uhdev = self.uhdev 420*b2c4944eSBenjamin Tissoires syn_event = self.syn_event 421*b2c4944eSBenjamin Tissoires 422*b2c4944eSBenjamin Tissoires r = uhdev.event( 423*b2c4944eSBenjamin Tissoires [ 424*b2c4944eSBenjamin Tissoires "1 and !", 425*b2c4944eSBenjamin Tissoires "2 and @", 426*b2c4944eSBenjamin Tissoires "3 and #", 427*b2c4944eSBenjamin Tissoires "4 and $", 428*b2c4944eSBenjamin Tissoires "5 and %", 429*b2c4944eSBenjamin Tissoires "6 and ^", 430*b2c4944eSBenjamin Tissoires ] 431*b2c4944eSBenjamin Tissoires ) 432*b2c4944eSBenjamin Tissoires expected = [syn_event] 433*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_1, 1)) 434*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_2, 1)) 435*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_3, 1)) 436*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_4, 1)) 437*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_5, 1)) 438*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_6, 1)) 439*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 440*b2c4944eSBenjamin Tissoires 441*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 442*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 443*b2c4944eSBenjamin Tissoires 444*b2c4944eSBenjamin Tissoires # ErrRollOver 445*b2c4944eSBenjamin Tissoires r = uhdev.event( 446*b2c4944eSBenjamin Tissoires [ 447*b2c4944eSBenjamin Tissoires "1 and !", 448*b2c4944eSBenjamin Tissoires "2 and @", 449*b2c4944eSBenjamin Tissoires "3 and #", 450*b2c4944eSBenjamin Tissoires "4 and $", 451*b2c4944eSBenjamin Tissoires "5 and %", 452*b2c4944eSBenjamin Tissoires "6 and ^", 453*b2c4944eSBenjamin Tissoires "7 and &", 454*b2c4944eSBenjamin Tissoires "8 and *", 455*b2c4944eSBenjamin Tissoires "9 and (", 456*b2c4944eSBenjamin Tissoires "0 and )", 457*b2c4944eSBenjamin Tissoires ] 458*b2c4944eSBenjamin Tissoires ) 459*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 460*b2c4944eSBenjamin Tissoires 461*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 462*b2c4944eSBenjamin Tissoires 463*b2c4944eSBenjamin Tissoires assert len(events) == 0 464*b2c4944eSBenjamin Tissoires 465*b2c4944eSBenjamin Tissoires r = uhdev.event([]) 466*b2c4944eSBenjamin Tissoires expected = [syn_event] 467*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_1, 0)) 468*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_2, 0)) 469*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_3, 0)) 470*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_4, 0)) 471*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_5, 0)) 472*b2c4944eSBenjamin Tissoires expected.append(libevdev.InputEvent(libevdev.EV_KEY.KEY_6, 0)) 473*b2c4944eSBenjamin Tissoires events = uhdev.next_sync_events() 474*b2c4944eSBenjamin Tissoires self.debug_reports(r, uhdev, events) 475*b2c4944eSBenjamin Tissoires self.assertInputEventsIn(expected, events) 476*b2c4944eSBenjamin Tissoires 477*b2c4944eSBenjamin Tissoires 478*b2c4944eSBenjamin Tissoiresclass TestLEDKeyboard(BaseTest.TestKeyboard): 479*b2c4944eSBenjamin Tissoires def create_device(self): 480*b2c4944eSBenjamin Tissoires return LEDKeyboard() 481*b2c4944eSBenjamin Tissoires 482*b2c4944eSBenjamin Tissoires 483*b2c4944eSBenjamin Tissoiresclass TestPrimaxKeyboard(BaseTest.TestKeyboard): 484*b2c4944eSBenjamin Tissoires def create_device(self): 485*b2c4944eSBenjamin Tissoires return PrimaxKeyboard() 486