mirror of
https://github.com/koreader/koreader
synced 2024-10-31 21:20:20 +00:00
fix #2219
The ABS_PRESSURE ABS code is also detected on some KOBO devices if ABS_PRESSURE events are feeded to handle orientation those devices will have a unresponsive screen as described in #2219. This patch registers an event adjustment handler for Kindle Oasis to adjust the ABS_PRESSURE code to ABS_OASIS_ORIENTATION code so that it won't affect event handling on other devices.
This commit is contained in:
parent
aa8d4f27ae
commit
7fd6037bb0
@ -40,9 +40,10 @@ local ABS_MT_POSITION_Y = 54
|
|||||||
local ABS_MT_TRACKING_ID = 57
|
local ABS_MT_TRACKING_ID = 57
|
||||||
local ABS_MT_PRESSURE = 58
|
local ABS_MT_PRESSURE = 58
|
||||||
|
|
||||||
-- For device orientation events (ABS.code)
|
-- For Kindle Oasis orientation events (ABS.code)
|
||||||
|
-- the ABS code of orientation event will be adjusted to -24 from 24(ABS_PRESSURE)
|
||||||
local ABS_PRESSURE = 24
|
-- as ABS_PRESSURE is also used to detect touch input in KOBO devices.
|
||||||
|
local ABS_OASIS_ORIENTATION = -24
|
||||||
local DEVICE_ORIENTATION_PORTRAIT_LEFT = 15
|
local DEVICE_ORIENTATION_PORTRAIT_LEFT = 15
|
||||||
local DEVICE_ORIENTATION_PORTRAIT_RIGHT = 17
|
local DEVICE_ORIENTATION_PORTRAIT_RIGHT = 17
|
||||||
local DEVICE_ORIENTATION_PORTRAIT = 19
|
local DEVICE_ORIENTATION_PORTRAIT = 19
|
||||||
@ -240,6 +241,12 @@ function Input:adjustTouchTranslate(ev, by)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function Input:adjustKindleOasisOrientation(ev)
|
||||||
|
if ev.type == EV_ABS and ev.code == ABS_PRESSURE then
|
||||||
|
ev.code = ABS_OASIS_ORIENTATION
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
function Input:setTimeout(cb, tv_out)
|
function Input:setTimeout(cb, tv_out)
|
||||||
local item = {
|
local item = {
|
||||||
callback = cb,
|
callback = cb,
|
||||||
@ -463,18 +470,19 @@ function Input:handleTouchEvPhoenix(ev)
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function Input:handleOrientationEv(ev)
|
function Input:handleOasisOrientationEv(ev)
|
||||||
if ev.type == EV_ABS then
|
|
||||||
if ev.code == ABS_PRESSURE then
|
|
||||||
|
|
||||||
local rotation_mode, screen_mode
|
local rotation_mode, screen_mode
|
||||||
if ev.value == DEVICE_ORIENTATION_PORTRAIT or ev.value == DEVICE_ORIENTATION_PORTRAIT_LEFT or ev.value == DEVICE_ORIENTATION_PORTRAIT_RIGHT then
|
if ev.value == DEVICE_ORIENTATION_PORTRAIT
|
||||||
|
or ev.value == DEVICE_ORIENTATION_PORTRAIT_LEFT
|
||||||
|
or ev.value == DEVICE_ORIENTATION_PORTRAIT_RIGHT then
|
||||||
rotation_mode = framebuffer.ORIENTATION_PORTRAIT
|
rotation_mode = framebuffer.ORIENTATION_PORTRAIT
|
||||||
screen_mode = 'portrait'
|
screen_mode = 'portrait'
|
||||||
elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE then
|
elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE then
|
||||||
rotation_mode = framebuffer.ORIENTATION_LANDSCAPE
|
rotation_mode = framebuffer.ORIENTATION_LANDSCAPE
|
||||||
screen_mode = 'landscape'
|
screen_mode = 'landscape'
|
||||||
elseif ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_LEFT or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_RIGHT then
|
elseif ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED
|
||||||
|
or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_LEFT
|
||||||
|
or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_RIGHT then
|
||||||
rotation_mode = framebuffer.ORIENTATION_PORTRAIT_ROTATED
|
rotation_mode = framebuffer.ORIENTATION_PORTRAIT_ROTATED
|
||||||
screen_mode = 'portrait'
|
screen_mode = 'portrait'
|
||||||
elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE_ROTATED then
|
elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE_ROTATED then
|
||||||
@ -483,19 +491,17 @@ function Input:handleOrientationEv(ev)
|
|||||||
end
|
end
|
||||||
|
|
||||||
local old_rotation_mode = self.device.screen:getRotationMode()
|
local old_rotation_mode = self.device.screen:getRotationMode()
|
||||||
local old_screen_mode = self.device.screen:getScreenMode();
|
local old_screen_mode = self.device.screen:getScreenMode()
|
||||||
DEBUG("old_rotation_mode: ", old_rotation_mode)
|
DEBUG:v("old_rotation_mode: ", old_rotation_mode)
|
||||||
DEBUG("new_rotation_mode: ", rotation_mode)
|
DEBUG:v("new_rotation_mode: ", rotation_mode)
|
||||||
DEBUG("old_screen_mode: ", old_screen_mode)
|
DEBUG:v("old_screen_mode: ", old_screen_mode)
|
||||||
DEBUG("new_screen_mode: ", screen_mode)
|
DEBUG:v("new_screen_mode: ", screen_mode)
|
||||||
if rotation_mode ~= old_rotation_mode and screen_mode == old_screen_mode then
|
if rotation_mode ~= old_rotation_mode and screen_mode == old_screen_mode then
|
||||||
self.device.screen:setRotationMode(rotation_mode)
|
self.device.screen:setRotationMode(rotation_mode)
|
||||||
local UIManager = require("ui/uimanager")
|
local UIManager = require("ui/uimanager")
|
||||||
UIManager:onRotation()
|
UIManager:onRotation()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
|
|
||||||
-- helpers for touch event data management:
|
-- helpers for touch event data management:
|
||||||
@ -593,13 +599,14 @@ function Input:waitEvent(timeout_us)
|
|||||||
if ok and ev then
|
if ok and ev then
|
||||||
if DEBUG.is_on and ev then
|
if DEBUG.is_on and ev then
|
||||||
DEBUG:logEv(ev)
|
DEBUG:logEv(ev)
|
||||||
|
DEBUG:v("ev", ev)
|
||||||
end
|
end
|
||||||
self:eventAdjustHook(ev)
|
self:eventAdjustHook(ev)
|
||||||
if ev.type == EV_KEY then
|
if ev.type == EV_KEY then
|
||||||
DEBUG("key ev", ev)
|
DEBUG("key ev", ev)
|
||||||
return self:handleKeyBoardEv(ev)
|
return self:handleKeyBoardEv(ev)
|
||||||
elseif ev.type == EV_ABS and ev.code == ABS_PRESSURE then
|
elseif ev.type == EV_ABS and ev.code == ABS_OASIS_ORIENTATION then
|
||||||
return self:handleOrientationEv(ev)
|
return self:handleOasisOrientationEv(ev)
|
||||||
elseif ev.type == EV_ABS or ev.type == EV_SYN then
|
elseif ev.type == EV_ABS or ev.type == EV_SYN then
|
||||||
return self:handleTouchEv(ev)
|
return self:handleTouchEv(ev)
|
||||||
elseif ev.type == EV_MSC then
|
elseif ev.type == EV_MSC then
|
||||||
|
@ -349,11 +349,12 @@ function KindleOasis:init()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
local lipc = require("liblipclua")
|
local haslipc, lipc = pcall(require, "liblipclua")
|
||||||
if lipc then
|
if haslipc and lipc then
|
||||||
local lipc_handle = lipc.init("com.github.koreader.screen")
|
local lipc_handle = lipc.init("com.github.koreader.screen")
|
||||||
if lipc_handle then
|
if lipc_handle then
|
||||||
local orientation_code = lipc_handle:get_string_property("com.lab126.winmgr", "accelerometer")
|
local orientation_code = lipc_handle:get_string_property(
|
||||||
|
"com.lab126.winmgr", "accelerometer")
|
||||||
local rotation_mode = 0
|
local rotation_mode = 0
|
||||||
if orientation_code then
|
if orientation_code then
|
||||||
if orientation_code == "V" then
|
if orientation_code == "V" then
|
||||||
@ -376,9 +377,10 @@ function KindleOasis:init()
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
Kindle.init(self)
|
Kindle.init(self)
|
||||||
|
|
||||||
|
self.input:registerEventAdjustHook(self.input.adjustKindleOasisOrientation)
|
||||||
|
|
||||||
self.input.open(self.touch_dev)
|
self.input.open(self.touch_dev)
|
||||||
self.input.open("/dev/input/by-path/platform-gpiokey.0-event")
|
self.input.open("/dev/input/by-path/platform-gpiokey.0-event")
|
||||||
|
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
describe("device module", function()
|
describe("device module", function()
|
||||||
local mock_fb, mock_input
|
local mock_fb, mock_input
|
||||||
|
local iopen = io.open
|
||||||
|
local osgetenv = os.getenv
|
||||||
|
|
||||||
setup(function()
|
setup(function()
|
||||||
mock_fb = {
|
mock_fb = {
|
||||||
new = function()
|
new = function()
|
||||||
@ -7,48 +10,51 @@ describe("device module", function()
|
|||||||
getSize = function() return {w = 600, h = 800} end,
|
getSize = function() return {w = 600, h = 800} end,
|
||||||
getWidth = function() return 600 end,
|
getWidth = function() return 600 end,
|
||||||
getDPI = function() return 72 end,
|
getDPI = function() return 72 end,
|
||||||
setViewport = function() end
|
setViewport = function() end,
|
||||||
|
getRotationMode = function() return 0 end,
|
||||||
|
getScreenMode = function() return "portrait" end,
|
||||||
|
setRotationMode = function() end,
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
}
|
}
|
||||||
require("commonrequire")
|
require("commonrequire")
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
before_each(function()
|
||||||
|
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
|
||||||
|
package.loaded['device/kindle/device'] = nil
|
||||||
|
package.loaded['device/kobo/device'] = nil
|
||||||
|
mock_input = require('device/input')
|
||||||
|
stub(mock_input, "open")
|
||||||
|
stub(os, "getenv")
|
||||||
|
stub(os, "execute")
|
||||||
|
end)
|
||||||
|
|
||||||
|
after_each(function()
|
||||||
|
mock_input.open:revert()
|
||||||
|
os.getenv:revert()
|
||||||
|
os.execute:revert()
|
||||||
|
|
||||||
|
os.getenv = osgetenv
|
||||||
|
io.open = iopen
|
||||||
|
end)
|
||||||
|
|
||||||
describe("kobo", function()
|
describe("kobo", function()
|
||||||
local TimeVal
|
local TimeVal
|
||||||
setup(function()
|
setup(function()
|
||||||
TimeVal = require("ui/timeval")
|
TimeVal = require("ui/timeval")
|
||||||
mock_fb = {
|
|
||||||
new = function()
|
|
||||||
return {
|
|
||||||
getSize = function() return {w = 600, h = 800} end,
|
|
||||||
getWidth = function() return 600 end,
|
|
||||||
getDPI = function() return 72 end,
|
|
||||||
setViewport = function() end
|
|
||||||
}
|
|
||||||
end
|
|
||||||
}
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("should initialize properly on Kobo dahlia", function()
|
it("should initialize properly on Kobo dahlia", function()
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
|
|
||||||
stub(os, "getenv")
|
|
||||||
os.getenv.returns("dahlia")
|
os.getenv.returns("dahlia")
|
||||||
local kobo_dev = require("device/kobo/device")
|
local kobo_dev = require("device/kobo/device")
|
||||||
|
|
||||||
mock_input = require('device/input')
|
|
||||||
stub(mock_input, "open")
|
|
||||||
kobo_dev:init()
|
kobo_dev:init()
|
||||||
assert.is.same("Kobo_dahlia", kobo_dev.model)
|
assert.is.same("Kobo_dahlia", kobo_dev.model)
|
||||||
|
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = nil
|
|
||||||
os.getenv:revert()
|
|
||||||
mock_input.open:revert()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("should setup eventAdjustHooks properly for input in trilogy", function()
|
it("should setup eventAdjustHooks properly for input in trilogy", function()
|
||||||
local saved_getenv = os.getenv
|
|
||||||
stub(os, "getenv")
|
|
||||||
os.getenv.invokes(function(key)
|
os.getenv.invokes(function(key)
|
||||||
if key == "PRODUCT" then
|
if key == "PRODUCT" then
|
||||||
return "trilogy"
|
return "trilogy"
|
||||||
@ -56,11 +62,8 @@ describe("device module", function()
|
|||||||
return saved_getenv(key)
|
return saved_getenv(key)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
package.loaded['device/kobo/device'] = nil
|
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
|
|
||||||
mock_input = require('device/input')
|
|
||||||
stub(mock_input, "open")
|
|
||||||
|
|
||||||
|
package.loaded['device/kobo/device'] = nil
|
||||||
local kobo_dev = require("device/kobo/device")
|
local kobo_dev = require("device/kobo/device")
|
||||||
kobo_dev:init()
|
kobo_dev:init()
|
||||||
local Screen = kobo_dev.screen
|
local Screen = kobo_dev.screen
|
||||||
@ -93,17 +96,12 @@ describe("device module", function()
|
|||||||
assert.is.same(y, ev_x.value)
|
assert.is.same(y, ev_x.value)
|
||||||
assert.is.same(ABS_Y, ev_x.code)
|
assert.is.same(ABS_Y, ev_x.code)
|
||||||
|
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = nil
|
|
||||||
os.getenv:revert()
|
|
||||||
mock_input.open:revert()
|
|
||||||
-- reset eventAdjustHook
|
-- reset eventAdjustHook
|
||||||
kobo_dev.input.eventAdjustHook = function() end
|
kobo_dev.input.eventAdjustHook = function() end
|
||||||
kobo_dev.touch_probe_ev_epoch_time = true
|
kobo_dev.touch_probe_ev_epoch_time = true
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("should setup eventAdjustHooks properly for trilogy with non-epoch ev time", function()
|
it("should setup eventAdjustHooks properly for trilogy with non-epoch ev time", function()
|
||||||
local saved_getenv = os.getenv
|
|
||||||
stub(os, "getenv")
|
|
||||||
os.getenv.invokes(function(key)
|
os.getenv.invokes(function(key)
|
||||||
if key == "PRODUCT" then
|
if key == "PRODUCT" then
|
||||||
return "trilogy"
|
return "trilogy"
|
||||||
@ -111,11 +109,6 @@ describe("device module", function()
|
|||||||
return saved_getenv(key)
|
return saved_getenv(key)
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
package.loaded['device/kobo/device'] = nil
|
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
|
|
||||||
mock_input = require('device/input')
|
|
||||||
stub(mock_input, "open")
|
|
||||||
|
|
||||||
local kobo_dev = require("device/kobo/device")
|
local kobo_dev = require("device/kobo/device")
|
||||||
kobo_dev:init()
|
kobo_dev:init()
|
||||||
local Screen = kobo_dev.screen
|
local Screen = kobo_dev.screen
|
||||||
@ -149,9 +142,6 @@ describe("device module", function()
|
|||||||
assert.truthy(cur_sec - ev_x.time.sec < 10)
|
assert.truthy(cur_sec - ev_x.time.sec < 10)
|
||||||
assert.truthy(cur_sec - ev_y.time.sec < 10)
|
assert.truthy(cur_sec - ev_y.time.sec < 10)
|
||||||
|
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = nil
|
|
||||||
os.getenv:revert()
|
|
||||||
mock_input.open:revert()
|
|
||||||
kobo_dev.input.eventAdjustHook = function() end
|
kobo_dev.input.eventAdjustHook = function() end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@ -195,44 +185,44 @@ describe("device module", function()
|
|||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
describe("kindle #notest #nocov", function()
|
describe("kindle", function()
|
||||||
it("should initialize voyage without error", function()
|
it("should initialize voyage without error", function()
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
|
io.open = function(filename, mode)
|
||||||
stub(io, "open")
|
if filename == "/proc/usid" then
|
||||||
io.open.returns({
|
return {
|
||||||
read = function()
|
read = function() return "XX13XX" end,
|
||||||
return "XX13XX"
|
|
||||||
end,
|
|
||||||
close = function() end
|
close = function() end
|
||||||
})
|
}
|
||||||
mock_input = require('device/input')
|
else
|
||||||
stub(mock_input, "open")
|
return iopen(filename, mode)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local kindle_dev = require("device/kindle/device")
|
local kindle_dev = require('device/kindle/device')
|
||||||
assert.is.same(kindle_dev.model, "KindleVoyage")
|
assert.is.same(kindle_dev.model, "KindleVoyage")
|
||||||
kindle_dev:init()
|
kindle_dev:init()
|
||||||
assert.is.same(kindle_dev.input.event_map[104], "LPgBack")
|
assert.is.same(kindle_dev.input.event_map[104], "LPgBack")
|
||||||
assert.is.same(kindle_dev.input.event_map[109], "LPgFwd")
|
assert.is.same(kindle_dev.input.event_map[109], "LPgFwd")
|
||||||
assert.is.same(kindle_dev.powerd.fl_min, 0)
|
assert.is.same(kindle_dev.powerd.fl_min, 0)
|
||||||
assert.is.same(kindle_dev.powerd.fl_max, 24)
|
assert.is.same(kindle_dev.powerd.fl_max, 24)
|
||||||
|
|
||||||
io.open:revert()
|
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = nil
|
|
||||||
mock_input.open:revert()
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
it("should toggle frontlight", function()
|
it("should toggle frontlight", function()
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = mock_fb
|
io.open = function(filename, mode)
|
||||||
stub(io, "open")
|
if filename == "/proc/usid" then
|
||||||
io.open.returns({
|
return {
|
||||||
read = function()
|
read = function() return "XX13XX" end,
|
||||||
return "12"
|
|
||||||
end,
|
|
||||||
close = function() end
|
close = function() end
|
||||||
})
|
}
|
||||||
mock_input = require('device/input')
|
elseif filename == "/sys/class/backlight/max77696-bl/brightness" then
|
||||||
stub(mock_input, "open")
|
return {
|
||||||
stub(os, "execute")
|
read = function() return "12" end,
|
||||||
|
close = function() end
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return iopen(filename, mode)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local kindle_dev = require("device/kindle/device")
|
local kindle_dev = require("device/kindle/device")
|
||||||
kindle_dev:init()
|
kindle_dev:init()
|
||||||
@ -251,11 +241,46 @@ describe("device module", function()
|
|||||||
kindle_dev.powerd:toggleFrontlight()
|
kindle_dev.powerd:toggleFrontlight()
|
||||||
assert.stub(os.execute).was_called_with(
|
assert.stub(os.execute).was_called_with(
|
||||||
"echo -n 5 > /sys/class/backlight/max77696-bl/brightness")
|
"echo -n 5 > /sys/class/backlight/max77696-bl/brightness")
|
||||||
|
end)
|
||||||
|
|
||||||
io.open:revert()
|
it("oasis should interpret orientation event", function()
|
||||||
package.loaded['ffi/framebuffer_mxcfb'] = nil
|
io.open = function(filename, mode)
|
||||||
mock_input.open:revert()
|
if filename == "/proc/usid" then
|
||||||
os.execute:revert()
|
return {
|
||||||
|
read = function()
|
||||||
|
return "XXX0GCXXX"
|
||||||
|
end,
|
||||||
|
close = function() end
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return iopen(filename, mode)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
mock_ffi_input = require('ffi/input')
|
||||||
|
stub(mock_ffi_input, "waitForEvent")
|
||||||
|
mock_ffi_input.waitForEvent.returns({
|
||||||
|
type = 3,
|
||||||
|
time = {
|
||||||
|
usec = 450565,
|
||||||
|
sec = 1471081881
|
||||||
|
},
|
||||||
|
code = 24,
|
||||||
|
value = 16
|
||||||
|
})
|
||||||
|
|
||||||
|
local UIManager = require("ui/uimanager")
|
||||||
|
stub(UIManager, "onRotation")
|
||||||
|
|
||||||
|
local kindle_dev = require('device/kindle/device')
|
||||||
|
assert.is.same("KindleOasis", kindle_dev.model)
|
||||||
|
kindle_dev:init()
|
||||||
|
|
||||||
|
kindle_dev.input:waitEvent()
|
||||||
|
assert.stub(UIManager.onRotation).was_called()
|
||||||
|
|
||||||
|
mock_ffi_input.waitForEvent:revert()
|
||||||
|
UIManager.onRotation:revert()
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user