def lookup(self, keysyms, modifiers, shift_lock=None): lock = (self.lock if shift_lock is None else XK_Shift_Lock if shift_lock else XK_Caps_Lock) return KeyboardMap.lookup_effective_keysym(keysyms, modifiers, self.group, self.num_lock, lock)
def assertEffectiveKeysyms(self, keysyms, effective_keysyms): self.assertEqual(len(keysyms), len(effective_keysyms)) for i in range(len(keysyms)): self.assertEqual(KeyboardMap.effective_keysym(keysyms, i), effective_keysyms[i])
def setUp(self): super(TestKeyboardMap, self).setUp() self.keymap = KeyboardMap(self.conn)
class TestKeyboardMap(MappingTestCase): def setUp(self): super(TestKeyboardMap, self).setUp() self.keymap = KeyboardMap(self.conn) def change_keyboard_mapping(self, first_keycode, keysyms): """Given an initial keycode and a list of lists of keysyms, make an appropriate ChangeKeyboardMapping request. All of the keysym lists must be of the same length.""" keycode_count = len(keysyms) keysyms_per_keycode = len(keysyms[0]) keysyms = flatten(keysyms) self.assertEqual(len(keysyms), keycode_count * keysyms_per_keycode) self.conn.core.ChangeKeyboardMappingChecked(keycode_count, first_keycode, keysyms_per_keycode, keysyms).check() def test_init_with_cookie(self): cookie = self.conn.core.GetKeyboardMapping(8, 248) keymap = KeyboardMap(self.conn, cookie) self.assertEqual(len(keymap), 248) # Can't start with a partial keymap. cookie = self.conn.core.GetKeyboardMapping(8, 16) self.assertRaises(KeymapError, lambda: KeyboardMap(self.conn, cookie)) def test_full_refresh(self): keysyms = self.keymap.values() self.keymap.refresh() self.assertEqual(keysyms, self.keymap.values()) def test_partial_refresh(self): def make_keysym_list(letters=[chr(ord("a") + i) for i in range(26)]): keysym = string_to_keysym(choice(letters)) return [keysym, upper(keysym), keysym, upper(keysym)] n = 10 # a random number of keycodes keycode = 38 # a random keycode old = [self.keymap[keycode + i] for i in range(n)] new = [make_keysym_list() for i in range(n)] try: self.change_keyboard_mapping(keycode, new) self.keymap.refresh(keycode, n) self.assertEqual([list(self.keymap[keycode + i][:4]) for i in range(n)], new) finally: self.change_keyboard_mapping(keycode, old) self.keymap.refresh(keycode, n) self.assertEqual([self.keymap[keycode + i] for i in range(n)], old) def test_failed_partial_refresh(self): def make_keysym_list(length): # We should be able to just use lists consisting of nothing # but VoidSymbol, but some servers seem to special-case trailing # VoidSymbols, so we'll use numbers instead. return [string_to_keysym(chr(ord("1") + i)) for i in range(length)] keycode = 42 # another random keycode m = self.keymap.keysyms_per_keycode old = [self.keymap[keycode]] new = [make_keysym_list(m + 2)] try: self.change_keyboard_mapping(keycode, new) try: # This should fail, because keysyms-per-keycode in the reply # to the GetKeyboardMapping request will not match the cached # value. self.keymap.refresh(keycode, 1) except KeymapError: # However, a full refresh should succeed, since it can just # re-initialize the whole mapping. self.keymap.refresh() self.assertTrue(self.keymap.keysyms_per_keycode >= m + 2) self.assertEqual([list(self.keymap[keycode][:m + 2])], new) else: self.fail("partial refresh unexpectedly succeeded") finally: self.change_keyboard_mapping(keycode, old) self.keymap.refresh() # It's possible that the server might keep the new keysyms-per-keycode # (it is free to do so, even though it's no longer necessary), so we'll # check against the old value. self.assertEqual([self.keymap[keycode][:m]], old) def test_keycode_to_keysym(self): # We'll assume that there's a keycode that generates the symbol "a", # and that it has the usual list of keysyms bound to it. a = self.keymap.keysym_to_keycode(XK_a) self.assertTrue(a > 0) self.assertEqual(list(self.keymap[a][:4]), [XK_a, XK_A, XK_a, XK_A]) self.assertEqual(self.keymap[(a, 0)], XK_a) self.assertEqual(self.keymap[(a, 1)], XK_A) self.assertEqual(self.keymap[(a, 2)], XK_a) self.assertEqual(self.keymap[(a, 3)], XK_A) # We'll make a similar assumption for XK_Escape. esc = self.keymap.keysym_to_keycode(XK_Escape) self.assertTrue(esc > 0) self.assertEqual(list(self.keymap[esc][:4]), [XK_Escape, NoSymbol, XK_Escape, NoSymbol]) for i in range(4): # Although the second element in each group is NoSymbol, the # effectice keysym for all four positions should be the same. self.assertEqual(self.keymap[(esc, i)], XK_Escape) def test_scry_modifiers(self): # Save the current modifier map. reply = self.conn.core.GetModifierMapping().reply() saved_keycodes_per_modifier = reply.keycodes_per_modifier saved_keycodes = reply.keycodes try: # Set the modifier map to a known state. We'll assume that each # of the keysyms listed below is attached to some keycode. def keycode(keysym): return self.keymap.keysym_to_keycode(keysym) keycodes = [keycode(XK_Shift_L), # shift keycode(XK_Caps_Lock), # lock keycode(XK_Control_L), # control keycode(XK_Meta_L), # mod1 keycode(XK_Num_Lock), #mod2 keycode(XK_Mode_switch), # mod3 keycode(XK_Super_L), # mod4 0] # mod5 reply = self.conn.core.SetModifierMapping(1, keycodes).reply() self.assertEqual(reply.status, MappingStatus.Success) # Now check that we have what we ought to. self.keymap.scry_modifiers(ModifierMap(self.conn)) self.assertEqual(self.keymap.lock, XK_Caps_Lock) self.assertEqual(self.keymap.group, ModMask._3) self.assertEqual(self.keymap.num_lock, ModMask._2) self.assertEqual(self.keymap.meta, ModMask._1) self.assertEqual(self.keymap.super, ModMask._4) self.assertEqual(self.keymap.hyper, 0) finally: self.conn.core.SetModifierMapping(saved_keycodes_per_modifier, saved_keycodes).reply() def test_lookup_key(self): def lookup(keycode, mask): return self.keymap.lookup_key(keycode, mask) # We'll need the modifier key interpretations from the modifier map. self.keymap.scry_modifiers(ModifierMap(self.conn)) # We'll assume that there's a keycode that generates the symbol "a", # and that it has the usual list of keysyms bound to it. a = self.keymap.keysym_to_keycode(XK_a) self.assertTrue(a > 0) self.assertEqual(list(self.keymap[a][:2]), [XK_a, XK_A]) self.assertEqual(lookup(a, 0), XK_a) self.assertEqual(lookup(a, ModMask.Shift), XK_A) self.assertEqual(lookup(a, ModMask.Lock), XK_A) self.assertEqual(lookup(a, ModMask.Shift | ModMask.Lock), XK_A) # We'll make a similar assumption regarding the symbol "KP_1". num_lock = self.keymap.num_lock kp_1 = self.keymap.keysym_to_keycode(XK_KP_1) self.assertTrue(kp_1 > 0) self.assertEqual(list(self.keymap[kp_1][:2]), [XK_KP_End, XK_KP_1]) self.assertEqual(lookup(kp_1, 0), XK_KP_End) self.assertEqual(lookup(kp_1, ModMask.Shift), XK_KP_1) self.assertEqual(lookup(kp_1, ModMask.Lock), XK_KP_End) self.assertEqual(lookup(kp_1, ModMask.Shift | ModMask.Lock), XK_KP_1) self.assertEqual(lookup(kp_1, num_lock), XK_KP_1) self.assertEqual(lookup(kp_1, ModMask.Shift | num_lock), XK_KP_End)
def assertEffectiveIndices(self, keysyms, indices): self.assertEqual(len(keysyms), len(indices)) for i in range(len(keysyms)): self.assertEqual(KeyboardMap.effective_index(keysyms, i), indices[i])