def __init__(self): self.device = Device() self.device.name = "Virtual Keyboard Mouse" self.__add_mouse_keyboard_events() self.uinput = self.device.create_uinput_device() self._delay = 0.01
def create_device(self): self.device = Device() self.device.name = "Virtual Keyboard Mouse" self.__add_mouse_keyboard_events() self.uinput = self.device.create_uinput_device() # 在创建虚拟输入设备后等一秒,马上使用设备, # 会导致事件不生效。 sleep(1)
def start_filtering( evdev: Device, filter: Callable[[InputEvent], Union[InputEvent, None]]) -> NoReturn: """Start filtering input from a device.""" # grab the device to ourselves - now only we see the events it emits evdev.grab() # create a copy of the device that we can write to - this will emit the filtered events to anyone who listens uidev = evdev.create_uinput_device() while True: # since the descriptor is blocking, this blocks until there are events available for e in evdev.events(): if (f := filter(e)) is not None: send_event_packet(uidev, f)
def __init__(self, device=None): """ device: /dev/input/eventX, default: all keyboard. """ self._hotkey_list = [] self._hotkey_seq_dict = {} self.devices = [] mouses, kbms = libkbm.getkbm() if len(kbms) <= 0: raise HotKeyError("没有发现至少一个键盘。") if device is None: self.kbms = kbms else: if device not in kbms: raise ValueError(f"{device} 不是键盘设备。") else: self.kbms = device self.LISTEN = 1 self.REPLACE = 2 self._mode = self.LISTEN # 把device注册到selectors self._selector = DefaultSelector() self._fileobjs = [] for device in self.kbms: fd = open(device, "rb") devfd = Device(fd) self._selector.register(devfd.fd, EVENT_READ, devfd) self._fileobjs.append(fd)
def get_device(device_path: str) -> Device: """Safely get an evdev device handle.""" fd = open(device_path, 'rb') evdev = Device(fd) try: yield evdev finally: fd.close()
def registers(kbms): selector = selectors.DefaultSelector() for kbm in kbms: print("加入:", kbm) fd = os.open(kbm, os.O_NONBLOCK | os.O_RDONLY) fdobj = open(fd, "rb") #fcntl.fcntl(fd, fcntl.F_SETFL, os.O_NONBLOCK) device = Device(fdobj) selector.register(device.fd, selectors.EVENT_READ, data=device) return selector
def getkbm(baseinput="/dev/input"): mouses = [] keyboards = [] for dev in os.listdir(baseinput): devpath = path.join(baseinput, dev) if not path.isdir(devpath): devfd = open(devpath, 'rb') else: continue try: device = Device(devfd) except (OSError, Exception) as e: logger.info("打开 {} 异常:{}".format(dev, e)) continue if device.name == "Virtual Keyboard Mouse": continue #if device.has(EV_REL.REL_X) device.has(EV_REL.REL_Y and device.has(EV_KEY.BTN_LEFT) and device.has(EV_KEY.BTN_RIGHT) and device.has(EV_KEY.BTN_MIDDLE) and device.has(EV_KEY.WHEEL): MOUSE = [ EV_REL.REL_X, EV_REL.REL_Y, EV_REL.REL_WHEEL, EV_KEY.BTN_LEFT, EV_KEY.BTN_RIGHT, EV_KEY.BTN_MIDDLE ] KEYBOARD = [ EV_KEY.KEY_ESC, EV_KEY.KEY_SPACE, EV_KEY.KEY_BACKSPACE, EV_KEY.KEY_0, EV_KEY.KEY_A, EV_KEY.KEY_Z, EV_KEY.KEY_9, EV_KEY.KEY_F2 ] if all(map(device.has, MOUSE)): logger.info("应该是鼠标了: {} 路径:{}".format(device.name, device.fd)) mouses.append(devpath) elif all(map(device.has, KEYBOARD)): logger.info("应该是键盘了: {} 路径:{}".format(device.name, device.fd)) keyboards.append(devpath) else: logger.info("其他输入设备:", device.name, "路径:", device.fd) devfd.close() return (mouses, keyboards)
def registers(kbms): selector = selectors.DefaultSelector() for kbm in kbms: print("加入:", kbm) fd = os.open(kbm, os.O_NONBLOCK | os.O_RDONLY) #fd = os.open(kbm, os.O_NONBLOCK | os.O_RDWR) fdobj = open(fd, "rb") device = Device(fdobj) if MODE == REPLACE: #uinput.grab() pass elif MODE == LISTEN: pass selector.register(device.fd, selectors.EVENT_READ, data=device) return selector
if keyboard_detected != 2: print("Can't find keyboard, code " + str(keyboard_detected)) if touchpad_detected != 2: print("Can't find touchpad, code " + str(touchpad_detected)) if touchpad_detected == 2 and not device_id.isnumeric(): print("Can't find device id") sys.exit(1) else: break sleep(0.1) # Start monitoring the touchpad # fd_t = open('/dev/input/event' + str(touchpad), 'rb') fcntl(fd_t, F_SETFL, O_NONBLOCK) d_t = Device(fd_t) # Retrieve touchpad dimensions # ai = d_t.absinfo[EV_ABS.ABS_X] (minx, maxx) = (ai.minimum, ai.maximum) ai = d_t.absinfo[EV_ABS.ABS_Y] (miny, maxy) = (ai.minimum, ai.maximum) # Start monitoring the keyboard (numlock) # fd_k = open('/dev/input/event' + str(keyboard), 'rb') fcntl(fd_k, F_SETFL, O_NONBLOCK) d_k = Device(fd_k) # Create a new keyboard device to send numpad events # dev = Device() dev.name = "Asus Touchpad/Numpad" dev.enable(EV_KEY.KEY_KP1)
class VirtualKeyboardMouse: """ 虚拟键盘鼠标 """ def __init__(self): self._delay = 0.01 # 鼠标事件类型 mouse0 = [evbit(0, i) for i in range(15)] mouse1 = [evbit(1, i) for i in range(272, 276 + 1)] mouse2 = [evbit(2, 0), evbit(2, 1), evbit(2, 8), evbit(2, 11)] mouse = mouse0 + mouse1 + mouse2 # 键盘事件类型 keyboard = [evbit(1, i) for i in range(1, 128 + 1)] self.events = mouse + keyboard # key event 可输出的字符元组 self.keyevents2strings = [] for e in self.events: if e.name.startswith("KEY_"): self.keyevents2strings.append(e.name.lstrip("KEY_")) elif e.name.startswith("BTN_"): self.keyevents2strings.append(e.name.lstrip("BTN_")) def create_device(self): self.device = Device() self.device.name = "Virtual Keyboard Mouse" self.__add_mouse_keyboard_events() self.uinput = self.device.create_uinput_device() # 在创建虚拟输入设备后等一秒,马上使用设备, # 会导致事件不生效。 sleep(1) @property def delay(self): return self._delay @delay.setter def delay(self, t): if isinstance(t, float) or isinstance(t, int): self._delay = t else: raise ValueError("require is int or float unit seconds.") def __add_mouse_keyboard_events(self): """ 为虚拟键鼠添加鼠标事件。 """ self.device.enable(ev.EV_MSC.MSC_SCAN) # LEDs #led = [ evbit(17, 0), evbit(17, 1), evbit(17, 2) ] for e in self.events: self.device.enable(e) def listkey(self): """ list all support key. """ for e in self.keyevents2strings: print(e) def __mousebtn2seq(self, btn, downup=1): """ 鼠标点击。 param: btn: LEFT, RIGHT, MIDDLE param: downup: 1 or 0 """ btn = btn.upper() if btn == "LEFT": event_seq = [ InputEvent(ev.EV_MSC.MSC_SCAN, value=4), InputEvent(ev.EV_KEY.BTN_LEFT, value=downup), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] elif btn == "RIGHT": event_seq = [ InputEvent(ev.EV_MSC.MSC_SCAN, value=4), InputEvent(ev.EV_KEY.BTN_RIGHT, value=downup), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] elif btn == "MIDDLE": event_seq = [ InputEvent(ev.EV_MSC.MSC_SCAN, value=4), InputEvent(ev.EV_KEY.BTN_MIDDLE, value=downup), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] else: raise ValueError("btn require is LEFT or RIGHT or MIDDLE") return event_seq def __mousemove2seq(self, rel_x=0, rel_y=0): """ param: (rel_x, rel_y) """ if isinstance(rel_x, int) and isinstance(rel_y, int): pass else: raise ValueError("rel_x rel_y require is int") event_seq = [ InputEvent(ev.EV_REL.REL_X, value=rel_x), InputEvent(ev.EV_REL.REL_Y, value=rel_y), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] return event_seq def __mousewheel2seq(self, updown=1): """ EV_REL.REL_0B value 与鼠标滚轮方向对应为 -120 or 120 param: updown: 鼠标滚轮方向,value=1:向上,value=-1 向下 """ if updown == 1: event_seq = [ InputEvent(ev.EV_REL.REL_WHEEL, value=1), InputEvent(ev.EV_REL.REL_0B, value=120), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] elif updown == -1: event_seq = [ InputEvent(ev.EV_REL.REL_WHEEL, value=-1), InputEvent(ev.EV_REL.REL_0B, value=-120), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] else: raise ValueError("updown chioce: 1 or -1.") return event_seq def __key2seq(self, key, downup=1): """ 构建事件序列。 """ if downup == 1 or downup == 0: pass else: raise ValueError("param: downup chioce 1 or 0.") shiftdown = [ InputEvent(ev.EV_MSC.MSC_SCAN, value=4), InputEvent(evbit("KEY_LEFTSHIFT"), value=1), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] shiftup = [ InputEvent(ev.EV_MSC.MSC_SCAN, value=4), InputEvent(evbit("KEY_LEFTSHIFT"), value=0), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] key_seq = [ InputEvent(ev.EV_MSC.MSC_SCAN, value=4), InputEvent(evbit("KEY_" + key.upper()), value=downup), InputEvent(ev.EV_SYN.SYN_REPORT, value=0) ] if key.isupper(): event_seq = shiftdown + key_seq + shiftup elif key.islower(): event_seq = key_seq elif key.isdigit(): event_seq = key_seq return event_seq def keydown(self, key): """ 按下 key. """ self.uinput.send_events(self.__key2seq(key, 1)) sleep(self._delay) def keyup(self, key): """ 松开 key. """ self.uinput.send_events(self.__key2seq(key, 0)) sleep(self.delay) def key(self, key): self.keydown(key) self.keyup(key) def ctrlkey(self, key): """ ctrl+key """ self.keydown("LEFTCTRL") self.key(key) self.keyup("LEFTCTRL") def shiftkey(self, key): """ shift+key """ self.keydown("LEFTSHIFT") self.key(key) self.keyup("LEFTSHIFT") def altkey(self, key): """ alt+key """ self.keydown("LEFTALT") self.key(key) self.keyup("LEFTALT") def mousebtndown(self, btn): self.uinput.send_events(self.__mousebtn2seq(btn, downup=1)) sleep(self._delay) def mousebtnup(self, btn): self.uinput.send_events(self.__mousebtn2seq(btn, downup=0)) sleep(self._delay) def mouseclick(self, btn): # mouse click event list self.mousebtndown(btn) self.mousebtnup(btn) def mousewheel(self, updown): """ updown: "UP" or "DOWN" """ if updown == "UP": self.uinput.send_events(self.__mousewheel2seq(1)) elif updown == "DOWN": self.uinput.send_events(self.__mousewheel2seq(-1)) else: raise ValueError("updown: choice UP or DOWN") sleep(self._delay) def mousemove_relative(self, x, y): self.uinput.send_events(self.__mousemove2seq(x, y)) sleep(self._delay) def mousemove(self, x, y): """ 还未实现 """ #self.uinput.send_events(self.__mousemove2seq(x, y)) logger.warn("还未实现: mousemove(x, y)")
log.error("Can't find keyboard (code: %s)", keyboard_detected) if touchpad_detected != 2: log.error("Can't find touchpad (code: %s)", touchpad_detected) if touchpad_detected == 2 and not device_id.isnumeric(): log.error("Can't find device id") sys.exit(1) else: break sleep(model_layout.try_sleep) # Start monitoring the touchpad fd_t = open('/dev/input/event' + str(touchpad), 'rb') fcntl(fd_t, F_SETFL, os.O_NONBLOCK) d_t = Device(fd_t) # Retrieve touchpad dimensions # ai = d_t.absinfo[EV_ABS.ABS_X] (minx, maxx) = (ai.minimum, ai.maximum) ai = d_t.absinfo[EV_ABS.ABS_Y] (miny, maxy) = (ai.minimum, ai.maximum) log.debug('Touchpad min-max: x %d-%d, y %d-%d', minx, maxx, miny, maxy) # Start monitoring the keyboard (numlock) fd_k = open('/dev/input/event' + str(keyboard), 'rb') fcntl(fd_k, F_SETFL, os.O_NONBLOCK) d_k = Device(fd_k)
def send_event_packet(device: Device, event: InputEvent): """Send an event packet properly ending with a SYN_REPORT.""" packet = [event, InputEvent(libevdev.EV_SYN.SYN_REPORT, 0)] device.send_events(packet)