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