diff options
Diffstat (limited to 'quantum/process_keycode')
| -rw-r--r-- | quantum/process_keycode/process_chording.c | 60 | ||||
| -rw-r--r-- | quantum/process_keycode/process_chording.h | 16 | ||||
| -rw-r--r-- | quantum/process_keycode/process_leader.c | 38 | ||||
| -rw-r--r-- | quantum/process_keycode/process_leader.h | 23 | ||||
| -rw-r--r-- | quantum/process_keycode/process_midi.c | 68 | ||||
| -rw-r--r-- | quantum/process_keycode/process_midi.h | 207 | ||||
| -rw-r--r-- | quantum/process_keycode/process_music.c | 176 | ||||
| -rw-r--r-- | quantum/process_keycode/process_music.h | 27 | ||||
| -rw-r--r-- | quantum/process_keycode/process_tap_dance.c | 136 | ||||
| -rw-r--r-- | quantum/process_keycode/process_tap_dance.h | 72 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode.c | 239 | ||||
| -rw-r--r-- | quantum/process_keycode/process_unicode.h | 165 |
12 files changed, 1227 insertions, 0 deletions
diff --git a/quantum/process_keycode/process_chording.c b/quantum/process_keycode/process_chording.c new file mode 100644 index 000000000..d7814629f --- /dev/null +++ b/quantum/process_keycode/process_chording.c | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | #include "process_chording.h" | ||
| 2 | |||
| 3 | bool keys_chord(uint8_t keys[]) { | ||
| 4 | uint8_t keys_size = sizeof(keys)/sizeof(keys[0]); | ||
| 5 | bool pass = true; | ||
| 6 | uint8_t in = 0; | ||
| 7 | for (uint8_t i = 0; i < chord_key_count; i++) { | ||
| 8 | bool found = false; | ||
| 9 | for (uint8_t j = 0; j < keys_size; j++) { | ||
| 10 | if (chord_keys[i] == (keys[j] & 0xFF)) { | ||
| 11 | in++; // detects key in chord | ||
| 12 | found = true; | ||
| 13 | break; | ||
| 14 | } | ||
| 15 | } | ||
| 16 | if (found) | ||
| 17 | continue; | ||
| 18 | if (chord_keys[i] != 0) { | ||
| 19 | pass = false; // makes sure rest are blank | ||
| 20 | } | ||
| 21 | } | ||
| 22 | return (pass && (in == keys_size)); | ||
| 23 | } | ||
| 24 | |||
| 25 | bool process_chording(uint16_t keycode, keyrecord_t *record) { | ||
| 26 | if (keycode >= QK_CHORDING && keycode <= QK_CHORDING_MAX) { | ||
| 27 | if (record->event.pressed) { | ||
| 28 | if (!chording) { | ||
| 29 | chording = true; | ||
| 30 | for (uint8_t i = 0; i < CHORDING_MAX; i++) | ||
| 31 | chord_keys[i] = 0; | ||
| 32 | chord_key_count = 0; | ||
| 33 | chord_key_down = 0; | ||
| 34 | } | ||
| 35 | chord_keys[chord_key_count] = (keycode & 0xFF); | ||
| 36 | chord_key_count++; | ||
| 37 | chord_key_down++; | ||
| 38 | return false; | ||
| 39 | } else { | ||
| 40 | if (chording) { | ||
| 41 | chord_key_down--; | ||
| 42 | if (chord_key_down == 0) { | ||
| 43 | chording = false; | ||
| 44 | // Chord Dictionary | ||
| 45 | if (keys_chord((uint8_t[]){KC_ENTER, KC_SPACE})) { | ||
| 46 | register_code(KC_A); | ||
| 47 | unregister_code(KC_A); | ||
| 48 | return false; | ||
| 49 | } | ||
| 50 | for (uint8_t i = 0; i < chord_key_count; i++) { | ||
| 51 | register_code(chord_keys[i]); | ||
| 52 | unregister_code(chord_keys[i]); | ||
| 53 | return false; | ||
| 54 | } | ||
| 55 | } | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | return true; | ||
| 60 | } \ No newline at end of file | ||
diff --git a/quantum/process_keycode/process_chording.h b/quantum/process_keycode/process_chording.h new file mode 100644 index 000000000..49c97db3b --- /dev/null +++ b/quantum/process_keycode/process_chording.h | |||
| @@ -0,0 +1,16 @@ | |||
| 1 | #ifndef PROCESS_CHORDING_H | ||
| 2 | #define PROCESS_CHORDING_H | ||
| 3 | |||
| 4 | #include "quantum.h" | ||
| 5 | |||
| 6 | // Chording stuff | ||
| 7 | #define CHORDING_MAX 4 | ||
| 8 | bool chording = false; | ||
| 9 | |||
| 10 | uint8_t chord_keys[CHORDING_MAX] = {0}; | ||
| 11 | uint8_t chord_key_count = 0; | ||
| 12 | uint8_t chord_key_down = 0; | ||
| 13 | |||
| 14 | bool process_chording(uint16_t keycode, keyrecord_t *record); | ||
| 15 | |||
| 16 | #endif \ No newline at end of file | ||
diff --git a/quantum/process_keycode/process_leader.c b/quantum/process_keycode/process_leader.c new file mode 100644 index 000000000..e53d221e7 --- /dev/null +++ b/quantum/process_keycode/process_leader.c | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | #include "process_leader.h" | ||
| 2 | |||
| 3 | __attribute__ ((weak)) | ||
| 4 | void leader_start(void) {} | ||
| 5 | |||
| 6 | __attribute__ ((weak)) | ||
| 7 | void leader_end(void) {} | ||
| 8 | |||
| 9 | // Leader key stuff | ||
| 10 | bool leading = false; | ||
| 11 | uint16_t leader_time = 0; | ||
| 12 | |||
| 13 | uint16_t leader_sequence[5] = {0, 0, 0, 0, 0}; | ||
| 14 | uint8_t leader_sequence_size = 0; | ||
| 15 | |||
| 16 | bool process_leader(uint16_t keycode, keyrecord_t *record) { | ||
| 17 | // Leader key set-up | ||
| 18 | if (record->event.pressed) { | ||
| 19 | if (!leading && keycode == KC_LEAD) { | ||
| 20 | leader_start(); | ||
| 21 | leading = true; | ||
| 22 | leader_time = timer_read(); | ||
| 23 | leader_sequence_size = 0; | ||
| 24 | leader_sequence[0] = 0; | ||
| 25 | leader_sequence[1] = 0; | ||
| 26 | leader_sequence[2] = 0; | ||
| 27 | leader_sequence[3] = 0; | ||
| 28 | leader_sequence[4] = 0; | ||
| 29 | return false; | ||
| 30 | } | ||
| 31 | if (leading && timer_elapsed(leader_time) < LEADER_TIMEOUT) { | ||
| 32 | leader_sequence[leader_sequence_size] = keycode; | ||
| 33 | leader_sequence_size++; | ||
| 34 | return false; | ||
| 35 | } | ||
| 36 | } | ||
| 37 | return true; | ||
| 38 | } \ No newline at end of file | ||
diff --git a/quantum/process_keycode/process_leader.h b/quantum/process_keycode/process_leader.h new file mode 100644 index 000000000..c83db8abb --- /dev/null +++ b/quantum/process_keycode/process_leader.h | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | #ifndef PROCESS_LEADER_H | ||
| 2 | #define PROCESS_LEADER_H | ||
| 3 | |||
| 4 | #include "quantum.h" | ||
| 5 | |||
| 6 | bool process_leader(uint16_t keycode, keyrecord_t *record); | ||
| 7 | |||
| 8 | void leader_start(void); | ||
| 9 | void leader_end(void); | ||
| 10 | |||
| 11 | #ifndef LEADER_TIMEOUT | ||
| 12 | #define LEADER_TIMEOUT 200 | ||
| 13 | #endif | ||
| 14 | #define SEQ_ONE_KEY(key) if (leader_sequence[0] == (key) && leader_sequence[1] == 0 && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) | ||
| 15 | #define SEQ_TWO_KEYS(key1, key2) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == 0 && leader_sequence[3] == 0 && leader_sequence[4] == 0) | ||
| 16 | #define SEQ_THREE_KEYS(key1, key2, key3) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == 0 && leader_sequence[4] == 0) | ||
| 17 | #define SEQ_FOUR_KEYS(key1, key2, key3, key4) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == 0) | ||
| 18 | #define SEQ_FIVE_KEYS(key1, key2, key3, key4, key5) if (leader_sequence[0] == (key1) && leader_sequence[1] == (key2) && leader_sequence[2] == (key3) && leader_sequence[3] == (key4) && leader_sequence[4] == (key5)) | ||
| 19 | |||
| 20 | #define LEADER_EXTERNS() extern bool leading; extern uint16_t leader_time; extern uint16_t leader_sequence[5]; extern uint8_t leader_sequence_size | ||
| 21 | #define LEADER_DICTIONARY() if (leading && timer_elapsed(leader_time) > LEADER_TIMEOUT) | ||
| 22 | |||
| 23 | #endif \ No newline at end of file | ||
diff --git a/quantum/process_keycode/process_midi.c b/quantum/process_keycode/process_midi.c new file mode 100644 index 000000000..577dad43a --- /dev/null +++ b/quantum/process_keycode/process_midi.c | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | #include "process_midi.h" | ||
| 2 | |||
| 3 | bool midi_activated = false; | ||
| 4 | uint8_t midi_starting_note = 0x0C; | ||
| 5 | int midi_offset = 7; | ||
| 6 | |||
| 7 | bool process_midi(uint16_t keycode, keyrecord_t *record) { | ||
| 8 | if (keycode == MI_ON && record->event.pressed) { | ||
| 9 | midi_activated = true; | ||
| 10 | #ifdef AUDIO_ENABLE | ||
| 11 | music_scale_user(); | ||
| 12 | #endif | ||
| 13 | return false; | ||
| 14 | } | ||
| 15 | |||
| 16 | if (keycode == MI_OFF && record->event.pressed) { | ||
| 17 | midi_activated = false; | ||
| 18 | midi_send_cc(&midi_device, 0, 0x7B, 0); | ||
| 19 | return false; | ||
| 20 | } | ||
| 21 | |||
| 22 | if (midi_activated) { | ||
| 23 | if (record->event.key.col == (MATRIX_COLS - 1) && record->event.key.row == (MATRIX_ROWS - 1)) { | ||
| 24 | if (record->event.pressed) { | ||
| 25 | midi_starting_note++; // Change key | ||
| 26 | midi_send_cc(&midi_device, 0, 0x7B, 0); | ||
| 27 | } | ||
| 28 | return false; | ||
| 29 | } | ||
| 30 | if (record->event.key.col == (MATRIX_COLS - 2) && record->event.key.row == (MATRIX_ROWS - 1)) { | ||
| 31 | if (record->event.pressed) { | ||
| 32 | midi_starting_note--; // Change key | ||
| 33 | midi_send_cc(&midi_device, 0, 0x7B, 0); | ||
| 34 | } | ||
| 35 | return false; | ||
| 36 | } | ||
| 37 | if (record->event.key.col == (MATRIX_COLS - 3) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { | ||
| 38 | midi_offset++; // Change scale | ||
| 39 | midi_send_cc(&midi_device, 0, 0x7B, 0); | ||
| 40 | return false; | ||
| 41 | } | ||
| 42 | if (record->event.key.col == (MATRIX_COLS - 4) && record->event.key.row == (MATRIX_ROWS - 1) && record->event.pressed) { | ||
| 43 | midi_offset--; // Change scale | ||
| 44 | midi_send_cc(&midi_device, 0, 0x7B, 0); | ||
| 45 | return false; | ||
| 46 | } | ||
| 47 | // basic | ||
| 48 | // uint8_t note = (midi_starting_note + SCALE[record->event.key.col + midi_offset])+12*(MATRIX_ROWS - record->event.key.row); | ||
| 49 | // advanced | ||
| 50 | // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+12*(MATRIX_ROWS - record->event.key.row); | ||
| 51 | // guitar | ||
| 52 | uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+5*(MATRIX_ROWS - record->event.key.row); | ||
| 53 | // violin | ||
| 54 | // uint8_t note = (midi_starting_note + record->event.key.col + midi_offset)+7*(MATRIX_ROWS - record->event.key.row); | ||
| 55 | |||
| 56 | if (record->event.pressed) { | ||
| 57 | // midi_send_noteon(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127); | ||
| 58 | midi_send_noteon(&midi_device, 0, note, 127); | ||
| 59 | } else { | ||
| 60 | // midi_send_noteoff(&midi_device, record->event.key.row, midi_starting_note + SCALE[record->event.key.col], 127); | ||
| 61 | midi_send_noteoff(&midi_device, 0, note, 127); | ||
| 62 | } | ||
| 63 | |||
| 64 | if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through | ||
| 65 | return false; | ||
| 66 | } | ||
| 67 | return true; | ||
| 68 | } | ||
diff --git a/quantum/process_keycode/process_midi.h b/quantum/process_keycode/process_midi.h new file mode 100644 index 000000000..acd4fc1b1 --- /dev/null +++ b/quantum/process_keycode/process_midi.h | |||
| @@ -0,0 +1,207 @@ | |||
| 1 | #ifndef PROCESS_MIDI_H | ||
| 2 | #define PROCESS_MIDI_H | ||
| 3 | |||
| 4 | #include "quantum.h" | ||
| 5 | |||
| 6 | bool process_midi(uint16_t keycode, keyrecord_t *record); | ||
| 7 | |||
| 8 | #define MIDI(n) ((n) | 0x6000) | ||
| 9 | #define MIDI12 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000, 0x6000 | ||
| 10 | |||
| 11 | #define CHNL(note, channel) (note + (channel << 8)) | ||
| 12 | |||
| 13 | #define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ | ||
| 14 | 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ | ||
| 15 | 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ | ||
| 16 | 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ | ||
| 17 | 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } | ||
| 18 | |||
| 19 | #define N_CN1 (0x600C + (12 * -1) + 0 ) | ||
| 20 | #define N_CN1S (0x600C + (12 * -1) + 1 ) | ||
| 21 | #define N_DN1F (0x600C + (12 * -1) + 1 ) | ||
| 22 | #define N_DN1 (0x600C + (12 * -1) + 2 ) | ||
| 23 | #define N_DN1S (0x600C + (12 * -1) + 3 ) | ||
| 24 | #define N_EN1F (0x600C + (12 * -1) + 3 ) | ||
| 25 | #define N_EN1 (0x600C + (12 * -1) + 4 ) | ||
| 26 | #define N_FN1 (0x600C + (12 * -1) + 5 ) | ||
| 27 | #define N_FN1S (0x600C + (12 * -1) + 6 ) | ||
| 28 | #define N_GN1F (0x600C + (12 * -1) + 6 ) | ||
| 29 | #define N_GN1 (0x600C + (12 * -1) + 7 ) | ||
| 30 | #define N_GN1S (0x600C + (12 * -1) + 8 ) | ||
| 31 | #define N_AN1F (0x600C + (12 * -1) + 8 ) | ||
| 32 | #define N_AN1 (0x600C + (12 * -1) + 9 ) | ||
| 33 | #define N_AN1S (0x600C + (12 * -1) + 10) | ||
| 34 | #define N_BN1F (0x600C + (12 * -1) + 10) | ||
| 35 | #define N_BN1 (0x600C + (12 * -1) + 11) | ||
| 36 | #define N_C0 (0x600C + (12 * 0) + 0 ) | ||
| 37 | #define N_C0S (0x600C + (12 * 0) + 1 ) | ||
| 38 | #define N_D0F (0x600C + (12 * 0) + 1 ) | ||
| 39 | #define N_D0 (0x600C + (12 * 0) + 2 ) | ||
| 40 | #define N_D0S (0x600C + (12 * 0) + 3 ) | ||
| 41 | #define N_E0F (0x600C + (12 * 0) + 3 ) | ||
| 42 | #define N_E0 (0x600C + (12 * 0) + 4 ) | ||
| 43 | #define N_F0 (0x600C + (12 * 0) + 5 ) | ||
| 44 | #define N_F0S (0x600C + (12 * 0) + 6 ) | ||
| 45 | #define N_G0F (0x600C + (12 * 0) + 6 ) | ||
| 46 | #define N_G0 (0x600C + (12 * 0) + 7 ) | ||
| 47 | #define N_G0S (0x600C + (12 * 0) + 8 ) | ||
| 48 | #define N_A0F (0x600C + (12 * 0) + 8 ) | ||
| 49 | #define N_A0 (0x600C + (12 * 0) + 9 ) | ||
| 50 | #define N_A0S (0x600C + (12 * 0) + 10) | ||
| 51 | #define N_B0F (0x600C + (12 * 0) + 10) | ||
| 52 | #define N_B0 (0x600C + (12 * 0) + 11) | ||
| 53 | #define N_C1 (0x600C + (12 * 1) + 0 ) | ||
| 54 | #define N_C1S (0x600C + (12 * 1) + 1 ) | ||
| 55 | #define N_D1F (0x600C + (12 * 1) + 1 ) | ||
| 56 | #define N_D1 (0x600C + (12 * 1) + 2 ) | ||
| 57 | #define N_D1S (0x600C + (12 * 1) + 3 ) | ||
| 58 | #define N_E1F (0x600C + (12 * 1) + 3 ) | ||
| 59 | #define N_E1 (0x600C + (12 * 1) + 4 ) | ||
| 60 | #define N_F1 (0x600C + (12 * 1) + 5 ) | ||
| 61 | #define N_F1S (0x600C + (12 * 1) + 6 ) | ||
| 62 | #define N_G1F (0x600C + (12 * 1) + 6 ) | ||
| 63 | #define N_G1 (0x600C + (12 * 1) + 7 ) | ||
| 64 | #define N_G1S (0x600C + (12 * 1) + 8 ) | ||
| 65 | #define N_A1F (0x600C + (12 * 1) + 8 ) | ||
| 66 | #define N_A1 (0x600C + (12 * 1) + 9 ) | ||
| 67 | #define N_A1S (0x600C + (12 * 1) + 10) | ||
| 68 | #define N_B1F (0x600C + (12 * 1) + 10) | ||
| 69 | #define N_B1 (0x600C + (12 * 1) + 11) | ||
| 70 | #define N_C2 (0x600C + (12 * 2) + 0 ) | ||
| 71 | #define N_C2S (0x600C + (12 * 2) + 1 ) | ||
| 72 | #define N_D2F (0x600C + (12 * 2) + 1 ) | ||
| 73 | #define N_D2 (0x600C + (12 * 2) + 2 ) | ||
| 74 | #define N_D2S (0x600C + (12 * 2) + 3 ) | ||
| 75 | #define N_E2F (0x600C + (12 * 2) + 3 ) | ||
| 76 | #define N_E2 (0x600C + (12 * 2) + 4 ) | ||
| 77 | #define N_F2 (0x600C + (12 * 2) + 5 ) | ||
| 78 | #define N_F2S (0x600C + (12 * 2) + 6 ) | ||
| 79 | #define N_G2F (0x600C + (12 * 2) + 6 ) | ||
| 80 | #define N_G2 (0x600C + (12 * 2) + 7 ) | ||
| 81 | #define N_G2S (0x600C + (12 * 2) + 8 ) | ||
| 82 | #define N_A2F (0x600C + (12 * 2) + 8 ) | ||
| 83 | #define N_A2 (0x600C + (12 * 2) + 9 ) | ||
| 84 | #define N_A2S (0x600C + (12 * 2) + 10) | ||
| 85 | #define N_B2F (0x600C + (12 * 2) + 10) | ||
| 86 | #define N_B2 (0x600C + (12 * 2) + 11) | ||
| 87 | #define N_C3 (0x600C + (12 * 3) + 0 ) | ||
| 88 | #define N_C3S (0x600C + (12 * 3) + 1 ) | ||
| 89 | #define N_D3F (0x600C + (12 * 3) + 1 ) | ||
| 90 | #define N_D3 (0x600C + (12 * 3) + 2 ) | ||
| 91 | #define N_D3S (0x600C + (12 * 3) + 3 ) | ||
| 92 | #define N_E3F (0x600C + (12 * 3) + 3 ) | ||
| 93 | #define N_E3 (0x600C + (12 * 3) + 4 ) | ||
| 94 | #define N_F3 (0x600C + (12 * 3) + 5 ) | ||
| 95 | #define N_F3S (0x600C + (12 * 3) + 6 ) | ||
| 96 | #define N_G3F (0x600C + (12 * 3) + 6 ) | ||
| 97 | #define N_G3 (0x600C + (12 * 3) + 7 ) | ||
| 98 | #define N_G3S (0x600C + (12 * 3) + 8 ) | ||
| 99 | #define N_A3F (0x600C + (12 * 3) + 8 ) | ||
| 100 | #define N_A3 (0x600C + (12 * 3) + 9 ) | ||
| 101 | #define N_A3S (0x600C + (12 * 3) + 10) | ||
| 102 | #define N_B3F (0x600C + (12 * 3) + 10) | ||
| 103 | #define N_B3 (0x600C + (12 * 3) + 11) | ||
| 104 | #define N_C4 (0x600C + (12 * 4) + 0 ) | ||
| 105 | #define N_C4S (0x600C + (12 * 4) + 1 ) | ||
| 106 | #define N_D4F (0x600C + (12 * 4) + 1 ) | ||
| 107 | #define N_D4 (0x600C + (12 * 4) + 2 ) | ||
| 108 | #define N_D4S (0x600C + (12 * 4) + 3 ) | ||
| 109 | #define N_E4F (0x600C + (12 * 4) + 3 ) | ||
| 110 | #define N_E4 (0x600C + (12 * 4) + 4 ) | ||
| 111 | #define N_F4 (0x600C + (12 * 4) + 5 ) | ||
| 112 | #define N_F4S (0x600C + (12 * 4) + 6 ) | ||
| 113 | #define N_G4F (0x600C + (12 * 4) + 6 ) | ||
| 114 | #define N_G4 (0x600C + (12 * 4) + 7 ) | ||
| 115 | #define N_G4S (0x600C + (12 * 4) + 8 ) | ||
| 116 | #define N_A4F (0x600C + (12 * 4) + 8 ) | ||
| 117 | #define N_A4 (0x600C + (12 * 4) + 9 ) | ||
| 118 | #define N_A4S (0x600C + (12 * 4) + 10) | ||
| 119 | #define N_B4F (0x600C + (12 * 4) + 10) | ||
| 120 | #define N_B4 (0x600C + (12 * 4) + 11) | ||
| 121 | #define N_C5 (0x600C + (12 * 5) + 0 ) | ||
| 122 | #define N_C5S (0x600C + (12 * 5) + 1 ) | ||
| 123 | #define N_D5F (0x600C + (12 * 5) + 1 ) | ||
| 124 | #define N_D5 (0x600C + (12 * 5) + 2 ) | ||
| 125 | #define N_D5S (0x600C + (12 * 5) + 3 ) | ||
| 126 | #define N_E5F (0x600C + (12 * 5) + 3 ) | ||
| 127 | #define N_E5 (0x600C + (12 * 5) + 4 ) | ||
| 128 | #define N_F5 (0x600C + (12 * 5) + 5 ) | ||
| 129 | #define N_F5S (0x600C + (12 * 5) + 6 ) | ||
| 130 | #define N_G5F (0x600C + (12 * 5) + 6 ) | ||
| 131 | #define N_G5 (0x600C + (12 * 5) + 7 ) | ||
| 132 | #define N_G5S (0x600C + (12 * 5) + 8 ) | ||
| 133 | #define N_A5F (0x600C + (12 * 5) + 8 ) | ||
| 134 | #define N_A5 (0x600C + (12 * 5) + 9 ) | ||
| 135 | #define N_A5S (0x600C + (12 * 5) + 10) | ||
| 136 | #define N_B5F (0x600C + (12 * 5) + 10) | ||
| 137 | #define N_B5 (0x600C + (12 * 5) + 11) | ||
| 138 | #define N_C6 (0x600C + (12 * 6) + 0 ) | ||
| 139 | #define N_C6S (0x600C + (12 * 6) + 1 ) | ||
| 140 | #define N_D6F (0x600C + (12 * 6) + 1 ) | ||
| 141 | #define N_D6 (0x600C + (12 * 6) + 2 ) | ||
| 142 | #define N_D6S (0x600C + (12 * 6) + 3 ) | ||
| 143 | #define N_E6F (0x600C + (12 * 6) + 3 ) | ||
| 144 | #define N_E6 (0x600C + (12 * 6) + 4 ) | ||
| 145 | #define N_F6 (0x600C + (12 * 6) + 5 ) | ||
| 146 | #define N_F6S (0x600C + (12 * 6) + 6 ) | ||
| 147 | #define N_G6F (0x600C + (12 * 6) + 6 ) | ||
| 148 | #define N_G6 (0x600C + (12 * 6) + 7 ) | ||
| 149 | #define N_G6S (0x600C + (12 * 6) + 8 ) | ||
| 150 | #define N_A6F (0x600C + (12 * 6) + 8 ) | ||
| 151 | #define N_A6 (0x600C + (12 * 6) + 9 ) | ||
| 152 | #define N_A6S (0x600C + (12 * 6) + 10) | ||
| 153 | #define N_B6F (0x600C + (12 * 6) + 10) | ||
| 154 | #define N_B6 (0x600C + (12 * 6) + 11) | ||
| 155 | #define N_C7 (0x600C + (12 * 7) + 0 ) | ||
| 156 | #define N_C7S (0x600C + (12 * 7) + 1 ) | ||
| 157 | #define N_D7F (0x600C + (12 * 7) + 1 ) | ||
| 158 | #define N_D7 (0x600C + (12 * 7) + 2 ) | ||
| 159 | #define N_D7S (0x600C + (12 * 7) + 3 ) | ||
| 160 | #define N_E7F (0x600C + (12 * 7) + 3 ) | ||
| 161 | #define N_E7 (0x600C + (12 * 7) + 4 ) | ||
| 162 | #define N_F7 (0x600C + (12 * 7) + 5 ) | ||
| 163 | #define N_F7S (0x600C + (12 * 7) + 6 ) | ||
| 164 | #define N_G7F (0x600C + (12 * 7) + 6 ) | ||
| 165 | #define N_G7 (0x600C + (12 * 7) + 7 ) | ||
| 166 | #define N_G7S (0x600C + (12 * 7) + 8 ) | ||
| 167 | #define N_A7F (0x600C + (12 * 7) + 8 ) | ||
| 168 | #define N_A7 (0x600C + (12 * 7) + 9 ) | ||
| 169 | #define N_A7S (0x600C + (12 * 7) + 10) | ||
| 170 | #define N_B7F (0x600C + (12 * 7) + 10) | ||
| 171 | #define N_B7 (0x600C + (12 * 7) + 11) | ||
| 172 | #define N_C8 (0x600C + (12 * 8) + 0 ) | ||
| 173 | #define N_C8S (0x600C + (12 * 8) + 1 ) | ||
| 174 | #define N_D8F (0x600C + (12 * 8) + 1 ) | ||
| 175 | #define N_D8 (0x600C + (12 * 8) + 2 ) | ||
| 176 | #define N_D8S (0x600C + (12 * 8) + 3 ) | ||
| 177 | #define N_E8F (0x600C + (12 * 8) + 3 ) | ||
| 178 | #define N_E8 (0x600C + (12 * 8) + 4 ) | ||
| 179 | #define N_F8 (0x600C + (12 * 8) + 5 ) | ||
| 180 | #define N_F8S (0x600C + (12 * 8) + 6 ) | ||
| 181 | #define N_G8F (0x600C + (12 * 8) + 6 ) | ||
| 182 | #define N_G8 (0x600C + (12 * 8) + 7 ) | ||
| 183 | #define N_G8S (0x600C + (12 * 8) + 8 ) | ||
| 184 | #define N_A8F (0x600C + (12 * 8) + 8 ) | ||
| 185 | #define N_A8 (0x600C + (12 * 8) + 9 ) | ||
| 186 | #define N_A8S (0x600C + (12 * 8) + 10) | ||
| 187 | #define N_B8F (0x600C + (12 * 8) + 10) | ||
| 188 | #define N_B8 (0x600C + (12 * 8) + 11) | ||
| 189 | #define N_C8 (0x600C + (12 * 8) + 0 ) | ||
| 190 | #define N_C8S (0x600C + (12 * 8) + 1 ) | ||
| 191 | #define N_D8F (0x600C + (12 * 8) + 1 ) | ||
| 192 | #define N_D8 (0x600C + (12 * 8) + 2 ) | ||
| 193 | #define N_D8S (0x600C + (12 * 8) + 3 ) | ||
| 194 | #define N_E8F (0x600C + (12 * 8) + 3 ) | ||
| 195 | #define N_E8 (0x600C + (12 * 8) + 4 ) | ||
| 196 | #define N_F8 (0x600C + (12 * 8) + 5 ) | ||
| 197 | #define N_F8S (0x600C + (12 * 8) + 6 ) | ||
| 198 | #define N_G8F (0x600C + (12 * 8) + 6 ) | ||
| 199 | #define N_G8 (0x600C + (12 * 8) + 7 ) | ||
| 200 | #define N_G8S (0x600C + (12 * 8) + 8 ) | ||
| 201 | #define N_A8F (0x600C + (12 * 8) + 8 ) | ||
| 202 | #define N_A8 (0x600C + (12 * 8) + 9 ) | ||
| 203 | #define N_A8S (0x600C + (12 * 8) + 10) | ||
| 204 | #define N_B8F (0x600C + (12 * 8) + 10) | ||
| 205 | #define N_B8 (0x600C + (12 * 8) + 11) | ||
| 206 | |||
| 207 | #endif \ No newline at end of file | ||
diff --git a/quantum/process_keycode/process_music.c b/quantum/process_keycode/process_music.c new file mode 100644 index 000000000..2d52e47a7 --- /dev/null +++ b/quantum/process_keycode/process_music.c | |||
| @@ -0,0 +1,176 @@ | |||
| 1 | #include "process_music.h" | ||
| 2 | |||
| 3 | bool music_activated = false; | ||
| 4 | uint8_t starting_note = 0x0C; | ||
| 5 | int offset = 7; | ||
| 6 | |||
| 7 | // music sequencer | ||
| 8 | static bool music_sequence_recording = false; | ||
| 9 | static bool music_sequence_recorded = false; | ||
| 10 | static bool music_sequence_playing = false; | ||
| 11 | static float music_sequence[16] = {0}; | ||
| 12 | static uint8_t music_sequence_count = 0; | ||
| 13 | static uint8_t music_sequence_position = 0; | ||
| 14 | |||
| 15 | static uint16_t music_sequence_timer = 0; | ||
| 16 | static uint16_t music_sequence_interval = 100; | ||
| 17 | |||
| 18 | bool process_music(uint16_t keycode, keyrecord_t *record) { | ||
| 19 | |||
| 20 | if (keycode == AU_ON && record->event.pressed) { | ||
| 21 | audio_on(); | ||
| 22 | return false; | ||
| 23 | } | ||
| 24 | |||
| 25 | if (keycode == AU_OFF && record->event.pressed) { | ||
| 26 | audio_off(); | ||
| 27 | return false; | ||
| 28 | } | ||
| 29 | |||
| 30 | if (keycode == AU_TOG && record->event.pressed) { | ||
| 31 | if (is_audio_on()) | ||
| 32 | { | ||
| 33 | audio_off(); | ||
| 34 | } | ||
| 35 | else | ||
| 36 | { | ||
| 37 | audio_on(); | ||
| 38 | } | ||
| 39 | return false; | ||
| 40 | } | ||
| 41 | |||
| 42 | if (keycode == MU_ON && record->event.pressed) { | ||
| 43 | music_on(); | ||
| 44 | return false; | ||
| 45 | } | ||
| 46 | |||
| 47 | if (keycode == MU_OFF && record->event.pressed) { | ||
| 48 | music_off(); | ||
| 49 | return false; | ||
| 50 | } | ||
| 51 | |||
| 52 | if (keycode == MU_TOG && record->event.pressed) { | ||
| 53 | if (music_activated) | ||
| 54 | { | ||
| 55 | music_off(); | ||
| 56 | } | ||
| 57 | else | ||
| 58 | { | ||
| 59 | music_on(); | ||
| 60 | } | ||
| 61 | return false; | ||
| 62 | } | ||
| 63 | |||
| 64 | if (keycode == MUV_IN && record->event.pressed) { | ||
| 65 | voice_iterate(); | ||
| 66 | music_scale_user(); | ||
| 67 | return false; | ||
| 68 | } | ||
| 69 | |||
| 70 | if (keycode == MUV_DE && record->event.pressed) { | ||
| 71 | voice_deiterate(); | ||
| 72 | music_scale_user(); | ||
| 73 | return false; | ||
| 74 | } | ||
| 75 | |||
| 76 | if (music_activated) { | ||
| 77 | |||
| 78 | if (keycode == KC_LCTL && record->event.pressed) { // Start recording | ||
| 79 | stop_all_notes(); | ||
| 80 | music_sequence_recording = true; | ||
| 81 | music_sequence_recorded = false; | ||
| 82 | music_sequence_playing = false; | ||
| 83 | music_sequence_count = 0; | ||
| 84 | return false; | ||
| 85 | } | ||
| 86 | |||
| 87 | if (keycode == KC_LALT && record->event.pressed) { // Stop recording/playing | ||
| 88 | stop_all_notes(); | ||
| 89 | if (music_sequence_recording) { // was recording | ||
| 90 | music_sequence_recorded = true; | ||
| 91 | } | ||
| 92 | music_sequence_recording = false; | ||
| 93 | music_sequence_playing = false; | ||
| 94 | return false; | ||
| 95 | } | ||
| 96 | |||
| 97 | if (keycode == KC_LGUI && record->event.pressed && music_sequence_recorded) { // Start playing | ||
| 98 | stop_all_notes(); | ||
| 99 | music_sequence_recording = false; | ||
| 100 | music_sequence_playing = true; | ||
| 101 | music_sequence_position = 0; | ||
| 102 | music_sequence_timer = 0; | ||
| 103 | return false; | ||
| 104 | } | ||
| 105 | |||
| 106 | if (keycode == KC_UP) { | ||
| 107 | if (record->event.pressed) | ||
| 108 | music_sequence_interval-=10; | ||
| 109 | return false; | ||
| 110 | } | ||
| 111 | |||
| 112 | if (keycode == KC_DOWN) { | ||
| 113 | if (record->event.pressed) | ||
| 114 | music_sequence_interval+=10; | ||
| 115 | return false; | ||
| 116 | } | ||
| 117 | |||
| 118 | float freq = ((float)220.0)*pow(2.0, -5.0)*pow(2.0,(starting_note + SCALE[record->event.key.col + offset])/12.0+(MATRIX_ROWS - record->event.key.row)); | ||
| 119 | if (record->event.pressed) { | ||
| 120 | play_note(freq, 0xF); | ||
| 121 | if (music_sequence_recording) { | ||
| 122 | music_sequence[music_sequence_count] = freq; | ||
| 123 | music_sequence_count++; | ||
| 124 | } | ||
| 125 | } else { | ||
| 126 | stop_note(freq); | ||
| 127 | } | ||
| 128 | |||
| 129 | if (keycode < 0xFF) // ignores all normal keycodes, but lets RAISE, LOWER, etc through | ||
| 130 | return false; | ||
| 131 | } | ||
| 132 | return true; | ||
| 133 | } | ||
| 134 | |||
| 135 | bool is_music_on(void) { | ||
| 136 | return (music_activated != 0); | ||
| 137 | } | ||
| 138 | |||
| 139 | void music_toggle(void) { | ||
| 140 | if (!music_activated) { | ||
| 141 | music_on(); | ||
| 142 | } else { | ||
| 143 | music_off(); | ||
| 144 | } | ||
| 145 | } | ||
| 146 | |||
| 147 | void music_on(void) { | ||
| 148 | music_activated = 1; | ||
| 149 | music_on_user(); | ||
| 150 | } | ||
| 151 | |||
| 152 | void music_off(void) { | ||
| 153 | music_activated = 0; | ||
| 154 | stop_all_notes(); | ||
| 155 | } | ||
| 156 | |||
| 157 | |||
| 158 | __attribute__ ((weak)) | ||
| 159 | void music_on_user() {} | ||
| 160 | |||
| 161 | __attribute__ ((weak)) | ||
| 162 | void audio_on_user() {} | ||
| 163 | |||
| 164 | __attribute__ ((weak)) | ||
| 165 | void music_scale_user() {} | ||
| 166 | |||
| 167 | void matrix_scan_music(void) { | ||
| 168 | if (music_sequence_playing) { | ||
| 169 | if ((music_sequence_timer == 0) || (timer_elapsed(music_sequence_timer) > music_sequence_interval)) { | ||
| 170 | music_sequence_timer = timer_read(); | ||
| 171 | stop_note(music_sequence[(music_sequence_position - 1 < 0)?(music_sequence_position - 1 + music_sequence_count):(music_sequence_position - 1)]); | ||
| 172 | play_note(music_sequence[music_sequence_position], 0xF); | ||
| 173 | music_sequence_position = (music_sequence_position + 1) % music_sequence_count; | ||
| 174 | } | ||
| 175 | } | ||
| 176 | } | ||
diff --git a/quantum/process_keycode/process_music.h b/quantum/process_keycode/process_music.h new file mode 100644 index 000000000..318b3e387 --- /dev/null +++ b/quantum/process_keycode/process_music.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | #ifndef PROCESS_MUSIC_H | ||
| 2 | #define PROCESS_MUSIC_H | ||
| 3 | |||
| 4 | #include "quantum.h" | ||
| 5 | |||
| 6 | bool process_music(uint16_t keycode, keyrecord_t *record); | ||
| 7 | |||
| 8 | bool is_music_on(void); | ||
| 9 | void music_toggle(void); | ||
| 10 | void music_on(void); | ||
| 11 | void music_off(void); | ||
| 12 | |||
| 13 | void audio_on_user(void); | ||
| 14 | void music_on_user(void); | ||
| 15 | void music_scale_user(void); | ||
| 16 | |||
| 17 | void matrix_scan_music(void); | ||
| 18 | |||
| 19 | #ifndef SCALE | ||
| 20 | #define SCALE (int8_t []){ 0 + (12*0), 2 + (12*0), 4 + (12*0), 5 + (12*0), 7 + (12*0), 9 + (12*0), 11 + (12*0), \ | ||
| 21 | 0 + (12*1), 2 + (12*1), 4 + (12*1), 5 + (12*1), 7 + (12*1), 9 + (12*1), 11 + (12*1), \ | ||
| 22 | 0 + (12*2), 2 + (12*2), 4 + (12*2), 5 + (12*2), 7 + (12*2), 9 + (12*2), 11 + (12*2), \ | ||
| 23 | 0 + (12*3), 2 + (12*3), 4 + (12*3), 5 + (12*3), 7 + (12*3), 9 + (12*3), 11 + (12*3), \ | ||
| 24 | 0 + (12*4), 2 + (12*4), 4 + (12*4), 5 + (12*4), 7 + (12*4), 9 + (12*4), 11 + (12*4), } | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #endif \ No newline at end of file | ||
diff --git a/quantum/process_keycode/process_tap_dance.c b/quantum/process_keycode/process_tap_dance.c new file mode 100644 index 000000000..6ae362c4c --- /dev/null +++ b/quantum/process_keycode/process_tap_dance.c | |||
| @@ -0,0 +1,136 @@ | |||
| 1 | #include "quantum.h" | ||
| 2 | #include "action_tapping.h" | ||
| 3 | |||
| 4 | static uint16_t last_td; | ||
| 5 | static int8_t highest_td = -1; | ||
| 6 | |||
| 7 | void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data) { | ||
| 8 | qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; | ||
| 9 | |||
| 10 | if (state->count == 1) { | ||
| 11 | register_code16 (pair->kc1); | ||
| 12 | } else if (state->count == 2) { | ||
| 13 | register_code16 (pair->kc2); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data) { | ||
| 18 | qk_tap_dance_pair_t *pair = (qk_tap_dance_pair_t *)user_data; | ||
| 19 | |||
| 20 | if (state->count == 1) { | ||
| 21 | unregister_code16 (pair->kc1); | ||
| 22 | } else if (state->count == 2) { | ||
| 23 | unregister_code16 (pair->kc2); | ||
| 24 | } | ||
| 25 | } | ||
| 26 | |||
| 27 | static inline void _process_tap_dance_action_fn (qk_tap_dance_state_t *state, | ||
| 28 | void *user_data, | ||
| 29 | qk_tap_dance_user_fn_t fn) | ||
| 30 | { | ||
| 31 | if (fn) { | ||
| 32 | fn(state, user_data); | ||
| 33 | } | ||
| 34 | } | ||
| 35 | |||
| 36 | static inline void process_tap_dance_action_on_each_tap (qk_tap_dance_action_t *action) | ||
| 37 | { | ||
| 38 | _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_each_tap); | ||
| 39 | } | ||
| 40 | |||
| 41 | static inline void process_tap_dance_action_on_dance_finished (qk_tap_dance_action_t *action) | ||
| 42 | { | ||
| 43 | if (action->state.finished) | ||
| 44 | return; | ||
| 45 | action->state.finished = true; | ||
| 46 | _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_dance_finished); | ||
| 47 | } | ||
| 48 | |||
| 49 | static inline void process_tap_dance_action_on_reset (qk_tap_dance_action_t *action) | ||
| 50 | { | ||
| 51 | _process_tap_dance_action_fn (&action->state, action->user_data, action->fn.on_reset); | ||
| 52 | } | ||
| 53 | |||
| 54 | bool process_tap_dance(uint16_t keycode, keyrecord_t *record) { | ||
| 55 | uint16_t idx = keycode - QK_TAP_DANCE; | ||
| 56 | qk_tap_dance_action_t *action; | ||
| 57 | |||
| 58 | if (last_td && last_td != keycode) { | ||
| 59 | (&tap_dance_actions[last_td - QK_TAP_DANCE])->state.interrupted = true; | ||
| 60 | } | ||
| 61 | |||
| 62 | switch(keycode) { | ||
| 63 | case QK_TAP_DANCE ... QK_TAP_DANCE_MAX: | ||
| 64 | if ((int16_t)idx > highest_td) | ||
| 65 | highest_td = idx; | ||
| 66 | action = &tap_dance_actions[idx]; | ||
| 67 | |||
| 68 | action->state.pressed = record->event.pressed; | ||
| 69 | if (record->event.pressed) { | ||
| 70 | action->state.keycode = keycode; | ||
| 71 | action->state.count++; | ||
| 72 | action->state.timer = timer_read(); | ||
| 73 | process_tap_dance_action_on_each_tap (action); | ||
| 74 | |||
| 75 | if (last_td && last_td != keycode) { | ||
| 76 | qk_tap_dance_action_t *paction = &tap_dance_actions[last_td - QK_TAP_DANCE]; | ||
| 77 | paction->state.interrupted = true; | ||
| 78 | process_tap_dance_action_on_dance_finished (paction); | ||
| 79 | reset_tap_dance (&paction->state); | ||
| 80 | } | ||
| 81 | |||
| 82 | last_td = keycode; | ||
| 83 | } | ||
| 84 | |||
| 85 | break; | ||
| 86 | |||
| 87 | default: | ||
| 88 | if (!record->event.pressed) | ||
| 89 | return true; | ||
| 90 | |||
| 91 | if (highest_td == -1) | ||
| 92 | return true; | ||
| 93 | |||
| 94 | for (int i = 0; i <= highest_td; i++) { | ||
| 95 | action = &tap_dance_actions[i]; | ||
| 96 | if (action->state.count == 0) | ||
| 97 | continue; | ||
| 98 | action->state.interrupted = true; | ||
| 99 | process_tap_dance_action_on_dance_finished (action); | ||
| 100 | reset_tap_dance (&action->state); | ||
| 101 | } | ||
| 102 | break; | ||
| 103 | } | ||
| 104 | |||
| 105 | return true; | ||
| 106 | } | ||
| 107 | |||
| 108 | void matrix_scan_tap_dance () { | ||
| 109 | if (highest_td == -1) | ||
| 110 | return; | ||
| 111 | |||
| 112 | for (int i = 0; i <= highest_td; i++) { | ||
| 113 | qk_tap_dance_action_t *action = &tap_dance_actions[i]; | ||
| 114 | |||
| 115 | if (action->state.count && timer_elapsed (action->state.timer) > TAPPING_TERM) { | ||
| 116 | process_tap_dance_action_on_dance_finished (action); | ||
| 117 | reset_tap_dance (&action->state); | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | void reset_tap_dance (qk_tap_dance_state_t *state) { | ||
| 123 | qk_tap_dance_action_t *action; | ||
| 124 | |||
| 125 | if (state->pressed) | ||
| 126 | return; | ||
| 127 | |||
| 128 | action = &tap_dance_actions[state->keycode - QK_TAP_DANCE]; | ||
| 129 | |||
| 130 | process_tap_dance_action_on_reset (action); | ||
| 131 | |||
| 132 | state->count = 0; | ||
| 133 | state->interrupted = false; | ||
| 134 | state->finished = false; | ||
| 135 | last_td = 0; | ||
| 136 | } | ||
diff --git a/quantum/process_keycode/process_tap_dance.h b/quantum/process_keycode/process_tap_dance.h new file mode 100644 index 000000000..f753cbba6 --- /dev/null +++ b/quantum/process_keycode/process_tap_dance.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | #ifndef PROCESS_TAP_DANCE_H | ||
| 2 | #define PROCESS_TAP_DANCE_H | ||
| 3 | |||
| 4 | #ifdef TAP_DANCE_ENABLE | ||
| 5 | |||
| 6 | #include <stdbool.h> | ||
| 7 | #include <inttypes.h> | ||
| 8 | |||
| 9 | typedef struct | ||
| 10 | { | ||
| 11 | uint8_t count; | ||
| 12 | uint16_t keycode; | ||
| 13 | uint16_t timer; | ||
| 14 | bool interrupted; | ||
| 15 | bool pressed; | ||
| 16 | bool finished; | ||
| 17 | } qk_tap_dance_state_t; | ||
| 18 | |||
| 19 | #define TD(n) (QK_TAP_DANCE + n) | ||
| 20 | |||
| 21 | typedef void (*qk_tap_dance_user_fn_t) (qk_tap_dance_state_t *state, void *user_data); | ||
| 22 | |||
| 23 | typedef struct | ||
| 24 | { | ||
| 25 | struct { | ||
| 26 | qk_tap_dance_user_fn_t on_each_tap; | ||
| 27 | qk_tap_dance_user_fn_t on_dance_finished; | ||
| 28 | qk_tap_dance_user_fn_t on_reset; | ||
| 29 | } fn; | ||
| 30 | qk_tap_dance_state_t state; | ||
| 31 | void *user_data; | ||
| 32 | } qk_tap_dance_action_t; | ||
| 33 | |||
| 34 | typedef struct | ||
| 35 | { | ||
| 36 | uint16_t kc1; | ||
| 37 | uint16_t kc2; | ||
| 38 | } qk_tap_dance_pair_t; | ||
| 39 | |||
| 40 | #define ACTION_TAP_DANCE_DOUBLE(kc1, kc2) { \ | ||
| 41 | .fn = { NULL, qk_tap_dance_pair_finished, qk_tap_dance_pair_reset }, \ | ||
| 42 | .user_data = (void *)&((qk_tap_dance_pair_t) { kc1, kc2 }), \ | ||
| 43 | } | ||
| 44 | |||
| 45 | #define ACTION_TAP_DANCE_FN(user_fn) { \ | ||
| 46 | .fn = { NULL, user_fn, NULL }, \ | ||
| 47 | .user_data = NULL, \ | ||
| 48 | } | ||
| 49 | |||
| 50 | #define ACTION_TAP_DANCE_FN_ADVANCED(user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset) { \ | ||
| 51 | .fn = { user_fn_on_each_tap, user_fn_on_dance_finished, user_fn_on_dance_reset }, \ | ||
| 52 | .user_data = NULL, \ | ||
| 53 | } | ||
| 54 | |||
| 55 | extern qk_tap_dance_action_t tap_dance_actions[]; | ||
| 56 | |||
| 57 | /* To be used internally */ | ||
| 58 | |||
| 59 | bool process_tap_dance(uint16_t keycode, keyrecord_t *record); | ||
| 60 | void matrix_scan_tap_dance (void); | ||
| 61 | void reset_tap_dance (qk_tap_dance_state_t *state); | ||
| 62 | |||
| 63 | void qk_tap_dance_pair_finished (qk_tap_dance_state_t *state, void *user_data); | ||
| 64 | void qk_tap_dance_pair_reset (qk_tap_dance_state_t *state, void *user_data); | ||
| 65 | |||
| 66 | #else | ||
| 67 | |||
| 68 | #define TD(n) KC_NO | ||
| 69 | |||
| 70 | #endif | ||
| 71 | |||
| 72 | #endif | ||
diff --git a/quantum/process_keycode/process_unicode.c b/quantum/process_keycode/process_unicode.c new file mode 100644 index 000000000..37dd471ff --- /dev/null +++ b/quantum/process_keycode/process_unicode.c | |||
| @@ -0,0 +1,239 @@ | |||
| 1 | #include "process_unicode.h" | ||
| 2 | |||
| 3 | static uint8_t input_mode; | ||
| 4 | |||
| 5 | __attribute__((weak)) | ||
| 6 | uint16_t hex_to_keycode(uint8_t hex) | ||
| 7 | { | ||
| 8 | if (hex == 0x0) { | ||
| 9 | return KC_0; | ||
| 10 | } else if (hex < 0xA) { | ||
| 11 | return KC_1 + (hex - 0x1); | ||
| 12 | } else { | ||
| 13 | return KC_A + (hex - 0xA); | ||
| 14 | } | ||
| 15 | } | ||
| 16 | |||
| 17 | void set_unicode_input_mode(uint8_t os_target) | ||
| 18 | { | ||
| 19 | input_mode = os_target; | ||
| 20 | } | ||
| 21 | |||
| 22 | uint8_t get_unicode_input_mode(void) { | ||
| 23 | return input_mode; | ||
| 24 | } | ||
| 25 | |||
| 26 | __attribute__((weak)) | ||
| 27 | void unicode_input_start (void) { | ||
| 28 | switch(input_mode) { | ||
| 29 | case UC_OSX: | ||
| 30 | register_code(KC_LALT); | ||
| 31 | break; | ||
| 32 | case UC_LNX: | ||
| 33 | register_code(KC_LCTL); | ||
| 34 | register_code(KC_LSFT); | ||
| 35 | register_code(KC_U); | ||
| 36 | unregister_code(KC_U); | ||
| 37 | unregister_code(KC_LSFT); | ||
| 38 | unregister_code(KC_LCTL); | ||
| 39 | break; | ||
| 40 | case UC_WIN: | ||
| 41 | register_code(KC_LALT); | ||
| 42 | register_code(KC_PPLS); | ||
| 43 | unregister_code(KC_PPLS); | ||
| 44 | break; | ||
| 45 | } | ||
| 46 | wait_ms(UNICODE_TYPE_DELAY); | ||
| 47 | } | ||
| 48 | |||
| 49 | __attribute__((weak)) | ||
| 50 | void unicode_input_finish (void) { | ||
| 51 | switch(input_mode) { | ||
| 52 | case UC_OSX: | ||
| 53 | case UC_WIN: | ||
| 54 | unregister_code(KC_LALT); | ||
| 55 | break; | ||
| 56 | case UC_LNX: | ||
| 57 | register_code(KC_SPC); | ||
| 58 | unregister_code(KC_SPC); | ||
| 59 | break; | ||
| 60 | } | ||
| 61 | } | ||
| 62 | |||
| 63 | void register_hex(uint16_t hex) { | ||
| 64 | for(int i = 3; i >= 0; i--) { | ||
| 65 | uint8_t digit = ((hex >> (i*4)) & 0xF); | ||
| 66 | register_code(hex_to_keycode(digit)); | ||
| 67 | unregister_code(hex_to_keycode(digit)); | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | bool process_unicode(uint16_t keycode, keyrecord_t *record) { | ||
| 72 | if (keycode > QK_UNICODE && record->event.pressed) { | ||
| 73 | uint16_t unicode = keycode & 0x7FFF; | ||
| 74 | unicode_input_start(); | ||
| 75 | register_hex(unicode); | ||
| 76 | unicode_input_finish(); | ||
| 77 | } | ||
| 78 | return true; | ||
| 79 | } | ||
| 80 | |||
| 81 | #ifdef UNICODEMAP_ENABLE | ||
| 82 | __attribute__((weak)) | ||
| 83 | const uint32_t PROGMEM unicode_map[] = { | ||
| 84 | }; | ||
| 85 | |||
| 86 | // 5 digit max because of linux limitation | ||
| 87 | void register_hex32(uint32_t hex) { | ||
| 88 | for(int i = 4; i >= 0; i--) { | ||
| 89 | uint8_t digit = ((hex >> (i*4)) & 0xF); | ||
| 90 | register_code(hex_to_keycode(digit)); | ||
| 91 | unregister_code(hex_to_keycode(digit)); | ||
| 92 | } | ||
| 93 | } | ||
| 94 | |||
| 95 | bool process_unicode_map(uint16_t keycode, keyrecord_t *record) { | ||
| 96 | if ((keycode & QK_UNICODE_MAP) == QK_UNICODE_MAP && record->event.pressed) { | ||
| 97 | const uint32_t* map = unicode_map; | ||
| 98 | uint16_t index = keycode & 0x7FF; | ||
| 99 | unicode_input_start(); | ||
| 100 | register_hex32(pgm_read_dword_far(&map[index])); | ||
| 101 | unicode_input_finish(); | ||
| 102 | } | ||
| 103 | return true; | ||
| 104 | } | ||
| 105 | #endif | ||
| 106 | |||
| 107 | #ifdef UCIS_ENABLE | ||
| 108 | qk_ucis_state_t qk_ucis_state; | ||
| 109 | |||
| 110 | void qk_ucis_start(void) { | ||
| 111 | qk_ucis_state.count = 0; | ||
| 112 | qk_ucis_state.in_progress = true; | ||
| 113 | |||
| 114 | qk_ucis_start_user(); | ||
| 115 | } | ||
| 116 | |||
| 117 | __attribute__((weak)) | ||
| 118 | void qk_ucis_start_user(void) { | ||
| 119 | unicode_input_start(); | ||
| 120 | register_hex(0x2328); | ||
| 121 | unicode_input_finish(); | ||
| 122 | } | ||
| 123 | |||
| 124 | static bool is_uni_seq(char *seq) { | ||
| 125 | uint8_t i; | ||
| 126 | |||
| 127 | for (i = 0; seq[i]; i++) { | ||
| 128 | uint16_t code; | ||
| 129 | if (('1' <= seq[i]) && (seq[i] <= '0')) | ||
| 130 | code = seq[i] - '1' + KC_1; | ||
| 131 | else | ||
| 132 | code = seq[i] - 'a' + KC_A; | ||
| 133 | |||
| 134 | if (i > qk_ucis_state.count || qk_ucis_state.codes[i] != code) | ||
| 135 | return false; | ||
| 136 | } | ||
| 137 | |||
| 138 | return (qk_ucis_state.codes[i] == KC_ENT || | ||
| 139 | qk_ucis_state.codes[i] == KC_SPC); | ||
| 140 | } | ||
| 141 | |||
| 142 | __attribute__((weak)) | ||
| 143 | void qk_ucis_symbol_fallback (void) { | ||
| 144 | for (uint8_t i = 0; i < qk_ucis_state.count - 1; i++) { | ||
| 145 | uint8_t code = qk_ucis_state.codes[i]; | ||
| 146 | register_code(code); | ||
| 147 | unregister_code(code); | ||
| 148 | wait_ms(UNICODE_TYPE_DELAY); | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | void register_ucis(const char *hex) { | ||
| 153 | for(int i = 0; hex[i]; i++) { | ||
| 154 | uint8_t kc = 0; | ||
| 155 | char c = hex[i]; | ||
| 156 | |||
| 157 | switch (c) { | ||
| 158 | case '0': | ||
| 159 | kc = KC_0; | ||
| 160 | break; | ||
| 161 | case '1' ... '9': | ||
| 162 | kc = c - '1' + KC_1; | ||
| 163 | break; | ||
| 164 | case 'a' ... 'f': | ||
| 165 | kc = c - 'a' + KC_A; | ||
| 166 | break; | ||
| 167 | case 'A' ... 'F': | ||
| 168 | kc = c - 'A' + KC_A; | ||
| 169 | break; | ||
| 170 | } | ||
| 171 | |||
| 172 | if (kc) { | ||
| 173 | register_code (kc); | ||
| 174 | unregister_code (kc); | ||
| 175 | wait_ms (UNICODE_TYPE_DELAY); | ||
| 176 | } | ||
| 177 | } | ||
| 178 | } | ||
| 179 | |||
| 180 | bool process_ucis (uint16_t keycode, keyrecord_t *record) { | ||
| 181 | uint8_t i; | ||
| 182 | |||
| 183 | if (!qk_ucis_state.in_progress) | ||
| 184 | return true; | ||
| 185 | |||
| 186 | if (qk_ucis_state.count >= UCIS_MAX_SYMBOL_LENGTH && | ||
| 187 | !(keycode == KC_BSPC || keycode == KC_ESC || keycode == KC_SPC || keycode == KC_ENT)) { | ||
| 188 | return false; | ||
| 189 | } | ||
| 190 | |||
| 191 | if (!record->event.pressed) | ||
| 192 | return true; | ||
| 193 | |||
| 194 | qk_ucis_state.codes[qk_ucis_state.count] = keycode; | ||
| 195 | qk_ucis_state.count++; | ||
| 196 | |||
| 197 | if (keycode == KC_BSPC) { | ||
| 198 | if (qk_ucis_state.count >= 2) { | ||
| 199 | qk_ucis_state.count -= 2; | ||
| 200 | return true; | ||
| 201 | } else { | ||
| 202 | qk_ucis_state.count--; | ||
| 203 | return false; | ||
| 204 | } | ||
| 205 | } | ||
| 206 | |||
| 207 | if (keycode == KC_ENT || keycode == KC_SPC || keycode == KC_ESC) { | ||
| 208 | bool symbol_found = false; | ||
| 209 | |||
| 210 | for (i = qk_ucis_state.count; i > 0; i--) { | ||
| 211 | register_code (KC_BSPC); | ||
| 212 | unregister_code (KC_BSPC); | ||
| 213 | wait_ms(UNICODE_TYPE_DELAY); | ||
| 214 | } | ||
| 215 | |||
| 216 | if (keycode == KC_ESC) { | ||
| 217 | qk_ucis_state.in_progress = false; | ||
| 218 | return false; | ||
| 219 | } | ||
| 220 | |||
| 221 | unicode_input_start(); | ||
| 222 | for (i = 0; ucis_symbol_table[i].symbol; i++) { | ||
| 223 | if (is_uni_seq (ucis_symbol_table[i].symbol)) { | ||
| 224 | symbol_found = true; | ||
| 225 | register_ucis(ucis_symbol_table[i].code + 2); | ||
| 226 | break; | ||
| 227 | } | ||
| 228 | } | ||
| 229 | if (!symbol_found) { | ||
| 230 | qk_ucis_symbol_fallback(); | ||
| 231 | } | ||
| 232 | unicode_input_finish(); | ||
| 233 | |||
| 234 | qk_ucis_state.in_progress = false; | ||
| 235 | return false; | ||
| 236 | } | ||
| 237 | return true; | ||
| 238 | } | ||
| 239 | #endif | ||
diff --git a/quantum/process_keycode/process_unicode.h b/quantum/process_keycode/process_unicode.h new file mode 100644 index 000000000..a6c7e4584 --- /dev/null +++ b/quantum/process_keycode/process_unicode.h | |||
| @@ -0,0 +1,165 @@ | |||
| 1 | #ifndef PROCESS_UNICODE_H | ||
| 2 | #define PROCESS_UNICODE_H | ||
| 3 | |||
| 4 | #include "quantum.h" | ||
| 5 | |||
| 6 | #define UC_OSX 0 | ||
| 7 | #define UC_LNX 1 | ||
| 8 | #define UC_WIN 2 | ||
| 9 | #define UC_BSD 3 | ||
| 10 | |||
| 11 | #ifndef UNICODE_TYPE_DELAY | ||
| 12 | #define UNICODE_TYPE_DELAY 10 | ||
| 13 | #endif | ||
| 14 | |||
| 15 | void set_unicode_input_mode(uint8_t os_target); | ||
| 16 | uint8_t get_unicode_input_mode(void); | ||
| 17 | void unicode_input_start(void); | ||
| 18 | void unicode_input_finish(void); | ||
| 19 | void register_hex(uint16_t hex); | ||
| 20 | |||
| 21 | bool process_unicode(uint16_t keycode, keyrecord_t *record); | ||
| 22 | |||
| 23 | #ifdef UNICODEMAP_ENABLE | ||
| 24 | bool process_unicode_map(uint16_t keycode, keyrecord_t *record); | ||
| 25 | #endif | ||
| 26 | |||
| 27 | #ifdef UCIS_ENABLE | ||
| 28 | #ifndef UCIS_MAX_SYMBOL_LENGTH | ||
| 29 | #define UCIS_MAX_SYMBOL_LENGTH 32 | ||
| 30 | #endif | ||
| 31 | |||
| 32 | typedef struct { | ||
| 33 | char *symbol; | ||
| 34 | char *code; | ||
| 35 | } qk_ucis_symbol_t; | ||
| 36 | |||
| 37 | typedef struct { | ||
| 38 | uint8_t count; | ||
| 39 | uint16_t codes[UCIS_MAX_SYMBOL_LENGTH]; | ||
| 40 | bool in_progress:1; | ||
| 41 | } qk_ucis_state_t; | ||
| 42 | |||
| 43 | extern qk_ucis_state_t qk_ucis_state; | ||
| 44 | |||
| 45 | #define UCIS_TABLE(...) {__VA_ARGS__, {NULL, NULL}} | ||
| 46 | #define UCIS_SYM(name, code) {name, #code} | ||
| 47 | |||
| 48 | extern const qk_ucis_symbol_t ucis_symbol_table[]; | ||
| 49 | |||
| 50 | void qk_ucis_start(void); | ||
| 51 | void qk_ucis_start_user(void); | ||
| 52 | void qk_ucis_symbol_fallback (void); | ||
| 53 | void register_ucis(const char *hex); | ||
| 54 | bool process_ucis (uint16_t keycode, keyrecord_t *record); | ||
| 55 | |||
| 56 | #endif | ||
| 57 | |||
| 58 | #define UC_BSPC UC(0x0008) | ||
| 59 | |||
| 60 | #define UC_SPC UC(0x0020) | ||
| 61 | |||
| 62 | #define UC_EXLM UC(0x0021) | ||
| 63 | #define UC_DQUT UC(0x0022) | ||
| 64 | #define UC_HASH UC(0x0023) | ||
| 65 | #define UC_DLR UC(0x0024) | ||
| 66 | #define UC_PERC UC(0x0025) | ||
| 67 | #define UC_AMPR UC(0x0026) | ||
| 68 | #define UC_QUOT UC(0x0027) | ||
| 69 | #define UC_LPRN UC(0x0028) | ||
| 70 | #define UC_RPRN UC(0x0029) | ||
| 71 | #define UC_ASTR UC(0x002A) | ||
| 72 | #define UC_PLUS UC(0x002B) | ||
| 73 | #define UC_COMM UC(0x002C) | ||
| 74 | #define UC_DASH UC(0x002D) | ||
| 75 | #define UC_DOT UC(0x002E) | ||
| 76 | #define UC_SLSH UC(0x002F) | ||
| 77 | |||
| 78 | #define UC_0 UC(0x0030) | ||
| 79 | #define UC_1 UC(0x0031) | ||
| 80 | #define UC_2 UC(0x0032) | ||
| 81 | #define UC_3 UC(0x0033) | ||
| 82 | #define UC_4 UC(0x0034) | ||
| 83 | #define UC_5 UC(0x0035) | ||
| 84 | #define UC_6 UC(0x0036) | ||
| 85 | #define UC_7 UC(0x0037) | ||
| 86 | #define UC_8 UC(0x0038) | ||
| 87 | #define UC_9 UC(0x0039) | ||
| 88 | |||
| 89 | #define UC_COLN UC(0x003A) | ||
| 90 | #define UC_SCLN UC(0x003B) | ||
| 91 | #define UC_LT UC(0x003C) | ||
| 92 | #define UC_EQL UC(0x003D) | ||
| 93 | #define UC_GT UC(0x003E) | ||
| 94 | #define UC_QUES UC(0x003F) | ||
| 95 | #define UC_AT UC(0x0040) | ||
| 96 | |||
| 97 | #define UC_A UC(0x0041) | ||
| 98 | #define UC_B UC(0x0042) | ||
| 99 | #define UC_C UC(0x0043) | ||
| 100 | #define UC_D UC(0x0044) | ||
| 101 | #define UC_E UC(0x0045) | ||
| 102 | #define UC_F UC(0x0046) | ||
| 103 | #define UC_G UC(0x0047) | ||
| 104 | #define UC_H UC(0x0048) | ||
| 105 | #define UC_I UC(0x0049) | ||
| 106 | #define UC_J UC(0x004A) | ||
| 107 | #define UC_K UC(0x004B) | ||
| 108 | #define UC_L UC(0x004C) | ||
| 109 | #define UC_M UC(0x004D) | ||
| 110 | #define UC_N UC(0x004E) | ||
| 111 | #define UC_O UC(0x004F) | ||
| 112 | #define UC_P UC(0x0050) | ||
| 113 | #define UC_Q UC(0x0051) | ||
| 114 | #define UC_R UC(0x0052) | ||
| 115 | #define UC_S UC(0x0053) | ||
| 116 | #define UC_T UC(0x0054) | ||
| 117 | #define UC_U UC(0x0055) | ||
| 118 | #define UC_V UC(0x0056) | ||
| 119 | #define UC_W UC(0x0057) | ||
| 120 | #define UC_X UC(0x0058) | ||
| 121 | #define UC_Y UC(0x0059) | ||
| 122 | #define UC_Z UC(0x005A) | ||
| 123 | |||
| 124 | #define UC_LBRC UC(0x005B) | ||
| 125 | #define UC_BSLS UC(0x005C) | ||
| 126 | #define UC_RBRC UC(0x005D) | ||
| 127 | #define UC_CIRM UC(0x005E) | ||
| 128 | #define UC_UNDR UC(0x005F) | ||
| 129 | |||
| 130 | #define UC_GRV UC(0x0060) | ||
| 131 | |||
| 132 | #define UC_a UC(0x0061) | ||
| 133 | #define UC_b UC(0x0062) | ||
| 134 | #define UC_c UC(0x0063) | ||
| 135 | #define UC_d UC(0x0064) | ||
| 136 | #define UC_e UC(0x0065) | ||
| 137 | #define UC_f UC(0x0066) | ||
| 138 | #define UC_g UC(0x0067) | ||
| 139 | #define UC_h UC(0x0068) | ||
| 140 | #define UC_i UC(0x0069) | ||
| 141 | #define UC_j UC(0x006A) | ||
| 142 | #define UC_k UC(0x006B) | ||
| 143 | #define UC_l UC(0x006C) | ||
| 144 | #define UC_m UC(0x006D) | ||
| 145 | #define UC_n UC(0x006E) | ||
| 146 | #define UC_o UC(0x006F) | ||
| 147 | #define UC_p UC(0x0070) | ||
| 148 | #define UC_q UC(0x0071) | ||
| 149 | #define UC_r UC(0x0072) | ||
| 150 | #define UC_s UC(0x0073) | ||
| 151 | #define UC_t UC(0x0074) | ||
| 152 | #define UC_u UC(0x0075) | ||
| 153 | #define UC_v UC(0x0076) | ||
| 154 | #define UC_w UC(0x0077) | ||
| 155 | #define UC_x UC(0x0078) | ||
| 156 | #define UC_y UC(0x0079) | ||
| 157 | #define UC_z UC(0x007A) | ||
| 158 | |||
| 159 | #define UC_LCBR UC(0x007B) | ||
| 160 | #define UC_PIPE UC(0x007C) | ||
| 161 | #define UC_RCBR UC(0x007D) | ||
| 162 | #define UC_TILD UC(0x007E) | ||
| 163 | #define UC_DEL UC(0x007F) | ||
| 164 | |||
| 165 | #endif | ||
