|
|
@ -25,13 +25,6 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
|
|
extern keymap_config_t keymap_config; |
|
|
|
|
|
|
|
|
|
|
|
static inline void add_key_byte(uint8_t code); |
|
|
|
static inline void del_key_byte(uint8_t code); |
|
|
|
#ifdef NKRO_ENABLE |
|
|
|
static inline void add_key_bit(uint8_t code); |
|
|
|
static inline void del_key_bit(uint8_t code); |
|
|
|
#endif |
|
|
|
|
|
|
|
static uint8_t real_mods = 0; |
|
|
|
static uint8_t weak_mods = 0; |
|
|
|
static uint8_t macro_mods = 0; |
|
|
@ -134,7 +127,7 @@ void send_keyboard_report(void) { |
|
|
|
} |
|
|
|
#endif |
|
|
|
keyboard_report->mods |= oneshot_mods; |
|
|
|
if (has_anykey()) { |
|
|
|
if (has_anykey(keyboard_report)) { |
|
|
|
clear_oneshot_mods(); |
|
|
|
} |
|
|
|
} |
|
|
@ -148,22 +141,22 @@ void add_key(uint8_t key) |
|
|
|
{ |
|
|
|
#ifdef NKRO_ENABLE |
|
|
|
if (keyboard_protocol && keymap_config.nkro) { |
|
|
|
add_key_bit(key); |
|
|
|
add_key_bit(keyboard_report, key); |
|
|
|
return; |
|
|
|
} |
|
|
|
#endif |
|
|
|
add_key_byte(key); |
|
|
|
add_key_byte(keyboard_report, key); |
|
|
|
} |
|
|
|
|
|
|
|
void del_key(uint8_t key) |
|
|
|
{ |
|
|
|
#ifdef NKRO_ENABLE |
|
|
|
if (keyboard_protocol && keymap_config.nkro) { |
|
|
|
del_key_bit(key); |
|
|
|
del_key_bit(keyboard_report, key); |
|
|
|
return; |
|
|
|
} |
|
|
|
#endif |
|
|
|
del_key_byte(key); |
|
|
|
del_key_byte(keyboard_report, key); |
|
|
|
} |
|
|
|
|
|
|
|
void clear_keys(void) |
|
|
@ -221,166 +214,7 @@ uint8_t get_oneshot_mods(void) |
|
|
|
/* |
|
|
|
* inspect keyboard state |
|
|
|
*/ |
|
|
|
uint8_t has_anykey(void) |
|
|
|
{ |
|
|
|
uint8_t cnt = 0; |
|
|
|
for (uint8_t i = 1; i < KEYBOARD_REPORT_SIZE; i++) { |
|
|
|
if (keyboard_report->raw[i]) |
|
|
|
cnt++; |
|
|
|
} |
|
|
|
return cnt; |
|
|
|
} |
|
|
|
|
|
|
|
uint8_t has_anymod(void) |
|
|
|
{ |
|
|
|
return bitpop(real_mods); |
|
|
|
} |
|
|
|
|
|
|
|
uint8_t get_first_key(void) |
|
|
|
{ |
|
|
|
#ifdef NKRO_ENABLE |
|
|
|
if (keyboard_protocol && keymap_config.nkro) { |
|
|
|
uint8_t i = 0; |
|
|
|
for (; i < KEYBOARD_REPORT_BITS && !keyboard_report->nkro.bits[i]; i++) |
|
|
|
; |
|
|
|
return i<<3 | biton(keyboard_report->nkro.bits[i]); |
|
|
|
} |
|
|
|
#endif |
|
|
|
#ifdef USB_6KRO_ENABLE |
|
|
|
uint8_t i = cb_head; |
|
|
|
do { |
|
|
|
if (keyboard_report->keys[i] != 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
i = RO_INC(i); |
|
|
|
} while (i != cb_tail); |
|
|
|
return keyboard_report->keys[i]; |
|
|
|
#else |
|
|
|
return keyboard_report->keys[0]; |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* local functions */ |
|
|
|
static inline void add_key_byte(uint8_t code) |
|
|
|
{ |
|
|
|
#ifdef USB_6KRO_ENABLE |
|
|
|
int8_t i = cb_head; |
|
|
|
int8_t empty = -1; |
|
|
|
if (cb_count) { |
|
|
|
do { |
|
|
|
if (keyboard_report->keys[i] == code) { |
|
|
|
return; |
|
|
|
} |
|
|
|
if (empty == -1 && keyboard_report->keys[i] == 0) { |
|
|
|
empty = i; |
|
|
|
} |
|
|
|
i = RO_INC(i); |
|
|
|
} while (i != cb_tail); |
|
|
|
if (i == cb_tail) { |
|
|
|
if (cb_tail == cb_head) { |
|
|
|
// buffer is full |
|
|
|
if (empty == -1) { |
|
|
|
// pop head when has no empty space |
|
|
|
cb_head = RO_INC(cb_head); |
|
|
|
cb_count--; |
|
|
|
} |
|
|
|
else { |
|
|
|
// left shift when has empty space |
|
|
|
uint8_t offset = 1; |
|
|
|
i = RO_INC(empty); |
|
|
|
do { |
|
|
|
if (keyboard_report->keys[i] != 0) { |
|
|
|
keyboard_report->keys[empty] = keyboard_report->keys[i]; |
|
|
|
keyboard_report->keys[i] = 0; |
|
|
|
empty = RO_INC(empty); |
|
|
|
} |
|
|
|
else { |
|
|
|
offset++; |
|
|
|
} |
|
|
|
i = RO_INC(i); |
|
|
|
} while (i != cb_tail); |
|
|
|
cb_tail = RO_SUB(cb_tail, offset); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
// add to tail |
|
|
|
keyboard_report->keys[cb_tail] = code; |
|
|
|
cb_tail = RO_INC(cb_tail); |
|
|
|
cb_count++; |
|
|
|
#else |
|
|
|
int8_t i = 0; |
|
|
|
int8_t empty = -1; |
|
|
|
for (; i < KEYBOARD_REPORT_KEYS; i++) { |
|
|
|
if (keyboard_report->keys[i] == code) { |
|
|
|
break; |
|
|
|
} |
|
|
|
if (empty == -1 && keyboard_report->keys[i] == 0) { |
|
|
|
empty = i; |
|
|
|
} |
|
|
|
} |
|
|
|
if (i == KEYBOARD_REPORT_KEYS) { |
|
|
|
if (empty != -1) { |
|
|
|
keyboard_report->keys[empty] = code; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
static inline void del_key_byte(uint8_t code) |
|
|
|
{ |
|
|
|
#ifdef USB_6KRO_ENABLE |
|
|
|
uint8_t i = cb_head; |
|
|
|
if (cb_count) { |
|
|
|
do { |
|
|
|
if (keyboard_report->keys[i] == code) { |
|
|
|
keyboard_report->keys[i] = 0; |
|
|
|
cb_count--; |
|
|
|
if (cb_count == 0) { |
|
|
|
// reset head and tail |
|
|
|
cb_tail = cb_head = 0; |
|
|
|
} |
|
|
|
if (i == RO_DEC(cb_tail)) { |
|
|
|
// left shift when next to tail |
|
|
|
do { |
|
|
|
cb_tail = RO_DEC(cb_tail); |
|
|
|
if (keyboard_report->keys[RO_DEC(cb_tail)] != 0) { |
|
|
|
break; |
|
|
|
} |
|
|
|
} while (cb_tail != cb_head); |
|
|
|
} |
|
|
|
break; |
|
|
|
} |
|
|
|
i = RO_INC(i); |
|
|
|
} while (i != cb_tail); |
|
|
|
} |
|
|
|
#else |
|
|
|
for (uint8_t i = 0; i < KEYBOARD_REPORT_KEYS; i++) { |
|
|
|
if (keyboard_report->keys[i] == code) { |
|
|
|
keyboard_report->keys[i] = 0; |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |
|
|
|
} |
|
|
|
|
|
|
|
#ifdef NKRO_ENABLE |
|
|
|
static inline void add_key_bit(uint8_t code) |
|
|
|
{ |
|
|
|
if ((code>>3) < KEYBOARD_REPORT_BITS) { |
|
|
|
keyboard_report->nkro.bits[code>>3] |= 1<<(code&7); |
|
|
|
} else { |
|
|
|
dprintf("add_key_bit: can't add: %02X\n", code); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static inline void del_key_bit(uint8_t code) |
|
|
|
{ |
|
|
|
if ((code>>3) < KEYBOARD_REPORT_BITS) { |
|
|
|
keyboard_report->nkro.bits[code>>3] &= ~(1<<(code&7)); |
|
|
|
} else { |
|
|
|
dprintf("del_key_bit: can't del: %02X\n", code); |
|
|
|
} |
|
|
|
} |
|
|
|
#endif |