rpikvm/hidinput.py

169 lines
4.0 KiB
Python
Raw Normal View History

2020-05-24 11:08:49 +02:00
from flask import Response
from flask import Flask
from flask import render_template
from flask import request
2020-06-05 16:32:24 +02:00
from flask_socketio import SocketIO
2020-05-24 11:08:49 +02:00
import argparse
import json
2020-06-07 14:54:55 +02:00
import struct
from hidkeycodes import hidkeycodes
2020-06-04 13:43:51 +02:00
from jskeycodes import jscodehidmap
2020-05-24 11:08:49 +02:00
# initialize a flask object
app = Flask(__name__)
2020-06-05 16:32:24 +02:00
socketio = SocketIO(app)
2020-05-24 11:08:49 +02:00
hiddev = None
2020-06-05 15:04:27 +02:00
hidmouseabs = None
2020-05-24 11:08:49 +02:00
2020-06-04 13:50:01 +02:00
def hid_init():
global hiddev, hidmouseabs
2020-06-04 13:50:01 +02:00
hiddev = open('/dev/hidg0', 'rb+')
hidmouseabs = open('/dev/hidg1', 'rb+')
2020-06-04 13:50:01 +02:00
2020-05-24 11:08:49 +02:00
def hid_write(data):
2020-05-24 11:08:49 +02:00
if hiddev is None:
return False
2020-05-25 02:35:41 +02:00
hiddev.write(data)
2020-05-24 11:08:49 +02:00
hiddev.flush()
2020-06-04 13:50:01 +02:00
2020-06-05 15:04:27 +02:00
def hid_mouse_writeabs(btn, x, y, wheel):
if hidmouseabs is None:
return False
data = bytearray(6)
data[0] = btn
data[1:3] = x.to_bytes(2, byteorder='little')
data[3:5] = y.to_bytes(2, byteorder='little')
data[5] = wheel
hidmouseabs.write(data)
hidmouseabs.flush()
2020-05-25 10:14:49 +02:00
def send_key(hidkey, shift, alt, ctlr, mod):
2020-05-25 02:35:41 +02:00
data = bytearray(8)
2020-05-24 13:09:38 +02:00
if shift:
2020-05-25 02:35:41 +02:00
data[0] += hidkeycodes['KEY_MOD_LSHIFT']
2020-05-24 13:09:38 +02:00
if alt:
2020-05-25 02:35:41 +02:00
data[0] += hidkeycodes['KEY_MOD_LALT']
2020-05-24 13:09:38 +02:00
if ctlr:
2020-05-25 02:35:41 +02:00
data[0] += hidkeycodes['KEY_MOD_LCTRL']
2020-05-25 01:29:17 +02:00
2020-05-25 10:14:49 +02:00
if mod and (hidkey == hidkeycodes['KEY_MOD_LMETA'] or hidkey == hidkeycodes['KEY_MOD_RMETA']):
2020-05-25 02:35:41 +02:00
data[0] += hidkey
2020-06-04 13:50:01 +02:00
hidkey = 0
2020-05-24 13:09:38 +02:00
2020-05-25 02:35:41 +02:00
data[2] = hidkey
hid_write(data)
hid_write(bytearray(8))
def get_hid_by_jscode(rawkeycode):
hidkeycode = None
hidkeyname = None
2020-05-24 11:08:49 +02:00
2020-06-04 13:43:51 +02:00
if rawkeycode in jscodehidmap:
hidkeyname = jscodehidmap[rawkeycode]
if hidkeyname in hidkeycodes:
hidkeycode = hidkeycodes[hidkeyname]
else:
print("Code for key {} not found in HID mapping".format(hidkeyname))
else:
print("Javascript code for key {} not found".format(rawkeycode))
2020-05-24 11:08:49 +02:00
print ("JS key: {} HID key: {}({})".format(rawkeycode, hidkeyname, hidkeycode))
2020-05-25 10:14:49 +02:00
return hidkeycode, (hidkeyname is not None and "MOD" in hidkeyname)
2020-05-24 11:08:49 +02:00
2020-05-24 11:08:49 +02:00
@app.route("/")
def index():
2020-06-04 13:43:51 +02:00
return render_template("hid.html")
2020-05-24 11:08:49 +02:00
@app.route("/kvm.html")
def kvm():
return render_template("kvm.html")
2020-05-25 01:55:31 +02:00
@app.route("/mouse.html")
2020-05-25 02:35:10 +02:00
def mouseindex():
2020-06-04 13:43:51 +02:00
return render_template("mouse.html")
2020-05-25 01:55:31 +02:00
@app.route("/keyboard.html")
def keyboardIndex():
return render_template("keyboard.html")
2020-06-05 15:04:27 +02:00
2020-05-24 11:08:49 +02:00
2020-06-07 14:54:55 +02:00
@socketio.on('mouseEventRaw')
def handle_mouseEvent(data):
print(data)
2020-06-07 15:07:12 +02:00
btn = data[0]
x = data[1]
y = data[2]
wheel = data[3]
2020-06-07 14:54:55 +02:00
print("RAW Btn: {}, X: {}, Y: {}, W: {}".format(btn, x, y, wheel))
2020-06-07 15:09:19 +02:00
hid_mouse_writeabs(btn, x, y, wheel)
2020-06-07 14:54:55 +02:00
2020-06-05 16:32:24 +02:00
@socketio.on('mouseEvent')
2020-06-07 14:29:55 +02:00
def handle_mouseEvent(data):
2020-06-05 16:42:23 +02:00
mouseevent = json.loads(data)
2020-06-05 16:32:24 +02:00
print(mouseevent)
btn = mouseevent['btn']
x = mouseevent['x']
y = mouseevent['y']
wheel = mouseevent['wheel']
2020-06-05 17:06:08 +02:00
wheel = wheel if wheel >= 0 else 255-abs(wheel)
2020-06-05 16:32:24 +02:00
print("X: {}, Y: {}".format(x, y))
hid_mouse_writeabs(btn, x, y, wheel)
2020-06-07 14:29:55 +02:00
@socketio.on('kbdEvent')
def handle_kbdEvent(data):
keyevent = json.loads(data)
print("Raw data: {}".format(data))
rawkeycode = keyevent['code']
2020-05-25 10:14:49 +02:00
hidkeycode, mod = get_hid_by_jscode(rawkeycode)
if hidkeycode is not None:
try:
send_key(
hidkeycode,
keyevent['shiftKey'],
keyevent['altKey'],
2020-05-25 10:14:49 +02:00
keyevent['ctrlKey'],
mod)
except Exception as e:
print("Error sending HID message", e)
2020-06-05 16:42:23 +02:00
hid_init()
2020-05-24 11:08:49 +02:00
# check to see if this is the main thread of execution
if __name__ == '__main__':
# construct the argument parser and parse command line arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--ip", type=str, required=True,
help="ip address of the device")
ap.add_argument("-o", "--port", type=int, required=True,
help="ephemeral port number of the server (1024 to 65535)")
ap.add_argument("-f", "--frame-count", type=int, default=32,
help="# of frames used to construct the background model")
args = vars(ap.parse_args())
app.run(host=args["ip"], port=args["port"], debug=True,
2020-06-05 16:32:24 +02:00
use_reloader=False)