#include "key_action.h" #include "led_display.h" #include "layer.h" #include "usb_interfaces/usb_interface_mouse.h" #include "keymap.h" #include "peripherals/test_led.h" #include "slave_drivers/is31fl3731_driver.h" #include "slave_drivers/uhk_module_driver.h" #include "macros.h" #include "key_states.h" #include "right_key_matrix.h" #include "layer.h" #include "usb_report_updater.h" static uint8_t mouseWheelDivisorCounter = 0; static uint8_t mouseSpeedAccelDivisorCounter = 0; static uint8_t mouseSpeed = 3; static bool wasPreviousMouseActionWheelAction = false; void processMouseAction(key_action_t *action) { bool isWheelAction = action->mouse.scrollActions && !action->mouse.moveActions && !action->mouse.buttonActions; if (isWheelAction && wasPreviousMouseActionWheelAction) { mouseWheelDivisorCounter++; } if (action->mouse.scrollActions) { if (mouseWheelDivisorCounter == MOUSE_WHEEL_DIVISOR) { mouseWheelDivisorCounter = 0; if (action->mouse.scrollActions & MouseScroll_Up) { ActiveUsbMouseReport->wheelX = 1; } if (action->mouse.scrollActions & MouseScroll_Down) { ActiveUsbMouseReport->wheelX = -1; } } } if (action->mouse.moveActions & MouseMove_Accelerate || action->mouse.moveActions & MouseMove_Decelerate) { mouseSpeedAccelDivisorCounter++; if (mouseSpeedAccelDivisorCounter == MOUSE_SPEED_ACCEL_DIVISOR) { mouseSpeedAccelDivisorCounter = 0; if (action->mouse.moveActions & MouseMove_Accelerate) { if (mouseSpeed < MOUSE_MAX_SPEED) { mouseSpeed++; } } if (action->mouse.moveActions & MouseMove_Decelerate) { if (mouseSpeed > 1) { mouseSpeed--; } } } } else if (action->mouse.moveActions) { if (action->mouse.moveActions & MouseMove_Left) { ActiveUsbMouseReport->x = -mouseSpeed; } if (action->mouse.moveActions & MouseMove_Right) { ActiveUsbMouseReport->x = mouseSpeed; } if (action->mouse.moveActions & MouseMove_Up) { ActiveUsbMouseReport->y = -mouseSpeed; } if (action->mouse.moveActions & MouseMove_Down) { ActiveUsbMouseReport->y = mouseSpeed; } } ActiveUsbMouseReport->buttons |= action->mouse.buttonActions; wasPreviousMouseActionWheelAction = isWheelAction; } static uint8_t basicScancodeIndex = 0; static uint8_t mediaScancodeIndex = 0; static uint8_t systemScancodeIndex = 0; void applyKeyAction(key_state_t *keyState, key_action_t *action) { if (keyState->suppressed) { return; } switch (action->type) { case KeyActionType_Keystroke: ActiveUsbBasicKeyboardReport->modifiers |= action->keystroke.modifiers; switch (action->keystroke.keystrokeType) { case KeystrokeType_Basic: if (basicScancodeIndex >= USB_BASIC_KEYBOARD_MAX_KEYS || action->keystroke.scancode == 0) { break; } ActiveUsbBasicKeyboardReport->scancodes[basicScancodeIndex++] = action->keystroke.scancode; break; case KeystrokeType_Media: if (mediaScancodeIndex >= USB_MEDIA_KEYBOARD_MAX_KEYS) { break; } ActiveUsbMediaKeyboardReport->scancodes[mediaScancodeIndex++] = action->keystroke.scancode; break; case KeystrokeType_System: if (systemScancodeIndex >= USB_SYSTEM_KEYBOARD_MAX_KEYS) { break; } ActiveUsbSystemKeyboardReport->scancodes[systemScancodeIndex++] = action->keystroke.scancode; break; } break; case KeyActionType_Mouse: processMouseAction(action); break; case KeyActionType_SwitchKeymap: if (!keyState->previous && keyState->current) { SwitchKeymap(action->switchKeymap.keymapId); } break; } } static layer_id_t previousLayer = LayerId_Base; static uint8_t secondaryRoleState = SecondaryRoleState_Released; static uint8_t secondaryRoleSlotId; static uint8_t secondaryRoleKeyId; static secondary_role_t secondaryRole; void UpdateActiveUsbReports(void) { static uint8_t previousModifiers = 0; basicScancodeIndex = 0; mediaScancodeIndex = 0; systemScancodeIndex = 0; for (uint8_t keyId=0; keyId < RIGHT_KEY_MATRIX_KEY_COUNT; keyId++) { KeyStates[SlotId_RightKeyboardHalf][keyId].current = RightKeyMatrix.keyStates[keyId]; } layer_id_t activeLayer = LayerId_Base; if (secondaryRoleState == SecondaryRoleState_Triggered && IS_SECONDARY_ROLE_LAYER_SWITCHER(secondaryRole)) { activeLayer = SECONDARY_ROLE_LAYER_TO_LAYER_ID(secondaryRole); } if (activeLayer == LayerId_Base) { activeLayer = GetActiveLayer(); } bool suppressKeys = previousLayer != LayerId_Base && activeLayer == LayerId_Base; LedDisplay_SetLayer(activeLayer); if (MacroPlaying) { Macros_ContinueMacro(); memcpy(&ActiveUsbMouseReport, &MacroMouseReport, sizeof MacroMouseReport); memcpy(&ActiveUsbBasicKeyboardReport, &MacroBasicKeyboardReport, sizeof MacroBasicKeyboardReport); memcpy(&ActiveUsbMediaKeyboardReport, &MacroMediaKeyboardReport, sizeof MacroMediaKeyboardReport); memcpy(&ActiveUsbSystemKeyboardReport, &MacroSystemKeyboardReport, sizeof MacroSystemKeyboardReport); return; } for (uint8_t slotId=0; slotIdcurrent) { if (suppressKeys) { keyState->suppressed = true; } if (action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole) { // Press released secondary role key. if (!keyState->previous && action->type == KeyActionType_Keystroke && action->keystroke.secondaryRole && secondaryRoleState == SecondaryRoleState_Released) { secondaryRoleState = SecondaryRoleState_Pressed; secondaryRoleSlotId = slotId; secondaryRoleKeyId = keyId; secondaryRole = action->keystroke.secondaryRole; keyState->suppressed = true; } } else { // Trigger secondary role. if (!keyState->previous && secondaryRoleState == SecondaryRoleState_Pressed) { secondaryRoleState = SecondaryRoleState_Triggered; } else { applyKeyAction(keyState, action); } } } else { if (keyState->suppressed) { keyState->suppressed = false; } // Release secondary role key. if (keyState->previous && secondaryRoleSlotId == slotId && secondaryRoleKeyId == keyId) { // Trigger primary role. if (secondaryRoleState == SecondaryRoleState_Pressed) { applyKeyAction(keyState, action); } secondaryRoleState = SecondaryRoleState_Released; } } keyState->previous = keyState->current; } } // 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. if (activeLayer != LayerId_Base && activeLayer == PreviousHeldLayer && basicScancodeIndex == 0) { ActiveUsbBasicKeyboardReport->modifiers |= previousModifiers; } if (secondaryRoleState == SecondaryRoleState_Triggered && IS_SECONDARY_ROLE_MODIFIER(secondaryRole)) { ActiveUsbBasicKeyboardReport->modifiers |= SECONDARY_ROLE_MODIFIER_TO_HID_MODIFIER(secondaryRole); } previousModifiers = ActiveUsbBasicKeyboardReport->modifiers; previousLayer = activeLayer; }