implement global pointing device axis handling
This commit is contained in:
parent
470f16c97f
commit
69d47343e8
21
kmk/hid.py
21
kmk/hid.py
@ -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
|
||||||
|
@ -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, ...],
|
||||||
|
@ -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:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user