python-uinput: Move cros_[type_]keys.py out of patch
Makes it easier to edit the 2 python scripts manually, no
code change.
BUG=chromium:714950
TEST=emerge-elm -av python-uinput
equery-elm files python-uinput shows the 2 python scripts.
Change-Id: I3789d46d070c1445e5c9bb52877bf6350116441b
Reviewed-on: https://chromium-review.googlesource.com/486559
Commit-Ready: Nicolas Boichat <drinkcat@chromium.org>
Tested-by: Ilja H. Friedel <ihf@chromium.org>
Reviewed-by: Ilja H. Friedel <ihf@chromium.org>
Reviewed-by: Mike Frysinger <vapier@chromium.org>
diff --git a/dev-python/python-uinput/files/cros_keys.py b/dev-python/python-uinput/files/cros_keys.py
new file mode 100644
index 0000000..6b830dc
--- /dev/null
+++ b/dev-python/python-uinput/files/cros_keys.py
@@ -0,0 +1,288 @@
+# Copyright 2015 The Chromium OS Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import argparse
+# Get all evdev/uinput events in our namespace.
+# pylint: disable=wildcard-import, unused-wildcard-import
+from uinput.ev import *
+import subprocess
+import time
+import uinput
+
+# Default delay between key presses in seconds. 12ms is the xdotool default.
+default_delay = 0.012
+uinput_device_keyboard = None
+
+
+# This dictionary contains most 7 bit ASCII characters. Add more if needed.
+# TODO(ihf): Create this table using xkbcommon to support arbirtrary
+# character sets and keyboard layouts.
+_CROS_CHAR_MAP = {
+ "\b": [KEY_BACKSPACE],
+ "\t": [KEY_TAB],
+ "\n": [KEY_ENTER],
+
+ " ": [KEY_SPACE],
+ "!": [KEY_LEFTSHIFT, KEY_1],
+ '"': [KEY_LEFTSHIFT, KEY_APOSTROPHE],
+ "#": [KEY_LEFTSHIFT, KEY_3],
+ "$": [KEY_LEFTSHIFT, KEY_4],
+ "%": [KEY_LEFTSHIFT, KEY_5],
+ "&": [KEY_LEFTSHIFT, KEY_7],
+ "'": [KEY_APOSTROPHE],
+ "(": [KEY_LEFTSHIFT, KEY_9],
+ ")": [KEY_LEFTSHIFT, KEY_0],
+ "*": [KEY_KPASTERISK],
+ "+": [KEY_LEFTSHIFT, KEY_EQUAL],
+ ",": [KEY_COMMA],
+ "-": [KEY_MINUS],
+ ".": [KEY_DOT],
+ "/": [KEY_SLASH],
+
+ "0": [KEY_0],
+ "1": [KEY_1],
+ "2": [KEY_2],
+ "3": [KEY_3],
+ "4": [KEY_4],
+ "5": [KEY_5],
+ "6": [KEY_6],
+ "7": [KEY_7],
+ "8": [KEY_8],
+ "9": [KEY_9],
+
+ ":": [KEY_LEFTSHIFT, KEY_SEMICOLON],
+ ";": [KEY_SEMICOLON],
+ "<": [KEY_LEFTSHIFT, KEY_COMMA],
+ "=": [KEY_EQUAL],
+ ">": [KEY_LEFTSHIFT, KEY_DOT],
+ "?": [KEY_LEFTSHIFT, KEY_SLASH],
+ "@": [KEY_LEFTSHIFT, KEY_2],
+
+ "A": [KEY_LEFTSHIFT, KEY_A],
+ "B": [KEY_LEFTSHIFT, KEY_B],
+ "C": [KEY_LEFTSHIFT, KEY_C],
+ "D": [KEY_LEFTSHIFT, KEY_D],
+ "E": [KEY_LEFTSHIFT, KEY_E],
+ "F": [KEY_LEFTSHIFT, KEY_F],
+ "G": [KEY_LEFTSHIFT, KEY_G],
+ "H": [KEY_LEFTSHIFT, KEY_H],
+ "I": [KEY_LEFTSHIFT, KEY_I],
+ "J": [KEY_LEFTSHIFT, KEY_J],
+ "K": [KEY_LEFTSHIFT, KEY_K],
+ "L": [KEY_LEFTSHIFT, KEY_L],
+ "M": [KEY_LEFTSHIFT, KEY_M],
+ "N": [KEY_LEFTSHIFT, KEY_N],
+ "O": [KEY_LEFTSHIFT, KEY_O],
+ "P": [KEY_LEFTSHIFT, KEY_P],
+ "Q": [KEY_LEFTSHIFT, KEY_Q],
+ "R": [KEY_LEFTSHIFT, KEY_R],
+ "S": [KEY_LEFTSHIFT, KEY_S],
+ "T": [KEY_LEFTSHIFT, KEY_T],
+ "U": [KEY_LEFTSHIFT, KEY_U],
+ "V": [KEY_LEFTSHIFT, KEY_V],
+ "W": [KEY_LEFTSHIFT, KEY_W],
+ "X": [KEY_LEFTSHIFT, KEY_X],
+ "Y": [KEY_LEFTSHIFT, KEY_Y],
+ "Z": [KEY_LEFTSHIFT, KEY_Z],
+
+ "[": [KEY_LEFTBRACE],
+ "\\": [KEY_BACKSLASH],
+ "]": [KEY_RIGHTBRACE],
+ "^": [KEY_LEFTSHIFT, KEY_6],
+ "_": [KEY_LEFTSHIFT, KEY_MINUS],
+ "`": [KEY_GRAVE],
+
+ "a": [KEY_A],
+ "b": [KEY_B],
+ "c": [KEY_C],
+ "d": [KEY_D],
+ "e": [KEY_E],
+ "f": [KEY_F],
+ "g": [KEY_G],
+ "h": [KEY_H],
+ "i": [KEY_I],
+ "j": [KEY_J],
+ "k": [KEY_K],
+ "l": [KEY_L],
+ "m": [KEY_M],
+ "n": [KEY_N],
+ "o": [KEY_O],
+ "p": [KEY_P],
+ "q": [KEY_Q],
+ "r": [KEY_R],
+ "s": [KEY_S],
+ "t": [KEY_T],
+ "u": [KEY_U],
+ "v": [KEY_V],
+ "w": [KEY_W],
+ "x": [KEY_X],
+ "y": [KEY_Y],
+ "z": [KEY_Z],
+
+ "{": [KEY_LEFTSHIFT, KEY_LEFTBRACE],
+ "|": [KEY_LEFTSHIFT, KEY_BACKSLASH],
+ "}": [KEY_LEFTSHIFT, KEY_RIGHTBRACE],
+ "~": [KEY_LEFTSHIFT, KEY_GRAVE],
+}
+
+
+# A list of American English ChromeOS keys to define a keyboard device.
+_CROS_KEYS_ALL = [
+ # Function row.
+ KEY_ESC,
+ KEY_F1,
+ KEY_F2,
+ KEY_F3,
+ KEY_F4,
+ KEY_F5,
+ KEY_F6,
+ KEY_F7,
+ KEY_F8,
+ KEY_F9,
+ KEY_F10,
+ KEY_F11,
+ KEY_F12,
+ KEY_HOME,
+ KEY_END,
+ KEY_INSERT,
+ KEY_DELETE,
+ # First row.
+ KEY_GRAVE,
+ KEY_1,
+ KEY_2,
+ KEY_3,
+ KEY_4,
+ KEY_5,
+ KEY_6,
+ KEY_7,
+ KEY_8,
+ KEY_9,
+ KEY_0,
+ KEY_MINUS,
+ KEY_EQUAL,
+ KEY_BACKSPACE,
+ # Second row.
+ KEY_TAB,
+ KEY_Q,
+ KEY_W,
+ KEY_E,
+ KEY_R,
+ KEY_T,
+ KEY_Y,
+ KEY_U,
+ KEY_I,
+ KEY_O,
+ KEY_P,
+ KEY_LEFTBRACE,
+ KEY_RIGHTBRACE,
+ KEY_BACKSLASH,
+ # Third row
+ KEY_CAPSLOCK,
+ KEY_A,
+ KEY_S,
+ KEY_D,
+ KEY_F,
+ KEY_G,
+ KEY_H,
+ KEY_J,
+ KEY_K,
+ KEY_L,
+ KEY_SEMICOLON,
+ KEY_APOSTROPHE,
+ KEY_ENTER,
+ # Forth row.
+ KEY_LEFTSHIFT,
+ KEY_Z,
+ KEY_X,
+ KEY_C,
+ KEY_V,
+ KEY_B,
+ KEY_N,
+ KEY_M,
+ KEY_COMMA,
+ KEY_DOT,
+ KEY_SLASH,
+ KEY_RIGHTSHIFT,
+ # Fifth row.
+ KEY_LEFTCTRL,
+ KEY_FN,
+ KEY_SEARCH,
+ KEY_LEFTALT,
+ KEY_SPACE,
+ KEY_NUMLOCK,
+ KEY_SCROLLLOCK,
+ KEY_RIGHTALT,
+ KEY_RIGHTCTRL,
+ # Directional keys.
+ KEY_UP,
+ KEY_PAGEUP,
+ KEY_LEFT,
+ KEY_RIGHT,
+ KEY_DOWN,
+ KEY_PAGEDOWN,
+]
+
+
+def _chars_to_events(chars):
+ """
+ Translates string to key events.
+
+ @param chars: characters to translate to events.
+ @returns: list of lists of events representing characters.
+ """
+ events = []
+ for char in chars:
+ events.append(_CROS_CHAR_MAP[char])
+ return events
+
+
+def _get_uinput_device_keyboard():
+ """
+ Lazy initialize device and return it. We don't want to create a device
+ during build_packages or for tests that don't need it, hence init with None.
+ """
+ global uinput_device_keyboard
+ if uinput_device_keyboard is None:
+ # For DUTs without keyboard attached force load uinput.
+ subprocess.Popen(['modprobe', 'uinput']).wait()
+ uinput_device_keyboard = uinput.Device(_CROS_KEYS_ALL)
+ return uinput_device_keyboard
+
+
+def _uinput_translate_name(event_name):
+ """
+ Translates string |event_name| to uinput event.
+ """
+ return getattr(uinput, event_name)
+
+
+def _uinput_emit_keycombo(device, events, syn=True):
+ """
+ Wrapper for uinput.emit_combo. Emits sequence of events.
+ Example: [KEY_LEFTCTRL, KEY_LEFTALT, KEY_F5]
+ """
+ time.sleep(default_delay)
+ device.emit_combo(events, syn)
+
+
+def press_keys(keys):
+ """Presses the given keys as one combination.
+
+ Please do not leak uinput dependencies outside of the file.
+
+ @param key: A simple list of key strings, e.g. ['LEFTCTRL', 'F4']
+ """
+ events = [_uinput_translate_name(en) for en in keys]
+ _uinput_emit_keycombo(_get_uinput_device_keyboard(), events)
+
+
+def type_chars(text):
+ """Translates ASCII text to keystrokes and sends them as events.
+
+ @param text: string to send as events to keyboard.
+ """
+ events = _chars_to_events(text)
+ device = _get_uinput_device_keyboard()
+ for keys in events:
+ _uinput_emit_keycombo(device, keys)