Merge pull request #26 from algernon/f/mouse-actions
Mouse action handling
This commit is contained in:
201
right/src/action.c
Normal file
201
right/src/action.c
Normal file
@@ -0,0 +1,201 @@
|
|||||||
|
#include "action.h"
|
||||||
|
#include "led_display.h"
|
||||||
|
#include "layer.h"
|
||||||
|
#include "usb_interface_mouse.h"
|
||||||
|
|
||||||
|
static uint8_t keyMasks[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
||||||
|
|
||||||
|
static uint8_t ActiveLayer = LAYER_ID_BASE;
|
||||||
|
uint8_t prevKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
||||||
|
|
||||||
|
static inline __attribute__((always_inline)) uhk_key_t getKeycode(uint8_t slotId, uint8_t keyId)
|
||||||
|
{
|
||||||
|
if (keyId < MAX_KEY_COUNT_PER_MODULE) {
|
||||||
|
if (keyMasks[slotId][keyId]!=0 && keyMasks[slotId][keyId]!=ActiveLayer) {
|
||||||
|
// Mask out key presses after releasing modifier keys
|
||||||
|
return (uhk_key_t){.type = UHK_KEY_NONE};
|
||||||
|
}
|
||||||
|
|
||||||
|
uhk_key_t k = CurrentKeymap[ActiveLayer][slotId][keyId];
|
||||||
|
keyMasks[slotId][keyId] = ActiveLayer;
|
||||||
|
|
||||||
|
return k;
|
||||||
|
} else {
|
||||||
|
return (uhk_key_t){.type = UHK_KEY_NONE};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clearKeymasks(const uint8_t *leftKeyStates, const uint8_t *rightKeyStates){
|
||||||
|
int i;
|
||||||
|
for (i=0; i < MAX_KEY_COUNT_PER_MODULE; i++){
|
||||||
|
if (rightKeyStates[i]==0){
|
||||||
|
keyMasks[SLOT_ID_RIGHT_KEYBOARD_HALF][i] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftKeyStates[i]==0) {
|
||||||
|
keyMasks[SLOT_ID_LEFT_KEYBOARD_HALF][i] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool pressKey(uhk_key_t key, int scancodeIdx, usb_keyboard_report_t *report) {
|
||||||
|
if (key.type != UHK_KEY_SIMPLE) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!key.simple.key) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
|
if (key.simple.mods & (1 << i) || key.simple.key == HID_KEYBOARD_SC_LEFT_CONTROL + i) {
|
||||||
|
report->modifiers |= (1 << i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
report->scancodes[scancodeIdx] = key.simple.key;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool key_toggled_on(const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId) {
|
||||||
|
return (!prevKeyStates[keyId]) && currKeyStates[keyId];
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool key_is_pressed(const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId) {
|
||||||
|
return currKeyStates[keyId];
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool key_toggled_off(const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId) {
|
||||||
|
return (!currKeyStates[keyId]) && prevKeyStates[keyId];
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool handleKey(uhk_key_t key, int scancodeIdx, usb_keyboard_report_t *report, const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId) {
|
||||||
|
switch (key.type) {
|
||||||
|
case UHK_KEY_SIMPLE:
|
||||||
|
if (key_is_pressed(prevKeyStates, currKeyStates, keyId)) {
|
||||||
|
return pressKey(key, scancodeIdx, report);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case UHK_KEY_LAYER:
|
||||||
|
if (key_toggled_on(prevKeyStates, currKeyStates, keyId)) {
|
||||||
|
ActiveLayer = key.layer.target;
|
||||||
|
}
|
||||||
|
if (key_toggled_off(prevKeyStates, currKeyStates, keyId)) {
|
||||||
|
ActiveLayer = LAYER_ID_BASE;
|
||||||
|
}
|
||||||
|
LedDisplay_SetLayerLed(ActiveLayer);
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint8_t mouseWheelDivisorCounter = 0;
|
||||||
|
static uint8_t mouseSpeedAccelDivisorCounter = 0;
|
||||||
|
static uint8_t mouseSpeed = 3;
|
||||||
|
static bool wasPreviousMouseActionWheelAction = false;
|
||||||
|
|
||||||
|
static void handleMouseKey(usb_mouse_report_t *report, uhk_key_t key, const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId)
|
||||||
|
{
|
||||||
|
bool isWheelAction;
|
||||||
|
|
||||||
|
if (!key_is_pressed(prevKeyStates, currKeyStates, keyId))
|
||||||
|
return;
|
||||||
|
|
||||||
|
isWheelAction = !!(key.mouse.scrollActions) && !(key.mouse.moveActions) && !(key.mouse.buttonActions);
|
||||||
|
|
||||||
|
if (isWheelAction && wasPreviousMouseActionWheelAction) {
|
||||||
|
mouseWheelDivisorCounter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.mouse.scrollActions) {
|
||||||
|
if (mouseWheelDivisorCounter == MOUSE_WHEEL_DIVISOR) {
|
||||||
|
mouseWheelDivisorCounter = 0;
|
||||||
|
if (key.mouse.scrollActions & UHK_MOUSE_SCROLL_UP) {
|
||||||
|
report->wheelX = 1;
|
||||||
|
}
|
||||||
|
if (key.mouse.scrollActions & UHK_MOUSE_SCROLL_DOWN) {
|
||||||
|
report->wheelX = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key.mouse.moveActions & UHK_MOUSE_ACCELERATE || key.mouse.moveActions & UHK_MOUSE_DECELERATE) {
|
||||||
|
mouseSpeedAccelDivisorCounter++;
|
||||||
|
|
||||||
|
if (mouseSpeedAccelDivisorCounter == MOUSE_SPEED_ACCEL_DIVISOR) {
|
||||||
|
mouseSpeedAccelDivisorCounter = 0;
|
||||||
|
|
||||||
|
if (key.mouse.moveActions & UHK_MOUSE_ACCELERATE) {
|
||||||
|
if (mouseSpeed < MOUSE_MAX_SPEED) {
|
||||||
|
mouseSpeed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (key.mouse.moveActions & UHK_MOUSE_DECELERATE) {
|
||||||
|
if (mouseSpeed > 1) {
|
||||||
|
mouseSpeed--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (key.mouse.moveActions) {
|
||||||
|
if (key.mouse.moveActions & UHK_MOUSE_MOVE_LEFT) {
|
||||||
|
report->x = -mouseSpeed;
|
||||||
|
}
|
||||||
|
if (key.mouse.moveActions & UHK_MOUSE_MOVE_RIGHT) {
|
||||||
|
report->x = mouseSpeed;
|
||||||
|
}
|
||||||
|
if (key.mouse.moveActions & UHK_MOUSE_MOVE_UP) {
|
||||||
|
report->y = -mouseSpeed;
|
||||||
|
}
|
||||||
|
if (key.mouse.moveActions & UHK_MOUSE_MOVE_DOWN) {
|
||||||
|
report->y = mouseSpeed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
report->buttons |= key.mouse.buttonActions;
|
||||||
|
|
||||||
|
wasPreviousMouseActionWheelAction = isWheelAction;
|
||||||
|
}
|
||||||
|
|
||||||
|
void HandleKeyboardEvents(usb_keyboard_report_t *keyboardReport, usb_mouse_report_t *mouseReport, const uint8_t *leftKeyStates, const uint8_t *rightKeyStates) {
|
||||||
|
int scancodeIdx = 0;
|
||||||
|
|
||||||
|
clearKeymasks(leftKeyStates, rightKeyStates);
|
||||||
|
|
||||||
|
for (uint8_t keyId=0; keyId<KEY_STATE_COUNT; keyId++) {
|
||||||
|
if (scancodeIdx >= USB_KEYBOARD_MAX_KEYS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uhk_key_t code = getKeycode(SLOT_ID_RIGHT_KEYBOARD_HALF, keyId);
|
||||||
|
|
||||||
|
if (code.type == UHK_KEY_MOUSE) {
|
||||||
|
handleMouseKey(mouseReport, code, prevKeyStates[SLOT_ID_RIGHT_KEYBOARD_HALF], rightKeyStates, keyId);
|
||||||
|
} else {
|
||||||
|
if (handleKey(code, scancodeIdx, keyboardReport, prevKeyStates[SLOT_ID_RIGHT_KEYBOARD_HALF], rightKeyStates, keyId)) {
|
||||||
|
scancodeIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint8_t keyId=0; keyId<KEY_STATE_COUNT; keyId++) {
|
||||||
|
if (scancodeIdx >= USB_KEYBOARD_MAX_KEYS) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
uhk_key_t code = getKeycode(SLOT_ID_LEFT_KEYBOARD_HALF, keyId);
|
||||||
|
|
||||||
|
if (code.type == UHK_KEY_MOUSE) {
|
||||||
|
handleMouseKey(mouseReport, code, prevKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], leftKeyStates, keyId);
|
||||||
|
} else {
|
||||||
|
if (handleKey(code, scancodeIdx, keyboardReport, prevKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], leftKeyStates, keyId)) {
|
||||||
|
scancodeIdx++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memcpy(prevKeyStates[SLOT_ID_RIGHT_KEYBOARD_HALF], rightKeyStates, KEY_STATE_COUNT);
|
||||||
|
memcpy(prevKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], leftKeyStates, KEY_STATE_COUNT);
|
||||||
|
}
|
||||||
@@ -1,39 +1,111 @@
|
|||||||
#ifndef __ACTION_H__
|
#ifndef __UHK_ACTION_H_
|
||||||
#define __ACTION_H__
|
#define __UHK_ACTION_H_
|
||||||
|
|
||||||
// Macros:
|
#include <stdint.h>
|
||||||
|
#include "lufa/HIDClassCommon.h"
|
||||||
|
#include "usb_composite_device.h"
|
||||||
|
|
||||||
// The value of action ID can be any valid HID_KEYBOARD_SC_* scancode constants of LUFA.
|
#include "module.h"
|
||||||
// Hence, ACTION_ID_* values must not conflict with any of the HID_KEYBOARD_SC_* constants.
|
|
||||||
#define ACTION_ID_NONE 0xFF
|
|
||||||
#define ACTION_ID_SWITCH_LAYER 0xFE
|
|
||||||
#define ACTION_ID_MOUSE 0xFD
|
|
||||||
#define ACTION_ID_SWITCH_KEYMAP 0xFC
|
|
||||||
#define ACTION_ID_PLAY_MACRO 0xFB
|
|
||||||
|
|
||||||
#define ACTION_ARG_NONE 0
|
// Keyboard layout is a 2D array of scan codes.
|
||||||
|
//
|
||||||
|
// First dimension is the Key ID of a given key. Key IDs are the indices of the
|
||||||
|
// of the active keys of the key_matrix_t structure. In case of left half, an
|
||||||
|
// offset of 35 is added.
|
||||||
|
//
|
||||||
|
// For each Key ID, there are 4 different possible scan codes:
|
||||||
|
// - default, when no modifiers are pressed
|
||||||
|
// - mod layer
|
||||||
|
// - fn layer
|
||||||
|
// - mod+fn layer
|
||||||
|
|
||||||
#define ACTION_ARG_SWITCH_LAYER_MOD 0
|
#define KEY_STATE_COUNT (5*7)
|
||||||
#define ACTION_ARG_SWITCH_LAYER_FN 1
|
|
||||||
#define ACTION_ARG_SWITCH_LAYER_MOUSE 2
|
|
||||||
|
|
||||||
#define ACTION_ARG_MOUSE_MOVE_UP 0
|
typedef enum {
|
||||||
#define ACTION_ARG_MOUSE_MOVE_DOWN 1
|
UHK_KEY_NONE,
|
||||||
#define ACTION_ARG_MOUSE_MOVE_LEFT 3
|
UHK_KEY_SIMPLE,
|
||||||
#define ACTION_ARG_MOUSE_MOVE_RIGHT 4
|
UHK_KEY_MOUSE,
|
||||||
#define ACTION_ARG_MOUSE_CLICK_LEFT 5
|
UHK_KEY_LAYER,
|
||||||
#define ACTION_ARG_MOUSE_CLICK_MIDDLE 6
|
UHK_KEY_LAYER_TOGGLE,
|
||||||
#define ACTION_ARG_MOUSE_CLICK_RIGHT 7
|
UHK_KEY_KEYMAP,
|
||||||
#define ACTION_ARG_MOUSE_WHEEL_UP 8
|
UHK_KEY_MACRO,
|
||||||
#define ACTION_ARG_MOUSE_WHEEL_DOWN 9
|
UHK_KEY_LPRESSMOD,
|
||||||
#define ACTION_ARG_MOUSE_WHEEL_LEFT 10
|
UHK_KEY_LPRESSLAYER,
|
||||||
#define ACTION_ARG_MOUSE_WHEEL_RIGHT 11
|
} uhk_key_type_t;
|
||||||
|
|
||||||
// Typedefs:
|
enum {
|
||||||
|
UHK_MOUSE_BUTTON_LEFT = (1 << 0),
|
||||||
|
UHK_MOUSE_BUTTON_RIGHT = (1 << 1),
|
||||||
|
UHK_MOUSE_BUTTON_MIDDLE = (1 << 2),
|
||||||
|
UHK_MOUSE_BUTTON_4 = (1 << 3),
|
||||||
|
UHK_MOUSE_BUTTON_5 = (1 << 4),
|
||||||
|
UHK_MOUSE_BUTTON_6 = (1 << 5),
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct {
|
enum {
|
||||||
uint8_t id;
|
UHK_MOUSE_MOVE_UP = (1 << 0),
|
||||||
uint8_t arg;
|
UHK_MOUSE_MOVE_DOWN = (1 << 1),
|
||||||
} action_t;
|
UHK_MOUSE_MOVE_LEFT = (1 << 2),
|
||||||
|
UHK_MOUSE_MOVE_RIGHT = (1 << 3),
|
||||||
|
|
||||||
|
UHK_MOUSE_ACCELERATE = (1 << 4),
|
||||||
|
UHK_MOUSE_DECELERATE = (1 << 5),
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
UHK_MOUSE_SCROLL_UP = (1 << 0),
|
||||||
|
UHK_MOUSE_SCROLL_DOWN = (1 << 1),
|
||||||
|
UHK_MOUSE_SCROLL_LEFT = (1 << 2),
|
||||||
|
UHK_MOUSE_SCROLL_RIGHT = (1 << 3),
|
||||||
|
};
|
||||||
|
|
||||||
|
#define MOUSE_WHEEL_SPEED 1
|
||||||
|
#define MOUSE_WHEEL_DIVISOR 4
|
||||||
|
|
||||||
|
#define MOUSE_MAX_SPEED 10
|
||||||
|
#define MOUSE_SPEED_ACCEL_DIVISOR 50
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t type;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
uint8_t __unused_bits;
|
||||||
|
uint8_t mods;
|
||||||
|
uint8_t key;
|
||||||
|
} __attribute__ ((packed)) simple;
|
||||||
|
struct {
|
||||||
|
uint8_t buttonActions; // bitfield
|
||||||
|
uint8_t scrollActions; // bitfield
|
||||||
|
uint8_t moveActions; // bitfield
|
||||||
|
} __attribute__ ((packed)) mouse;
|
||||||
|
struct {
|
||||||
|
uint16_t __unused_bits;
|
||||||
|
uint8_t target;
|
||||||
|
} __attribute__ ((packed)) layer;
|
||||||
|
struct {
|
||||||
|
uint16_t __unused_bits;
|
||||||
|
uint8_t target;
|
||||||
|
} __attribute__ ((packed)) keymap;
|
||||||
|
struct {
|
||||||
|
uint8_t __unused_bits;
|
||||||
|
uint16_t index;
|
||||||
|
} __attribute__ ((packed)) macro;
|
||||||
|
struct {
|
||||||
|
uint8_t longPressMod; // single mod, or bitfield?
|
||||||
|
uint8_t mods; // for the alternate action
|
||||||
|
uint8_t key;
|
||||||
|
} __attribute__ ((packed)) longpressMod;
|
||||||
|
struct {
|
||||||
|
uint8_t longPressLayer;
|
||||||
|
uint8_t mods;
|
||||||
|
uint8_t key;
|
||||||
|
} __attribute__ ((packed)) longpressLayer;
|
||||||
|
};
|
||||||
|
} __attribute__ ((packed)) uhk_key_t;
|
||||||
|
|
||||||
|
extern uint8_t prevKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
||||||
|
extern uhk_key_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
||||||
|
|
||||||
|
void HandleKeyboardEvents(usb_keyboard_report_t *keyboardReport, usb_mouse_report_t *mouseReport, const uint8_t *leftKeyStates, const uint8_t *rightKeyStates);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#include "keyboard_layout.h"
|
#include "action.h"
|
||||||
|
|
||||||
uhk_key_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] = {
|
uhk_key_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] = {
|
||||||
// Layer 0
|
// Layer 0
|
||||||
|
|||||||
@@ -1,125 +0,0 @@
|
|||||||
#include "keyboard_layout.h"
|
|
||||||
#include "led_display.h"
|
|
||||||
#include "layer.h"
|
|
||||||
|
|
||||||
static uint8_t keyMasks[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
|
||||||
|
|
||||||
static uint8_t ActiveLayer = LAYER_ID_BASE;
|
|
||||||
uint8_t prevKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
|
||||||
|
|
||||||
static inline __attribute__((always_inline)) uhk_key_t getKeycode(uint8_t slotId, uint8_t keyId)
|
|
||||||
{
|
|
||||||
if (keyId < MAX_KEY_COUNT_PER_MODULE) {
|
|
||||||
if (keyMasks[slotId][keyId]!=0 && keyMasks[slotId][keyId]!=ActiveLayer) {
|
|
||||||
// Mask out key presses after releasing modifier keys
|
|
||||||
return (uhk_key_t){.type = UHK_KEY_NONE};
|
|
||||||
}
|
|
||||||
|
|
||||||
uhk_key_t k = CurrentKeymap[ActiveLayer][slotId][keyId];
|
|
||||||
keyMasks[slotId][keyId] = ActiveLayer;
|
|
||||||
|
|
||||||
return k;
|
|
||||||
} else {
|
|
||||||
return (uhk_key_t){.type = UHK_KEY_NONE};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void clearKeymasks(const uint8_t *leftKeyStates, const uint8_t *rightKeyStates){
|
|
||||||
int i;
|
|
||||||
for (i=0; i < MAX_KEY_COUNT_PER_MODULE; i++){
|
|
||||||
if (rightKeyStates[i]==0){
|
|
||||||
keyMasks[SLOT_ID_RIGHT_KEYBOARD_HALF][i] = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (leftKeyStates[i]==0) {
|
|
||||||
keyMasks[SLOT_ID_LEFT_KEYBOARD_HALF][i] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool pressKey(uhk_key_t key, int scancodeIdx, usb_keyboard_report_t *report) {
|
|
||||||
if (key.type != UHK_KEY_SIMPLE) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!key.simple.key) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
|
||||||
if (key.simple.mods & (1 << i) || key.simple.key == HID_KEYBOARD_SC_LEFT_CONTROL + i) {
|
|
||||||
report->modifiers |= (1 << i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
report->scancodes[scancodeIdx] = key.simple.key;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key_toggled_on(const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId) {
|
|
||||||
return (!prevKeyStates[keyId]) && currKeyStates[keyId];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key_is_pressed(const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId) {
|
|
||||||
return currKeyStates[keyId];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool key_toggled_off(const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId) {
|
|
||||||
return (!currKeyStates[keyId]) && prevKeyStates[keyId];
|
|
||||||
}
|
|
||||||
|
|
||||||
bool handleKey(uhk_key_t key, int scancodeIdx, usb_keyboard_report_t *report, const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId) {
|
|
||||||
switch (key.type) {
|
|
||||||
case UHK_KEY_SIMPLE:
|
|
||||||
if (key_is_pressed(prevKeyStates, currKeyStates, keyId)) {
|
|
||||||
return pressKey(key, scancodeIdx, report);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case UHK_KEY_LAYER:
|
|
||||||
if (key_toggled_on(prevKeyStates, currKeyStates, keyId)) {
|
|
||||||
ActiveLayer = key.layer.target;
|
|
||||||
}
|
|
||||||
if (key_toggled_off(prevKeyStates, currKeyStates, keyId)) {
|
|
||||||
ActiveLayer = LAYER_ID_BASE;
|
|
||||||
}
|
|
||||||
LedDisplay_SetLayerLed(ActiveLayer);
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fillKeyboardReport(usb_keyboard_report_t *report, const uint8_t *leftKeyStates, const uint8_t *rightKeyStates) {
|
|
||||||
int scancodeIdx = 0;
|
|
||||||
|
|
||||||
clearKeymasks(leftKeyStates, rightKeyStates);
|
|
||||||
|
|
||||||
for (uint8_t keyId=0; keyId<KEY_STATE_COUNT; keyId++) {
|
|
||||||
if (scancodeIdx >= USB_KEYBOARD_MAX_KEYS) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uhk_key_t code = getKeycode(SLOT_ID_RIGHT_KEYBOARD_HALF, keyId);
|
|
||||||
|
|
||||||
if (handleKey(code, scancodeIdx, report, prevKeyStates[SLOT_ID_RIGHT_KEYBOARD_HALF], rightKeyStates, keyId)) {
|
|
||||||
scancodeIdx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint8_t keyId=0; keyId<KEY_STATE_COUNT; keyId++) {
|
|
||||||
if (scancodeIdx >= USB_KEYBOARD_MAX_KEYS) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
uhk_key_t code = getKeycode(SLOT_ID_LEFT_KEYBOARD_HALF, keyId);
|
|
||||||
|
|
||||||
if (handleKey(code, scancodeIdx, report, prevKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], leftKeyStates, keyId)) {
|
|
||||||
scancodeIdx++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
memcpy(prevKeyStates[SLOT_ID_RIGHT_KEYBOARD_HALF], rightKeyStates, KEY_STATE_COUNT);
|
|
||||||
memcpy(prevKeyStates[SLOT_ID_LEFT_KEYBOARD_HALF], leftKeyStates, KEY_STATE_COUNT);
|
|
||||||
}
|
|
||||||
@@ -1,105 +0,0 @@
|
|||||||
#ifndef KEYBOARD_LAYOUT_H_
|
|
||||||
#define KEYBOARD_LAYOUT_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include "lufa/HIDClassCommon.h"
|
|
||||||
#include "usb_composite_device.h"
|
|
||||||
|
|
||||||
#include "module.h"
|
|
||||||
|
|
||||||
// Keyboard layout is a 2D array of scan codes.
|
|
||||||
//
|
|
||||||
// First dimension is the Key ID of a given key. Key IDs are the indices of the
|
|
||||||
// of the active keys of the key_matrix_t structure. In case of left half, an
|
|
||||||
// offset of 35 is added.
|
|
||||||
//
|
|
||||||
// For each Key ID, there are 4 different possible scan codes:
|
|
||||||
// - default, when no modifiers are pressed
|
|
||||||
// - mod layer
|
|
||||||
// - fn layer
|
|
||||||
// - mod+fn layer
|
|
||||||
|
|
||||||
#define KEY_STATE_COUNT (5*7)
|
|
||||||
|
|
||||||
typedef enum {
|
|
||||||
UHK_KEY_NONE,
|
|
||||||
UHK_KEY_SIMPLE,
|
|
||||||
UHK_KEY_MOUSE,
|
|
||||||
UHK_KEY_LAYER,
|
|
||||||
UHK_KEY_LAYER_TOGGLE,
|
|
||||||
UHK_KEY_KEYMAP,
|
|
||||||
UHK_KEY_MACRO,
|
|
||||||
UHK_KEY_LPRESSMOD,
|
|
||||||
UHK_KEY_LPRESSLAYER,
|
|
||||||
} uhk_key_type_t;
|
|
||||||
|
|
||||||
enum {
|
|
||||||
UHK_MOUSE_BUTTON_LEFT = (1 << 0),
|
|
||||||
UHK_MOUSE_BUTTON_RIGHT = (1 << 1),
|
|
||||||
UHK_MOUSE_BUTTON_MIDDLE = (1 << 2),
|
|
||||||
UHK_MOUSE_BUTTON_4 = (1 << 3),
|
|
||||||
UHK_MOUSE_BUTTON_5 = (1 << 4),
|
|
||||||
UHK_MOUSE_BUTTON_6 = (1 << 5),
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
UHK_MOUSE_MOVE_UP = (1 << 0),
|
|
||||||
UHK_MOUSE_MOVE_DOWN = (1 << 1),
|
|
||||||
UHK_MOUSE_MOVE_LEFT = (1 << 2),
|
|
||||||
UHK_MOUSE_MOVE_RIGHT = (1 << 3),
|
|
||||||
|
|
||||||
UHK_MOUSE_ACCELERATE = (1 << 4),
|
|
||||||
UHK_MOUSE_DECELERATE = (1 << 5),
|
|
||||||
};
|
|
||||||
|
|
||||||
enum {
|
|
||||||
UHK_MOUSE_SCROLL_UP = (1 << 0),
|
|
||||||
UHK_MOUSE_SCROLL_DOWN = (1 << 1),
|
|
||||||
UHK_MOUSE_SCROLL_LEFT = (1 << 2),
|
|
||||||
UHK_MOUSE_SCROLL_RIGHT = (1 << 3),
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
uint8_t type;
|
|
||||||
union {
|
|
||||||
struct {
|
|
||||||
uint8_t __unused_bits;
|
|
||||||
uint8_t mods;
|
|
||||||
uint8_t key;
|
|
||||||
} __attribute__ ((packed)) simple;
|
|
||||||
struct {
|
|
||||||
uint8_t buttonActions; // bitfield
|
|
||||||
uint8_t scrollActions; // bitfield
|
|
||||||
uint8_t moveActions; // bitfield
|
|
||||||
} __attribute__ ((packed)) mouse;
|
|
||||||
struct {
|
|
||||||
uint16_t __unused_bits;
|
|
||||||
uint8_t target;
|
|
||||||
} __attribute__ ((packed)) layer;
|
|
||||||
struct {
|
|
||||||
uint16_t __unused_bits;
|
|
||||||
uint8_t target;
|
|
||||||
} __attribute__ ((packed)) keymap;
|
|
||||||
struct {
|
|
||||||
uint8_t __unused_bits;
|
|
||||||
uint16_t index;
|
|
||||||
} __attribute__ ((packed)) macro;
|
|
||||||
struct {
|
|
||||||
uint8_t longPressMod; // single mod, or bitfield?
|
|
||||||
uint8_t mods; // for the alternate action
|
|
||||||
uint8_t key;
|
|
||||||
} __attribute__ ((packed)) longpressMod;
|
|
||||||
struct {
|
|
||||||
uint8_t longPressLayer;
|
|
||||||
uint8_t mods;
|
|
||||||
uint8_t key;
|
|
||||||
} __attribute__ ((packed)) longpressLayer;
|
|
||||||
};
|
|
||||||
} __attribute__ ((packed)) uhk_key_t;
|
|
||||||
|
|
||||||
extern uint8_t prevKeyStates[SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
|
||||||
extern uhk_key_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE];
|
|
||||||
|
|
||||||
void fillKeyboardReport(usb_keyboard_report_t *report, const uint8_t *leftKeyStates, const uint8_t *rightKeyStates);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
// Includes:
|
// Includes:
|
||||||
|
|
||||||
#include "action.h"
|
|
||||||
#include "layer.h"
|
#include "layer.h"
|
||||||
#include "slot.h"
|
#include "slot.h"
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
#include "action.h"
|
||||||
#include "fsl_port.h"
|
#include "fsl_port.h"
|
||||||
#include "usb_api.h"
|
#include "usb_api.h"
|
||||||
#include "usb_composite_device.h"
|
#include "usb_composite_device.h"
|
||||||
@@ -6,7 +7,6 @@
|
|||||||
#include "fsl_i2c.h"
|
#include "fsl_i2c.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "i2c_addresses.h"
|
#include "i2c_addresses.h"
|
||||||
#include "keyboard_layout.h"
|
|
||||||
|
|
||||||
static usb_device_endpoint_struct_t UsbKeyboardEndpoints[USB_KEYBOARD_ENDPOINT_COUNT] = {{
|
static usb_device_endpoint_struct_t UsbKeyboardEndpoints[USB_KEYBOARD_ENDPOINT_COUNT] = {{
|
||||||
USB_KEYBOARD_ENDPOINT_INDEX | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
|
USB_KEYBOARD_ENDPOINT_INDEX | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
|
||||||
@@ -100,7 +100,7 @@ void UsbKeyboadTask(){
|
|||||||
|
|
||||||
readLeftKeys(leftKeyStates);
|
readLeftKeys(leftKeyStates);
|
||||||
|
|
||||||
fillKeyboardReport(&UsbKeyboardReport[newLayout], leftKeyStates, keyMatrix.keyStates);
|
HandleKeyboardEvents(&UsbKeyboardReport[newLayout], &UsbMouseReport, leftKeyStates, keyMatrix.keyStates);
|
||||||
|
|
||||||
// Change to the new layout in atomic operation (int copy). Even if
|
// 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
|
// the copy is not atomic itself, only single bit changes. So it can
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
#include "fsl_i2c.h"
|
#include "fsl_i2c.h"
|
||||||
#include "i2c.h"
|
#include "i2c.h"
|
||||||
#include "reset_button.h"
|
#include "reset_button.h"
|
||||||
|
#include "action.h"
|
||||||
|
|
||||||
static usb_device_endpoint_struct_t UsbMouseEndpoints[USB_MOUSE_ENDPOINT_COUNT] = {{
|
static usb_device_endpoint_struct_t UsbMouseEndpoints[USB_MOUSE_ENDPOINT_COUNT] = {{
|
||||||
USB_MOUSE_ENDPOINT_INDEX | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
|
USB_MOUSE_ENDPOINT_INDEX | (USB_IN << USB_DESCRIPTOR_ENDPOINT_ADDRESS_DIRECTION_SHIFT),
|
||||||
@@ -36,25 +37,25 @@ usb_device_class_struct_t UsbMouseClass = {
|
|||||||
USB_DEVICE_CONFIGURATION_COUNT,
|
USB_DEVICE_CONFIGURATION_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
static usb_mouse_report_t UsbMouseReport;
|
usb_mouse_report_t UsbMouseReport;
|
||||||
|
|
||||||
static uint8_t scrollCounter = 0;
|
|
||||||
static volatile usb_status_t UsbMouseAction(void)
|
static volatile usb_status_t UsbMouseAction(void)
|
||||||
{
|
{
|
||||||
|
usb_status_t ret;
|
||||||
|
ret = USB_DeviceHidSend(UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX,
|
||||||
|
(uint8_t*)&UsbMouseReport, USB_MOUSE_REPORT_LENGTH);
|
||||||
UsbMouseReport.buttons = 0;
|
UsbMouseReport.buttons = 0;
|
||||||
UsbMouseReport.x = 0;
|
UsbMouseReport.x = 0;
|
||||||
UsbMouseReport.y = 0;
|
UsbMouseReport.y = 0;
|
||||||
UsbMouseReport.wheelX = 0;
|
UsbMouseReport.wheelX = 0;
|
||||||
UsbMouseReport.wheelY = 0;
|
UsbMouseReport.wheelY = 0;
|
||||||
|
|
||||||
if (RESET_BUTTON_IS_PRESSED) {
|
return ret;
|
||||||
if (!(scrollCounter % 10)) {
|
}
|
||||||
UsbMouseReport.wheelX = -1;
|
|
||||||
}
|
void fillMouseReport(uhk_key_t key, const uint8_t *prevKeyStates, const uint8_t *currKeyStates, uint8_t keyId)
|
||||||
}
|
{
|
||||||
scrollCounter++;
|
HandleMouseKey(&UsbMouseReport, key, prevKeyStates, currKeyStates, keyId);
|
||||||
return USB_DeviceHidSend(UsbCompositeDevice.mouseHandle, USB_MOUSE_ENDPOINT_INDEX,
|
|
||||||
(uint8_t*)&UsbMouseReport, USB_MOUSE_REPORT_LENGTH);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param)
|
usb_status_t UsbMouseCallback(class_handle_t handle, uint32_t event, void *param)
|
||||||
|
|||||||
@@ -38,4 +38,6 @@
|
|||||||
extern usb_status_t UsbMouseSetConfiguration(class_handle_t handle, uint8_t configuration);
|
extern usb_status_t UsbMouseSetConfiguration(class_handle_t handle, uint8_t configuration);
|
||||||
extern usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
extern usb_status_t UsbMouseSetInterface(class_handle_t handle, uint8_t interface, uint8_t alternateSetting);
|
||||||
|
|
||||||
|
extern usb_mouse_report_t UsbMouseReport;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user