Input: Some more followups to the input device auto-detection stuff (#11855)

Switch to a new `input.fdopen` API & wrapper so we can keep the fds opened by `fbink_input_scan` instead of closing them to re-open them right after that...

This should hopefully help on racy zForce devices that attempt to handle power management when opening/closing the device. We know this sometimes horribly fail to re-activate the IR grid (c.f., our manual activation on resume), but this apparently could also happen here (re: #11844) because of the quick succession of open->close->open.
reviewable/pr11858/r1
NiLuJe 1 month ago committed by GitHub
parent 1eb2095ead
commit 4d9c6523ad
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -1 +1 @@
Subproject commit f9c9316709a9683406a759888090ea04098cf46b
Subproject commit 61c05b668f0764988cc857f3a59024e35fded62b

@ -323,6 +323,29 @@ function Input.open(path, name)
end
end
--[[--
Wrapper for our Lua/C input module's fdopen.
Note that we adhere to the "." syntax here for compatibility.
The `name` argument is optional, and used for logging purposes only.
`path` is mandatory, though!
--]]
function Input.fdopen(fd, path, name)
-- Make sure we don't open the same device twice.
if not Input.opened_devices[path] then
input.fdopen(fd)
-- As with input.open, it will throw on error (closing the fd first)
Input.opened_devices[path] = fd
if name then
logger.dbg("Kept fd", fd, "open for input device", name, "@", path)
else
logger.dbg("Kept fd", fd, "open for input device @", path)
end
return fd
end
end
--[[--
Wrapper for our Lua/C input module's close.

@ -216,12 +216,12 @@ function Kindle:openInputDevices()
local dev_count = ffi.new("size_t[1]")
-- We care about: the touchscreen, a properly scaled stylus, pagination buttons, a home button and a fiveway.
local match_mask = bit.bor(C.INPUT_TOUCHSCREEN, C.INPUT_SCALED_TABLET, C.INPUT_PAGINATION_BUTTONS, C.INPUT_HOME_BUTTON, C.INPUT_DPAD)
local devices = FBInkInput.fbink_input_scan(match_mask, 0, C.SCAN_ONLY, dev_count)
local devices = FBInkInput.fbink_input_scan(match_mask, 0, 0, dev_count)
if devices ~= nil then
for i = 0, tonumber(dev_count[0]) - 1 do
local dev = devices[i]
if dev.matched then
self.input.open(ffi.string(dev.path), ffi.string(dev.name))
self.input.fdopen(tonumber(dev.fd), ffi.string(dev.path), ffi.string(dev.name))
end
end
C.free(devices)
@ -243,12 +243,12 @@ function Kindle:openInputDevices()
if self:hasGSensor() then
-- i.e., we want something that reports EV_ABS:ABS_PRESSURE that isn't *also* a pen (because those are pretty much guaranteed to report pressure...).
-- And let's add that isn't also a touchscreen to the mix, because while not true at time of writing, that's an event touchscreens sure can support...
devices = FBInkInput.fbink_input_scan(C.INPUT_ROTATION_EVENT, bit.bor(C.INPUT_TABLET, C.INPUT_TOUCHSCREEN), bit.bor(C.SCAN_ONLY, C.NO_RECAP), dev_count)
devices = FBInkInput.fbink_input_scan(C.INPUT_ROTATION_EVENT, bit.bor(C.INPUT_TABLET, C.INPUT_TOUCHSCREEN), C.NO_RECAP, dev_count)
if devices ~= nil then
for i = 0, tonumber(dev_count[0]) - 1 do
local dev = devices[i]
if dev.matched then
self.input.open(ffi.string(dev.path), ffi.string(dev.name))
self.input.fdopen(tonumber(dev.fd), ffi.string(dev.path), ffi.string(dev.name))
end
end
C.free(devices)

@ -867,7 +867,7 @@ function Kobo:init()
-- (and technically rotation events, but we'll get it with the device that provides the buttons on NTX).
-- We exclude keyboards to play nice with the ExternalKeyboard plugin, which will handle potential keyboards on its own.
local match_mask = bit.bor(C.INPUT_TOUCHSCREEN, C.INPUT_TABLET, C.INPUT_POWER_BUTTON, C.INPUT_SLEEP_COVER, C.INPUT_PAGINATION_BUTTONS)
local devices = FBInkInput.fbink_input_scan(match_mask, C.INPUT_KEYBOARD, C.SCAN_ONLY, dev_count)
local devices = FBInkInput.fbink_input_scan(match_mask, C.INPUT_KEYBOARD, 0, dev_count)
if devices ~= nil then
for i = 0, tonumber(dev_count[0]) - 1 do
local dev = devices[i]
@ -875,9 +875,9 @@ function Kobo:init()
-- We need to single out whichever device provides pagination buttons or sleep cover events, as we'll want to tweak key repeat there...
-- The first one will do, as it's extremely likely to be event0, and that's pretty fairly set in stone on NTX boards.
if (bit.band(dev.type, C.INPUT_PAGINATION_BUTTONS) ~= 0 or bit.band(dev.type, C.INPUT_SLEEP_COVER) ~= 0) and not self.ntx_fd then
self.ntx_fd = self.input.open(ffi.string(dev.path), ffi.string(dev.name))
self.ntx_fd = self.input.fdopen(tonumber(dev.fd), ffi.string(dev.path), ffi.string(dev.name))
else
self.input.open(ffi.string(dev.path), ffi.string(dev.name))
self.input.fdopen(tonumber(dev.fd), ffi.string(dev.path), ffi.string(dev.name))
end
end
end

@ -294,14 +294,14 @@ local function findKeyboards()
local FBInkInput = ffi.load("fbink_input")
local dev_count = ffi.new("size_t[1]")
local devices = FBInkInput.fbink_input_scan(C.INPUT_KEYBOARD, 0, C.SCAN_ONLY, dev_count)
local devices = FBInkInput.fbink_input_scan(C.INPUT_KEYBOARD, 0, 0, dev_count)
if devices ~= nil then
for i = 0, tonumber(dev_count[0]) - 1 do
local dev = devices[i]
if dev.matched then
-- Check if it provides a DPad, too.
local has_dpad = bit.band(dev.type, C.INPUT_DPAD) ~= 0
table.insert(keyboards, { event_path = ffi.string(dev.path), has_dpad = has_dpad })
table.insert(keyboards, { event_fd = tonumber(dev.fd), event_path = ffi.string(dev.path), name = ffi.string(dev.name), has_dpad = has_dpad })
end
end
C.free(devices)
@ -314,11 +314,13 @@ local function checkKeyboard(path)
local keyboard
local FBInkInput = ffi.load("fbink_input")
local dev = FBInkInput.fbink_input_check(path, C.INPUT_KEYBOARD, 0, C.SCAN_ONLY)
local dev = FBInkInput.fbink_input_check(path, C.INPUT_KEYBOARD, 0, 0)
if dev ~= nil then
if dev.matched then
keyboard = {
event_fd = tonumber(dev.fd),
event_path = ffi.string(dev.path),
name = ffi.string(dev.name),
has_dpad = bit.band(dev.type, C.INPUT_DPAD) ~= 0
}
end
@ -359,10 +361,10 @@ function ExternalKeyboard:setupKeyboard(data)
local has_dpad_func = Device.hasDPad
logger.dbg("ExternalKeyboard:setupKeyboard", keyboard_info.event_path, "has_dpad", keyboard_info.has_dpad)
logger.dbg("ExternalKeyboard:setupKeyboard", keyboard_info.name, "@", keyboard_info.event_path, "- has_dpad:", keyboard_info.has_dpad)
-- Check if we already know about this event file.
if ExternalKeyboard.keyboard_fds[keyboard_info.event_path] == nil then
local ok, fd = pcall(Device.input.open, keyboard_info.event_path)
local ok, fd = pcall(Device.input.fdopen, keyboard_info.event_fd, keyboard_info.event_path, keyboard_info.name)
if not ok then
UIManager:show(InfoMessage:new{
text = "Error opening keyboard:\n" .. tostring(fd),
@ -373,7 +375,7 @@ function ExternalKeyboard:setupKeyboard(data)
ExternalKeyboard.keyboard_fds[keyboard_info.event_path] = fd
ExternalKeyboard.connected_keyboards = ExternalKeyboard.connected_keyboards + 1
logger.dbg("ExternalKeyboard: USB keyboard", keyboard_info.event_path, "was connected; total:", ExternalKeyboard.connected_keyboards)
logger.dbg("ExternalKeyboard: USB keyboard", keyboard_info.name, "@", keyboard_info.event_path, "was connected; total:", ExternalKeyboard.connected_keyboards)
if keyboard_info.has_dpad then
has_dpad_func = yes

Loading…
Cancel
Save