mirror of
https://github.com/koreader/koreader.git
synced 2025-08-10 00:52:38 +00:00
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.
This commit is contained in:
2
base
2
base
Submodule base updated: f9c9316709...61c05b668f
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user