implement global pointing device axis handling

This commit is contained in:
xs5871 2022-10-16 19:39:02 +00:00 committed by xs5871
parent 470f16c97f
commit 69d47343e8
3 changed files with 46 additions and 8 deletions

View File

@ -5,6 +5,7 @@ from micropython import const
from storage import getmount from storage import getmount
from kmk.keys import FIRST_KMK_INTERNAL_KEY, ConsumerKey, ModifierKey from kmk.keys import FIRST_KMK_INTERNAL_KEY, ConsumerKey, ModifierKey
from kmk.utils import clamp
try: try:
from adafruit_ble import BLERadio from adafruit_ble import BLERadio
@ -72,6 +73,10 @@ class AbstractHID:
self._cc_report[0] = HIDReportTypes.CONSUMER self._cc_report[0] = HIDReportTypes.CONSUMER
self._cc_pending = False self._cc_pending = False
self._pd_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.MOUSE] + 1)
self._pd_report[0] = HIDReportTypes.MOUSE
self._pd_pending = False
self.post_init() self.post_init()
def __repr__(self): def __repr__(self):
@ -80,7 +85,7 @@ class AbstractHID:
def post_init(self): def post_init(self):
pass pass
def create_report(self, keys_pressed): def create_report(self, keys_pressed, axes):
self.clear_all() self.clear_all()
for key in keys_pressed: for key in keys_pressed:
@ -97,6 +102,9 @@ class AbstractHID:
for mod in key.has_modifiers: for mod in key.has_modifiers:
self.add_modifier(mod) self.add_modifier(mod)
for axis in axes.values():
self.move_axis(axis)
def hid_send(self, evt): def hid_send(self, evt):
# Don't raise a NotImplementedError so this can serve as our "dummy" HID # Don't raise a NotImplementedError so this can serve as our "dummy" HID
# when MCU/board doesn't define one to use (which should almost always be # when MCU/board doesn't define one to use (which should almost always be
@ -114,6 +122,10 @@ class AbstractHID:
self.hid_send(self._cc_report) self.hid_send(self._cc_report)
self._cc_pending = False self._cc_pending = False
if self._pd_pending:
self.hid_send(self._pd_report)
self._pd_pending = False
return self return self
def clear_all(self): def clear_all(self):
@ -193,6 +205,13 @@ class AbstractHID:
self._cc_pending = True self._cc_pending = True
self._cc_report[1] = 0x00 self._cc_report[1] = 0x00
def move_axis(self, axis):
if axis.delta != 0 or self._pd_report[axis.code + 2] != 0:
delta = clamp(axis.delta, -127, 127)
axis.delta -= delta
self._pd_report[axis.code + 2] = 0xFF & delta
self._pd_pending = True
class USBHID(AbstractHID): class USBHID(AbstractHID):
REPORT_BYTES = 9 REPORT_BYTES = 9

View File

@ -33,6 +33,15 @@ ALL_NUMBER_ALIASES = tuple(f'N{x}' for x in ALL_NUMBERS)
debug = Debug(__name__) debug = Debug(__name__)
class Axis:
def __init__(self, code: int) -> None:
self.code = code
self.delta = 0
def __repr__(self) -> str:
return f'Axis(code={self.code}, delta={self.delta})'
def maybe_make_key( def maybe_make_key(
code: Optional[int], code: Optional[int],
names: Tuple[str, ...], names: Tuple[str, ...],

View File

@ -49,6 +49,7 @@ class KMKKeyboard:
##### #####
# Internal State # Internal State
keys_pressed = set() keys_pressed = set()
axes = {}
_coordkeys_pressed = {} _coordkeys_pressed = {}
hid_type = HIDModes.USB hid_type = HIDModes.USB
secondary_hid_type = None secondary_hid_type = None
@ -88,6 +89,7 @@ class KMKKeyboard:
f' unicode_mode={self.unicode_mode}, ', f' unicode_mode={self.unicode_mode}, ',
f'_hid_helper={self._hid_helper},\n', f'_hid_helper={self._hid_helper},\n',
f' keys_pressed={self.keys_pressed},\n', f' keys_pressed={self.keys_pressed},\n',
f' axes={self.axes},\n',
f' _coordkeys_pressed={self._coordkeys_pressed},\n', f' _coordkeys_pressed={self._coordkeys_pressed},\n',
f' hid_pending={self.hid_pending}, ', f' hid_pending={self.hid_pending}, ',
f'active_layers={self.active_layers}, ', f'active_layers={self.active_layers}, ',
@ -100,16 +102,24 @@ class KMKKeyboard:
if debug.enabled: if debug.enabled:
debug(f'coordkeys_pressed={self._coordkeys_pressed}') debug(f'coordkeys_pressed={self._coordkeys_pressed}')
debug(f'keys_pressed={self.keys_pressed}') debug(f'keys_pressed={self.keys_pressed}')
# debug(f'axis={[ax for ax in self.axis.__iter__()]}')
def _send_hid(self) -> None: def _send_hid(self) -> None:
if self._hid_send_enabled: if not self._hid_send_enabled:
hid_report = self._hid_helper.create_report(self.keys_pressed) return
self._hid_helper.create_report(self.keys_pressed, self.axes)
try: try:
hid_report.send() self._hid_helper.send()
except KeyError as e: except KeyError as e:
if debug.enabled: if debug.enabled:
debug(f'HidNotFound(HIDReportType={e})') debug(f'HidNotFound(HIDReportType={e})')
self.hid_pending = False self.hid_pending = False
for axis in self.axes.values():
if axis.delta != 0:
self.hid_pending = True
break
def _handle_matrix_report(self, kevent: KeyEvent) -> None: def _handle_matrix_report(self, kevent: KeyEvent) -> None:
if kevent is not None: if kevent is not None: