Pocketbook: use raw input I/O (#6791)

This allows for better energy efficiency (no more 50Hz tick poll),
as well as lower input lag / higher precision - touch events are
native linux ones.

In addition, auto off/suspend plugin is used in this mode, as we need
to trigger (timed) sleep / poweroff on our own, since the OS ones
will no longer work whenever koreader has focus.

This is for rooted devices only, and possibly somewhat FW
specific, so enabled only on PB740-2 where it's reasonably tested.
reviewable/pr6800/r1
ezdiy 4 years ago committed by GitHub
parent 5e231d759a
commit 893909146d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -42,6 +42,19 @@ local PocketBook = Generic:new{
-- NTX chipsets *should* work (PB631), but in case it doesn't on your device, set this to "no" in here. -- NTX chipsets *should* work (PB631), but in case it doesn't on your device, set this to "no" in here.
canHWInvert = yes, canHWInvert = yes,
-- If we can access the necessary devices, input events can be handled directly.
-- This improves latency (~40ms), as well as power usage - we can spend more time asleep,
-- instead of busy looping at 50Hz the way inkview insists on doing.
-- In case this method fails (no root), we fallback to classic inkview api.
raw_input = nil, --[[{
-- value or function to adjust touch matrix orientiation.
touch_rotation = -3+4,
-- Works same as input.event_map, but for raw input EV_KEY translation
keymap = { [scan] = event },
}]]
-- Runtime state: whether raw input is actually used
is_using_raw_input = nil,
-- Private per-model kludges -- Private per-model kludges
_fb_init = function() end, _fb_init = function() end,
_model_init = function() end, _model_init = function() end,
@ -69,6 +82,9 @@ local function isB288(fb)
end end
function PocketBook:init() function PocketBook:init()
local raw_input = self.raw_input
local touch_rotation = raw_input and raw_input.touch_rotation or 0
self.screen = require("ffi/framebuffer_mxcfb"):new { self.screen = require("ffi/framebuffer_mxcfb"):new {
device = self, device = self,
debug = logger.dbg, debug = logger.dbg,
@ -87,8 +103,14 @@ function PocketBook:init()
end end
return self._fb_init(fb, finfo, vinfo) return self._fb_init(fb, finfo, vinfo)
end, end,
-- raw touch input orientiation is different from the screen
getTouchRotation = function(fb)
if type(touch_rotation) == "function" then
return touch_rotation(self, fb:getRotationMode())
end
return (4 + fb:getRotationMode() + touch_rotation) % 4
end,
} }
self.powerd = require("device/pocketbook/powerd"):new{device = self}
-- Whenever we lose focus, but also get suspended for real (we can't reliably tell atm), -- Whenever we lose focus, but also get suspended for real (we can't reliably tell atm),
-- plugins need to be notified to stop doing foreground stuff, and vice versa. To this end, -- plugins need to be notified to stop doing foreground stuff, and vice versa. To this end,
@ -98,7 +120,8 @@ function PocketBook:init()
self.input = require("device/input"):new{ self.input = require("device/input"):new{
device = self, device = self,
event_map = { raw_input = raw_input,
event_map = setmetatable({
[C.KEY_MENU] = "Menu", [C.KEY_MENU] = "Menu",
[C.KEY_PREV] = "LPgBack", [C.KEY_PREV] = "LPgBack",
[C.KEY_NEXT] = "LPgFwd", [C.KEY_NEXT] = "LPgFwd",
@ -107,7 +130,7 @@ function PocketBook:init()
[C.KEY_LEFT] = "Left", [C.KEY_LEFT] = "Left",
[C.KEY_RIGHT] = "Right", [C.KEY_RIGHT] = "Right",
[C.KEY_OK] = "Press", [C.KEY_OK] = "Press",
}, }, {__index=raw_input and raw_input.keymap or {}}),
handleMiscEv = function(this, ev) handleMiscEv = function(this, ev)
local ui = require("ui/uimanager") local ui = require("ui/uimanager")
if ev.code == C.EVT_HIDE or ev.code == C.EVT_BACKGROUND then if ev.code == C.EVT_HIDE or ev.code == C.EVT_BACKGROUND then
@ -156,7 +179,17 @@ function PocketBook:init()
end) end)
self._model_init() self._model_init()
self.input.open() if (not self.input.raw_input) or (not pcall(self.input.open, self.input, self.raw_input)) then
inkview.OpenScreen()
-- Raw mode open failed (no permissions?), so we'll run the usual way.
-- Disable touch coordinate translation as inkview will do that.
self.input.raw_input = nil
self.input:open()
touch_rotation = 0
else
self.canSuspend = yes
end
self.powerd = require("device/pocketbook/powerd"):new{device = self}
self:setAutoStandby(true) self:setAutoStandby(true)
Generic.init(self) Generic.init(self)
end end
@ -238,6 +271,10 @@ function PocketBook:powerOff()
inkview.PowerOff() inkview.PowerOff()
end end
function PocketBook:suspend()
inkview.SendGlobalRequest(C.REQ_KEYLOCK)
end
function PocketBook:reboot() function PocketBook:reboot()
inkview.iv_ipc_request(C.MSG_REBOOT, 1, nil, 0, 0) inkview.iv_ipc_request(C.MSG_REBOOT, 1, nil, 0, 0)
end end
@ -464,6 +501,14 @@ local PocketBook740_2 = PocketBook:new{
isAlwaysPortrait = yes, isAlwaysPortrait = yes,
usingForcedRotation = landscape_ccw, usingForcedRotation = landscape_ccw,
hasNaturalLight = yes, hasNaturalLight = yes,
raw_input = {
touch_rotation = -1,
keymap = {
[115] = "Menu",
[109] = "LPgFwd",
[104] = "LPgBack",
}
}
} }
-- PocketBook Color Lux (801) -- PocketBook Color Lux (801)

@ -14,7 +14,6 @@ local PocketBookPowerD = BasePowerD:new{
function PocketBookPowerD:init() function PocketBookPowerD:init()
-- needed for SetFrontlightState / GetFrontlightState -- needed for SetFrontlightState / GetFrontlightState
inkview.OpenScreen()
if self.device:hasNaturalLight() then if self.device:hasNaturalLight() then
local color = inkview.GetFrontlightColor() local color = inkview.GetFrontlightColor()
self.fl_warmth = color >= 0 and color or 0 self.fl_warmth = color >= 0 and color or 0

@ -1321,6 +1321,8 @@ function UIManager:suspend()
self.event_handlers["Suspend"]() self.event_handlers["Suspend"]()
elseif Device:isKindle() then elseif Device:isKindle() then
Device.powerd:toggleSuspend() Device.powerd:toggleSuspend()
elseif Device.isPocketBook() and Device.canSuspend() then
Device:suspend()
end end
end end

@ -14,6 +14,9 @@ if [ "${INSTANCE_PID}" != "" ] && [ -e "/proc/${INSTANCE_PID}" ]; then
exec /usr/bin/iv2sh SetActiveTask "${INSTANCE_PID}" 0 exec /usr/bin/iv2sh SetActiveTask "${INSTANCE_PID}" 0
fi fi
# try to bring in raw device input (on rooted devices)
/mnt/secure/su /bin/chmod 644 /dev/input/*
# we're first, so publish our instance # we're first, so publish our instance
echo $$ >/tmp/koreader.pid echo $$ >/tmp/koreader.pid

@ -1,6 +1,11 @@
local Device = require("device") local Device = require("device")
if not Device:isCervantes() and not Device:isKobo() and not Device:isRemarkable() and not Device:isSDL() and not Device:isSonyPRSTUX() then if not Device:isCervantes() and
not Device:isKobo() and
not Device:isRemarkable() and
not Device:isSDL() and
not Device:isSonyPRSTUX() and
not Device:isPocketBook() then
return { disabled = true, } return { disabled = true, }
end end
@ -21,6 +26,7 @@ local AutoSuspend = WidgetContainer:new{
autoshutdown_timeout_seconds = G_reader_settings:readSetting("autoshutdown_timeout_seconds") or default_autoshutdown_timeout_seconds, autoshutdown_timeout_seconds = G_reader_settings:readSetting("autoshutdown_timeout_seconds") or default_autoshutdown_timeout_seconds,
settings = LuaSettings:open(DataStorage:getSettingsDir() .. "/koboautosuspend.lua"), settings = LuaSettings:open(DataStorage:getSettingsDir() .. "/koboautosuspend.lua"),
last_action_sec = os.time(), last_action_sec = os.time(),
standby_prevented = false,
} }
function AutoSuspend:_readTimeoutSecFrom(settings) function AutoSuspend:_readTimeoutSecFrom(settings)
@ -60,7 +66,7 @@ function AutoSuspend:_schedule()
local delay_suspend, delay_shutdown local delay_suspend, delay_shutdown
if PluginShare.pause_auto_suspend then if PluginShare.pause_auto_suspend or Device.standby_prevented or Device.powerd:isCharging() then
delay_suspend = self.auto_suspend_sec delay_suspend = self.auto_suspend_sec
delay_shutdown = self.autoshutdown_timeout_seconds delay_shutdown = self.autoshutdown_timeout_seconds
else else
@ -68,12 +74,13 @@ function AutoSuspend:_schedule()
delay_shutdown = self.last_action_sec + self.autoshutdown_timeout_seconds - os.time() delay_shutdown = self.last_action_sec + self.autoshutdown_timeout_seconds - os.time()
end end
if delay_suspend <= 0 then -- Try to shutdown first, as we may have been woken up from suspend just for the sole purpose of doing that.
logger.dbg("AutoSuspend: will suspend the device") if delay_shutdown <= 0 then
UIManager:suspend()
elseif delay_shutdown <= 0 then
logger.dbg("AutoSuspend: initiating shutdown") logger.dbg("AutoSuspend: initiating shutdown")
UIManager:poweroff_action() UIManager:poweroff_action()
elseif delay_suspend <= 0 then
logger.dbg("AutoSuspend: will suspend the device")
UIManager:suspend()
else else
if self:_enabled() then if self:_enabled() then
logger.dbg("AutoSuspend: schedule suspend at ", os.time() + delay_suspend) logger.dbg("AutoSuspend: schedule suspend at ", os.time() + delay_suspend)
@ -100,6 +107,7 @@ function AutoSuspend:_start()
end end
function AutoSuspend:init() function AutoSuspend:init()
if Device:isPocketBook() and not Device:canSuspend() then return end
UIManager.event_hook:registerWidget("InputEvent", self) UIManager.event_hook:registerWidget("InputEvent", self)
self.auto_suspend_sec = self:_readTimeoutSec() self.auto_suspend_sec = self:_readTimeoutSec()
self:_unschedule() self:_unschedule()
@ -132,6 +140,14 @@ function AutoSuspend:onResume()
self:_start() self:_start()
end end
function AutoSuspend:onAllowStandby()
self.standby_prevented = false
end
function AutoSuspend:onPreventStandby()
self.standby_prevented = true
end
function AutoSuspend:addToMainMenu(menu_items) function AutoSuspend:addToMainMenu(menu_items)
menu_items.autosuspend = { menu_items.autosuspend = {
sorting_hint = "device", sorting_hint = "device",
@ -167,6 +183,7 @@ function AutoSuspend:addToMainMenu(menu_items)
} }
if not (Device:canPowerOff() or Device:isEmulator()) then return end if not (Device:canPowerOff() or Device:isEmulator()) then return end
menu_items.autoshutdown = { menu_items.autoshutdown = {
sorting_hint = "device",
text = _("Autoshutdown timeout"), text = _("Autoshutdown timeout"),
callback = function() callback = function()
local InfoMessage = require("ui/widget/infomessage") local InfoMessage = require("ui/widget/infomessage")

Loading…
Cancel
Save