Leader key implementation (#326)
[jackhill/qmk/firmware.git] / quantum / quantum.c
CommitLineData
1a8c0dd2
EZ
1#include "quantum.h"
2
3__attribute__ ((weak))
4void matrix_init_kb(void) {}
5
6__attribute__ ((weak))
7void matrix_scan_kb(void) {}
8
9__attribute__ ((weak))
10bool process_action_kb(keyrecord_t *record) {
11 return true;
12}
13
14__attribute__ ((weak))
15void leader_start(void) {}
16
17__attribute__ ((weak))
18void leader_end(void) {}
19
20#ifdef AUDIO_ENABLE
21 uint8_t starting_note = 0x0C;
22 int offset = 0;
23 bool music_activated = false;
24#endif
25
26// Leader key stuff
27bool leading = false;
28uint16_t leader_time = 0;
29
30uint16_t leader_sequence[3] = {0, 0, 0};
31uint8_t leader_sequence_size = 0;
32
33// Chording stuff
34#define CHORDING_MAX 4
35bool chording = false;
36
37uint8_t chord_keys[CHORDING_MAX] = {0};
38uint8_t chord_key_count = 0;
39uint8_t chord_key_down = 0;
40
41bool keys_chord(uint8_t keys[]) {
42 uint8_t keys_size = sizeof(keys)/sizeof(keys[0]);
43 bool pass = true;
44 uint8_t in = 0;
45 for (uint8_t i = 0; i < chord_key_count; i++) {
46 bool found = false;
47 for (uint8_t j = 0; j < keys_size; j++) {
48 if (chord_keys[i] == (keys[j] & 0xFF)) {
49 in++; // detects key in chord
50 found = true;
51 break;
52 }
53 }
54 if (found)
55 continue;
56 if (chord_keys[i] != 0) {
57 pass = false; // makes sure rest are blank
58 }
59 }
60 return (pass && (in == keys_size));
61}
62
63bool process_action_quantum(keyrecord_t *record) {
64
65 /* This gets the keycode from the key pressed */
66 keypos_t key = record->event.key;
67 uint16_t keycode;
68
69 #if !defined(NO_ACTION_LAYER) && defined(PREVENT_STUCK_MODIFIERS)
70 uint8_t layer;
71
72 if (record->event.pressed) {
73 layer = layer_switch_get_layer(key);
74 update_source_layers_cache(key, layer);
75 } else {
76 layer = read_source_layers_cache(key);
77 }
78 keycode = keymap_key_to_keycode(layer, key);
79 #else
80 keycode = keymap_key_to_keycode(layer_switch_get_layer(key), key);
81 #endif
82
83 #ifdef AUDIO_ENABLE
84 if (music_activated) {
85 if (record->event.pressed) {
86 play_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)), 0xF);
87 } else {
88 stop_note(((double)220.0)*pow(2.0, -4.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)));
89 }
90 if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through
91 return false;
92 }
93 #endif
94
95
96
97#ifndef DISABLE_LEADER
98 // Leader key set-up
99 if (record->event.pressed) {
100 if (!leading && keycode == KC_LEAD) {
101 leader_start();
102 leading = true;
103 leader_time = timer_read();
104 leader_sequence_size = 0;
105 leader_sequence[0] = 0;
106 leader_sequence[1] = 0;
107 leader_sequence[2] = 0;
108 return false;
109 }
110 if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) {
111 leader_sequence[leader_sequence_size] = keycode;
112 leader_sequence_size++;
113 return false;
114 }
115 }
116#endif
117
118#define DISABLE_CHORDING
119#ifndef DISABLE_CHORDING
120
121 if (keycode >= 0x5700 && keycode <= 0x57FF) {
122 if (record->event.pressed) {
123 if (!chording) {
124 chording = true;
125 for (uint8_t i = 0; i < CHORDING_MAX; i++)
126 chord_keys[i] = 0;
127 chord_key_count = 0;
128 chord_key_down = 0;
129 }
130 chord_keys[chord_key_count] = (keycode & 0xFF);
131 chord_key_count++;
132 chord_key_down++;
133 return false;
134 } else {
135 if (chording) {
136 chord_key_down--;
137 if (chord_key_down == 0) {
138 chording = false;
139 // Chord Dictionary
140 if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) {
141 register_code(KC_A);
142 unregister_code(KC_A);
143 return false;
144 }
145 for (uint8_t i = 0; i < chord_key_count; i++) {
146 register_code(chord_keys[i]);
147 unregister_code(chord_keys[i]);
148 return false;
149 }
150 }
151 }
152 }
153 }
154
155#endif
156
157
158 return process_action_kb(record);
159}
160
161void matrix_init_quantum() {
162 matrix_init_kb();
163}
164
165void matrix_scan_quantum() {
166 matrix_scan_kb();
167}