From 210ef31f273c7875f4d848cf7bc36f625698abb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A1szl=C3=B3=20Monda?= Date: Fri, 24 Nov 2017 13:00:05 +0100 Subject: [PATCH] Implement mouse movement acceleration and deceleration. --- right/src/config_parser/parse_keymap.c | 53 +++----------------- right/src/config_parser/parse_keymap.h | 4 ++ right/src/key_action.h | 27 +--------- right/src/keymap.c | 28 +++++------ right/src/usb_report_updater.c | 68 +++++++++++++++++--------- 5 files changed, 74 insertions(+), 106 deletions(-) diff --git a/right/src/config_parser/parse_keymap.c b/right/src/config_parser/parse_keymap.c index 2803f02..691ef91 100644 --- a/right/src/config_parser/parse_keymap.c +++ b/right/src/config_parser/parse_keymap.c @@ -82,53 +82,16 @@ static parser_error_t parsePlayMacroAction(key_action_t *keyAction, config_buffe static parser_error_t parseMouseAction(key_action_t *keyAction, config_buffer_t *buffer) { - uint8_t mouseAction = ReadUInt8(buffer); - keyAction->type = KeyActionType_Mouse; - memset(&keyAction->mouse, 0, sizeof keyAction->mouse); - switch (mouseAction) { - case SerializedMouseAction_LeftClick: - keyAction->mouse.buttonActions = MouseButton_Left; - break; - case SerializedMouseAction_MiddleClick: - keyAction->mouse.buttonActions = MouseButton_Middle; - break; - case SerializedMouseAction_RightClick: - keyAction->mouse.buttonActions = MouseButton_Right; - break; - case SerializedMouseAction_MoveUp: - keyAction->mouse.moveActions = MouseMove_Up; - break; - case SerializedMouseAction_MoveDown: - keyAction->mouse.moveActions = MouseMove_Down; - break; - case SerializedMouseAction_MoveLeft: - keyAction->mouse.moveActions = MouseMove_Left; - break; - case SerializedMouseAction_MoveRight: - keyAction->mouse.moveActions = MouseMove_Right; - break; - case SerializedMouseAction_ScrollUp: - keyAction->mouse.scrollActions = MouseScroll_Up; - break; - case SerializedMouseAction_ScrollDown: - keyAction->mouse.scrollActions = MouseScroll_Down; - break; - case SerializedMouseAction_ScrollLeft: - keyAction->mouse.scrollActions = MouseScroll_Left; - break; - case SerializedMouseAction_ScrollRight: - keyAction->mouse.scrollActions = MouseScroll_Right; - break; - case SerializedMouseAction_Accelerate: - keyAction->mouse.speedActions = MouseSpeed_Accelerate; - break; - case SerializedMouseAction_Decelerate: - keyAction->mouse.speedActions = MouseSpeed_Decelerate; - break; - default: - return ParserError_InvalidSerializedMouseAction; + + uint8_t mouseAction = ReadUInt8(buffer); + if (mouseAction > SerializedMouseAction_Last) { + return ParserError_InvalidSerializedMouseAction; } + + memset(&keyAction->mouseAction, 0, sizeof keyAction->mouseAction); + keyAction->mouseAction = mouseAction; + return ParserError_Success; } diff --git a/right/src/config_parser/parse_keymap.h b/right/src/config_parser/parse_keymap.h index 0a738c6..068150e 100644 --- a/right/src/config_parser/parse_keymap.h +++ b/right/src/config_parser/parse_keymap.h @@ -48,6 +48,10 @@ SerializedMouseAction_ScrollRight, SerializedMouseAction_Accelerate, SerializedMouseAction_Decelerate, + SerializedMouseAction_Last = SerializedMouseAction_Decelerate, + SerializedMouseAction_Button_4, + SerializedMouseAction_Button_5, + SerializedMouseAction_Button_6, } serialized_mouse_action_t; // Functions: diff --git a/right/src/key_action.h b/right/src/key_action.h index 245fb7c..5e09be6 100644 --- a/right/src/key_action.h +++ b/right/src/key_action.h @@ -8,6 +8,7 @@ #include "lufa/HIDClassCommon.h" #include "usb_composite_device.h" #include "module.h" + #include "config_parser/parse_keymap.h" // Typedefs: @@ -36,25 +37,6 @@ MouseButton_6 = 1 << 5, } mouse_button_t; - typedef enum { - MouseMove_Up = 1 << 0, - MouseMove_Down = 1 << 1, - MouseMove_Left = 1 << 2, - MouseMove_Right = 1 << 3, - } mouse_move_action_t; - - typedef enum { - MouseSpeed_Accelerate = 1 << 0, - MouseSpeed_Decelerate = 1 << 1, - } mouse_speed_action_t; - - typedef enum { - MouseScroll_Up = 1 << 0, - MouseScroll_Down = 1 << 1, - MouseScroll_Left = 1 << 2, - MouseScroll_Right = 1 << 3, - } mouse_scroll_t; - typedef struct { uint8_t type; union { @@ -64,12 +46,7 @@ uint8_t modifiers; uint16_t scancode; } ATTR_PACKED keystroke; - struct { - mouse_button_t buttonActions; - mouse_scroll_t scrollActions; - mouse_move_action_t moveActions; - mouse_speed_action_t speedActions; - } ATTR_PACKED mouse; + serialized_mouse_action_t mouseAction; struct { bool isToggle; uint8_t layer; diff --git a/right/src/keymap.c b/right/src/keymap.c index a623fe7..cf78bf6 100644 --- a/right/src/keymap.c +++ b/right/src/keymap.c @@ -332,23 +332,23 @@ key_action_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] = { .type = KeyActionType_None }, // Row 2 - { .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_4 }}, - { .type = KeyActionType_Mouse, .mouse = { .moveActions = MouseMove_Up }}, - { .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_5 }}, - { .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_6 }}, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Button_4 }, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_MoveUp }, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Button_5 }, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Button_6 }, { .type = KeyActionType_None }, { .type = KeyActionType_None }, { .type = KeyActionType_None }, - { .type = KeyActionType_Mouse, .mouse = { .scrollActions = MouseScroll_Up }}, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_ScrollUp }, // Row 3 - { .type = KeyActionType_Mouse, .mouse = { .moveActions = MouseMove_Left }}, - { .type = KeyActionType_Mouse, .mouse = { .moveActions = MouseMove_Down }}, - { .type = KeyActionType_Mouse, .mouse = { .moveActions = MouseMove_Right }}, + { .type = KeyActionType_Mouse, .mouseAction= SerializedMouseAction_MoveLeft }, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_MoveDown }, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_MoveRight }, { .type = KeyActionType_None }, { .type = KeyActionType_None }, { .type = KeyActionType_None }, - { .type = KeyActionType_Mouse, .mouse = { .scrollActions = MouseScroll_Down }}, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_ScrollDown }, // Row 4 { .type = KeyActionType_None }, @@ -391,9 +391,9 @@ key_action_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] = // Row 3 { .type = KeyActionType_SwitchLayer, .switchLayer = { .layer = LayerId_Mouse }}, { .type = KeyActionType_None }, - { .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_Right }}, - { .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_Middle }}, - { .type = KeyActionType_Mouse, .mouse = { .buttonActions = MouseButton_Left }}, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_RightClick }, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_MiddleClick }, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_LeftClick }, { .type = KeyActionType_None }, { .type = KeyActionType_None }, @@ -411,8 +411,8 @@ key_action_t CurrentKeymap[LAYER_COUNT][SLOT_COUNT][MAX_KEY_COUNT_PER_MODULE] = { .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_GUI }}, { .type = KeyActionType_Keystroke, .keystroke = { .scancode = HID_KEYBOARD_SC_LEFT_ALT }}, { .type = KeyActionType_None }, - { .type = KeyActionType_Mouse, .mouse = { .speedActions = MouseSpeed_Decelerate }}, - { .type = KeyActionType_Mouse, .mouse = { .speedActions = MouseSpeed_Accelerate }}, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Decelerate }, + { .type = KeyActionType_Mouse, .mouseAction = SerializedMouseAction_Accelerate }, { .type = KeyActionType_None }, } }, diff --git a/right/src/usb_report_updater.c b/right/src/usb_report_updater.c index eeb14d1..7692db7 100644 --- a/right/src/usb_report_updater.c +++ b/right/src/usb_report_updater.c @@ -14,6 +14,7 @@ #include "usb_report_updater.h" #include "timer.h" #include "key_debouncer.h" +#include "config_parser/parse_keymap.h" uint32_t UsbReportUpdateTime = 0; static uint32_t elapsedTime; @@ -29,7 +30,9 @@ static float mouseScrollSpeed = 0.1; static bool isMouseMoving; static bool wasMouseMoving; -void processMouseAction(key_action_t *action) +static bool activeMouseStates[SerializedMouseAction_Last]; + +void processMouseActions() { static float mouseMoveCurrentSpeed; @@ -37,17 +40,22 @@ void processMouseAction(key_action_t *action) mouseMoveCurrentSpeed = mouseMoveInitialSpeed; } - if (action->mouse.moveActions) { - isMouseMoving = true; + bool isMoveAction = activeMouseStates[SerializedMouseAction_MoveUp] || + activeMouseStates[SerializedMouseAction_MoveDown] || + activeMouseStates[SerializedMouseAction_MoveLeft] || + activeMouseStates[SerializedMouseAction_MoveRight]; - float targetSpeed; - if (action->mouse.speedActions & MouseSpeed_Accelerate) { - targetSpeed = mouseMoveAcceleratedSpeed; - } else if (action->mouse.speedActions & MouseSpeed_Decelerate) { - targetSpeed = mouseMoveDeceleratedSpeed; - } else { - targetSpeed = mouseMoveBaseSpeed; - } + float targetSpeed; + if (activeMouseStates[SerializedMouseAction_Accelerate]) { + targetSpeed = mouseMoveAcceleratedSpeed; + } else if (activeMouseStates[SerializedMouseAction_Decelerate]) { + targetSpeed = mouseMoveDeceleratedSpeed; + } else if (isMoveAction) { + targetSpeed = mouseMoveBaseSpeed; + } + + if (isMoveAction) { + isMouseMoving = true; if (mouseMoveCurrentSpeed < targetSpeed) { mouseMoveCurrentSpeed += mouseMoveBaseAcceleration * elapsedTime / 1000; @@ -63,35 +71,40 @@ void processMouseAction(key_action_t *action) uint16_t distance = mouseMoveCurrentSpeed * elapsedTime / 10; - if (action->mouse.moveActions & MouseMove_Left) { + if (activeMouseStates[SerializedMouseAction_MoveLeft]) { ActiveUsbMouseReport->x = -distance; - } else if (action->mouse.moveActions & MouseMove_Right) { + } else if (activeMouseStates[SerializedMouseAction_MoveRight]) { ActiveUsbMouseReport->x = distance; } - if (action->mouse.moveActions & MouseMove_Up) { + if (activeMouseStates[SerializedMouseAction_MoveUp]) { ActiveUsbMouseReport->y = -distance; - } else if (action->mouse.moveActions & MouseMove_Down) { + } else if (activeMouseStates[SerializedMouseAction_MoveDown]) { ActiveUsbMouseReport->y = distance; } } + bool isScrollAction = activeMouseStates[SerializedMouseAction_ScrollUp] || + activeMouseStates[SerializedMouseAction_ScrollDown] || + activeMouseStates[SerializedMouseAction_ScrollLeft] || + activeMouseStates[SerializedMouseAction_ScrollRight]; + static float mouseScrollDistanceSum = 0; - if (action->mouse.scrollActions) { + if (isScrollAction) { mouseScrollDistanceSum += mouseScrollSpeed; float mouseScrollDistanceIntegerSum; float mouseScrollDistanceFractionSum = modff(mouseScrollDistanceSum, &mouseScrollDistanceIntegerSum); if (mouseScrollDistanceIntegerSum) { - if (action->mouse.scrollActions & MouseScroll_Up) { + if (activeMouseStates[SerializedMouseAction_ScrollUp]) { ActiveUsbMouseReport->wheelX = mouseScrollDistanceIntegerSum; - } else if (action->mouse.scrollActions & MouseScroll_Down) { + } else if (activeMouseStates[SerializedMouseAction_ScrollDown]) { ActiveUsbMouseReport->wheelX = -mouseScrollDistanceIntegerSum; } - if (action->mouse.scrollActions & MouseScroll_Right) { + if (activeMouseStates[SerializedMouseAction_ScrollRight]) { ActiveUsbMouseReport->wheelY = mouseScrollDistanceIntegerSum; - } else if (action->mouse.scrollActions & MouseScroll_Left) { + } else if (activeMouseStates[SerializedMouseAction_ScrollLeft]) { ActiveUsbMouseReport->wheelY = -mouseScrollDistanceIntegerSum; } mouseScrollDistanceSum = mouseScrollDistanceFractionSum; @@ -100,7 +113,15 @@ void processMouseAction(key_action_t *action) mouseScrollDistanceSum = 0; } - ActiveUsbMouseReport->buttons |= action->mouse.buttonActions; + if (activeMouseStates[SerializedMouseAction_LeftClick]) { + ActiveUsbMouseReport->buttons |= MouseButton_Left; + } + if (activeMouseStates[SerializedMouseAction_MiddleClick]) { + ActiveUsbMouseReport->buttons |= MouseButton_Middle; + } + if (activeMouseStates[SerializedMouseAction_RightClick]) { + ActiveUsbMouseReport->buttons |= MouseButton_Right; + } } static uint8_t basicScancodeIndex = 0; @@ -139,7 +160,7 @@ void applyKeyAction(key_state_t *keyState, key_action_t *action) } break; case KeyActionType_Mouse: - processMouseAction(action); + activeMouseStates[action->mouseAction] = true; break; case KeyActionType_SwitchKeymap: if (!keyState->previous && keyState->current) { @@ -157,6 +178,7 @@ static secondary_role_t secondaryRole; void updateActiveUsbReports(void) { + memset(activeMouseStates, 0, SerializedMouseAction_Last); wasMouseMoving = isMouseMoving; isMouseMoving = false; @@ -243,6 +265,8 @@ void updateActiveUsbReports(void) } } + processMouseActions(); + // When a layer switcher key gets pressed along with another key that produces some modifiers // and the accomanying key gets released then keep the related modifiers active a long as the // layer switcher key stays pressed. Useful for Alt+Tab keymappings and the like.