xref: /linux/tools/testing/selftests/hid/tests/test_keyboard.py (revision 1ac731c529cd4d6adbce134754b51ff7d822b145)
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