Project

General

Profile

Submit #2921 » scrollwheel.py

example that maps a volume knob USB HID device to scrolling mouse events - tautolog, 06/10/2016 02:31 PM

 
#!/usr/bin/env python

# ccw: ??01004f1000
# cw: ??ff004f1000
# down: 01??004f1000
# up: 00??004f1000

def usage():
from sys import argv
print "%s [outport] [inport] [debug]" % argv[0]
print """
Generates sysmouse mouse-wheel events from USB HID Multimedia Controllers (USB volume knobs)

outport:
Named pipe for `moused -p $outport -t sysmouse`. Defaults to stdout for `moused -f -p /dev/stdin -t sysmouse -d -d` and enables debug mode.

inport:
The USB HID device node. Defaults to "/dev/uhid0".

debug:
If non-empty, this doesn't background the process, and prints CSV events to stderr.
If empty or non-existent, then the process will background and print the daemon PID to stdout and exit.
"""

def daemonize():
import os
pid = os.fork()
if pid != 0:
print pid
return True
else:
os.setsid()

return False

def main():
import os
from sys import argv, stdin, stdout, stderr
args = dict(enumerate(argv))

default_debug = False

if 1 in args:
if args[1] == "-h":
usage()
return

outport_path = args[1]
else:
outport_path = None
default_debug = True

if 2 in args:
inport = open(args[2], "rb")
else:
inport = open("/dev/uhid0", "rb")

if 3 in args:
debug = bool(args[3])
else:
debug = default_debug

if not debug:
if daemonize():
return

if outport_path is None:
outport = stdout
else:
try:
os.mkfifo(args[1], 0600)
except OSError:
pass
outport = open(outport_path, "ab")

separate = False

while True:
event = inport.read(6)
if event.endswith("\x00\x4f\x10\x00"):
delta = ((ord(event[1]) + 128) % 256) - 128

pressed = ord(event[0]) > 0
if pressed:
delta *= 32
if delta < -128:
delta = -128
elif delta > 127:
delta = 127

amount = abs(delta)
if amount == 0:
amount = 1

if separate:
if delta == 0:
b6 = None
elif delta > 0:
b6 = 0x01
elif delta < 0:
b6 = 0x7f

if b6 is not None:
for i in range(amount):
outport.write("\x87\x00\x00\x00\x00%s\x00\x7f" % (chr(b6)))
outport.flush()
else:
if delta == 0:
b6 = 0
b7 = 0
elif delta > 0:
if delta < 0x40:
b6 = delta
b7 = 0
else:
b6 = 0x3f
b7 = delta - 0x3f
elif delta < 0:
if delta < -0x40:
b6 = -0x40
b7 = delta + 0x40
else:
b6 = delta
b7 = 0
if b6 != 0 or b7 != 0:
if b6 < 0:
b6 += 0x80
if b7 < 0:
b7 += 0x80
outport.write("\x87\x00\x00\x00\x00%s%s\x7f" % (chr(b6), chr(b7)))
outport.flush()
if debug:
if delta < 0:
direction = "ccw"
elif delta > 0:
direction = "cw"
else:
direction = "none"

button = "down" if pressed else "up"

for i in range(amount):
stderr.write("%s,%s\r\n" % (direction, button))
stderr.flush()

if __name__ == '__main__':
main()
(2-2/2)