# Copyright 2020 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. """ Provides uinput utils for generating user input events. """ # Please limit the use of the uinput library to this file. Try not to spread # dependencies and abstract as much as possible to make switching to a different # input library in the future easier. import uinput # Don't create a device during build_packages or for tests that don't need it. uinput_device_keyboard = None uinput_device_touch = None uinput_device_mouse_rel = None # Don't add more events to this list than are used. For a complete list of # available events check python2.7/site-packages/uinput/ev.py. UINPUT_DEVICE_EVENTS_KEYBOARD = [ uinput.KEY_F4, uinput.KEY_F11, uinput.KEY_KPPLUS, uinput.KEY_KPMINUS, uinput.KEY_LEFTCTRL, uinput.KEY_TAB, uinput.KEY_UP, uinput.KEY_DOWN, uinput.KEY_LEFT, uinput.KEY_RIGHT, uinput.KEY_RIGHTSHIFT, uinput.KEY_LEFTALT, uinput.KEY_A, uinput.KEY_M, uinput.KEY_Q, uinput.KEY_V ] # TODO(ihf): Find an ABS sequence that actually works. UINPUT_DEVICE_EVENTS_TOUCH = [ uinput.BTN_TOUCH, uinput.ABS_MT_SLOT, uinput.ABS_MT_POSITION_X + (0, 2560, 0, 0), uinput.ABS_MT_POSITION_Y + (0, 1700, 0, 0), uinput.ABS_MT_TRACKING_ID + (0, 10, 0, 0), uinput.BTN_TOUCH ] UINPUT_DEVICE_EVENTS_MOUSE_REL = [ uinput.REL_X, uinput.REL_Y, uinput.BTN_MOUSE, uinput.BTN_LEFT, uinput.BTN_RIGHT ] def get_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: uinput_device_keyboard = uinput.Device(UINPUT_DEVICE_EVENTS_KEYBOARD) return uinput_device_keyboard def get_device_mouse_rel(): """ 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_mouse_rel if uinput_device_mouse_rel is None: uinput_device_mouse_rel = uinput.Device(UINPUT_DEVICE_EVENTS_MOUSE_REL) return uinput_device_mouse_rel def get_device_touch(): """ 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_touch if uinput_device_touch is None: uinput_device_touch = uinput.Device(UINPUT_DEVICE_EVENTS_TOUCH) return uinput_device_touch def translate_name(event_name): """ Translates string |event_name| to uinput event. """ return getattr(uinput, event_name) def emit(device, event_name, value, syn=True): """ Wrapper for uinput.emit. Emits event with value. Example: ('REL_X', 20), ('BTN_RIGHT', 1) """ event = translate_name(event_name) device.emit(event, value, syn) def emit_click(device, event_name, syn=True): """ Wrapper for uinput.emit_click. Emits click event. Only KEY and BTN events are accepted, otherwise ValueError is raised. Example: 'KEY_A' """ event = translate_name(event_name) device.emit_click(event, syn) def emit_combo(device, event_names, syn=True): """ Wrapper for uinput.emit_combo. Emits sequence of events. Example: ['KEY_LEFTCTRL', 'KEY_LEFTALT', 'KEY_F5'] """ events = [translate_name(en) for en in event_names] device.emit_combo(events, syn)