@ -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
@ -534,23 +536,30 @@ 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
return
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 )
-- 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
-- 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
return
end
end
@ -772,10 +781,9 @@ 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
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
@ -797,6 +805,47 @@ 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!
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
if self : getCurrentMtSlotData ( " 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: