Browse Source

initial version of multibow

develop
Harald Albrecht 5 years ago
commit
59850fd49b
  1. 19
      LICENSE
  2. 59
      README.md
  3. 210
      mock/keybow.lua
  4. 24
      mock/mockkeybow.lua
  5. BIN
      multibow.jpg
  6. 4
      sdcard/keys.lua
  7. 22
      sdcard/layouts/empty.lua
  8. 38
      sdcard/layouts/shift.lua
  9. 74
      sdcard/layouts/vsc-golang.lua
  10. 108
      sdcard/snippets/morekeys.lua
  11. 176
      sdcard/snippets/multibow.lua
  12. 63
      sdcard/snippets/routehandlers.lua
  13. 30
      test.lua

19
LICENSE

@ -0,0 +1,19 @@
Copyright 2019 Harald Albrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

59
README.md

@ -0,0 +1,59 @@
# Multibow
GitHub: [github.com/thediveo/multibow](https://github.com/thediveo/multibow)
Multibow turns a [Pimoroni Keybow](https://shop.pimoroni.com/products/keybow)
into a macro keyboard with multiple layouts, switchable at any time. (Keybow is
a solderless DIY 4x3 mechanical USB keyboard, powered by a Raspberry Pi. And
yes, these days even keyboards run Linux...)
![Multibow on Keybow](multibow.jpg)
Layouts included:
- Debug Go programs and packages in VisualStudio Code with its Go extension.
- "Empty" keyboard layout what does nothing, very useful when using cycling between different keyboard layouts to have one non-reacting layout.
- permanent layout for cycling between the other layouts and for changing the keybow LED brightness.
## Licenses
Multibow is (c) 2019 Harald Albrecht and is licensed under the MIT license, see
the [LICENSE](LICENSE) file.
The file `keybow.lua` included from
[pimoroni/keybow-firmware](https://github.com/pimoroni/keybow-firmware) for
testing purposes is licensed under the MIT license, as declared by Pimoroni's
keybow-firmware GitHub repository.
## Installation
1. Download the [Pibow
firmware](https://github.com/pimoroni/keybow-firmware/releases) and copy all
files inside its `sdcard/` subdirectory onto an empty, FAT32 formatted microSD
card. Copy only the files **inside** `sdcard/`, but do **not** place them into a
~~`sdcard`~~ directory on your microSD card.
2. Download all files from the `sdcard/` subdirectory of this repository and
then copy them onto the microSD card. This will overwrite but one file
`key.lua`, all other files are new.
## Multiple Keyboard Layouts
To enable one or more multibow keyboard layouts, edit `sdcard/keys.lua`
accordingly to require them. The default configuration is as follows:
```lua
require "layouts/shift" -- for cycling between layouts.
require "layouts/vsc-golang" -- debugging Go programs in VisualStudio Code.
require "layouts/empty" -- empty, do-nothing layout.
```
## Developing
For some basic testing, run `lua test.lua` from the base directory of this
repository. It pulls in `keybow`, then mocks some functionality of it, and
finally starts `sdcard/keys.lua` as usual.
This helps in detecting syntax and logic erros early, avoiding the
rinse-and-repeat cycle with copying to microSD card, starting the Keybow
hardware, and then wondering what went wrong, without any real clue.

210
mock/keybow.lua

@ -0,0 +1,210 @@
keybow = {}
local KEYCODES = "abcdefghijklmnopqrstuvwxyz1234567890\n\a\b\t -=[]\\#;'`,./"
local SHIFTED_KEYCODES = "ABCDEFGHIJKLMNOPQRSTUVWXYZ!@#$%^&*()\a\a\a\a\a_+{}|~:\"~<>?"
keybow.LEFT_CTRL = 0
keybow.LEFT_SHIFT = 1
keybow.LEFT_ALT = 2
keybow.LEFT_META = 3
keybow.RIGHT_CTRL = 4
keybow.RIGHT_SHIFT = 5
keybow.RIGHT_ALT = 6
keybow.RIGHT_META = 7
keybow.ENTER = 0x28
keybow.ESC = 0x29
keybow.BACKSPACE = 0x2a
keybow.TAB = 0x2b
keybow.SPACE = 0x2c
keybow.CAPSLOCK = 0x39
keybow.LEFT_ARROW = 0x50
keybow.RIGHT_ARROW = 0x4f
keybow.UP_ARROW = 0x52
keybow.DOWN_ARROW = 0x51
keybow.F1 = 0x3a
keybow.F2 = 0x3b
keybow.F3 = 0x3c
keybow.F4 = 0x3d
keybow.F5 = 0x3e
keybow.F6 = 0x3f
keybow.F7 = 0x40
keybow.F8 = 0x41
keybow.F9 = 0x42
keybow.F10 = 0x43
keybow.F11 = 0x44
keybow.F12 = 0x45
keybow.KEY_DOWN = true
keybow.KEY_UP = false
-- Functions exposed from C
function keybow.set_modifier(key, state)
keybow_set_modifier(key, state)
end
function keybow.sleep(time)
keybow_sleep(time)
end
function keybow.usleep(time)
keybow_usleep(time)
end
function keybow.text(text)
for i = 1, #text do
local c = text:sub(i, i)
keybow.tap_key(c)
end
keybow.set_modifier(keybow.LEFT_SHIFT, false)
end
-- Lighting control
function keybow.set_pixel(x, r, g, b)
keybow_set_pixel(x, r, g, b)
end
function keybow.auto_lights(state)
keybow_auto_lights(state)
end
function keybow.clear_lights()
keybow_clear_lights()
end
function keybow.load_pattern(file)
keybow_load_pattern(file)
end
-- Meta keys - ctrl, shift, alt and win/apple
function keybow.tap_left_ctrl()
keybow.set_modifier(keybow.LEFT_CTRL, keybow.KEY_DOWN)
keybow.set_modifier(keybow.LEFT_CTRL, keybow.KEY_UP)
end
function keybow.tap_right_ctrl()
keybow.set_modifier(keybow.RIGHT_CTRL, keybow.KEY_DOWN)
keybow.set_modifier(keybow.RIGHT_CTRL, keybow.KEY_UP)
end
function keybow.tap_left_shift()
keybow.set_modifier(keybow.LEFT_SHIFT, keybow.KEY_DOWN)
keybow.set_modifier(keybow.LEFT_SHIFT, keybow.KEY_UP)
end
function keybow.tap_right_shift()
keybow.set_modifier(keybow.RIGHT_SHIFT, keybow.KEY_DOWN)
keybow.set_modifier(keybow.RIGHT_SHIFT, keybow.KEY_UP)
end
function keybow.tap_left_alt()
keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_DOWN)
keybow.set_modifier(keybow.LEFT_ALT, keybow.KEY_UP)
end
function keybow.tap_right_alt()
keybow.set_modifier(keybow.RIGHT_ALT, keybow.KEY_DOWN)
keybow.set_modifier(keybow.RIGHT_ALT, keybow.KEY_UP)
end
function keybow.tap_left_meta()
keybow.set_modifier(keybow.LEFT_META, keybow.KEY_DOWN)
keybow.set_modifier(keybow.LEFT_META, keybow.KEY_UP)
end
function keybow.tap_right_meta()
keybow.set_modifier(keybow.RIGHT_META, keybow.KEY_DOWN)
keybow.set_modifier(keybow.RIGHT_META, keybow.KEY_UP)
end
-- Function keys
function keybow.tap_function_key(index)
index = 57 + index -- Offset to 0x39 (F1 is 0x3a)
keybow.set_key(index, true)
keybow.set_key(index, false)
end
function keybow.ascii_to_shift(key)
if not (type(key) == "string") then
return false
end
return SHIFTED_KEYCODES.find(key) ~= nil
end
function keybow.ascii_to_hid(key)
if not (type(key) == "string") then
return key
end
key = key:lower()
code = KEYCODES:find(key)
if code == nil then return nil end
return code + 3
end
function keybow.set_key(key, pressed)
if type(key) == "string" then
local hid_code = nil
local shifted = SHIFTED_KEYCODES:find(key, 1, true) ~= nil
if shifted then
hid_code = SHIFTED_KEYCODES:find(key, 1, true)
else
hid_code = KEYCODES:find(key, 1, true)
end
if not (hid_code == nil) then
hid_code = hid_code + 3
if shifted then keybow.set_modifier(keybow.LEFT_SHIFT, pressed) end
keybow_set_key(hid_code, pressed)
end
else -- already a key code
keybow_set_key(key, pressed)
end
end
function keybow.tap_enter()
keybow.set_key(keybow.ENTER, true)
keybow.set_key(keybow.ENTER, false)
end
function keybow.tap_space()
keybow.set_key(keybow.SPACE, true)
keybow.set_key(keybow.SPACE, false)
end
function keybow.tap_shift()
keybow.set_key(keybow.LEFT_SHIFT, true)
keybow.set_key(keybow.LEFT_SHIFT, false)
end
function keybow.tap_tab()
keybow.set_key(keybow.TAB, true)
keybow.set_key(keybow.TAB, false)
end
function keybow.tap_key(key)
keybow.set_key(key, true)
keybow.set_key(key, false)
end
function keybow.press_key(key)
keybow.set_key(key, true)
end
function keybow.release_key(key)
keybow.set_key(key, false)
end

24
mock/mockkeybow.lua

@ -0,0 +1,24 @@
require "keybow"
function keybow.set_pixel(pix, r, g, b)
-- print("set_pixel", pix, r, g, b)
end
function keybow.auto_lights(onoff)
-- print("auto_lights", onoff)
end
function keybow.clear_lights()
-- print("clear_lights")
end
function keybow.tap_key(key)
print("tap_key", key)
end
function keybow.set_modifier(mod, key)
print("set_modifier", mod, key)
end
require "keys"
setup()

BIN
multibow.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

4
sdcard/keys.lua

@ -0,0 +1,4 @@
require "keybow"
require "layouts/shift"
require "layouts/vsc-golang"
require "layouts/empty"

22
sdcard/layouts/empty.lua

@ -0,0 +1,22 @@
-- An empty Multibow Keybow layout. Useful for "switching off" the keyboard,
require "snippets/multibow"
--[[
The Keybow layout is as follows when in landscape orientation, with the USB
cable going off "northwards":
11 8 5 2
10 7 4 1
9 6 3 0
]]--
mb.register_keymap({}, "empty")

38
sdcard/layouts/shift.lua

@ -0,0 +1,38 @@
-- A permanent SHIFT layout toggler
require "snippets/multibow"
--[[
The Keybow layout is as follows when in landscape orientation, with the USB
cable going off "northwards":
11 8 5 2
10 7 4 1
9 6 3 0
]]--
shift = {}
function shift.cycle(key)
print("permanent SHIFT")
mb.cycle_keymaps()
end
function shift.brightness(key)
local b = mb.brightness + 0.3
if b > 1 then; b = 0.4; end
mb.set_brightness(b)
end
mb.register_permanent_keymap({
[11] = {c={r=1, g=1, b=1}, h=shift.cycle},
[8] = {c={r=0.5, g=0.5, b=0.5}, h=shift.brightness}
}, "shift")

74
sdcard/layouts/vsc-golang.lua

@ -0,0 +1,74 @@
-- VSC Go extension debug Keybow layout
require "snippets/multibow"
--[[
The Keybow layout is as follows when in landscape orientation, with the USB
cable going off "northwards":
11 8 5 2
10 7 4 1
9 6 3 0
]]--
RED = { r=1, g=0, b=0 }
YELLOW = { r=1, g=0.8, b=0 }
GREEN = { r=0, g=1, b=0 }
BLUE = { r=0, g=0, b=1 }
BLUECYAN = { r=0, g=0.7, b=1 }
BLUEGRAY = { r=0.7, g=0.7, b=1 }
CYAN = { r=0, g=1, b=1 }
-- AND NOW FOR SOMETHING DIFFERENT: THE REAL MEAT --
function debug_stop(key)
mb.tap(key, keybow.F5, keybow.LEFT_SHIFT)
end
function debug_restart(key)
mb.tap(key, keybow.F5, keybow.LEFT_SHIFT, keybow.LEFT_CTRL)
end
function debug_continue(key)
mb.tap(key, keybow.F5)
end
function debug_stepover(key)
mb.tap(key, keybow.F10)
end
function debug_stepinto(key)
mb.tap(key, keybow.F11)
end
function debug_stepout(key)
mb.tap(key, keybow.F11, keybow.LEFT_SHIFT)
end
function go_test_package(key)
mb.tap(key, "P", keybow.LEFT_SHIFT, keybow.LEFT_CTRL)
keybow.sleep(250)
keybow.text("go test package")
keybow.tap_enter()
end
mb.register_keymap({
[10] = {c=RED, h=debug_stop},
[7] = {c=YELLOW, h=debug_restart},
[1] = {c=CYAN, h=go_test_package},
[9] = {c=GREEN, h=debug_continue},
[6] = {c=BLUECYAN, h=debug_stepinto},
[3] = {c=BLUE, h=debug_stepover},
[0] = {c=BLUEGRAY, h=debug_stepout},
}, 'vsc-golang-debug')

108
sdcard/snippets/morekeys.lua

@ -0,0 +1,108 @@
--[[
Provide additional keybow USB HID key definitions.
For more information about USB HID keyboard scan codes, for instance,
see: https://gist.github.com/MightyPork/6da26e382a7ad91b5496ee55fdc73db2
Copyright 2019 Harald Albrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--
require("keybow")
keybow.SYSRQ = 0x46
keybow.SCROLLLOCK = 0x47
keybow.PAUSE = 0x48
keybow.INSERT = 0x49
keybow.DELETE = 0x4c
keybow.HOME = 0x4a
keybow.END = 0x4d
keybow.PAGEUP = 0x4b
keybow.PAGEOWN = 0x4e
keybow.F13 = 0x68
keybow.F14 = 0x69
keybow.F15 = 0x6a
keybow.F16 = 0x6b
keybow.F17 = 0x6c
keybow.F18 = 0x6d
keybow.F19 = 0x6e
keybow.F20 = 0x6f
keybow.F21 = 0x70
keybow.F22 = 0x71
keybow.F23 = 0x72
keybow.F24 = 0x73
keybow.KPSLASH = 0x54
keybow.KPASTERISK = 0x55
keybow.KPMINUS = 0x56
keybow.KPPLUS = 0x57
keybow.KPENTER = 0x58
keybow.KP1 = 0x59
keybow.KP2 = 0x5a
keybow.KP3 = 0x5b
keybow.KP4 = 0x5c
keybow.KP5 = 0x5d
keybow.KP6 = 0x5e
keybow.KP7 = 0x5f
keybow.KP8 = 0x60
keybow.KP9 = 0x61
keybow.KP0 = 0x62
keybow.KPDOT = 0x63
keybow.KPEQUAL = 0x67
keybow.COMPOSE = 0x65
keybow.POWER = 0x66
keybow.OPEN = 0x74
keybow.HELP = 0x75
keybow.PROPS = 0x76
keybow.FRONT = 0x77
keybow.STOP = 0x78
keybow.AGAIN = 0x79
keybow.UNDO = 0x7a
keybow.CUT = 0x7b
keybow.COPY = 0x7c
keybow.PASTE = 0x7d
keybow.FIND = 0x7e
keybow.MUTE = 0x7f
keybow.VOLUMEUP = 0x80
keybow.VOLUMEDOWN = 0x81
keybow.MEDIA_PLAYPAUSE = 0xe8
keybow.MEDIA_STOPCD = 0xe9
keybow.MEDIA_PREVIOUSSONG = 0xea
keybow.MEDIA_NEXTSONG = 0xeb
keybow.MEDIA_EJECTCD = 0xec
keybow.MEDIA_VOLUMEUP = 0xed
keybow.MEDIA_VOLUMEDOWN = 0xee
keybow.MEDIA_MUTE = 0xef
keybow.MEDIA_WWW = 0xf0
keybow.MEDIA_BACK = 0xf1
keybow.MEDIA_FORWARD = 0xf2
keybow.MEDIA_STOP = 0xf3
keybow.MEDIA_FIND = 0xf4
keybow.MEDIA_SCROLLUP = 0xf5
keybow.MEDIA_SCROLLDOWN = 0xf6
keybow.MEDIA_EDIT = 0xf7
keybow.MEDIA_SLEEP = 0xf8
keybow.MEDIA_COFFEE = 0xf9
keybow.MEDIA_REFRESH = 0xfa
keybow.MEDIA_CALC = 0xfb

176
sdcard/snippets/multibow.lua

@ -0,0 +1,176 @@
--[[
Copyright 2019 Harald Albrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--
require "keybow"
mb = {}
mb.path = (...):match("^(.-)[^%/]+$")
require(mb.path .. "morekeys")
require(mb.path .. "routehandlers")
mb.brightness = 0.4
mb.keymaps = {}
mb.permanent_keymaps = {}
mb.current_keymap_set = nil
mb.current_keymap_idx = 0
--
function mb.tap(keyno, key, ...)
for modifier_argno = 1, select('#', ...) do
local modifier = select(modifier_argno, ...)
if modifier then; keybow.set_modifier(modifier, keybow.KEY_DOWN); end
end
keybow.tap_key(key)
for modifier_argno = 1, select('#', ...) do
local modifier = select(modifier_argno, ...)
if modifier then; keybow.set_modifier(modifier, keybow.KEY_UP); end
end
end
-- Registers a keymap by name (and optional) index. The name is simply used
-- for allowing multiple SHIFT (modifier) levels for the same keyboard layout.
-- The indices are then used to differentiate between different SHIFT/modifier
-- levels of the same keyboard layout.
--
-- Indices start at 0, this is the un-SHIFT-ed keymap for a layout.
--
-- If this is the first keymap getting registered, then it will also made
-- activated.
function mb.register_keymap(keymap, name, index)
-- register
local kms = mb.keymaps[name]
kms = kms and kms or {} -- if name isn't known yet, create new keymap array for name
local index = index and #kms or 0 -- appends keymap if index is nil
kms[index] = keymap
mb.keymaps[name] = kms
-- ensure that first registered keymap also automatically gets activated
-- (albeit the LEDs will only update later).
if mb.current_keymap_set == nil then
mb.current_keymap_set = kms
mb.current_keymap_idx = index
end
end
-- Cycles through the available (non-permanent) keymaps. When switching to
-- the next keymap, we will always activate the index 0 layout.
function mb.cycle_keymaps()
local first_kms
local first_name
local next = false
local next_kms
local next_name
for name, kms in pairs(mb.keymaps) do
if first_kms == nil then
first_kms = kms; first_name = name
end
if kms == mb.current_keymap_set then
next = true
elseif next then
next_kms = kms; next_name = name
next = false
end
end
if next_kms == nil then
next_kms = first_kms; next_name = first_name
end
mb.activate_keymap(next_name, 0)
end
-- Activates a specific keymap by name and index.
function mb.activate_keymap(name, index)
print("activate_keymap", name, index)
local kms = mb.keymaps[name]
mb.current_keymap_set = kms
mb.current_keymap_idx = index
keybow.clear_lights()
mb.activate_leds()
end
-- Registers a permanent keymap (as opposed to switchable keymaps). As their
-- name suggest, permanent keymaps are permanently active and have priority
-- over any "standard" activated keymap. As they are permanent, there is no
-- "index" sub-layout mechanism, but instead all permanent keymaps are always
-- active. If permanent keymaps define overlapping keys, then the result is
-- undefined.
function mb.register_permanent_keymap(keymap, name)
-- register
mb.permanent_keymaps[name] = keymap
mb.activate_leds()
end
-- Sets the Keybow key LEDs maximum brightness, in the range [0.1..1].
function mb.set_brightness(brightness)
if brightness < 0.1 then; brightness = 0.1; end
if brightness > 1 then; brightness = 1; end
mb.brightness = brightness
mb.activate_leds()
end
-- Sets key LED to specific color, taking brightness into consideration.
-- The color is a triple (table) with the elements r, g, and b. Each color
-- component is in the range [0..1].
function mb.led(keyno, color)
if color ~= nil then
keybow.set_pixel(keyno,
color.r * mb.brightness * 255, color.g * mb.brightness * 255, color.b * mb.brightness * 255)
else
keybow.set_pixel(keyno, 0, 0, 0)
end
end
-- Restores Keybow LEDs according to current keymap and the permanent keymaps.
function mb.activate_leds()
-- current keymap
if mb.current_keymap_set ~= nil then
for keyno, keydef in pairs(mb.current_keymap_set[mb.current_keymap_idx]) do
print("LED", keyno)
mb.led(keyno, keydef.c)
end
end
-- permanent keymap(s)
for name, pkm in pairs(mb.permanent_keymaps) do
for keyno, keydef in pairs(pkm) do
print("pLED", keyno)
mb.led(keyno, keydef.c)
end
end
end
-- Disables the automatic Keybow lightshow and sets the key LED colors.
function setup()
-- Disables the automatic keybow lightshow and switches all key LEDs off
-- because the LEDs might be in a random state after power on.
keybow.auto_lights(false)
keybow.clear_lights()
mb.activate_leds()
end

63
sdcard/snippets/routehandlers.lua

@ -0,0 +1,63 @@
--[[
Copyright 2019 Harald Albrecht
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
]]--
-- This all-key, central key router forwards Keybow key events to
-- their correct handlers, depending on which keyboard layout currently
-- is active.
function mb.route(keyno, pressed)
-- Check key in permanent keymaps
local keydef
for name, pkm in pairs(mb.permanent_keymaps) do
keydef = pkm[keyno]
if keydef ~= nil then; break; end
end
-- Check key in current keymap
if keydef == nil and mb.current_keymap_set ~= nil then
keydef = mb.current_keymap_set[mb.current_keymap_idx][keyno]
end
if keydef == nil then; return; end
if pressed then
for led = 0, 11 do
if led ~= keyno then; mb.led(led, {r=0, g=0, b=0}); end
end
print("route to key #", keyno)
keydef.h(keyno)
else
mb.activate_leds()
end
end
-- Routes all keybow key handling through our central key router
function handle_key_00(pressed); mb.route(0, pressed); end
function handle_key_01(pressed); mb.route(1, pressed); end
function handle_key_02(pressed); mb.route(2, pressed); end
function handle_key_03(pressed); mb.route(3, pressed); end
function handle_key_04(pressed); mb.route(4, pressed); end
function handle_key_05(pressed); mb.route(5, pressed); end
function handle_key_06(pressed); mb.route(6, pressed); end
function handle_key_07(pressed); mb.route(7, pressed); end
function handle_key_08(pressed); mb.route(8, pressed); end
function handle_key_09(pressed); mb.route(9, pressed); end
function handle_key_10(pressed); mb.route(10, pressed); end
function handle_key_11(pressed); mb.route(11, pressed); end

30
test.lua

@ -0,0 +1,30 @@
package.path = "./sdcard/?.lua;./mock/?.lua;" .. package.path
require "mockkeybow"
print()
print("**** key 00...")
handle_key_00(true)
handle_key_00(false)
print()
print("**** key 03...")
handle_key_03(true)
handle_key_03(false)
print()
print("**** key 11...")
handle_key_11(true)
handle_key_11(false)
print("**** key 00...")
handle_key_00(true)
handle_key_00(false)
print()
print("**** key 11...")
handle_key_11(true)
handle_key_11(false)
print("**** key 00...")
handle_key_00(true)
handle_key_00(false)
Loading…
Cancel
Save