fixed keyboard
This commit is contained in:
parent
704943ba62
commit
b9aa0ee5f3
@ -1,12 +1,20 @@
|
|||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
import sys
|
import sys
|
||||||
from os import path
|
from os import path
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class DeviceType(Enum):
|
||||||
|
KEYBOARD = 0
|
||||||
|
POINTER = 1
|
||||||
|
TOUCH = 2
|
||||||
|
OTHER = 3
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class DeviceInfo:
|
class DeviceInfo:
|
||||||
path: str
|
path: str
|
||||||
device_type: str
|
device_type: DeviceType
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
@ -57,8 +65,8 @@ def get_config() -> tuple[NetConfig, list[DeviceInfo]]:
|
|||||||
case "--event": value = "/dev/input/"
|
case "--event": value = "/dev/input/"
|
||||||
case "--full-path": pass
|
case "--full-path": pass
|
||||||
case "--type":
|
case "--type":
|
||||||
match args[n+1]:
|
match args[n+1].upper():
|
||||||
case "pointer" | "keyboard": key = "type"
|
case "POINTER" | "KEYBOARD" | "TOUCH" | "OTHER": key = "type"
|
||||||
case _: raise ValueError(f"Invalid device type {args[n+1]}")
|
case _: raise ValueError(f"Invalid device type {args[n+1]}")
|
||||||
n += 1
|
n += 1
|
||||||
match key:
|
match key:
|
||||||
@ -66,7 +74,8 @@ def get_config() -> tuple[NetConfig, list[DeviceInfo]]:
|
|||||||
value = f"{value}{args[n]}"
|
value = f"{value}{args[n]}"
|
||||||
if path.exists(value):
|
if path.exists(value):
|
||||||
devices_info[-1].path = value
|
devices_info[-1].path = value
|
||||||
case "type": devices_info[-1].device_type = args[n]
|
case "type":
|
||||||
|
devices_info[-1].device_type = getattr(DeviceType, args[n].upper())
|
||||||
n += 1
|
n += 1
|
||||||
|
|
||||||
if cfg.ip_address == "auto":
|
if cfg.ip_address == "auto":
|
||||||
|
@ -2,15 +2,101 @@ from evdev import UInput
|
|||||||
from socket import socket
|
from socket import socket
|
||||||
import json
|
import json
|
||||||
from typing import Generator
|
from typing import Generator
|
||||||
|
from ..config import DeviceType
|
||||||
|
|
||||||
|
|
||||||
|
class EventSequence:
|
||||||
|
def __init__(self, name: str = "", sequence: list[tuple[int, int, int]] = None):
|
||||||
|
if sequence is None:
|
||||||
|
sequence = []
|
||||||
|
self.name = name
|
||||||
|
self.sequence = sequence
|
||||||
|
self.curr = {}
|
||||||
|
|
||||||
|
def add(self, event_type: int, event_code: int, event_value: int):
|
||||||
|
self.sequence.append((event_type, event_code, event_value))
|
||||||
|
|
||||||
|
def next(self, fd: int, event_type: int, event_code: int, event_value: int):
|
||||||
|
if len(self.sequence) == 0:
|
||||||
|
return True
|
||||||
|
if fd not in self.curr:
|
||||||
|
self.curr[fd] = 0
|
||||||
|
if self.sequence[self.curr[fd]] == (event_type, event_code, event_value):
|
||||||
|
self.curr[fd] += 1
|
||||||
|
if self.curr[fd] == len(self.sequence):
|
||||||
|
self.curr[fd] = 0
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
self.curr[fd] = 0
|
||||||
|
return False
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
self.curr = {}
|
||||||
|
|
||||||
|
|
||||||
|
class SequenceCollection:
|
||||||
|
def __init__(self, name: str = "", sequences: list[EventSequence] = None):
|
||||||
|
if sequences is None:
|
||||||
|
sequences = []
|
||||||
|
self.name = name
|
||||||
|
self.sequences = sequences
|
||||||
|
|
||||||
|
def add(self, sequence: EventSequence):
|
||||||
|
self.sequences.append(sequence)
|
||||||
|
|
||||||
|
def next(self, *args):
|
||||||
|
return sum([sequence.next(*args) for sequence in self.sequences])
|
||||||
|
|
||||||
|
def reset(self):
|
||||||
|
for sequence in self.sequences:
|
||||||
|
sequence.reset()
|
||||||
|
|
||||||
|
|
||||||
|
def get_double_control_sequences() -> SequenceCollection:
|
||||||
|
return SequenceCollection("doublecontrol", [
|
||||||
|
EventSequence("rllr", [
|
||||||
|
(4, 4, 29),
|
||||||
|
(1, 29, 1),
|
||||||
|
(0, 0, 0),
|
||||||
|
(4, 4, 29),
|
||||||
|
(0, 0, 0),
|
||||||
|
(4, 4, 157)
|
||||||
|
]),
|
||||||
|
EventSequence("lrrl", [
|
||||||
|
(4, 4, 157),
|
||||||
|
(1, 97, 1),
|
||||||
|
(0, 0, 0),
|
||||||
|
(4, 4, 157),
|
||||||
|
(0, 0, 0),
|
||||||
|
(4, 4, 29)
|
||||||
|
]),
|
||||||
|
EventSequence("rlrl", [
|
||||||
|
(4, 4, 29),
|
||||||
|
(1, 29, 1),
|
||||||
|
(0, 0, 0),
|
||||||
|
(4, 4, 157),
|
||||||
|
(0, 0, 0),
|
||||||
|
(4, 4, 29)
|
||||||
|
]),
|
||||||
|
EventSequence("lrlr", [
|
||||||
|
(4, 4, 157),
|
||||||
|
(1, 97, 1),
|
||||||
|
(0, 0, 0),
|
||||||
|
(4, 4, 29),
|
||||||
|
(0, 0, 0),
|
||||||
|
(4, 4, 157)
|
||||||
|
])
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
def receive_devices(s: socket) -> Generator[tuple[int, UInput], None, None]:
|
def receive_devices(s: socket) -> Generator[tuple[int, UInput], None, None]:
|
||||||
while buf_size := int.from_bytes(s.recv(4), byteorder='big'):
|
while buf_size := int.from_bytes(s.recv(4), byteorder='big'):
|
||||||
fd = int.from_bytes(s.recv(4), byteorder='big')
|
fd = int.from_bytes(s.recv(4), byteorder='big')
|
||||||
|
device_type = DeviceType(int.from_bytes(s.recv(1), byteorder='big'))
|
||||||
cap = json.loads(s.recv(buf_size).decode())
|
cap = json.loads(s.recv(buf_size).decode())
|
||||||
cap = {int(key): cap[key] for key in cap}
|
cap = {int(key): cap[key] for key in cap}
|
||||||
del cap[0]
|
del cap[0]
|
||||||
yield fd, UInput(cap, name=f"web-evdev-device-fd{fd}")
|
yield fd, UInput(cap, name=f"web-evdev-device-fd{fd}"), device_type
|
||||||
|
|
||||||
|
|
||||||
def receive_event(s: socket) -> tuple[int, tuple[int, int, int]]:
|
def receive_event(s: socket) -> tuple[int, tuple[int, int, int]]:
|
||||||
@ -21,28 +107,46 @@ def receive_event(s: socket) -> tuple[int, tuple[int, int, int]]:
|
|||||||
return fd, (event_type, code, value)
|
return fd, (event_type, code, value)
|
||||||
|
|
||||||
|
|
||||||
def handle_client(s: socket):
|
def reset_control(d: dict[int: tuple[UInput, DeviceType]]):
|
||||||
d = {}
|
print("trying to reset controls")
|
||||||
for fd, device in receive_devices(s):
|
for fd in d:
|
||||||
d[fd] = device
|
if d[fd][1] != DeviceType.KEYBOARD:
|
||||||
|
continue
|
||||||
|
print(f"resetting control keys on keyboard {fd}")
|
||||||
|
for key in [29, 97]:
|
||||||
|
d[fd][0].write(1, key, 0)
|
||||||
|
d[fd][0].syn()
|
||||||
|
|
||||||
active_keys = {}
|
|
||||||
|
def handle_client(s: socket):
|
||||||
|
control_sequences = get_double_control_sequences()
|
||||||
|
d = {}
|
||||||
|
for fd, device, device_type in receive_devices(s):
|
||||||
|
d[fd] = (device, device_type)
|
||||||
|
|
||||||
|
got_control = False
|
||||||
while True:
|
while True:
|
||||||
fd, event = receive_event(s)
|
fd, event = receive_event(s)
|
||||||
if event[0] == 1:
|
|
||||||
active_keys[event[1]] = event[2]
|
|
||||||
print(i for i in active_keys if active_keys[i])
|
|
||||||
if fd == 4294967295:
|
if fd == 4294967295:
|
||||||
s.close()
|
s.close()
|
||||||
for fd in d:
|
for fd in d:
|
||||||
d[fd].close()
|
d[fd][0].close()
|
||||||
print("Exiting")
|
print("Exiting")
|
||||||
exit()
|
exit()
|
||||||
elif fd == 4278124286:
|
elif fd == 4278124286:
|
||||||
|
got_control = True
|
||||||
|
control_sequences.reset()
|
||||||
print("Control was given")
|
print("Control was given")
|
||||||
elif fd == 4261281277:
|
elif fd == 4261281277:
|
||||||
|
reset_control(d)
|
||||||
print("Control was taken")
|
print("Control was taken")
|
||||||
elif event[0] == 0:
|
|
||||||
d[fd].syn()
|
|
||||||
else:
|
else:
|
||||||
d[fd].write(*event)
|
if not got_control:
|
||||||
|
if event[0] == 0:
|
||||||
|
d[fd][0].syn()
|
||||||
|
else:
|
||||||
|
d[fd][0].write(*event)
|
||||||
|
else:
|
||||||
|
if d[fd][1] == DeviceType.KEYBOARD:
|
||||||
|
if control_sequences.next(fd, *event):
|
||||||
|
got_control = False
|
||||||
|
@ -4,13 +4,14 @@ from select import select
|
|||||||
import json
|
import json
|
||||||
from time import time
|
from time import time
|
||||||
|
|
||||||
from ..config import DeviceInfo
|
from ..config import DeviceInfo, DeviceType
|
||||||
|
|
||||||
|
|
||||||
def send_device(s: socket, device: InputDevice):
|
def send_device(s: socket, device: InputDevice, device_type: DeviceType):
|
||||||
buf = json.dumps(device.capabilities()).encode()
|
buf = json.dumps(device.capabilities()).encode()
|
||||||
s.sendall(len(buf).to_bytes(4, byteorder='big'))
|
s.sendall(len(buf).to_bytes(4, byteorder='big'))
|
||||||
s.sendall(device.fd.to_bytes(4, byteorder='big'))
|
s.sendall(device.fd.to_bytes(4, byteorder='big'))
|
||||||
|
s.sendall(device_type.value.to_bytes(1, byteorder='big'))
|
||||||
s.sendall(buf)
|
s.sendall(buf)
|
||||||
|
|
||||||
|
|
||||||
@ -31,57 +32,9 @@ def exit_nice(s: socket, d: dict[int: InputDevice], guest_input: bool):
|
|||||||
exit()
|
exit()
|
||||||
|
|
||||||
|
|
||||||
def double_control(s: socket,
|
def give_control(s: socket, d: dict[int: InputDevice]):
|
||||||
d: dict[int: InputDevice],
|
|
||||||
active_keys: list[int],
|
|
||||||
guest_input: bool,
|
|
||||||
ctrl2: bool,
|
|
||||||
device_fd: int,
|
|
||||||
event_value: int) -> bool:
|
|
||||||
if 14 in active_keys:
|
|
||||||
exit_nice(s, d, guest_input)
|
|
||||||
elif not ctrl2:
|
|
||||||
guest_input = not guest_input
|
|
||||||
event = ({29, 157} ^ {event_value}).pop()
|
|
||||||
send_input_event(s, device_fd, InputEvent(0, 0, 4, 4, event))
|
|
||||||
if guest_input:
|
|
||||||
send_input_event(s, device_fd, InputEvent(
|
|
||||||
0, 0, 1,
|
|
||||||
event if event == 29 else 97,
|
|
||||||
1,
|
|
||||||
))
|
|
||||||
send_input_event(s, device_fd, InputEvent(0, 0, 0, 0, 0))
|
|
||||||
print("Giving up control")
|
|
||||||
s.sendall(b'\xfe' * 20)
|
s.sendall(b'\xfe' * 20)
|
||||||
for fd in d:
|
print("Giving up control")
|
||||||
d[fd].grab()
|
|
||||||
else:
|
|
||||||
send_input_event(s, device_fd, InputEvent(
|
|
||||||
0, 0, 1,
|
|
||||||
event if event == 29 else 97,
|
|
||||||
0,
|
|
||||||
))
|
|
||||||
send_input_event(s, device_fd, InputEvent(0, 0, 0, 0, 0))
|
|
||||||
print("Taking control")
|
|
||||||
s.sendall(b'\xfd' * 20)
|
|
||||||
for fd in d:
|
|
||||||
d[fd].ungrab()
|
|
||||||
return guest_input
|
|
||||||
|
|
||||||
|
|
||||||
def handle_client(s: socket, devices_info: list[DeviceInfo]):
|
|
||||||
|
|
||||||
ctrl2 = False
|
|
||||||
guest_input = True
|
|
||||||
d = []
|
|
||||||
device_types = {}
|
|
||||||
for device_info in devices_info:
|
|
||||||
d.append(InputDevice(device_info.path))
|
|
||||||
device_types[device_info.path] = device_info.device_type
|
|
||||||
send_device(s, d[-1])
|
|
||||||
s.sendall((0).to_bytes(4, byteorder='big'))
|
|
||||||
d = {device.fd: device for device in d}
|
|
||||||
device_types = {fd: device_types[d[fd].path] for fd in d}
|
|
||||||
prnt = time()
|
prnt = time()
|
||||||
while True:
|
while True:
|
||||||
for fd in d:
|
for fd in d:
|
||||||
@ -95,14 +48,52 @@ def handle_client(s: socket, devices_info: list[DeviceInfo]):
|
|||||||
continue
|
continue
|
||||||
for fd in d:
|
for fd in d:
|
||||||
d[fd].grab()
|
d[fd].grab()
|
||||||
|
|
||||||
|
|
||||||
|
def take_control(s: socket, d: dict[int: InputDevice]):
|
||||||
|
print("Taking control")
|
||||||
|
s.sendall(b'\xfd' * 20)
|
||||||
|
for fd in d:
|
||||||
|
d[fd].ungrab()
|
||||||
|
|
||||||
|
|
||||||
|
def double_control(s: socket,
|
||||||
|
d: dict[int: InputDevice],
|
||||||
|
active_keys: list[int],
|
||||||
|
guest_input: bool,
|
||||||
|
ctrl2: bool) -> bool:
|
||||||
|
if 14 in active_keys:
|
||||||
|
exit_nice(s, d, guest_input)
|
||||||
|
elif not ctrl2:
|
||||||
|
guest_input = not guest_input
|
||||||
|
if guest_input:
|
||||||
|
give_control(s, d)
|
||||||
|
else:
|
||||||
|
take_control(s, d)
|
||||||
|
return guest_input
|
||||||
|
|
||||||
|
|
||||||
|
def handle_client(s: socket, devices_info: list[DeviceInfo]):
|
||||||
|
ctrl2 = False
|
||||||
|
guest_input = True
|
||||||
|
d = []
|
||||||
|
device_types = {}
|
||||||
|
for device_info in devices_info:
|
||||||
|
device = InputDevice(device_info.path)
|
||||||
|
d.append(device)
|
||||||
|
device_types[device.fd] = device_info.device_type
|
||||||
|
send_device(s, device, device_info.device_type)
|
||||||
|
s.sendall((0).to_bytes(4, byteorder='big'))
|
||||||
|
d = {device.fd: device for device in d}
|
||||||
|
give_control(s, d)
|
||||||
while True:
|
while True:
|
||||||
r, w, x = select(d, [], [])
|
r, w, x = select(d, [], [])
|
||||||
for fd in r:
|
for fd in r:
|
||||||
events = [event for event in d[fd].read()]
|
events = [event for event in d[fd].read()]
|
||||||
if device_types[fd] == "keyboard":
|
if device_types[fd] == DeviceType.KEYBOARD:
|
||||||
active_keys = d[fd].active_keys()
|
active_keys = d[fd].active_keys()
|
||||||
if 29 in active_keys and 97 in active_keys:
|
if 29 in active_keys and 97 in active_keys:
|
||||||
guest_input = double_control(s, d, active_keys, guest_input, ctrl2, fd, events[0].value)
|
guest_input = double_control(s, d, active_keys, guest_input, ctrl2)
|
||||||
ctrl2 = True
|
ctrl2 = True
|
||||||
else:
|
else:
|
||||||
ctrl2 = False
|
ctrl2 = False
|
||||||
|
Loading…
Reference in New Issue
Block a user