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