On Monza, the lift frame can report these for *multiple contacts* without an id or a slot, which is super-duper invalid -_-".
(And we have ABS_MT_POSITION_X & ABS_MT_POSITION_Y for the "saner" frames, plus these devices generally don't support pens, so we don't make use of pressure).
(Also, switched to a dedicated handler like for the phoenix quirks, to avoid bogging down the standard handler with hacks for broken drivers).
Fix#11910
Switch to a new `input.fdopen` API & wrapper so we can keep the fds opened by `fbink_input_scan` instead of closing them to re-open them right after that...
This should hopefully help on racy zForce devices that attempt to handle power management when opening/closing the device. We know this sometimes horribly fail to re-activate the IR grid (c.f., our manual activation on resume), but this apparently could also happen here (re: #11844) because of the quick succession of open->close->open.
* Kobo: Drop a bunch of if ladder crap and switch to auto-detection of input devices via fbink_input
* Kindle: Drop an even larger bundle of crap to do the same ;p. (re: #11392)
* ExternalKeyboard: Switch to fbink_input to whitelist keyboards instead of the manual parsing of caps via its FindKeyboard class
* Input: Extended open/close wrappers to handle logging & tracking of dupe open/close calls.
If there's only one contact, we won't get an ABS_MT_SLOT, so we need to
make sure we fall back to the main finger slot once we've caught a tool
switch.
Also, move the dedicated pen slot further away, so it has zero chance of
being detected as a potential buddy contact to a finger contact.
Fix#11514
We currently don't do anything with it, but this might help someone come
up with fancier smartcover handling, like we do on Kobo...
Simplify the fake events w/args checks:
We can just hitcheck the table directly, no need for another hash
Also catch ExitedSS on Kindle.
And, again, dn't do anything with it ;p.
* 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)
Namely, don't recompute layouts, as they do not change.
(The gyro codepaths were already doing something similar.)
* Keep ConfigDialog, FileManagerMenu & ReaderMenu open on rotation.
(In practice, only ConfigDialog is affected, as *Menu doesn't handle the rotation event.)
* Plugged an instance leak in the aforementioned Menu classes.
* Unify behavior & code with the gyro codepaths.
we use it as text anyway and test if it is the empty string also.
this fixes a crash in viewhtml when holding a selector with an empty clipboard, we try to contcate getClipboardText which is nil (on !SDL & !Android)
Make sure we only send Suspend/Resume events when we *actually* suspend/resume. This is done via the Device `_beforeSuspend`/`_afterResume` methods, and those were called by the *input handlers*, not the PM logic; which means they would fire, while the PM logic could actually take a smarter decision and *not* do what the event just sent implied ;).
(i.e., sleep with a cover -> suspend + actual suspend, OK; but if you then resume with a button -> input assumes resume, but PM will actually suspend again!).
Existing design issue made more apparent by #9448 ;).
Also fixes/generalizes a few corner-cases related to screen_saver_lock handling (e.g., don't allow USBMS during a lock).
And deal with the fallout of the main change to the Kobo frontlight ramp behavior ;).
Add a dedicated handler to handle mixed pen + panel, when panel sends both mt + st and stylus only st
Don't stomp on panel slots in the Wacom protocol handler
Get rid of a few superfluous nil guards
Return early in the EV_KEY handler for touch-related events (i.e., BTN_)
* Get rid of the `canToggleGSensor` Device cap, it's now mandatory for `hasGSensor` devices. (This means Kindles can now toggle the gyro, fix#9136).
* This also means that `Device:toggleGSensor` is now implemented by `Generic`.
* Update the Screen & Gyro rotation constants to be clearer (c.f., https://github.com/koreader/koreader-base/pull/1568) (/!\ This might conceivably break some `rotation_map` user-patches).
* Input: Move the platform-specific gyro handling to Device implementations, and let Input only handle a single, custom protocol (`EV_MSC:MSC_GYRO`).
* Input: Refine the `rotation_map` disable method implemented in 43b021d37c. Instead of directly poking at the internal field, use a new method, `disableRotationMap` (/!\ Again, this might break some `rotation_map` user-patches).
* Input: Minor tweaks to event adjust hooks to make them more modular, allowing the Kobo implementation to build and use a single composite hook. API compatibility maintained with wrappers.
(This involves moving it to the instance object to avoid inheritance).
Pocketbook: Disable rotation_map on the Era (fix#9556)
It would appear that InkView handles the translation for us, now...
* Added a new plugin external-keyboard. It listens to USB events. When keyboard is plugged in or plugged out, it updates device and input configuration accordingly.
* Added new fake events UsbDevicePlugIn and UsbDevicePlugOut that are emitted when a device is connected to a book reader that plays the role of USB host. The usage of the existing events UsbPlugIn and UsbPlugOut has not changed - they are used when a reader is connected to a host. The koreader-base has a related PR for those events.
* Did a small refactoring of initialization for the modules FocusManager and InputText. They check device keyboard capabilities on their when the module is first loaded and store it. Some of the initialization code has been extracted into functions, so that we can re-initialize them when keyboard is (dis)connected.
* Initial implementation centered around text input, and tested with USB keyboards on devices with OTG support.
* Said OTG shenanigans are so far supported on devices with debugfs & the chipidea driver, or sunxi devices.
* UIManager: Support more specialized update modes for corner-cases:
* A2, which we'll use for the VirtualKeyboards keys (they'd... inadvertently switched to UI with the highlight refactor).
* NO_MERGE variants of ui & partial (for sunxi). Use `[ui]` in ReaderHighlight's popup, because of a Sage kernel bug that could otherwise make it translucent, sometimes completely so (*sigh*).
* UIManager: Assorted code cleanups & simplifications.
* Logger & dbg: Unify logging style, and code cleanups.
* SDL: Unbreak suspend/resume outside of the emulator (fix#9567).
* NetworkMgr: Cache the network status, and allow it to be queried. (Used by AutoSuspend to avoid repeatedly poking the system when computing the standby schedule delay).
* OneTimeMigration: Don't forget about `NETWORK_PROXY` & `STARDICT_DATA_DIR` when migrating `defaults.persistent.lua` (fix#9573)
* WakeupMgr: Workaround an apparent limitation of the RTC found on i.MX5 Kobo devices, where setting a wakealarm further than UINT16_MAX seconds in the future would apparently overflow and wraparound... (fix#8039, many thanks to @yfede for the extensive deep-dive and for actually accurately pinpointing the issue!).
* Kobo: Handle standby transitions at full CPU clock speeds, in order to limit the latency hit.
* UIManager: Properly quit on reboot & exit. This ensures our exit code is preserved, as we exit on our own terms (instead of being killed by the init system). This is important on platforms where exit codes are semantically meaningful (e.g., Kobo).
* UIManager: Speaking of reboot & exit, make sure the Screensaver shows in all circumstances (e.g., autoshutdown, re: #9542)), and that there aren't any extraneous refreshes triggered. (Additionally, fix a minor regression since #9448 about tracking this very transient state on Kobo & Cervantes).
* Kindle: ID the upcoming Scribe.
* Bump base (https://github.com/koreader/koreader-base/pull/1524)
* Kobo: Discriminate between the Touch A/B and the Touch C properly, and implement actual support for the A/B input quirks. This means the clunky touchscreen probe widget shown on fresh installs on those devices is now gone :}.
* Input: Fix an off-by-one in most adjustTouchMirrorX/Y callers (only rM was doing it right), and adjust their documentation to avoid similar mistakes in the future.
* GestureDetector: Unify logging to always display transformed coordinates for simple gestures.
* GestureDetector: Fix two-contact hold lifts to be computed at the midpoint between the two contacts, like their holds counterpart already did.
* Kobo: Switch ST devices to a dedicated input handler
Instead of shoehorning a hack into the standard handler.
* Use setCurrentMtSlotChecked in handleTouchEvLegacy
slots
This ensures we won't leave *any* slot in an undefined state because
we skipped parsing 'em because what we consumed first yielded a
gesture.
(In particular, this could leave a few slots dangling in the "hold"
state in corner cases involving spider-hand finger tapping ;p).
Cleans up the slot state clearing in GestureDetector to only clear the
necessary slots (e.g., two-finger gestures now only clear their own two
slots; and holds only clear their own slot).
The fact that every slot will be consumed ensures that every slot will
naturally get their contact up handled, which wasn't the case before,
hence those crappy workarounds.
As far as timerfd callbacks are concerned, this *does* introduce the
possibility of deadline collisions, so, do reimplement minimal safety
checks to ensure we run (and free) the right timerfd callback.
Some drivers can bundle the same slot multiple times in the same input
frame. We were only correctly coalescing *consecutive* slots, but some
drivers can do that in non-consecutive sequences (e.g., 1a -> 2a -> 1b
-> 2b), so, handle that, too.
Seen on neonode v2 grids.
Make sure we always create the storage table when we add its reference
to the MTSlots list instead.
(The reasoning being we only add the reference once, and it's the first
thing we do, and we kinda need the storage to be created to get its
reference anyway; while we may set multiple keys per frame).
For realz, this time.
This reverts the original attempt, because it was gratuitous
overcomplexification that turns out to be completely unnecessary.
This also fixes a few subtle MT handling snafus on some devices.
Multitouch gestures can create multiple timers on the same deadline, but
on different slots, so simply hoping that the head of the list would
match was somewhat optimistic... ;o).
Fix#9376
It's trickier in the !timerfd case, though,
so do the best we can there...
(It wouldn't crash, but it might fire the "wrong" callback).
Commonize fullscreen code across different devices.
Add fullscreen toggle on SDL desktop targets.
Expose the toggle to the dispatcher and map it to F11.
Hide touchmenu when resizing.
* GestureDetector: Downgrade probeClockSource log messages to debug
We're seeing a bit more of 'em between autostandby and inhibitInput now,
and the whole thing was implemented long enough ago that it's no longer
critical to see this in random non-debug logs ;).
* Input: Reset gesture state in inhibitInput
Should prevent bogus gestures when re-enabling the handlers if we were
called in the middle of gesture detection.
* Disable all non power management related input during suspend. (This prevents wonky touch events from being tripped when closing a sleep cover on an already-in-suspend device, among other things).
* Kobo: Use our WakeupMgr instance, not the class.
* WakupMgr: split `removeTask` in two:
* `removeTask`, which *only* takes a queue index as input, and only removes a single task. Greatly simplifies the function (i.e., it's just a `table.remove`).
* `removeTasks`, which takes an epoch or a cb ref, and removes *every* task that matches.
* Both of these will also *always* re-schedule the next task (if any) on exit, since we can have multiple WakeupMgr tasks queued, but we can only have a single RTC wake alarm set ;).
* `wakeupAction` now takes a `proximity` argument, which it passes on to its `validateWakeupAlarmByProximity` call, allowing call sites to avoir having to duplicate that call themselves when they want to use a custom proximity window.
* `wakeupAction` now re-schedules the next task (if any) on exit.
* Simplify `Kobo:checkUnexpectedWakeup`, by removing the duplicate `WakerupMgr:validateWakeupAlarmByProximity` call, now that we can pass a proximity window to `WakeuoMgr:wakeupAction`.
* The various network activity timeouts are now halved when autostandby is enabled.
* Autostandby: get rid of the dummy deadline_guard task, as it's no longer necessary since #9009.
* UIManager: The previous change allows us to simplify `getNextTaskTimes` into a simpler `getNextTaskTime` variant, getting rid of a table & a loop.
* ReaderFooter & ReaderHeader: Make sure we only perform a single refresh when exiting standby.
* Kobo: Rewrite sysfs writes to use ANSI C via FFI instead of stdio via Lua, as it obscured some common error cases (e.g., EBUSY on /sys/power/state).
* Kobo: Simplify `suspend`, now that we have sane error handling in sysfs writes.
* Kobo.powerd: Change `isCharging` & `isAuxCharging` behavior to match the behavior of the NTX ioctl (i.e., Charging == Plugged-in). This has the added benefit of making the AutoSuspend checks behave sensibly in the "fully-charged but still plugged in" scenario (because being plugged in is enough to break PM on `!canPowerSaveWhileCharging` devices).
* AutoSuspend: Disable our `AllowStandby` handler when auto standby is disabled, so as to not interfere with other modules using `UIManager:allowStandby` (fix#9038).
* PowerD: Allow platforms to implement `isCharged`, indicating that the battery is full while still plugged in to a power source (battery icon becomes a power plug icon).
* Kobo.powerd: Implement `isCharged`, and kill charging LEDs once battery is full.
* Kindle.powerd: Implement `isCharged` on post-Wario devices. (`isCharging` is still true in that state, as it ought to).
* Decode EV_KEY:KEY_BATTERY
* Input: Only drop hovering *pen* events.
There are currently too many broken 0-pressure *finger* events being
reported on the Elipsa, making a dumb rejection highly annoying.
* Bump base
https://github.com/koreader/koreader-base/pull/1393
* Rely on actual events to detect loss of contact for the "snow"
protocol.
Allows simplifying the whole thing.
* Use `ipairs` over `pairs` for pure arrays.
* Input: Don't create a new TimeVal object for input frame timestamps, just promote our existing table by assigning it the `TimeVal` metatable.
* TimeVal: Export (const) `zero` & `huge` TimeVal objects, because they're common enough in our codebase. (NOTE: not actually const, that's a Lua 5.4 feature ;p).
* GestureDetector: Explain the behavior of the `last_tevs` & `first_tevs` tables, and why one needs a new object and not the other.
* Speaking of, simplify the copy method for `first_tevs`, because it doesn't need to create a new TimeVal object, we can just reference the original, it's unique and re-assigned for each frame.
* TimeVal: Log the results of the COARSE probes in debug logs
* GestureDetector: Print details of failed clock probes in debug logs
* GestureDetector: Skip the BOOTTIME probe when CLOCK_BOOTTIME is unsupported.
* Input: Decode ABS_DISTANCE events in debug logs
* Get rid of duplicated <linux/input.h> constants, use the FFI module everywhere (re #7536)
* Kobo: Get rid of the `touch_alyssum_protocol` quirk. Replace it by setting `main_finger_slot` to `1`, like on the H2O.
Requires https://github.com/koreader/koreader-base/pull/1344 & https://github.com/koreader/koreader-base/pull/1346 (fix#7485)
Assorted input fixes:
* Actually handle errors in the "there's a callback timer" input polling loop.
* Don't break timerfd when the clock probe was inconclusive.
Not directly related, but noticed because of duplicate onInputEvent handlers:
* HookContainer: Fix deregistration to actually deregister properly. "Regression" extant since its inception in #2933 (!).
* Made sure the three plugins (basically the trio of AutoThingies ;p) that were using HookContainer actually unschedule their task on teardown.
* Actually load librt properly on old Linux systems (fix#7472)
* Made sure SDL & Android honored timeouts properly in some edgy (or not so edgy, in SDL's case) cases (c.f., https://github.com/koreader/koreader-base/pull/1343).
* Try harder not to consume a timer callback when the timerfd backend is in use and `select` timed out *not* because of a timerfd expiring. This would take some particularly heinous timing to reproduce (e.g., a timerfd set, but a task deadline expiring *before* it). May or may not help with #7473.
* Decode `BTN_` KEY codes in verbose debug logs.
* Fix MultiTouch on the H2O (GestureDetector was hard-coding the two slots as 0 & 1, but the H2O kernel is a special snowflake that doesn't use slot 0, instead switching to slot 1 & 2).