accel_wheel.lua (2101B)
1 local fn_fw, fn_acc = ... 2 3 local input = require("lib.input") 4 local uinput = require("lib.uinput") 5 local poll = require("lib.helper.posix_io").poll_read 6 7 local inp_fwd, inp_acc = input(fn_fw), input(fn_acc) 8 local ui = uinput() 9 10 local function to_float(axis) 11 local info = inp_acc.absinfo[axis] 12 local min, max = info.minimum, info.maximum 13 if min < 0 and min == -max then 14 local mul = 1/max 15 return function(v) return v.value * mul end 16 else 17 local mul = 2 / (max - min) 18 return function(v) return (v.value + min) * mul - 1 end 19 end 20 end 21 22 local MAP = { X = to_float("X"), Z = to_float("Z") } 23 local AXIS = "X" 24 local MUL = 0xffff 25 26 ui:copy_caps(inp_fwd) 27 ui:abs_setup("Z", {minimum=0,maximum=256*2-1}) 28 ui:abs_setup("RZ", {minimum=0,maximum=256*2-1}) 29 30 if AXIS then ui:abs_setup(AXIS, {minimum = -MUL, maximum = MUL}) end 31 ui:setup{ 32 -- id=inp.device_id, 33 -- some apps (like wine) doesn't like if you have multiple devices with the 34 -- same id, in that case fake something here: 35 id={bustype="BLUETOOTH", vendor=1, product=2}, 36 name="Virtual gamepad", 37 ff_effects_max=inp_fwd.ff_count 38 } 39 40 ui:create() 41 print("created", ui.sysname) 42 inp_fwd:grab() -- ! DANGER 43 inp_acc:grab() 44 45 local to_poll = { inp_fwd, inp_acc, ui } 46 local ui_ff = ui:gen_ff_forwarder(inp_fwd) 47 48 local vals = { X = 0, Z = 0 } 49 local function recalc() 50 local v = math.atan2(-vals.X, -vals.Z) 51 if v < -1 then v = -1 elseif v > 1 then v = 1 end 52 --print(v*MUL) 53 ui:write{type="ABS", code=AXIS, value=v*MUL} 54 end 55 56 while true do 57 local rdy = poll(to_poll) 58 if rdy[inp_fwd] then 59 local rd = inp_fwd:read() 60 if rd.type ~= "ABS" or rd.code ~= AXIS then 61 if rd.type == "ABS" and (rd.code == "Z" or rd.code == "RZ") then 62 rd.value = rd.value + 256 63 end 64 ui:write(rd) 65 end 66 end 67 if rdy[ui] then ui_ff() end 68 69 if rdy[inp_acc] then 70 local rd = inp_acc:read() 71 if rd.type == "ABS" and MAP[rd.code] then 72 local c = rd.code 73 vals[c] = MAP[c](rd) 74 elseif rd.type == "SYN" and rd.code == "REPORT" and AXIS then 75 recalc() 76 ui:write{type="SYN", code="REPORT"} 77 end 78 end 79 end