factor out consumer control from keyboard hid
This commit is contained in:
parent
27f101d139
commit
470f16c97f
75
kmk/hid.py
75
kmk/hid.py
@ -68,6 +68,10 @@ class AbstractHID:
|
||||
self.report_mods = memoryview(self._evt)[1:2]
|
||||
self.report_non_mods = memoryview(self._evt)[3:]
|
||||
|
||||
self._cc_report = bytearray(HID_REPORT_SIZES[HIDReportTypes.CONSUMER] + 1)
|
||||
self._cc_report[0] = HIDReportTypes.CONSUMER
|
||||
self._cc_pending = False
|
||||
|
||||
self.post_init()
|
||||
|
||||
def __repr__(self):
|
||||
@ -79,44 +83,19 @@ class AbstractHID:
|
||||
def create_report(self, keys_pressed):
|
||||
self.clear_all()
|
||||
|
||||
consumer_key = None
|
||||
for key in keys_pressed:
|
||||
if isinstance(key, ConsumerKey):
|
||||
consumer_key = key
|
||||
break
|
||||
if key.code >= FIRST_KMK_INTERNAL_KEY:
|
||||
continue
|
||||
|
||||
reporting_device = self.report_device[0]
|
||||
needed_reporting_device = HIDReportTypes.KEYBOARD
|
||||
|
||||
if consumer_key:
|
||||
needed_reporting_device = HIDReportTypes.CONSUMER
|
||||
|
||||
if reporting_device != needed_reporting_device:
|
||||
# If we are about to change reporting devices, release
|
||||
# all keys and close our proverbial tab on the existing
|
||||
# device, or keys will get stuck (mostly when releasing
|
||||
# media/consumer keys)
|
||||
self.send()
|
||||
|
||||
self.report_device[0] = needed_reporting_device
|
||||
|
||||
if consumer_key:
|
||||
self.add_key(consumer_key)
|
||||
else:
|
||||
for key in keys_pressed:
|
||||
if key.code >= FIRST_KMK_INTERNAL_KEY:
|
||||
continue
|
||||
|
||||
if isinstance(key, ModifierKey):
|
||||
self.add_modifier(key)
|
||||
else:
|
||||
self.add_key(key)
|
||||
|
||||
if key.has_modifiers:
|
||||
for mod in key.has_modifiers:
|
||||
self.add_modifier(mod)
|
||||
|
||||
return self
|
||||
if isinstance(key, ModifierKey):
|
||||
self.add_modifier(key)
|
||||
elif isinstance(key, ConsumerKey):
|
||||
self.add_cc(key)
|
||||
else:
|
||||
self.add_key(key)
|
||||
if key.has_modifiers:
|
||||
for mod in key.has_modifiers:
|
||||
self.add_modifier(mod)
|
||||
|
||||
def hid_send(self, evt):
|
||||
# Don't raise a NotImplementedError so this can serve as our "dummy" HID
|
||||
@ -131,12 +110,18 @@ class AbstractHID:
|
||||
self._prev_evt[:] = self._evt
|
||||
self.hid_send(self._evt)
|
||||
|
||||
if self._cc_pending:
|
||||
self.hid_send(self._cc_report)
|
||||
self._cc_pending = False
|
||||
|
||||
return self
|
||||
|
||||
def clear_all(self):
|
||||
for idx, _ in enumerate(self.report_keys):
|
||||
self.report_keys[idx] = 0x00
|
||||
|
||||
self.remove_cc()
|
||||
|
||||
return self
|
||||
|
||||
def clear_non_modifiers(self):
|
||||
@ -175,9 +160,6 @@ class AbstractHID:
|
||||
|
||||
where_to_place = self.report_non_mods
|
||||
|
||||
if self.report_device[0] == HIDReportTypes.CONSUMER:
|
||||
where_to_place = self.report_keys
|
||||
|
||||
for idx, _ in enumerate(where_to_place):
|
||||
if where_to_place[idx] == 0x00:
|
||||
where_to_place[idx] = key.code
|
||||
@ -193,15 +175,24 @@ class AbstractHID:
|
||||
def remove_key(self, key):
|
||||
where_to_place = self.report_non_mods
|
||||
|
||||
if self.report_device[0] == HIDReportTypes.CONSUMER:
|
||||
where_to_place = self.report_keys
|
||||
|
||||
for idx, _ in enumerate(where_to_place):
|
||||
if where_to_place[idx] == key.code:
|
||||
where_to_place[idx] = 0x00
|
||||
|
||||
return self
|
||||
|
||||
def add_cc(self, cc):
|
||||
# Add (or write over) consumer control report. There can only be one CC
|
||||
# active at any time.
|
||||
self._cc_report[1] = cc.code
|
||||
self._cc_pending = True
|
||||
|
||||
def remove_cc(self):
|
||||
# Remove consumer control report.
|
||||
if self._cc_report[1]:
|
||||
self._cc_pending = True
|
||||
self._cc_report[1] = 0x00
|
||||
|
||||
|
||||
class USBHID(AbstractHID):
|
||||
REPORT_BYTES = 9
|
||||
|
Loading…
Reference in New Issue
Block a user