From 2678d2c49b375eb20b95161e0ce8b689d648ece4 Mon Sep 17 00:00:00 2001 From: NiLuJe Date: Wed, 31 Aug 2022 07:12:33 +0200 Subject: [PATCH] Input: Unbreak evdev handling on Kobo single-touch devices (#9465) * Kobo: Switch ST devices to a dedicated input handler Instead of shoehorning a hack into the standard handler. * Use setCurrentMtSlotChecked in handleTouchEvLegacy --- frontend/device/input.lua | 74 +++++++++++++-------------- frontend/device/kobo/device.lua | 6 +-- frontend/device/remarkable/device.lua | 1 + 3 files changed, 41 insertions(+), 40 deletions(-) diff --git a/frontend/device/input.lua b/frontend/device/input.lua index b74cfc7eb..bdca6e85c 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -56,6 +56,10 @@ local MSC_RAW_GSENSOR_LANDSCAPE_LEFT = 0x1a local MSC_RAW_GSENSOR_BACK = 0x1b local MSC_RAW_GSENSOR_FRONT = 0x1c +-- Based on ABS_MT_TOOL_TYPE values on Elan panels +local TOOL_TYPE_FINGER = 0 +local TOOL_TYPE_PEN = 1 + -- For debug logging of ev.type local linux_evdev_type_map = { [C.EV_SYN] = "EV_SYN", @@ -459,6 +463,7 @@ end 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, @@ -485,6 +490,26 @@ function Input:handleKeyBoardEv(ev) return end + elseif self.wacom_protocol then + if ev.code == C.BTN_TOOL_PEN then + -- Always send pen data to slot 0 + self:setupSlotData(0) + 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) + end + end end local keycode = self.event_map[ev.code] @@ -711,29 +736,14 @@ function Input:handleTouchEv(ev) elseif ev.code == C.ABS_MT_TOOL_TYPE then -- NOTE: On the Elipsa: Finger == 0; Pen == 1 self:setCurrentMtSlot("tool", ev.value) - elseif ev.code == C.ABS_MT_POSITION_X then + elseif ev.code == C.ABS_MT_POSITION_X or ev.code == C.ABS_X then self:setCurrentMtSlotChecked("x", ev.value) - elseif ev.code == C.ABS_MT_POSITION_Y then + 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 -- Drop hovering *pen* events local tool = self:getCurrentMtSlotData("tool") - if tool and tool == 1 then - self:setCurrentMtSlot("id", -1) - end - - -- Emulate MT protocol on ST Kobos: - -- we "confirm" ABS_X, ABS_Y only when ABS_PRESSURE ~= 0 - elseif ev.code == C.ABS_X then - self:setCurrentMtSlotChecked("abs_x", ev.value) - elseif ev.code == C.ABS_Y then - self:setCurrentMtSlotChecked("abs_y", ev.value) - elseif ev.code == C.ABS_PRESSURE then - if ev.value ~= 0 then - self:setCurrentMtSlot("id", 1) - self:confirmAbsxy() - else - self:cleanAbsxy() + if tool and tool == TOOL_TYPE_PEN then self:setCurrentMtSlot("id", -1) end end @@ -754,6 +764,7 @@ function Input:handleTouchEv(ev) end end end + function Input:handleTouchEvPhoenix(ev) -- Hack on handleTouchEV for the Kobo Aura -- It seems to be using a custom protocol: @@ -813,22 +824,21 @@ function Input:handleTouchEvPhoenix(ev) end end end + function Input:handleTouchEvLegacy(ev) - -- Single Touch Protocol. Some devices emit both singletouch and multitouch events. - -- In those devices the 'handleTouchEv' function doesn't work as expected. Use this function instead. + -- Single Touch Protocol. + -- Some devices emit both singletouch and multitouch events, + -- on those devices, the 'handleTouchEv' function may not behave as expected. Use this one instead. if ev.type == C.EV_ABS then - if #self.MTSlots == 0 then - self:addSlot(self.cur_slot) - end if ev.code == C.ABS_X then - self:setCurrentMtSlot("x", ev.value) + self:setCurrentMtSlotChecked("x", ev.value) elseif ev.code == C.ABS_Y then - self:setCurrentMtSlot("y", ev.value) + self:setCurrentMtSlotChecked("y", ev.value) elseif ev.code == C.ABS_PRESSURE then if ev.value ~= 0 then - self:setCurrentMtSlot("id", 1) + self:setCurrentMtSlotChecked("id", 1) else - self:setCurrentMtSlot("id", -1) + self:setCurrentMtSlotChecked("id", -1) end end elseif ev.type == C.EV_SYN then @@ -1059,16 +1069,6 @@ function Input:setupSlotData(value) end end -function Input:confirmAbsxy() - self:setCurrentMtSlot("x", self.ev_slots[self.cur_slot]["abs_x"]) - self:setCurrentMtSlot("y", self.ev_slots[self.cur_slot]["abs_y"]) -end - -function Input:cleanAbsxy() - self:setCurrentMtSlot("abs_x", nil) - self:setCurrentMtSlot("abs_y", nil) -end - function Input:isEvKeyPress(ev) return ev.value == EVENT_VALUE_KEY_PRESS end diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index 7d336619f..19ba69ef7 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -791,10 +791,10 @@ function Kobo:initEventAdjustHooks() if self.touch_snow_protocol then self.input.snow_protocol = true - end - - if self.touch_phoenix_protocol then + elseif self.touch_phoenix_protocol then self.input.handleTouchEv = self.input.handleTouchEvPhoenix + elseif not self:hasMultitouch() then + self.input.handleTouchEv = self.input.handleTouchEvLegacy end -- Accelerometer on the Forma diff --git a/frontend/device/remarkable/device.lua b/frontend/device/remarkable/device.lua index 43b100596..32e252d25 100644 --- a/frontend/device/remarkable/device.lua +++ b/frontend/device/remarkable/device.lua @@ -143,6 +143,7 @@ function Remarkable:init() self.input = require("device/input"):new{ device = self, event_map = require("device/remarkable/event_map"), + wacom_protocol = true, } self.input.open(self.input_wacom) -- Wacom