mirror of
https://github.com/comma-hacks/webrtc.git
synced 2025-10-06 00:26:52 +08:00
migrate mousemove to libevdev
This commit is contained in:
@@ -1,41 +1,85 @@
|
|||||||
import pyautogui
|
|
||||||
import numpy
|
import numpy
|
||||||
import evdev
|
|
||||||
import keymap
|
import keymap
|
||||||
|
import libevdev
|
||||||
pyautogui.FAILSAFE = False
|
from libevdev import InputEvent, InputAbsInfo
|
||||||
|
|
||||||
class DesktopControlInterface():
|
class DesktopControlInterface():
|
||||||
def __init__(self, resolution):
|
def __init__(self, resolution):
|
||||||
|
global uinput
|
||||||
self.resolution = resolution
|
self.resolution = resolution
|
||||||
self.ui = evdev.UInput()
|
self.dev = libevdev.Device()
|
||||||
self.valid_actions = ["keyboard", "click", "rightclick", "mousemove", "joystick", "paste"]
|
self.dev.name = 'virtual mouse and keyboard'
|
||||||
|
x_info = InputAbsInfo(minimum=0, maximum=resolution.width, resolution=200)
|
||||||
|
self.dev.enable(libevdev.EV_ABS.ABS_X, data=x_info)
|
||||||
|
y_info = InputAbsInfo(minimum=0, maximum=resolution.height, resolution=200)
|
||||||
|
self.dev.enable(libevdev.EV_ABS.ABS_Y, data=y_info)
|
||||||
|
self.dev.enable(libevdev.EV_KEY.BTN_LEFT)
|
||||||
|
self.dev.enable(libevdev.EV_KEY.BTN_MIDDLE)
|
||||||
|
self.dev.enable(libevdev.EV_KEY.BTN_RIGHT)
|
||||||
|
self.uinput = self.dev.create_uinput_device()
|
||||||
|
|
||||||
def handle_action(self, action, data):
|
def handle_action(self, action, data):
|
||||||
if action == "mousemove":
|
if action == "mousemove":
|
||||||
x = numpy.interp(data["cursorPositionX"], (0, data["displayWidth"]), (0, self.resolution.width))
|
x = numpy.interp(data["cursorPositionX"], (0, data["displayWidth"]), (0, self.resolution.width))
|
||||||
y = numpy.interp(data["cursorPositionY"], (0, data["displayHeight"]), (0, self.resolution.height))
|
y = numpy.interp(data["cursorPositionY"], (0, data["displayHeight"]), (0, self.resolution.height))
|
||||||
pyautogui.moveTo(x, y, _pause=False)
|
print(f"mousemove {x} {y}")
|
||||||
# elif action == "joystick":
|
events = [InputEvent(libevdev.EV_ABS.ABS_X, int(x)),
|
||||||
# x = numpy.interp(data["x"], (-38, 38), (0, self.resolution.width))
|
InputEvent(libevdev.EV_ABS.ABS_Y, int(y)),
|
||||||
# y = numpy.interp(data["y"], (-38, 38), (self.resolution.height, 0))
|
InputEvent(libevdev.EV_SYN.SYN_REPORT, 0)]
|
||||||
# print(f'{data["y"]} {self.resolution.height} {y}')
|
self.uinput.send_events(events)
|
||||||
# pyautogui.moveTo(x, y, _pause=False)
|
|
||||||
elif action == "click":
|
elif action == "mousedown":
|
||||||
pyautogui.click()
|
pass
|
||||||
|
elif action == "mouseup":
|
||||||
|
pass
|
||||||
elif action == "rightclick":
|
elif action == "rightclick":
|
||||||
pyautogui.rightClick()
|
pass
|
||||||
elif action == "keyboard":
|
elif action == "keyboard":
|
||||||
try:
|
try:
|
||||||
# keymap.reload()
|
# keymap.reload()
|
||||||
osKey = keymap.iOStoLinux[data["key"]]
|
osKey = keymap.iOStoLinux[data["key"]]
|
||||||
self.ui.write(evdev.ecodes.EV_KEY, osKey, data["direction"])
|
print(osKey)
|
||||||
self.ui.syn()
|
# self.ui.write(e.EV_KEY, osKey, data["direction"])
|
||||||
|
# self.ui.syn()
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print(f"Unknown key: {data['key']}")
|
print(f"Unknown key: {data['key']}")
|
||||||
elif action == "paste":
|
elif action == "paste":
|
||||||
|
pass
|
||||||
# might as well support the secureput protocol completely
|
# might as well support the secureput protocol completely
|
||||||
pyautogui.write(data["payload"]["string"])
|
# pyautogui.write(data["payload"]["string"])
|
||||||
|
|
||||||
|
def supports(self, action):
|
||||||
|
return action in ["keyboard", "click", "rightclick", "mousemove", "joystick", "paste"]
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
self.ui.close()
|
pass
|
||||||
|
# self.ui.close()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import time
|
||||||
|
import libevdev
|
||||||
|
from libevdev import InputEvent, InputAbsInfo
|
||||||
|
dev = libevdev.Device()
|
||||||
|
dev.name = 'some test device'
|
||||||
|
a = InputAbsInfo(minimum=0, maximum=1920, resolution=200)
|
||||||
|
dev.enable(libevdev.EV_ABS.ABS_X, data=a)
|
||||||
|
a = InputAbsInfo(minimum=0, maximum=1080, resolution=200)
|
||||||
|
dev.enable(libevdev.EV_ABS.ABS_Y, data=a)
|
||||||
|
dev.enable(libevdev.EV_KEY.BTN_LEFT)
|
||||||
|
dev.enable(libevdev.EV_KEY.BTN_MIDDLE)
|
||||||
|
dev.enable(libevdev.EV_KEY.BTN_RIGHT)
|
||||||
|
|
||||||
|
uinput = dev.create_uinput_device()
|
||||||
|
print("New device at {} ({})".format(uinput.devnode, uinput.syspath))
|
||||||
|
|
||||||
|
# Sleep for a bit so udev, libinput, Xorg, Wayland, ... all have had
|
||||||
|
# a chance to see the device and initialize it. Otherwise the event
|
||||||
|
# will be sent by the kernel but nothing is ready to listen to the
|
||||||
|
# device yet.
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
|
||||||
|
events = [InputEvent(libevdev.EV_ABS.ABS_X, 1900),
|
||||||
|
InputEvent(libevdev.EV_ABS.ABS_Y, 1000),
|
||||||
|
InputEvent(libevdev.EV_SYN.SYN_REPORT, 0)]
|
||||||
|
@@ -12,7 +12,7 @@ class DesktopStreamTrack(VideoStreamTrack):
|
|||||||
def __init__(self):
|
def __init__(self):
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self.resolution = Xlib.display.Display(os.environ["DISPLAY"]).screen().root.get_geometry()
|
self.resolution = Xlib.display.Display(os.environ["DISPLAY"]).screen().root.get_geometry()
|
||||||
self.control_interface = DesktopControlInterface(self.resolution)
|
self.input = DesktopControlInterface(self.resolution)
|
||||||
options = {
|
options = {
|
||||||
'draw_mouse': '1',
|
'draw_mouse': '1',
|
||||||
'i':':0.0+0,0',
|
'i':':0.0+0,0',
|
||||||
@@ -30,13 +30,10 @@ class DesktopStreamTrack(VideoStreamTrack):
|
|||||||
frame.pts = pts
|
frame.pts = pts
|
||||||
frame.time_base = time_base
|
frame.time_base = time_base
|
||||||
return frame
|
return frame
|
||||||
|
|
||||||
def handle_action(self, action, data):
|
|
||||||
self.control_interface.handle_action(action, data)
|
|
||||||
|
|
||||||
def stop(self) -> None:
|
def stop(self) -> None:
|
||||||
super().stop()
|
super().stop()
|
||||||
self.control_interface.stop()
|
self.input.stop()
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
from time import time_ns
|
from time import time_ns
|
||||||
|
@@ -164,8 +164,8 @@ async def signal(signaling):
|
|||||||
print(data)
|
print(data)
|
||||||
elif data["type"] == "joystick":
|
elif data["type"] == "joystick":
|
||||||
webjoystick(data["x"], data["y"])
|
webjoystick(data["x"], data["y"])
|
||||||
elif desktop_track and data["type"] in desktop_track.control_interface.valid_actions:
|
elif desktop_track and desktop_track.input.supports(data["type"]):
|
||||||
desktop_track.handle_action(data["type"], data)
|
desktop_track.input.handle_action(data["type"], data)
|
||||||
else:
|
else:
|
||||||
print("ignored message")
|
print("ignored message")
|
||||||
print(data)
|
print(data)
|
||||||
|
Reference in New Issue
Block a user