Merge pull request #6 from xdever/modifier_mask
Fix the bug of additional characters when mod key is released before the other key.
This commit is contained in:
83
right/src/keyboard_layout.c
Normal file
83
right/src/keyboard_layout.c
Normal file
@@ -0,0 +1,83 @@
|
||||
#include "keyboard_layout.h"
|
||||
|
||||
static uint8_t keyMasks[LAYOUT_KEY_COUNT];
|
||||
|
||||
static inline __attribute__((always_inline)) uint8_t getKeycode(KEYBOARD_LAYOUT(layout), uint8_t keyId, uint8_t modifierState)
|
||||
{
|
||||
if (keyId<LAYOUT_KEY_COUNT) {
|
||||
if (keyMasks[keyId]!=0 && keyMasks[keyId]!=modifierState){
|
||||
//Mask out key presses after releasing modifier keys
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t k = layout[keyId][modifierState];
|
||||
keyMasks[keyId] = modifierState;
|
||||
|
||||
if (k==0) {
|
||||
k = layout[keyId][0];
|
||||
}
|
||||
|
||||
return k;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static uint8_t getModifierState(const uint8_t *leftKeyStates, const uint8_t *rightKeyStates){
|
||||
uint8_t mod = 0;
|
||||
if (leftKeyStates[KEYID_LEFT_MOD]) {
|
||||
mod |= MODIFIER_MOD_PRESSED;
|
||||
}
|
||||
if (leftKeyStates[KEYID_LEFT_FN] | rightKeyStates[KEYID_RIGHT_FN]) {
|
||||
mod |= MODIFIER_FN_PRESSED;
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
|
||||
static void clearKeymasks(const uint8_t *leftKeyStates, const uint8_t *rightKeyStates){
|
||||
int i;
|
||||
for (i=0; i<KEY_STATE_COUNT; ++i){
|
||||
if (rightKeyStates[i]==0){
|
||||
keyMasks[i] = 0;
|
||||
}
|
||||
|
||||
if (leftKeyStates[i]==0){
|
||||
keyMasks[LAYOUT_LEFT_OFFSET+i] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void fillKeyboardReport(usb_keyboard_report_t *report, const uint8_t *leftKeyStates, const uint8_t *rightKeyStates, KEYBOARD_LAYOUT(layout)){
|
||||
int scancodeIdx = 0;
|
||||
|
||||
clearKeymasks(leftKeyStates, rightKeyStates);
|
||||
uint8_t modifierState=getModifierState(leftKeyStates, rightKeyStates);
|
||||
|
||||
for (uint8_t keyId=0; keyId<KEY_STATE_COUNT; keyId++) {
|
||||
if (scancodeIdx>=USB_KEYBOARD_MAX_KEYS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (rightKeyStates[keyId]) {
|
||||
uint8_t code=getKeycode(layout, keyId, modifierState);
|
||||
if (code) {
|
||||
report->scancodes[scancodeIdx++] = code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t keyId=0; keyId<KEY_STATE_COUNT; keyId++) {
|
||||
if (scancodeIdx>=USB_KEYBOARD_MAX_KEYS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (leftKeyStates[keyId]) {
|
||||
uint8_t code=getKeycode(layout, LAYOUT_LEFT_OFFSET+keyId, modifierState);
|
||||
if (code) {
|
||||
report->scancodes[scancodeIdx++] = code;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include "lufa/HIDClassCommon.h"
|
||||
#include "usb_composite_device.h"
|
||||
|
||||
/**
|
||||
* Keyboard layout is a 2D array of scan codes.
|
||||
@@ -35,31 +36,6 @@
|
||||
#define MODIFIER_MOD_PRESSED 1
|
||||
#define MODIFIER_FN_PRESSED 2
|
||||
|
||||
|
||||
static inline __attribute__((always_inline)) uint8_t getKeycode(KEYBOARD_LAYOUT(layout), uint8_t keyId, uint8_t modifierState)
|
||||
{
|
||||
if (keyId<LAYOUT_KEY_COUNT) {
|
||||
uint8_t k = layout[keyId][modifierState];
|
||||
if (k==0) {
|
||||
k = layout[keyId][0];
|
||||
}
|
||||
|
||||
return k;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static inline __attribute__((always_inline)) uint8_t getModifierState(const uint8_t *leftKeyStates, const uint8_t *rightKeyStates){
|
||||
uint8_t mod = 0;
|
||||
if (leftKeyStates[KEYID_LEFT_MOD]) {
|
||||
mod |= MODIFIER_MOD_PRESSED;
|
||||
}
|
||||
if (leftKeyStates[KEYID_LEFT_FN] | rightKeyStates[KEYID_RIGHT_FN]) {
|
||||
mod |= MODIFIER_FN_PRESSED;
|
||||
}
|
||||
|
||||
return mod;
|
||||
}
|
||||
void fillKeyboardReport(usb_keyboard_report_t *report, const uint8_t *leftKeyStates, const uint8_t *rightKeyStates, KEYBOARD_LAYOUT(layout));
|
||||
|
||||
#endif
|
||||
|
||||
@@ -41,7 +41,7 @@ usb_device_class_struct_t UsbKeyboardClass = {
|
||||
};
|
||||
|
||||
volatile static int activeLayout=0;
|
||||
volatile static usb_keyboard_report_t UsbKeyboardReport[2];
|
||||
static usb_keyboard_report_t UsbKeyboardReport[2];
|
||||
|
||||
#define KEYBOARD_MATRIX_COLS_NUM 7
|
||||
#define KEYBOARD_MATRIX_ROWS_NUM 5
|
||||
@@ -100,34 +100,7 @@ void usbKeyboadTask(){
|
||||
|
||||
readLeftKeys(leftKeyStates);
|
||||
|
||||
uint8_t modifierState = getModifierState(leftKeyStates, keyMatrix.keyStates);
|
||||
|
||||
int scancodeIdx = 0;
|
||||
for (uint8_t keyId=0; keyId<KEYBOARD_MATRIX_COLS_NUM*KEYBOARD_MATRIX_ROWS_NUM; keyId++) {
|
||||
if (scancodeIdx>=USB_KEYBOARD_MAX_KEYS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (keyMatrix.keyStates[keyId]) {
|
||||
uint8_t code=getKeycode(defaultKeyboardLayout, keyId, modifierState);
|
||||
if (code) {
|
||||
UsbKeyboardReport[newLayout].scancodes[scancodeIdx++] = code;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (uint8_t keyId=0; keyId<KEY_STATE_COUNT; keyId++) {
|
||||
if (scancodeIdx>=USB_KEYBOARD_MAX_KEYS) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (leftKeyStates[keyId]) {
|
||||
uint8_t code=getKeycode(defaultKeyboardLayout, LAYOUT_LEFT_OFFSET+keyId, modifierState);
|
||||
if (code) {
|
||||
UsbKeyboardReport[newLayout].scancodes[scancodeIdx++] = code;
|
||||
}
|
||||
}
|
||||
}
|
||||
fillKeyboardReport(&UsbKeyboardReport[newLayout], leftKeyStates, keyMatrix.keyStates, defaultKeyboardLayout);
|
||||
|
||||
//Change to the new layout in atomic operation (int copy). Even if
|
||||
//the copy is not atomic itself, only single bit changes. So it can
|
||||
|
||||
Reference in New Issue
Block a user