Performing an asynchronous commit on an inactive pipe would yield
USB_COMMIT_INACTVE and *not* invoke the callback (as intended),
which usb_commit_sync() ignored, causing a freeze.
This issue appeared after a world switch, which (for reasons not yet
known) appear to fail the first writes until a commit, and that commit
would then hit an inactive pipe.
Having repeat settings only for getkey() meant that repeats that occur
while getkey() is not running (i.e., all of them) would be lost. This is
due to e57efb5e3 which replaced on-demand repeats with normal event
generation.
Now the settings are applied globally, which allows repeats to be
enabled even when getkey() is not active. This also reduces the feature
gap between getkey() and raw events, which reduces the risk of running
into edges cases by using both.
The previous API is retained for source compatibility until gint 3.0 but
the changes are now applied globally so the semantics are slightly
different.
* Create a heap arena over the OS stack, large enough to hold two VRAMs
as was previously done, unless GINT_NO_OS_STACK is set at compile
time. (This replaces GINT_USER_VRAM.)
* Allocate a single VRAM in the heap at startup.
* Use double buffering by default as triple buffering is almost entirely
useless. dudpate() waits if both VRAMs are identical to prevent
corruption, but this can be bypassed with R61524 functions as usual.
This adds about 180 kB of heap data to any add-in using default
settings.
* Stop trying to be smart and generate repeats on the fly; this breaks
time consistency. Also if repeats are not handled in time this causes
infinite loops.
* Move rarely-used functions to external files, simplify stuff, get rid
of internal driver events; saves ~1 kB per add-in overall.