Merge branch 'master' of ssh://github.com/keyboardio/KeyboardioFirmware

pull/117/head
Jesse Vincent 8 years ago
commit 66e8d74a32

@ -17,9 +17,6 @@
#include "Kaleidoscope-LEDEffect-Rainbow.h" #include "Kaleidoscope-LEDEffect-Rainbow.h"
#include "Kaleidoscope-Model01-TestMode.h" #include "Kaleidoscope-Model01-TestMode.h"
uint8_t primary_keymap = 0;
uint8_t temporary_keymap = 0;
#define NUMPAD_KEYMAP 2 #define NUMPAD_KEYMAP 2
#define COLEMAK KEYMAP ( \ #define COLEMAK KEYMAP ( \
@ -128,7 +125,7 @@ const macro_t *macroAction(uint8_t macroIndex, uint8_t keyState) {
} }
void setup() { void setup() {
Kaleidoscope.setup(KEYMAP_SIZE); Kaleidoscope.setup();
Kaleidoscope.use(&TestMode, Kaleidoscope.use(&TestMode,
&LEDControl, &LEDOff, &LEDControl, &LEDOff,

@ -1,32 +1,29 @@
#include "Kaleidoscope.h" #include "Kaleidoscope.h"
#include <stdarg.h> #include <stdarg.h>
Kaleidoscope_::eventHandlerHook Kaleidoscope_::eventHandlers[HOOK_MAX];
Kaleidoscope_::loopHook Kaleidoscope_::loopHooks[HOOK_MAX];
Kaleidoscope_::Kaleidoscope_(void) { Kaleidoscope_::Kaleidoscope_(void) {
memset(eventHandlers, 0, HOOK_MAX * sizeof(custom_handler_t));
memset(loopHooks, 0, HOOK_MAX * sizeof(custom_handler_t));
} }
void void
Kaleidoscope_::setup(const byte keymap_count) { Kaleidoscope_::setup(void) {
wdt_disable(); wdt_disable();
delay(100); delay(100);
Keyboard.begin(); Keyboard.begin();
KeyboardHardware.setup(); KeyboardHardware.setup();
event_handler_hook_use (NULL); // A workaround, so that the compiler does not optimize this out...
loop_hook_use (NULL); handle_key_event (Key_NoKey, 255, 255, 0);
Layer.defaultLayer (KeyboardHardware.load_primary_layer (keymap_count));
} }
custom_loop_t loopHooks[HOOK_MAX];
void void
Kaleidoscope_::loop(void) { Kaleidoscope_::loop(void) {
KeyboardHardware.scan_matrix(); KeyboardHardware.scan_matrix();
for (byte i = 0; loopHooks[i] != NULL && i < HOOK_MAX; i++) { for (byte i = 0; loopHooks[i] != NULL && i < HOOK_MAX; i++) {
custom_loop_t hook = loopHooks[i]; loopHook hook = loopHooks[i];
(*hook)(false); (*hook)(false);
} }
@ -34,7 +31,7 @@ Kaleidoscope_::loop(void) {
Keyboard.releaseAll(); Keyboard.releaseAll();
for (byte i = 0; loopHooks[i] != NULL && i < HOOK_MAX; i++) { for (byte i = 0; loopHooks[i] != NULL && i < HOOK_MAX; i++) {
custom_loop_t hook = loopHooks[i]; loopHook hook = loopHooks[i];
(*hook)(true); (*hook)(true);
} }
} }
@ -52,4 +49,52 @@ Kaleidoscope_::use(KaleidoscopePlugin *plugin, ...) {
va_end(ap); va_end(ap);
} }
void
Kaleidoscope_::replaceEventHandlerHook(eventHandlerHook oldHook, eventHandlerHook newHook) {
for (byte i = 0; i < HOOK_MAX; i++) {
if (eventHandlers[i] == oldHook) {
eventHandlers[i] = newHook;
return;
}
}
}
void
Kaleidoscope_::appendEventHandlerHook (eventHandlerHook hook) {
replaceEventHandlerHook((eventHandlerHook)NULL, hook);
}
void
Kaleidoscope_::useEventHandlerHook (eventHandlerHook hook) {
for (byte i = 0; i < HOOK_MAX; i++) {
if (eventHandlers[i] == hook)
return;
}
appendEventHandlerHook(hook);
}
void
Kaleidoscope_::replaceLoopHook(loopHook oldHook, loopHook newHook) {
for (byte i = 0; i < HOOK_MAX; i++) {
if (loopHooks[i] == oldHook) {
loopHooks[i] = newHook;
return;
}
}
}
void
Kaleidoscope_::appendLoopHook(loopHook hook) {
replaceLoopHook((loopHook)NULL, hook);
}
void
Kaleidoscope_::useLoopHook(loopHook hook) {
for (byte i = 0; i < HOOK_MAX; i++) {
if (loopHooks[i] == hook)
return;
}
appendLoopHook (hook);
}
Kaleidoscope_ Kaleidoscope; Kaleidoscope_ Kaleidoscope;

@ -22,9 +22,10 @@ void setup();
#include KALEIDOSCOPE_HARDWARE_H #include KALEIDOSCOPE_HARDWARE_H
#include "key_events.h" #include "key_events.h"
#include "plugin.h"
#include "layers.h" #include "layers.h"
#define HOOK_MAX 64
extern HARDWARE_IMPLEMENTATION KeyboardHardware; extern HARDWARE_IMPLEMENTATION KeyboardHardware;
#ifndef VERSION #ifndef VERSION
@ -33,13 +34,76 @@ extern HARDWARE_IMPLEMENTATION KeyboardHardware;
#define KEYMAP_SIZE (sizeof(keymaps) / ROWS / COLS / sizeof(Key)) #define KEYMAP_SIZE (sizeof(keymaps) / ROWS / COLS / sizeof(Key))
/*
* The `USE_PLUGINS()` macro is a clever hack, to make it seem like
* `Kaleidoscope.use()` is type-safe. It pushes its arguments into an
* appropriately typed array, so anything that does not fit the criteria, will
* trigger a compiler error.
*
* It then never uses the array, and passes the plugins over to
* `Kaleidoscope.use`, adding the trailing `NULL`, making it even easier to use.
*
* Since the array this macro creates is never used, the compiler will optimize
* it out fully. As such, by using this macro, we incur neither any size
* penalties, nor any run-time penalties. Everything happens at compile-time.
*/
#define USE_PLUGINS(plugins...) ({ \
static KaleidoscopePlugin *__p[] = {plugins, NULL}; \
Kaleidoscope.use(plugins, NULL); \
})
class KaleidoscopePlugin {
public:
virtual void begin(void) = 0;
};
class Kaleidoscope_ { class Kaleidoscope_ {
public: public:
Kaleidoscope_(void); Kaleidoscope_(void);
void setup(const byte keymap_count); void setup(const byte keymap_count) { setup(); };
void setup(void);
void loop(void); void loop(void);
void use(KaleidoscopePlugin *plugin, ...) __attribute__((sentinel)); void use(KaleidoscopePlugin *plugin, ...) __attribute__((sentinel));
// ---- hooks ----
/*
* In most cases, one only wants a single copy of a hook. On the other hand,
* plugins that depend on other plugins, may want to make it easier for the
* end-user to use the plugin, and call the setup function of the dependent
* plugins too. In case the end-user calls the same setup function, we'd end up
* with hooks registered multiple times.
*
* To avoid this, protection against double-registration has been introduced.
* The `event_handler_hook_use` and `loop_hook_use` functions will only allow
* one copy of the hook. The `event_handler_hook_append` and `loop_hook_append`
* functions will, on the other hand, just append the hooks, and not care about
* protection.
*/
typedef Key (*eventHandlerHook)(Key mappedKey, byte row, byte col, uint8_t keyState);
static eventHandlerHook eventHandlers[HOOK_MAX];
static void replaceEventHandlerHook(eventHandlerHook oldHook, eventHandlerHook newHook);
static void appendEventHandlerHook(eventHandlerHook hook);
static void useEventHandlerHook(eventHandlerHook hook);
typedef void (*loopHook)(bool postClear);
static loopHook loopHooks[HOOK_MAX];
static void replaceLoopHook(loopHook oldHook, loopHook newHook);
static void appendLoopHook(loopHook hook);
static void useLoopHook(loopHook hook);
}; };
extern Kaleidoscope_ Kaleidoscope; extern Kaleidoscope_ Kaleidoscope;
/* -- DEPRECATED aliases; remove them when there are no more users. -- */
#define event_handler_hook_use(hook) Kaleidoscope.useEventHandlerHook(hook);
#define event_handler_hook_append(hook) Kaleidoscope.appendEventHandlerHook(hook)
#define event_handler_hook_replace(oldHook, newHook) Kaleidoscope.replaceEventHandlerHook(oldHook, newHook)
#define loop_hook_use(hook) Kaleidoscope.useLoopHook(hook)
#define loop_hook_append(hook) Kaleidoscope.appendLoopHook(hook)
#define loop_hook_replace(oldHook, newHook) Kaleidoscope.replaceLoopHook(oldHook, newHook)

@ -1,49 +0,0 @@
#include "hooks.h"
void
event_handler_hook_replace (custom_handler_t oldHook, custom_handler_t newHook) {
for (byte i = 0; i < HOOK_MAX; i++) {
if (eventHandlers[i] == oldHook) {
eventHandlers[i] = newHook;
return;
}
}
}
void
event_handler_hook_append (custom_handler_t hook) {
event_handler_hook_replace ((custom_handler_t)NULL, hook);
}
void
event_handler_hook_use (custom_handler_t hook) {
for (byte i = 0; i < HOOK_MAX; i++) {
if (eventHandlers[i] == hook)
return;
}
event_handler_hook_append (hook);
}
void
loop_hook_replace (custom_loop_t oldHook, custom_loop_t newHook) {
for (byte i = 0; i < HOOK_MAX; i++) {
if (loopHooks[i] == oldHook) {
loopHooks[i] = newHook;
return;
}
}
}
void
loop_hook_append (custom_loop_t hook) {
loop_hook_replace ((custom_loop_t)NULL, hook);
}
void
loop_hook_use (custom_loop_t hook) {
for (byte i = 0; i < HOOK_MAX; i++) {
if (loopHooks[i] == hook)
return;
}
loop_hook_append (hook);
}

@ -1,34 +0,0 @@
#pragma once
#include <Arduino.h>
#include "key_defs.h"
#define HOOK_MAX 64
typedef Key (*custom_handler_t)(Key mappedKey, byte row, byte col, uint8_t keyState);
extern custom_handler_t eventHandlers[HOOK_MAX];
/*
* In most cases, one only wants a single copy of a hook. On the other hand,
* plugins that depend on other plugins, may want to make it easier for the
* end-user to use the plugin, and call the setup function of the dependent
* plugins too. In case the end-user calls the same setup function, we'd end up
* with hooks registered multiple times.
*
* To avoid this, protection against double-registration has been introduced.
* The `event_handler_hook_use` and `loop_hook_use` functions will only allow
* one copy of the hook. The `event_handler_hook_append` and `loop_hook_append`
* functions will, on the other hand, just append the hooks, and not care about
* protection.
*/
void event_handler_hook_use (custom_handler_t hook);
void event_handler_hook_append (custom_handler_t hook);
void event_handler_hook_replace (custom_handler_t oldHook, custom_handler_t newHook);
typedef void (*custom_loop_t)(bool postClear);
extern custom_loop_t loopHooks[HOOK_MAX];
void loop_hook_use (custom_loop_t hook);
void loop_hook_append (custom_loop_t hook);
void loop_hook_replace (custom_loop_t oldHook, custom_loop_t newHook);

@ -1,5 +1,4 @@
#include "key_events.h" #include "Kaleidoscope.h"
#include "layers.h"
static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) { static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) {
if (mappedKey.flags & RESERVED) if (mappedKey.flags & RESERVED)
@ -14,9 +13,9 @@ static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) {
if (mappedKey.flags & IS_INTERNAL) { if (mappedKey.flags & IS_INTERNAL) {
return false; return false;
} else if (mappedKey.flags & IS_CONSUMER) { } else if (mappedKey.flags & IS_CONSUMER) {
ConsumerControl.press(mappedKey.keyCode); ConsumerControl.write(mappedKey.keyCode);
} else if (mappedKey.flags & IS_SYSCTL) { } else if (mappedKey.flags & IS_SYSCTL) {
SystemControl.press(mappedKey.keyCode); SystemControl.write(mappedKey.keyCode);
} else if (mappedKey.flags & SWITCH_TO_KEYMAP) { } else if (mappedKey.flags & SWITCH_TO_KEYMAP) {
// Should not happen, handled elsewhere. // Should not happen, handled elsewhere.
} }
@ -24,8 +23,6 @@ static bool handle_synthetic_key_event(Key mappedKey, uint8_t keyState) {
return true; return true;
} }
custom_handler_t eventHandlers[HOOK_MAX];
static bool handle_key_event_default(Key mappedKey, byte row, byte col, uint8_t keyState) { static bool handle_key_event_default(Key mappedKey, byte row, byte col, uint8_t keyState) {
//for every newly pressed button, figure out what logical key it is and send a key down event //for every newly pressed button, figure out what logical key it is and send a key down event
// for every newly released button, figure out what logical key it is and send a key up event // for every newly released button, figure out what logical key it is and send a key up event
@ -83,8 +80,8 @@ void handle_key_event(Key mappedKey, byte row, byte col, uint8_t keyState) {
if (!(keyState & INJECTED)) { if (!(keyState & INJECTED)) {
mappedKey = Layer.lookup(row, col); mappedKey = Layer.lookup(row, col);
} }
for (byte i = 0; eventHandlers[i] != NULL && i < HOOK_MAX; i++) { for (byte i = 0; Kaleidoscope.eventHandlers[i] != NULL && i < HOOK_MAX; i++) {
custom_handler_t handler = eventHandlers[i]; Kaleidoscope_::eventHandlerHook handler = Kaleidoscope.eventHandlers[i];
mappedKey = (*handler)(mappedKey, row, col, keyState); mappedKey = (*handler)(mappedKey, row, col, keyState);
if (mappedKey.raw == Key_NoKey.raw) if (mappedKey.raw == Key_NoKey.raw)
return; return;

@ -5,7 +5,6 @@
#include KALEIDOSCOPE_HARDWARE_H #include KALEIDOSCOPE_HARDWARE_H
#include "key_defs.h" #include "key_defs.h"
#include "keyswitch_state.h" #include "keyswitch_state.h"
#include "hooks.h"
extern const Key keymaps[][ROWS][COLS]; extern const Key keymaps[][ROWS][COLS];

@ -1,11 +1,11 @@
#include "layers.h" #include "Kaleidoscope.h"
#include "key_events.h"
static uint8_t DefaultLayer; static uint8_t DefaultLayer;
static uint32_t LayerState; static uint32_t LayerState;
uint8_t Layer_::highestLayer; uint8_t Layer_::highestLayer;
uint8_t Layer_::keyMap[ROWS][COLS]; uint8_t Layer_::keyMap[ROWS][COLS];
Key (*Layer_::getKey)(uint8_t layer, byte row, byte col) = Layer.getKeyFromPROGMEM;
static void handle_keymap_key_event(Key keymapEntry, uint8_t keyState) { static void handle_keymap_key_event(Key keymapEntry, uint8_t keyState) {
if (keymapEntry.keyCode >= MOMENTARY_OFFSET) { if (keymapEntry.keyCode >= MOMENTARY_OFFSET) {
@ -52,6 +52,15 @@ Layer_::Layer_ (void) {
defaultLayer (0); defaultLayer (0);
} }
Key
Layer_::getKeyFromPROGMEM (uint8_t layer, byte row, byte col) {
Key key;
key.raw = pgm_read_word(&(keymaps[layer][row][col]));
return key;
}
void void
Layer_::mergeLayers(void) { Layer_::mergeLayers(void) {
@ -66,9 +75,7 @@ Layer_::mergeLayers(void) {
while (layer > DefaultLayer) { while (layer > DefaultLayer) {
if (Layer.isOn (layer)) { if (Layer.isOn (layer)) {
Key mappedKey; Key mappedKey = (*getKey)(layer, r, c);
mappedKey.raw = pgm_read_word(&(keymaps[layer][r][c]));
if (mappedKey != Key_Transparent) { if (mappedKey != Key_Transparent) {
keyMap[r][c] = layer; keyMap[r][c] = layer;
@ -83,10 +90,8 @@ Layer_::mergeLayers(void) {
Key Layer_::lookup(byte row, byte col) { Key Layer_::lookup(byte row, byte col) {
uint8_t layer = keyMap[row][col]; uint8_t layer = keyMap[row][col];
Key mappedKey;
mappedKey.raw = pgm_read_word(&(keymaps[layer][row][col]));
return mappedKey; return (*getKey)(layer, row, col);
} }
uint8_t Layer_::top (void) { uint8_t Layer_::top (void) {

@ -2,7 +2,6 @@
#include <Arduino.h> #include <Arduino.h>
#include "key_defs.h" #include "key_defs.h"
#include "plugin.h"
#include KALEIDOSCOPE_HARDWARE_H #include KALEIDOSCOPE_HARDWARE_H
class Layer_ { class Layer_ {
@ -27,6 +26,10 @@ class Layer_ {
static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState); static Key eventHandler(Key mappedKey, byte row, byte col, uint8_t keyState);
static Key (*getKey)(uint8_t layer, byte row, byte col);
static Key getKeyFromPROGMEM(uint8_t layer, byte row, byte col);
private: private:
static uint8_t highestLayer; static uint8_t highestLayer;
static uint8_t keyMap[ROWS][COLS]; static uint8_t keyMap[ROWS][COLS];
@ -34,4 +37,6 @@ class Layer_ {
static void mergeLayers(void); static void mergeLayers(void);
}; };
Key layer_getKey (uint8_t layer, uint8_t r, uint8_t c);
extern Layer_ Layer; extern Layer_ Layer;

@ -1,7 +0,0 @@
#pragma once
class KaleidoscopePlugin {
public:
virtual void begin(void) = 0;
};
Loading…
Cancel
Save