From a06009058adc8ec117e838ec4fd986c0bb78fc02 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Tue, 28 Feb 2023 18:17:07 +0100 Subject: [PATCH 01/11] rM: Disable input shenanigans on mainline kernels Re: #10012 --- frontend/device/remarkable/device.lua | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/frontend/device/remarkable/device.lua b/frontend/device/remarkable/device.lua index e2db4d8d46d4..0cd33ea9d783 100644 --- a/frontend/device/remarkable/device.lua +++ b/frontend/device/remarkable/device.lua @@ -59,8 +59,7 @@ local Remarkable1 = Remarkable:extend{ function Remarkable1:adjustTouchEvent(ev, by) if ev.type == C.EV_ABS then - -- Mirror X and Y and scale up both X & Y as touch input is different res from - -- display + -- Mirror X and Y and scale up both X & Y as touch input is different res from display if ev.code == C.ABS_MT_POSITION_X then ev.value = (Remarkable1.mt_width - ev.value) * by.mt_scale_x end @@ -82,8 +81,7 @@ local Remarkable2 = Remarkable:extend{ function Remarkable2:adjustTouchEvent(ev, by) if ev.type == C.EV_ABS then - -- Mirror Y and scale up both X & Y as touch input is different res from - -- display + -- Mirror Y and scale up both X & Y as touch input is different res from display if ev.code == C.ABS_MT_POSITION_X then ev.value = (ev.value) * by.mt_scale_x end @@ -153,8 +151,23 @@ function Remarkable:init() local scalex = screen_width / self.mt_width local scaley = screen_height / self.mt_height - self.input:registerEventAdjustHook(adjustAbsEvt) - self.input:registerEventAdjustHook(self.adjustTouchEvent, {mt_scale_x=scalex, mt_scale_y=scaley}) + -- Assume input stuff is saner on mainline kernels... + -- (c.f., https://github.com/koreader/koreader/issues/10012) + local is_mainline = false + --- @fixme: Find a better way to discriminate mainline from stock... + local std_out = io.popen("uname -r", "r") + if std_out then + local release = std_out:read("*line") + release = release:match("^(%d+%.%d+)%.%d+.*$") + release = tonumber(release) + if release and release >= 6.2 then + is_mainline = true + end + end + if not is_mainline then + self.input:registerEventAdjustHook(adjustAbsEvt) + self.input:registerEventAdjustHook(self.adjustTouchEvent, {mt_scale_x=scalex, mt_scale_y=scaley}) + end -- USB plug/unplug, battery charge/not charging are generated as fake events self.input.open("fake_events") From 9c2d5d0b95055e169a76bd164f918092d0ddd03e Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 1 Mar 2023 11:04:30 +0100 Subject: [PATCH 02/11] Forgot a close there ;o) --- frontend/device/remarkable/device.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/frontend/device/remarkable/device.lua b/frontend/device/remarkable/device.lua index 0cd33ea9d783..bc4e48b06b75 100644 --- a/frontend/device/remarkable/device.lua +++ b/frontend/device/remarkable/device.lua @@ -158,6 +158,7 @@ function Remarkable:init() local std_out = io.popen("uname -r", "r") if std_out then local release = std_out:read("*line") + std_out:close() release = release:match("^(%d+%.%d+)%.%d+.*$") release = tonumber(release) if release and release >= 6.2 then From 7f000ddd8e94f63808486462bf38b8ae17ab3479 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 1 Mar 2023 11:19:58 +0100 Subject: [PATCH 03/11] Unbreak touch panel Wacom will probably need some more trickery... --- frontend/device/remarkable/device.lua | 27 +++++++++++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/frontend/device/remarkable/device.lua b/frontend/device/remarkable/device.lua index bc4e48b06b75..82ec6003eb4c 100644 --- a/frontend/device/remarkable/device.lua +++ b/frontend/device/remarkable/device.lua @@ -114,7 +114,6 @@ local adjustAbsEvt = function(self, ev) end end - function Remarkable:init() local oxide_running = os.execute("systemctl is-active --quiet tarnish") == 0 logger.info(string.format("Oxide running?: %s", oxide_running)) @@ -165,7 +164,31 @@ function Remarkable:init() is_mainline = true end end - if not is_mainline then + if is_mainline then + local mt_height = self.mt_height + local mainlineInputManging = function(self, ev) + if ev.type == C.EV_ABS then + -- Mirror Y for the touch panel + if ev.code == C.ABS_MT_POSITION_Y then + ev.value = mt_height - ev.value + -- Handle the Wacom pen + --- @fixme: The panel also spits out ABS_X & ABS_Y events... + --- and later than their MT counterpart, so we can't do that here. + --- Assuming the Wacom frames report a tool type, + -- this'll probably require a protocol tweak to ingnore non-MT coordinate events for the panel... + --[[ + elseif ev.code == C.ABS_X then + ev.code = C.ABS_Y + ev.value = (wacom_height - ev.value) * wacom_scale_y + elseif ev.code == C.ABS_Y then + ev.code = C.ABS_X + ev.value = ev.value * wacom_scale_x + --]] + end + end + end + self.input:registerEventAdjustHook(mainlineInputManging) + else self.input:registerEventAdjustHook(adjustAbsEvt) self.input:registerEventAdjustHook(self.adjustTouchEvent, {mt_scale_x=scalex, mt_scale_y=scaley}) end From 800ea0e5f5f5148cba04008a308ea7e5385181cb Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 1 Mar 2023 11:29:05 +0100 Subject: [PATCH 04/11] Luacheck'ed --- frontend/device/remarkable/device.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/device/remarkable/device.lua b/frontend/device/remarkable/device.lua index 82ec6003eb4c..c9d0408efb6f 100644 --- a/frontend/device/remarkable/device.lua +++ b/frontend/device/remarkable/device.lua @@ -166,7 +166,7 @@ function Remarkable:init() end if is_mainline then local mt_height = self.mt_height - local mainlineInputManging = function(self, ev) + local mainlineInputManging = function(this, ev) if ev.type == C.EV_ABS then -- Mirror Y for the touch panel if ev.code == C.ABS_MT_POSITION_Y then From d9057989e3a1b8908e649278416c29aba7989418 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 1 Mar 2023 11:29:25 +0100 Subject: [PATCH 05/11] More sleep would be good ;p. --- frontend/device/remarkable/device.lua | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/device/remarkable/device.lua b/frontend/device/remarkable/device.lua index c9d0408efb6f..1be709fc9247 100644 --- a/frontend/device/remarkable/device.lua +++ b/frontend/device/remarkable/device.lua @@ -166,7 +166,7 @@ function Remarkable:init() end if is_mainline then local mt_height = self.mt_height - local mainlineInputManging = function(this, ev) + local mainlineInputMangling = function(this, ev) if ev.type == C.EV_ABS then -- Mirror Y for the touch panel if ev.code == C.ABS_MT_POSITION_Y then @@ -187,7 +187,7 @@ function Remarkable:init() end end end - self.input:registerEventAdjustHook(mainlineInputManging) + self.input:registerEventAdjustHook(mainlineInputMangling) else self.input:registerEventAdjustHook(adjustAbsEvt) self.input:registerEventAdjustHook(self.adjustTouchEvent, {mt_scale_x=scalex, mt_scale_y=scaley}) From d1dec4324f76d5d9e73efe60a8759fe5d731d0ec Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 1 Mar 2023 13:30:40 +0100 Subject: [PATCH 06/11] =?UTF-8?q?Add=20a=20dedicated=20handler=20to=20hand?= =?UTF-8?q?le=20mixed=20pen=20=C2=B0+=20panel,=20when=20panel=20sends=20bo?= =?UTF-8?q?th=20mt=20+=20st=20and=20stylus=20only=20st?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- frontend/device/input.lua | 43 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/frontend/device/input.lua b/frontend/device/input.lua index ca6e5e0a16c6..e9a21c9f2b2b 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -797,6 +797,49 @@ function Input:handleTouchEv(ev) end end +-- This is a slightly modified version of the above, tailored to play nice with devices with multiple absolute input devices, +-- (i.e., screen + pen), where one or both of these send conflicting events that we need to hook... (e.g., rM on mainline). +function Input:handleMixedTouchEv(ev) + if ev.type == C.EV_ABS then + if ev.code == C.ABS_MT_SLOT then + self:setupSlotData(ev.value) + elseif ev.code == C.ABS_MT_TRACKING_ID then + self:setCurrentMtSlotChecked("id", ev.value) + elseif ev.code == C.ABS_MT_POSITION_X then + -- Panel + self:setCurrentMtSlotChecked("x", ev.value) + elseif ev.code == C.ABS_X then + -- Panel + Stylus, but we only want to honor stylus! + local tool = self:getCurrentMtSlotData("tool") + if tool and tool == TOOL_TYPE_PEN then + self:setCurrentMtSlotChecked("x", ev.value) + end + elseif ev.code == C.ABS_MT_POSITION_Y then + self:setCurrentMtSlotChecked("y", ev.value) + elseif ev.code == C.ABS_Y then + local tool = self:getCurrentMtSlotData("tool") + if tool and tool == TOOL_TYPE_PEN then + self:setCurrentMtSlotChecked("y", ev.value) + end + end + elseif ev.type == C.EV_SYN then + if ev.code == C.SYN_REPORT then + for _, MTSlot in ipairs(self.MTSlots) do + self:setMtSlot(MTSlot.slot, "timev", time.timeval(ev.time)) + end + -- feed ev in all slots to state machine + local touch_gestures = self.gesture_detector:feedEvent(self.MTSlots) + self:newFrame() + local ges_evs = {} + for _, touch_ges in ipairs(touch_gestures) do + self:gestureAdjustHook(touch_ges) + table.insert(ges_evs, Event:new("Gesture", self.gesture_detector:adjustGesCoordinate(touch_ges))) + end + return ges_evs + end + end +end + function Input:handleTouchEvPhoenix(ev) -- Hack on handleTouchEV for the Kobo Aura -- It seems to be using a custom protocol: From 6a828e1996592673c2678ce65d673c646b668c51 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 1 Mar 2023 13:33:46 +0100 Subject: [PATCH 07/11] Don't stomp on panel slots in the wacom protocol handler --- frontend/device/input.lua | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/frontend/device/input.lua b/frontend/device/input.lua index e9a21c9f2b2b..3d6851197a72 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -534,22 +534,26 @@ function Input:handleKeyBoardEv(ev) end elseif self.wacom_protocol then if ev.code == C.BTN_TOOL_PEN then - -- Always send pen data to slot 0 - self:setupSlotData(0) + -- Always send pen data to slot 2 + self:setupSlotData(2) if ev.value == 1 then self:setCurrentMtSlot("tool", TOOL_TYPE_PEN) else self:setCurrentMtSlot("tool", TOOL_TYPE_FINGER) end elseif ev.code == C.BTN_TOUCH then - -- Much like on snow, use this to detect contact down & lift, - -- as ABS_PRESSURE may be entirely omitted from hover events, - -- and ABS_DISTANCE is not very clear cut... - self:setupSlotData(0) - if ev.value == 1 then - self:setCurrentMtSlot("id", 0) - else - self:setCurrentMtSlot("id", -1) + local tool = self:getCurrentMtSlotData("tool") + -- BTN_TOUCH is bracketed by BTN_TOOL_PEN, so we can limit this to pens, to avoid stomping on panel slots. + if tool and tool == TOOL_TYPE_PEN then + -- Much like on snow, use this to detect contact down & lift, + -- as ABS_PRESSURE may be entirely omitted from hover events, + -- and ABS_DISTANCE is not very clear cut... + self:setupSlotData(2) + if ev.value == 1 then + self:setCurrentMtSlot("id", 2) + else + self:setCurrentMtSlot("id", -1) + end end end end From d5587a6edeeaea0b0175467e7a081ab6e400f589 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 1 Mar 2023 13:37:56 +0100 Subject: [PATCH 08/11] Use the new mixed handler on rm2 mainline Should properly deal with both panel & pen --- frontend/device/remarkable/device.lua | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/frontend/device/remarkable/device.lua b/frontend/device/remarkable/device.lua index 1be709fc9247..7edb9d3674fc 100644 --- a/frontend/device/remarkable/device.lua +++ b/frontend/device/remarkable/device.lua @@ -165,6 +165,10 @@ function Remarkable:init() end end if is_mainline then + -- NOTE: The panel sends *both* ABS_MT_ & ABS_ coordinates, while the pen only sends ABS_ coordinates. + -- Since we have to apply *different* mangling to each of them, + -- we use a custom input handler that'll ignore ABS_ coordinates from the panel... + self.input.handleTouchEv = self.input.handleMixedTouchEv local mt_height = self.mt_height local mainlineInputMangling = function(this, ev) if ev.type == C.EV_ABS then @@ -172,18 +176,12 @@ function Remarkable:init() if ev.code == C.ABS_MT_POSITION_Y then ev.value = mt_height - ev.value -- Handle the Wacom pen - --- @fixme: The panel also spits out ABS_X & ABS_Y events... - --- and later than their MT counterpart, so we can't do that here. - --- Assuming the Wacom frames report a tool type, - -- this'll probably require a protocol tweak to ingnore non-MT coordinate events for the panel... - --[[ elseif ev.code == C.ABS_X then ev.code = C.ABS_Y ev.value = (wacom_height - ev.value) * wacom_scale_y elseif ev.code == C.ABS_Y then ev.code = C.ABS_X ev.value = ev.value * wacom_scale_x - --]] end end end From 27444b3d46e934d591c36baebbe48b63c5fbfe7d Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Thu, 2 Mar 2023 17:53:33 +0100 Subject: [PATCH 09/11] Simplify the tool checks getCurrentMtSlotData will return `nil` if no tool has been seen, `nil == 1` is perfectly valid test, no need for an explicit nil guard. --- frontend/device/input.lua | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/frontend/device/input.lua b/frontend/device/input.lua index 3d6851197a72..a616b52d301f 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -542,9 +542,8 @@ function Input:handleKeyBoardEv(ev) self:setCurrentMtSlot("tool", TOOL_TYPE_FINGER) end elseif ev.code == C.BTN_TOUCH then - local tool = self:getCurrentMtSlotData("tool") -- BTN_TOUCH is bracketed by BTN_TOOL_PEN, so we can limit this to pens, to avoid stomping on panel slots. - if tool and tool == TOOL_TYPE_PEN then + if self:getCurrentMtSlotData("tool") == TOOL_TYPE_PEN then -- Much like on snow, use this to detect contact down & lift, -- as ABS_PRESSURE may be entirely omitted from hover events, -- and ABS_DISTANCE is not very clear cut... @@ -778,8 +777,7 @@ function Input:handleTouchEv(ev) self:setCurrentMtSlotChecked("y", ev.value) elseif self.pressure_event and ev.code == self.pressure_event and ev.value == 0 then -- Drop hovering *pen* events - local tool = self:getCurrentMtSlotData("tool") - if tool and tool == TOOL_TYPE_PEN then + if self:getCurrentMtSlotData("tool") == TOOL_TYPE_PEN then self:setCurrentMtSlot("id", -1) end end @@ -814,15 +812,13 @@ function Input:handleMixedTouchEv(ev) self:setCurrentMtSlotChecked("x", ev.value) elseif ev.code == C.ABS_X then -- Panel + Stylus, but we only want to honor stylus! - local tool = self:getCurrentMtSlotData("tool") - if tool and tool == TOOL_TYPE_PEN then + if self:getCurrentMtSlotData("tool") == TOOL_TYPE_PEN then self:setCurrentMtSlotChecked("x", ev.value) end elseif ev.code == C.ABS_MT_POSITION_Y then self:setCurrentMtSlotChecked("y", ev.value) elseif ev.code == C.ABS_Y then - local tool = self:getCurrentMtSlotData("tool") - if tool and tool == TOOL_TYPE_PEN then + if self:getCurrentMtSlotData("tool") == TOOL_TYPE_PEN then self:setCurrentMtSlotChecked("y", ev.value) end end From d92f9f468b3700a748f37fd43cb90de565d98e3c Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Thu, 2 Mar 2023 17:56:12 +0100 Subject: [PATCH 10/11] Ditto, the nil guard is superfluous here --- frontend/device/input.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/device/input.lua b/frontend/device/input.lua index a616b52d301f..c78caf935ee0 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -775,7 +775,7 @@ function Input:handleTouchEv(ev) self:setCurrentMtSlotChecked("x", ev.value) elseif ev.code == C.ABS_MT_POSITION_Y or ev.code == C.ABS_Y then self:setCurrentMtSlotChecked("y", ev.value) - elseif self.pressure_event and ev.code == self.pressure_event and ev.value == 0 then + elseif ev.code == self.pressure_event and ev.value == 0 then -- Drop hovering *pen* events if self:getCurrentMtSlotData("tool") == TOOL_TYPE_PEN then self:setCurrentMtSlot("id", -1) From cc3a0c0b2f7ad081dc9e9adba9e9cc5d1bf8ac4c Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Thu, 2 Mar 2023 17:59:26 +0100 Subject: [PATCH 11/11] Return early in the EV_KEY handler for touch-related events (i.e., BTN_) --- frontend/device/input.lua | 44 ++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 19 deletions(-) diff --git a/frontend/device/input.lua b/frontend/device/input.lua index c78caf935ee0..6079a4c9368e 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -507,26 +507,28 @@ function Input:handleKeyBoardEv(ev) -- Detect loss of contact for the "snow" protocol... -- NOTE: Some ST devices may also behave similarly, but we handle those via ABS_PRESSURE if self.snow_protocol then - if ev.code == C.BTN_TOUCH and ev.value == 0 then - -- Kernel sends it after loss of contact for *all* slots, - -- only once the final contact point has been lifted. - if #self.MTSlots == 0 then - -- Likely, since this is usually in its own event stream, - -- meaning self.MTSlots has *just* been cleared by our last EV_SYN:SYN_REPORT handler... - -- So, poke at the actual data to find the slots that are currently active (i.e., in the down state), - -- and re-populate a minimal self.MTSlots array that simply switches them to the up state ;). - for _, slot in pairs(self.ev_slots) do - if slot.id ~= -1 then - table.insert(self.MTSlots, slot) - slot.id = -1 + if ev.code == C.BTN_TOUCH then + if ev.value == 0 then + -- Kernel sends it after loss of contact for *all* slots, + -- only once the final contact point has been lifted. + if #self.MTSlots == 0 then + -- Likely, since this is usually in its own event stream, + -- meaning self.MTSlots has *just* been cleared by our last EV_SYN:SYN_REPORT handler... + -- So, poke at the actual data to find the slots that are currently active (i.e., in the down state), + -- and re-populate a minimal self.MTSlots array that simply switches them to the up state ;). + for _, slot in pairs(self.ev_slots) do + if slot.id ~= -1 then + table.insert(self.MTSlots, slot) + slot.id = -1 + end + end + else + -- Unlikely, given what we mentioned above... + -- Note that, funnily enough, its EV_KEY:BTN_TOUCH:1 counterpart + -- *can* be in the same initial event stream as the EV_ABS batch... + for _, MTSlot in ipairs(self.MTSlots) do + self:setMtSlot(MTSlot.slot, "id", -1) end - end - else - -- Unlikely, given what we mentioned above... - -- Note that, funnily enough, its EV_KEY:BTN_TOUCH:1 counterpart - -- *can* be in the same initial event stream as the EV_ABS batch... - for _, MTSlot in ipairs(self.MTSlots) do - self:setMtSlot(MTSlot.slot, "id", -1) end end @@ -541,6 +543,8 @@ function Input:handleKeyBoardEv(ev) else self:setCurrentMtSlot("tool", TOOL_TYPE_FINGER) end + + return elseif ev.code == C.BTN_TOUCH then -- BTN_TOUCH is bracketed by BTN_TOOL_PEN, so we can limit this to pens, to avoid stomping on panel slots. if self:getCurrentMtSlotData("tool") == TOOL_TYPE_PEN then @@ -554,6 +558,8 @@ function Input:handleKeyBoardEv(ev) self:setCurrentMtSlot("id", -1) end end + + return end end