keyboard_comm: remove vial batch keymap fetch, use via's method

main
Ilya Zhuravlev 2020-12-26 20:15:04 -05:00
parent b15a017750
commit 5d40bec15b
2 changed files with 33 additions and 34 deletions

View File

@ -17,6 +17,7 @@ CMD_VIA_MACRO_GET_BUFFER_SIZE = 0x0D
CMD_VIA_MACRO_GET_BUFFER = 0x0E
CMD_VIA_MACRO_SET_BUFFER = 0x0F
CMD_VIA_GET_LAYER_COUNT = 0x11
CMD_VIA_KEYMAP_GET_BUFFER = 0x12
CMD_VIA_VIAL_PREFIX = 0xFE
VIA_LAYOUT_OPTIONS = 0x02
@ -26,10 +27,9 @@ CMD_VIAL_GET_SIZE = 0x01
CMD_VIAL_GET_DEFINITION = 0x02
CMD_VIAL_GET_ENCODER = 0x03
CMD_VIAL_SET_ENCODER = 0x04
CMD_VIAL_GET_KEYMAP_FAST = 0x05
# how much of a macro we can read/write per packet
MACRO_CHUNK = 28
# how much of a macro/keymap buffer we can read/write per packet
BUFFER_FETCH_CHUNK = 28
class Keyboard:
@ -128,7 +128,7 @@ class Keyboard:
row, col = int(row), int(col)
key.row = row
key.col = col
self.rowcol.setdefault(row, []).append(col)
self.rowcol[(row, col)] = True
self.keys.append(key)
# bottom right corner determines layout index and option in this layout
@ -141,26 +141,21 @@ class Keyboard:
def reload_keymap(self):
""" Load current key mapping from the keyboard """
for layer in range(self.layers):
for row, cols in self.rowcol.items():
# if this is a sideload, we have to assume it's a VIA keyboard
# and does not support fast keymap retrieval
if self.sideload:
for col in cols:
data = self.usb_send(self.dev, struct.pack("BBBB", CMD_VIA_GET_KEYCODE, layer, row, col))
keycode = struct.unpack(">H", data[4:6])[0]
self.layout[(layer, row, col)] = keycode
else:
for chunk in chunks(cols, 16):
req = struct.pack("BBBB", CMD_VIA_VIAL_PREFIX, CMD_VIAL_GET_KEYMAP_FAST, layer, row)
for col in chunk:
req += struct.pack("B", col)
req += b"\xFF" * (MSG_LEN - len(req))
keymap = b""
# calculate what the size of keymap will be and retrieve the entire binary buffer
size = self.layers * self.rows * self.cols * 2
for x in range(0, size, BUFFER_FETCH_CHUNK):
offset = x
sz = min(size - offset, BUFFER_FETCH_CHUNK)
data = self.usb_send(self.dev, struct.pack(">BHB", CMD_VIA_KEYMAP_GET_BUFFER, offset, sz))
keymap += data[4:4+sz]
data = self.usb_send(self.dev, req)
for x, col in enumerate(chunk):
keycode = struct.unpack(">H", data[x*2:x*2+2])[0]
self.layout[(layer, row, col)] = keycode
for layer in range(self.layers):
for row, col in self.rowcol.keys():
# determine where this (layer, row, col) will be located in keymap array
offset = layer * self.rows * self.cols * 2 + row * self.cols * 2 + col * 2
keycode = struct.unpack(">H", keymap[offset:offset+2])[0]
self.layout[(layer, row, col)] = keycode
for layer in range(self.layers):
for idx in self.encoderpos:
@ -181,8 +176,8 @@ class Keyboard:
self.macro = b""
# now retrieve the entire buffer, MACRO_CHUNK bytes at a time, as that is what fits into a packet
for x in range(0, self.macro_memory, MACRO_CHUNK):
sz = min(MACRO_CHUNK, self.macro_memory - x)
for x in range(0, self.macro_memory, BUFFER_FETCH_CHUNK):
sz = min(BUFFER_FETCH_CHUNK, self.macro_memory - x)
data = self.usb_send(self.dev, struct.pack(">BHB", CMD_VIA_MACRO_GET_BUFFER, x, sz))
self.macro += data[4:4+sz]
# macros are stored as NUL-separated strings, so let's clean up the buffer
@ -212,8 +207,8 @@ class Keyboard:
if len(data) > self.macro_memory:
raise RuntimeError("the macro is too big: got {} max {}".format(len(data), self.macro_memory))
for x, chunk in enumerate(chunks(data, MACRO_CHUNK)):
off = x * MACRO_CHUNK
for x, chunk in enumerate(chunks(data, BUFFER_FETCH_CHUNK)):
off = x * BUFFER_FETCH_CHUNK
self.usb_send(self.dev, struct.pack(">BHB", CMD_VIA_MACRO_SET_BUFFER, off, len(chunk)) + chunk)
self.macro = data

View File

@ -4,7 +4,7 @@ import struct
from keyboard_comm import Keyboard
from util import chunks
from util import chunks, MSG_LEN
LAYOUT_2x2 = """
{"name":"test","vendorId":"0x0000","productId":"0x1111","lighting":"none","matrix":{"rows":2,"cols":2},"layouts":{"keymap":[["0,0","0,1"],["1,0","1,1"]]}}
@ -28,6 +28,7 @@ class SimulatedDevice:
inp = bytes.fromhex(inp)
if isinstance(out, str):
out = bytes.fromhex(out)
out += b"\x00" * (MSG_LEN - len(out))
self.expect_data.append((inp, out))
def expect_keyboard_id(self, kbid):
@ -46,10 +47,15 @@ class SimulatedDevice:
self.expect("11", struct.pack("BB", 0x11, layers))
def expect_keymap(self, keymap):
for l, layer in enumerate(keymap):
for r, row in enumerate(layer):
for c, col in enumerate(row):
self.expect(struct.pack("BBBB", 4, l, r, c), struct.pack(">BBBBH", 4, l, r, c, col))
buffer = b""
for layer in keymap:
for row in layer:
for col in row:
buffer += struct.pack(">H", col)
# client will retrieve our keymap buffer in chunks of 28 bytes
for x, chunk in enumerate(chunks(buffer, 28)):
query = struct.pack(">BHB", 0x12, x, len(chunk))
self.expect(query, query + chunk)
def expect_encoders(self, encoders):
for l, layer in enumerate(encoders):
@ -101,8 +107,6 @@ class TestKeyboard(unittest.TestCase):
dev.expect("0D", "0D0000")
kb = Keyboard(dev, dev.sim_send)
# simulate old VIA keymap retrieval in tests for now
kb.sideload = True
kb.reload()
return kb, dev