* Input: Harden setCurrentMtSlotChecked
The current implementation was assuming that the only case where we
might be missing slot storage was for the *first* contact point,
given that ABS_MT_SLOT is (if all goes well) guaranteed to be present
and come first for every subsequent additional contact points.
While this works just fine in practice, we can simplify and generalize
the check by just checking if we've actually recorded the requested
slot, even if it's not the first contact point.
The hit check is possibly ever so slightly faster than the length
computation, to boot.
* Input: Handle snow_protocol devices with newer hardware revisions that do *NOT* need the snow quirks.
If a sane input frame is detected, the snow quirks will be disabled at runtime, ensuring sane behavior.
Given the extremely non-standard behavior of the snow quirks, this is fairly easy to detect,
as a snow device will *never* emit EV_ABS:ABS_MT_TRACKING_ID:-1, so if we catch one, it's not snow ;).
(We've had reports of this on a Clara HD, FWIW)
-- NOTE: Simply skipping the slot storage setup for -1 would not be enough, as it would only fix ST handling.
-- MT would be broken, because buddy contact detection in GestureDetector looks at slot +/- 1,
-- whereas we'd be having the main contact point at a stupidly large slot number
-- (because it would match ABS_MT_TRACKING_ID, given the lack of ABS_MT_SLOT, at least for the first input frame),
-- while the second contact would be at slot 1, because it would immediately have required emitting a proper ABS_MT_SLOT event...
logger.warn("Input: Disabled snow_protocol quirks because your device's hardware revision doesn't appear to need them!")
self.snow_protocol=false
else
self:setupSlotData(ev.value)
end
end
self:setCurrentMtSlot("id",ev.value)
self:setCurrentMtSlotChecked("id",ev.value)
elseifev.code==C.ABS_MT_TOOL_TYPEthen
-- NOTE: On the Elipsa: Finger == 0; Pen == 1
self:setCurrentMtSlot("tool",ev.value)
@ -934,14 +944,15 @@ end
functionInput:handleTouchEvLegacy(ev)
-- 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.
-- Some devices emit both singletouch and multitouch events.
-- On those devices, `handleTouchEv` may not behave as expected. Use this one instead.
ifev.type==C.EV_ABSthen
ifev.code==C.ABS_Xthen
self:setCurrentMtSlotChecked("x",ev.value)
elseifev.code==C.ABS_Ythen
self:setCurrentMtSlotChecked("y",ev.value)
elseifev.code==C.ABS_PRESSUREthen
-- This is the least common denominator we can use to detect contact down & lift...
ifev.value~=0then
self:setCurrentMtSlotChecked("id",1)
else
@ -1051,29 +1062,29 @@ function Input:initMtSlot(slot)
end
end
functionInput:getMtSlot(slot)
returnself.ev_slots[slot]
end
functionInput:getCurrentMtSlot()
returnself.ev_slots[self.cur_slot]
end
functionInput:setMtSlot(slot,key,val)
self.ev_slots[slot][key]=val
end
functionInput:setCurrentMtSlot(key,val)
self:setMtSlot(self.cur_slot,key,val)
self.ev_slots[self.cur_slot][key]=val
end
-- Same as above, but ensures the current slot actually has a live ref first
functionInput:setCurrentMtSlotChecked(key,val)
if#self.MTSlots==0then
ifnotself.active_slots[self.cur_slot]then
self:addSlot(self.cur_slot)
end
self:setMtSlot(self.cur_slot,key,val)
end
functionInput:getMtSlot(slot)
returnself.ev_slots[slot]
end
functionInput:getCurrentMtSlot()
returnself:getMtSlot(self.cur_slot)
self.ev_slots[self.cur_slot][key]=val
end
functionInput:getCurrentMtSlotData(key)
@ -1100,22 +1111,13 @@ function Input:addSlot(value)
self.cur_slot=value
end
functionInput:addSlotIfChanged(value)
ifself.cur_slot~=valuethen
-- We've already seen that slot in this frame, don't insert a duplicate reference!
ifself.active_slots[value]then
self.cur_slot=value
else
self:addSlot(value)
end
end
end
functionInput:setupSlotData(value)
if#self.MTSlots==0then
ifnotself.active_slots[value]then
self:addSlot(value)
else
self:addSlotIfChanged(value)
-- We've already seen that slot in this frame, don't insert a duplicate reference!
-- NOTE: May already be set to the correct value if the driver repeats ABS_MT_SLOT (e.g., our android/PB translation layers; or ABS_MT_TRACKING_ID for snow_protocol).