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