#!/usr/bin/env python # -*- coding: utf-8 -*- # # Copyright 2016 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. # Note: This is a py2/3 compatible file. from __future__ import print_function import string import subprocess import sys KEYMATRIX_0 = { "`": (3, 1), "1": (6, 1), "2": (6, 4), "3": (6, 2), "4": (6, 3), "5": (3, 3), "6": (3, 6), "7": (6, 6), "8": (6, 5), "9": (6, 9), "0": (6, 8), "-": (3, 8), "=": (0, 8), "q": (7, 1), "w": (7, 4), "e": (7, 2), "r": (7, 3), "t": (2, 3), "y": (2, 6), "u": (7, 6), "i": (7, 5), "o": (7, 9), "p": (7, 8), "[": (2, 8), "]": (2, 5), "\\": (3, 11), "a": (4, 1), "s": (4, 4), "d": (4, 2), "f": (4, 3), "g": (1, 3), "h": (1, 6), "j": (4, 6), "k": (4, 5), "l": (4, 9), ";": (4, 8), "'": (1, 8), "z": (5, 1), "x": (5, 4), "c": (5, 2), "v": (5, 3), "b": (0, 3), "n": (0, 6), "m": (5, 6), ",": (5, 5), ".": (5, 9), "/": (5, 8), " ": (5, 11), "": (6, 12), "": (0, 10), "": (6, 11), "": (2, 1), "": (0, 4), "": (7, 7), "": (4, 0), "": (1, 1), "": (1, 11), "": (3, 2), "": (6, 10), "": (2, 0), "": (0, 2), "": (0, 1), "": (2, 2), "": (1, 2), "": (3, 4), "": (2, 4), "": (1, 4), "": (2, 9), "": (1, 9), "": (7, 11), "": (5, 7), "": (4, 11), "": (7, 12), } KEYMATRIX_1 = { "`": (3, 1), "1": (7, 1), "2": (6, 4), "3": (6, 2), "4": (6, 3), "5": (3, 3), "6": (3, 6), "7": (6, 6), "8": (6, 5), "9": (6, 9), "0": (0, 9), "-": (3, 8), "=": (0, 8), "q": (6, 12), "w": (7, 4), "e": (5, 8), "r": (7, 3), "t": (2, 3), "y": (2, 6), "u": (7, 6), "i": (7, 5), "o": (6, 8), "p": (7, 8), "[": (2, 8), "]": (2, 5), "\\": (1, 11), "a": (4, 1), "s": (5, 6), "d": (0, 14), "f": (4, 3), "g": (1, 3), "h": (1, 6), "j": (4, 6), "k": (4, 5), "l": (4, 9), ";": (4, 8), "'": (1, 8), "z": (7, 9), "x": (5, 5), "c": (7, 13), "v": (7, 2), "b": (0, 3), "n": (0, 6), "m": (5, 1), ",": (5, 4), ".": (5, 9), "/": (6, 11), " ": (5, 3), "": (1, 12), "": (0, 10), "": (5, 11), "": (6, 1), "": (1, 4), "": (7, 7), "": (4, 0), "": (1, 1), "": (7, 11), "": (3, 2), "": (6, 10), "": (2, 0), "": (4, 2), "": (3, 0), "": (2, 2), "": (1, 2), "": (4, 4), "": (3, 4), "": (2, 4), "": (2, 9), "": (1, 9), "": (2, 11), "": (1, 7), "": (4, 11), "": (0, 12), } # Extensible: when new model comes up in future that deviates from default keyboard matrix, # and most certainly different from frostflow, new KEYMATRIX_x entry can be defined first, # and then add an "model_name" : KEYMATRIX_x to here. MODEL_KBMATRIX_MAP = { "default_matrix": KEYMATRIX_0, "frostflow": KEYMATRIX_1, # "mithrax" is another model that uses same kb matrix with frostflow, # can add "mithrax" : KEYMATRIX_1 } UNSHIFT_TABLE = { "~": "`", "!": "1", "@": "2", "#": "3", "$": "4", "%": "5", "^": "6", "&": "7", "*": "8", "(": "9", ")": "0", "_": "-", "+": "=", "{": "[", "}": "]", "|": "\\", ":": ";", '"': "'", "<": ",", ">": ".", "?": "/", } for c in string.ascii_lowercase: UNSHIFT_TABLE[c.upper()] = c def inject_event(key, press): """Function inject_event().""" if len(key) >= 2 and key[0] != "<": key = "<" + key + ">" if key not in KEYMATRIX: print("%s: invalid key: %s" % (this_script, key)) sys.exit(1) (row, col) = KEYMATRIX[key] subprocess.call( ["ectool", "kbpress", str(row), str(col), "1" if press else "0"] ) def inject_key(key): """Function inject_key().""" inject_event(key, True) inject_event(key, False) def inject_string(string): """Function inject_string().""" for c in string: if c in KEYMATRIX: inject_key(c) elif c in UNSHIFT_TABLE: inject_event("", True) inject_key(UNSHIFT_TABLE[c]) inject_event("", False) else: print("unimplemented character:", c) sys.exit(1) def read_dutmodel(): """Function read_dutmodel().""" try: output = subprocess.check_output( "cros_config / name", stderr=subprocess.DEVNULL, shell=True ) modelstr = str(output, "UTF-8") except subprocess.SubprocessError: modelstr = "" return modelstr def usage(): """Function usage().""" print( "Usage: %s [-s ] [-k ]" % this_script, "[-p ] [-r ] ...", ) print("Examples:") print("%s -s MyPassw0rd -k enter" % this_script) print("%s -p ctrl_l -p alt_l -k f3 -r alt_l -r ctrl_l" % this_script) def help(): """Function help().""" usage() print("Valid keys are:") i = 0 for key in KEYMATRIX: print("%12s" % key, end="") i += 1 if i % 4 == 0: print() print() print("angle brackets may be omitted") def usage_check(asserted_condition, message): """Function usage_check().""" if asserted_condition: return print("%s:" % this_script, message) usage() sys.exit(1) # -- main this_script = sys.argv[0] arg_len = len(sys.argv) if arg_len > 1 and sys.argv[1] == "--help": help() sys.exit(0) usage_check(arg_len > 1, "not enough arguments") usage_check(arg_len % 2 == 1, "mismatched arguments") for i in range(1, arg_len, 2): usage_check( sys.argv[i] in ("-s", "-k", "-p", "-r"), "unknown flag: %s" % sys.argv[i], ) KEYMATRIX = KEYMATRIX_0 model = read_dutmodel() if model in MODEL_KBMATRIX_MAP: KEYMATRIX = MODEL_KBMATRIX_MAP[model] for i in range(1, arg_len, 2): flag = sys.argv[i] arg = sys.argv[i + 1] if flag == "-s": inject_string(arg) elif flag == "-k": inject_key(arg) elif flag == "-p": inject_event(arg, True) elif flag == "-r": inject_event(arg, False)