]> git.donarmstrong.com Git - qmk_firmware.git/commitdiff
Implemented basic key combination feature
authorOfer Plesser <plesserofer@gmail.com>
Fri, 9 Dec 2016 22:49:11 +0000 (00:49 +0200)
committerOfer Plesser <plesserofer@gmail.com>
Fri, 9 Dec 2016 22:49:11 +0000 (00:49 +0200)
build_keyboard.mk
quantum/process_keycode/process_combo.c [new file with mode: 0644]
quantum/process_keycode/process_combo.h [new file with mode: 0644]
quantum/quantum.c
quantum/quantum.h

index ce505de126743772a4b289f4f3359bbaf9a61125..14f4f36bc9790473fc1cc945a98c5f1b2928a60a 100644 (file)
@@ -144,6 +144,11 @@ ifeq ($(strip $(MIDI_ENABLE)), yes)
        SRC += $(QUANTUM_DIR)/process_keycode/process_midi.c
 endif
 
+ifeq ($(strip $(COMBO_ENABLE)), yes)
+    OPT_DEFS += -DCOMBO_ENABLE
+       SRC += $(QUANTUM_DIR)/process_keycode/process_combo.c
+endif
+
 ifeq ($(strip $(VIRTSER_ENABLE)), yes)
     OPT_DEFS += -DVIRTSER_ENABLE
 endif
diff --git a/quantum/process_keycode/process_combo.c b/quantum/process_keycode/process_combo.c
new file mode 100644 (file)
index 0000000..a6cfed1
--- /dev/null
@@ -0,0 +1,66 @@
+#include "process_combo.h"
+#include "print.h"
+
+// __attribute__ ((weak))
+// combo_t key_combos[] = {
+
+// };
+
+#define SEND_KEY(key) \
+do { \
+    register_code16(key); \
+    send_keyboard_report(); \
+    unregister_code16(key); \
+} while(0)
+
+
+#define ALL_COMBO_KEYS_ARE_DOWN (((1<<count)-1) == combo->state)
+static bool process_single_combo(combo_t *combo, uint16_t keycode, keyrecord_t *record) 
+{
+    uint8_t count = 0;
+    bool is_combo_key = false;
+    // bool combo_key_released = false;
+
+    // Count the number of combo keys
+    for (const uint16_t *key = combo->keys; COMBO_END != pgm_read_word(key); ++key, ++count);
+
+    for (uint8_t i = 0; i < count; ++i) {
+        uint16_t key = pgm_read_word(&combo->keys[i]);
+
+        if (key == keycode) {
+            is_combo_key = true;
+
+            if (record->event.pressed) {
+                combo->state |= (1<<i);
+            } else { // Combo key released
+                if (!combo->state) {
+                    // The combo was sent, no need to send released key
+                    return true;
+                }
+
+                combo->state &= ~(1<<i);
+                SEND_KEY(key);
+            }
+        }
+    }
+
+    if (ALL_COMBO_KEYS_ARE_DOWN) {
+        SEND_KEY(combo->action);
+        combo->state = 0;    
+    }
+
+    return is_combo_key;
+}
+
+
+bool process_combo(uint16_t keycode, keyrecord_t *record)
+{
+    bool is_combo_key = false;
+
+    for (int i = 0; i < NUM_ELEMS(key_combos); ++i) {
+        combo_t *combo = &key_combos[i];
+        is_combo_key |= process_single_combo(combo, keycode, record);
+    }    
+
+    return !is_combo_key;
+}
\ No newline at end of file
diff --git a/quantum/process_keycode/process_combo.h b/quantum/process_keycode/process_combo.h
new file mode 100644 (file)
index 0000000..68786c0
--- /dev/null
@@ -0,0 +1,25 @@
+#ifndef PROCESS_COMBO_H
+#define PROCESS_COMBO_H
+
+#include <stdint.h>
+#include "progmem.h"
+#include "quantum.h"
+
+
+typedef struct
+{
+    const uint16_t *keys;
+    uint16_t action;        
+    uint32_t state;
+} combo_t;
+
+
+#define COMBO_END 0
+#define NUM_ELEMS(a) (sizeof(a)/sizeof 0[a])
+
+
+extern combo_t key_combos[1];
+
+bool process_combo(uint16_t keycode, keyrecord_t *record);
+
+#endif
\ No newline at end of file
index f653564a67dea8396b04db82500c4b9dc531a480..eabeacff87c58174fb055fd4bf8339ed8ca227fb 100644 (file)
@@ -113,6 +113,9 @@ bool process_record_quantum(keyrecord_t *record) {
 
   if (!(
     process_record_kb(keycode, record) &&
+  #ifdef COMBO_ENABLE
+    process_combo(keycode, record) &&
+  #endif
   #ifdef MIDI_ENABLE
     process_midi(keycode, record) &&
   #endif
index e6adf974aba58aa006a876c58d00f2d19d6099c7..8614c053abc51b11239844b52e70a2a79c9376cd 100644 (file)
@@ -63,6 +63,10 @@ extern uint32_t default_layer_state;
        #include "process_printer.h"
 #endif
 
+#ifdef COMBO_ENABLE
+       #include "process_combo.h"
+#endif
+
 #define SEND_STRING(str) send_string(PSTR(str))
 void send_string(const char *str);