1# Lint as: python2, python3 2# Copyright 2020 The Chromium OS Authors. All rights reserved. 3# Use of this source code is governed by a BSD-style license that can be 4# found in the LICENSE file. 5 6""" 7Provides uinput utils for generating user input events. 8""" 9 10# Please limit the use of the uinput library to this file. Try not to spread 11# dependencies and abstract as much as possible to make switching to a different 12# input library in the future easier. 13import uinput 14 15 16# Don't create a device during build_packages or for tests that don't need it. 17uinput_device_keyboard = None 18uinput_device_touch = None 19uinput_device_mouse_rel = None 20 21# Don't add more events to this list than are used. For a complete list of 22# available events check python2.7/site-packages/uinput/ev.py. 23UINPUT_DEVICE_EVENTS_KEYBOARD = [ 24 uinput.KEY_F4, 25 uinput.KEY_F11, 26 uinput.KEY_KPPLUS, 27 uinput.KEY_KPMINUS, 28 uinput.KEY_LEFTCTRL, 29 uinput.KEY_TAB, 30 uinput.KEY_UP, 31 uinput.KEY_DOWN, 32 uinput.KEY_LEFT, 33 uinput.KEY_RIGHT, 34 uinput.KEY_RIGHTSHIFT, 35 uinput.KEY_LEFTALT, 36 uinput.KEY_A, 37 uinput.KEY_M, 38 uinput.KEY_Q, 39 uinput.KEY_V 40] 41# TODO(ihf): Find an ABS sequence that actually works. 42UINPUT_DEVICE_EVENTS_TOUCH = [ 43 uinput.BTN_TOUCH, 44 uinput.ABS_MT_SLOT, 45 uinput.ABS_MT_POSITION_X + (0, 2560, 0, 0), 46 uinput.ABS_MT_POSITION_Y + (0, 1700, 0, 0), 47 uinput.ABS_MT_TRACKING_ID + (0, 10, 0, 0), 48 uinput.BTN_TOUCH 49] 50UINPUT_DEVICE_EVENTS_MOUSE_REL = [ 51 uinput.REL_X, 52 uinput.REL_Y, 53 uinput.BTN_MOUSE, 54 uinput.BTN_LEFT, 55 uinput.BTN_RIGHT 56] 57 58 59def get_device_keyboard(): 60 """ 61 Lazy initialize device and return it. We don't want to create a device 62 during build_packages or for tests that don't need it, hence init with None. 63 """ 64 global uinput_device_keyboard 65 if uinput_device_keyboard is None: 66 uinput_device_keyboard = uinput.Device(UINPUT_DEVICE_EVENTS_KEYBOARD) 67 return uinput_device_keyboard 68 69 70def get_device_mouse_rel(): 71 """ 72 Lazy initialize device and return it. We don't want to create a device 73 during build_packages or for tests that don't need it, hence init with None. 74 """ 75 global uinput_device_mouse_rel 76 if uinput_device_mouse_rel is None: 77 uinput_device_mouse_rel = uinput.Device(UINPUT_DEVICE_EVENTS_MOUSE_REL) 78 return uinput_device_mouse_rel 79 80 81def get_device_touch(): 82 """ 83 Lazy initialize device and return it. We don't want to create a device 84 during build_packages or for tests that don't need it, hence init with None. 85 """ 86 global uinput_device_touch 87 if uinput_device_touch is None: 88 uinput_device_touch = uinput.Device(UINPUT_DEVICE_EVENTS_TOUCH) 89 return uinput_device_touch 90 91 92def translate_name(event_name): 93 """ 94 Translates string |event_name| to uinput event. 95 """ 96 return getattr(uinput, event_name) 97 98 99def emit(device, event_name, value, syn=True): 100 """ 101 Wrapper for uinput.emit. Emits event with value. 102 Example: ('REL_X', 20), ('BTN_RIGHT', 1) 103 """ 104 event = translate_name(event_name) 105 device.emit(event, value, syn) 106 107 108def emit_click(device, event_name, syn=True): 109 """ 110 Wrapper for uinput.emit_click. Emits click event. Only KEY and BTN events 111 are accepted, otherwise ValueError is raised. Example: 'KEY_A' 112 """ 113 event = translate_name(event_name) 114 device.emit_click(event, syn) 115 116 117def emit_combo(device, event_names, syn=True): 118 """ 119 Wrapper for uinput.emit_combo. Emits sequence of events. 120 Example: ['KEY_LEFTCTRL', 'KEY_LEFTALT', 'KEY_F5'] 121 """ 122 events = [translate_name(en) for en in event_names] 123 device.emit_combo(events, syn) 124