|
@@ -0,0 +1,120 @@
|
|
|
+
|
|
|
+ *
|
|
|
+ * This program is free software: you can redistribute it and/or modify
|
|
|
+ * it under the terms of the GNU General Public License as published by
|
|
|
+ * the Free Software Foundation, either version 2 of the License, or
|
|
|
+ * (at your option) any later version.
|
|
|
+ *
|
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
+ * GNU General Public License for more details.
|
|
|
+ *
|
|
|
+ * You should have received a copy of the GNU General Public License
|
|
|
+ * along with this program. If not, see <http:
|
|
|
+ */
|
|
|
+
|
|
|
+#include "inttypes.h"
|
|
|
+#include "stdint.h"
|
|
|
+#include "process_key_lock.h"
|
|
|
+
|
|
|
+#define SHIFT(shift) (((uint64_t)1) << (shift))
|
|
|
+#define GET_KEY_ARRAY(code) (((code) < 0x40) ? key_state[0] : \
|
|
|
+ ((code) < 0x80) ? key_state[1] : \
|
|
|
+ ((code) < 0xC0) ? key_state[2] : key_state[3])
|
|
|
+#define GET_CODE_INDEX(code) (((code) < 0x40) ? (code) : \
|
|
|
+ ((code) < 0x80) ? (code) - 0x40 : \
|
|
|
+ ((code) < 0xC0) ? (code) - 0x80 : (code) - 0xC0)
|
|
|
+#define KEY_STATE(code) (GET_KEY_ARRAY(code) & SHIFT(GET_CODE_INDEX(code))) == SHIFT(GET_CODE_INDEX(code))
|
|
|
+#define SET_KEY_ARRAY_STATE(code, val) do { \
|
|
|
+ switch (code) { \
|
|
|
+ case 0x00 ... 0x3F: \
|
|
|
+ key_state[0] = (val); \
|
|
|
+ break; \
|
|
|
+ case 0x40 ... 0x7F: \
|
|
|
+ key_state[1] = (val); \
|
|
|
+ break; \
|
|
|
+ case 0x80 ... 0xBF: \
|
|
|
+ key_state[2] = (val); \
|
|
|
+ break; \
|
|
|
+ case 0xC0 ... 0xFF: \
|
|
|
+ key_state[3] = (val); \
|
|
|
+ break; \
|
|
|
+ } \
|
|
|
+} while(0)
|
|
|
+#define SET_KEY_STATE(code) SET_KEY_ARRAY_STATE(code, (GET_KEY_ARRAY(code) | SHIFT(GET_CODE_INDEX(code))))
|
|
|
+#define UNSET_KEY_STATE(code) SET_KEY_ARRAY_STATE(code, (GET_KEY_ARRAY(code)) & ~(SHIFT(GET_CODE_INDEX(code))))
|
|
|
+#define IS_STANDARD_KEYCODE(code) ((code) <= 0xFF)
|
|
|
+#define print_hex64(num) do { print_hex32((num & 0xFFFFFFFF00000000) >> 32); print_hex32(num & 0x00000000FFFFFFFF); } while (0)
|
|
|
+
|
|
|
+
|
|
|
+uint64_t key_state[4] = { 0x0, 0x0, 0x0, 0x0 };
|
|
|
+bool watching = false;
|
|
|
+
|
|
|
+bool process_key_lock(uint16_t keycode, keyrecord_t *record) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (record->event.pressed) {
|
|
|
+
|
|
|
+ if (!(IS_STANDARD_KEYCODE(keycode) || keycode == KC_LOCK)) {
|
|
|
+ watching = false;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (keycode == KC_LOCK) {
|
|
|
+ watching = !watching;
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (IS_STANDARD_KEYCODE(keycode)) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (watching) {
|
|
|
+ watching = false;
|
|
|
+ SET_KEY_STATE(keycode);
|
|
|
+
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (KEY_STATE(keycode)) {
|
|
|
+ UNSET_KEY_STATE(keycode);
|
|
|
+
|
|
|
+
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+
|
|
|
+ return !(IS_STANDARD_KEYCODE(keycode) && KEY_STATE(keycode));
|
|
|
+ }
|
|
|
+}
|