Skip to content

Commit

Permalink
Merge branch 'master' of github.com:UltimateHackingKeyboard/firmware
Browse files Browse the repository at this point in the history
  • Loading branch information
mondalaci committed Jun 25, 2023
2 parents 1787a74 + fcf0f01 commit 9d6414c
Show file tree
Hide file tree
Showing 13 changed files with 194 additions and 42 deletions.
14 changes: 8 additions & 6 deletions cla/cla-1.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,19 +98,21 @@ IF THE DISCLAIMER AND DAMAGE WAIVER MENTIONED IN SECTION 4. AND SECTION 5. CANNO
I have read this Agreement, and fully agree to it by signing it with my GitHub username:

- @abcminiuser
- @benedekkupper
- @bodograumann
- @dancek
- @eltang
- @ert78gb
- @hxv
- @kareltucek
- @kenhys
- @Lauszus
- @mondalaci
- @santiagogf89
- @soraxas
- @steamraven
- @stephengroat
- @tastyger
- @xdever
- @stephengroat
- @ert78gb
- @xxxajk
- @dancek
- @steamraven
- @benedekkupper
- @hxv
- @Zynh0722
11 changes: 8 additions & 3 deletions doc-dev/reference-manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ The following grammar is supported:
COMMAND = holdKeymapLayerMax KEYMAPID LAYERID <time in ms (NUMBER)>
COMMAND = resolveSecondary <time in ms (NUMBER)> [<time in ms (NUMBER)>] <primary action macro action index (ADDRESS)> <secondary action macro action index (ADDRESS)>
COMMAND = resolveNextKeyId
COMMAND = activateKeyPostponed [atLayer LAYERID] KEYID
COMMAND = activateKeyPostponed [atLayer LAYERID] [append | prepend] KEYID
COMMAND = consumePending <number of keys (NUMBER)>
COMMAND = postponeNext <number of commands (NUMER)>
COMMAND = break
Expand Down Expand Up @@ -119,7 +119,7 @@ The following grammar is supported:
COMMAND = set backlight.constantRgb.rgb <number 0-255 (NUMBER)> <number 0-255 (NUMBER)> <number 0-255 (NUMBER)><number 0-255 (NUMBER)>
COMMAND = set leds.enabled BOOLEAN
COMMAND = set leds.brightness <0-1 multiple of default (FLOAT)>
COMMAND = set leds.fadeTimeout <minutes to fade after (NUMBER)>
COMMAND = set leds.fadeTimeout <seconds to fade after (NUMBER)>
COMMAND = set modifierLayerTriggers.{shift|alt|super|ctrl} {left|right|both}
CONDITION = {ifShortcut | ifNotShortcut} [IFSHORTCUTFLAGS]* [KEYID]+
CONDITION = {ifGesture | ifNotGesture} [IFSHORTCUTFLAGS]* [KEYID]+
Expand Down Expand Up @@ -320,7 +320,7 @@ We allow postponing key activations in order to allow deciding between some scen
- `ifPendingKeyReleased/ifNotPendingKeyReleased <queue idx>` is true if the key pending at `idx` in queue has been released. I.e., if there exists matching release event in the queue.
- `ifKeyPendingAt/ifNotKeyPendingAt <idx> <keyId>` looks into postponing queue at `idx`th waiting key nad compares it to the `keyId`.
- `consumePending <n>` will remove n records from the queue.
- `activateKeyPostponed KEYID` will add tap of KEYID at the end of queue. If `atLayer LAYERID` is specified, action will be taken from that layer rather than current one.
- `activateKeyPostponed KEYID` will add tap of KEYID at the end of queue. If `atLayer LAYERID` is specified, action will be taken from that layer rather than current one. If `prepend` option is specified, event will be place at the beginning of the queue.
- `resolveSecondary` allows resolution of secondary roles depending on the next key - this allows us to accurately distinguish random press from intentional press of shortcut via secondary role. See `resolveSecondary` entry under Layer switching. Implicitly applies `postponeKeys` modifier.
- `ifPrimary/ifSecondary` act as an abreviation for `resolveSecondary`. They use postponing mechanism and allow distinguishing between primary and secondary roles.
- `ifShortcut/ifNotShortcut/ifGesture/ifNotGesture [IFSHORTCUTFLAGS]* [KEYID]*` will wait for next keypresses until sufficient number of keys has been pressed. If the next keypresses correspond to the provided arguments (hardware ids), the keypresses are consumed and the condition is performed. Consuming takes place in both `if` and `ifNot` versions if the full list is matched. E.g., `ifShortcut 090 089 final tapKey C-V; holdKey v`.
Expand Down Expand Up @@ -513,6 +513,11 @@ For the purpose of toggling functionality on and off, and for global constants m
- `backlight.strategy { functional | constantRgb }` sets backlight strategy.
- `backlight.constantRgb.rgb NUMBER NUMBER NUMBER` allows setting custom constant colour for entire keyboard. E.g.: `set backlight.strategy constantRgb; set backlight.constantRgb.rgb 255 0 0` to make entire keyboard shine red.

- general led configuration:
- `leds.enabled BOOLEAN` turns on/off all keyboard leds: i.e., backlight, indicator leds, segment display
- `leds.brightness <0-1 multiple of default (FLOAT)>` allows scaling default brightness. E.g., `0.5` will dim entire keyboard to half of the default values that are configured in Agent
- `leds.fadeTimeout <seconds to fade after (NUMBER)>` will turn off leds after configured interval.

- modifier layer triggers:
- `set modifierLayerTriggers.{shift|alt|super|ctrl} {left|right|both}` controls whether modifier layers are triggered by left or right or either of the modifiers.

Expand Down
4 changes: 2 additions & 2 deletions doc-dev/user-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ releaseKey a

Complex key sequences can be achieved using `tapKeySeq`. For instance, following emoji macro (uses linux Ctrl+U notation) will produce a shrugging person.
```
tapKeySeq CS-u 1 f 6 0 5 space
tapKeySeq CS-u 1 f 9 3 7 space
```

With these commands, modifiers are encoded using `CSAG`, with optional `LR` for left and right side. E.g., `LC-a` means `left control + a`.
Expand Down Expand Up @@ -290,7 +290,7 @@ holdLayer mouse
ifNotInterrupted tapKey enter
```

Regular secondary role with prevention of accidential key taps: (Activates the secondary role immediately, but activates the primary role only if the key has been pressed for at least a certain amount of time. This could be used to emulate the [Space Cadet Shift feature](https://beta.docs.qmk.fm/using-qmk/advanced-keycodes/feature_space_cadet).)
Regular secondary role with prevention of accidential key taps: (Activates the secondary role immediately, but activates the primary role only if the key has been pressed for at least a certain amount of time. This could be used to emulate the [Space Cadet Shift feature](https://docs.qmk.fm/#/feature_space_cadet).)

```
holdKey leftShift
Expand Down
3 changes: 3 additions & 0 deletions right/src/keymap.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "arduino_hid/ConsumerAPI.h"
#include "arduino_hid/SystemAPI.h"
#include "keymap.h"
#include "layer_switcher.h"
#include "led_display.h"
#include "ledmap.h"
#include "config_parser/parse_keymap.h"
Expand All @@ -27,7 +28,9 @@ void SwitchKeymapById(uint8_t index)
ParseKeymap(&ValidatedUserConfigBuffer, index, AllKeymapsCount, AllMacrosCount);
LedDisplay_UpdateText();
UpdateLayerLeds();
MacroEvent_RegisterLayerMacros();
MacroEvent_OnKeymapChange(index);
MacroEvent_OnLayerChange(ActiveLayer);
}

uint8_t FindKeymapByAbbreviation(uint8_t length, const char *abbrev) {
Expand Down
8 changes: 7 additions & 1 deletion right/src/layer_switcher.c
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "layer_switcher.h"
#include "layer.h"
#include "ledmap.h"
#include "macro_events.h"
#include "timer.h"
#include "macros.h"
#include "debug.h"
Expand Down Expand Up @@ -53,6 +54,7 @@ void updateActiveLayer() {
// beware lower-upper case typos!

// apply stock layer switching
layer_id_t previousLayer = ActiveLayer;
layer_id_t activeLayer = NONE;
bool activeLayerHeld = false;
if(activeLayer == NONE) {
Expand All @@ -77,8 +79,12 @@ void updateActiveLayer() {
//(write actual ActiveLayer atomically, so that random observer is not confused)
ActiveLayer = activeLayer;
ActiveLayerHeld = activeLayerHeld;
UpdateLayerLeds();
LedDisplay_SetLayer(ActiveLayer);

if (ActiveLayer != previousLayer) {
UpdateLayerLeds();
MacroEvent_OnLayerChange(activeLayer);
}
}

/*
Expand Down
81 changes: 74 additions & 7 deletions right/src/macro_events.c
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#include "layer.h"
#include "string.h"
#include "str_utils.h"
#include "macro_events.h"
#include "config_parser/parse_macro.h"
Expand All @@ -6,6 +8,11 @@
#include "led_display.h"
#include "debug.h"


static macro_index_t anyLayerChangeMacro = MacroIndex_None;
static macro_index_t layerChangeMacro[LayerId_Count];
static macro_index_t keymapLayerChangeMacro[LayerId_Count];

/**
* Future possible extensions:
* - generalize change to always handle "in" and "out" events
Expand All @@ -26,7 +33,15 @@ void MacroEvent_OnInit()
}
}

void processOnKeymapChange(const char* curAbbrev, const char* curAbbrevEnd)
static void startMacroInSlot(macro_index_t macroIndex, uint8_t* slotId) {
if (*slotId != 255 && MacroState[*slotId].ms.macroPlaying) {
*slotId = Macros_QueueMacro(macroIndex, NULL, *slotId);
} else {
*slotId = Macros_StartMacro(macroIndex, NULL, 255, false);
}
}

static void processOnKeymapChange(const char* curAbbrev, const char* curAbbrevEnd)
{
for (int i = 0; i < AllMacrosCount; i++) {
const char *thisName, *thisNameEnd;
Expand All @@ -36,18 +51,13 @@ void processOnKeymapChange(const char* curAbbrev, const char* curAbbrevEnd)
const char* macroArg = NextTok(thisName,thisNameEnd);

if (TokenMatches2(macroArg, thisNameEnd, curAbbrev, curAbbrevEnd)) {
if (previousEventMacroSlot != 255 && MacroState[previousEventMacroSlot].ms.macroPlaying) {
previousEventMacroSlot = Macros_QueueMacro(i, NULL, previousEventMacroSlot);
} else {
previousEventMacroSlot = Macros_StartMacro(i, NULL, 255, false);
}
startMacroInSlot(i, &previousEventMacroSlot);
}
}
}

}


void MacroEvent_OnKeymapChange(uint8_t keymapIdx)
{
keymap_reference_t *keymap = AllKeymaps + keymapIdx;
Expand All @@ -58,6 +68,63 @@ void MacroEvent_OnKeymapChange(uint8_t keymapIdx)

processOnKeymapChange(any, any + strlen(any));
processOnKeymapChange(curAbbrev, curAbbrevEnd);
}

void MacroEvent_RegisterLayerMacros()
{
keymap_reference_t *keymap = AllKeymaps + CurrentKeymapIndex;
const char* curAbbrev = keymap->abbreviation;
const char* curAbbrevEnd = keymap->abbreviation + keymap->abbreviationLen;

anyLayerChangeMacro = MacroIndex_None;
memset(layerChangeMacro, MacroIndex_None, sizeof layerChangeMacro);
memset(keymapLayerChangeMacro, MacroIndex_None, sizeof layerChangeMacro);

bool oldParserStatus = Macros_ParserError;
Macros_ParserError = false;

for (int i = 0; i < AllMacrosCount; i++) {
const char *thisName, *thisNameEnd;
FindMacroName(&AllMacros[i], &thisName, &thisNameEnd);

if (TokenMatches(thisName, thisNameEnd, "$onKeymapLayerChange")) {
const char* macroArg = NextTok(thisName,thisNameEnd);
const char* macroArg2 = NextTok(macroArg,thisNameEnd);
const layer_id_t layerId = Macros_ParseLayerId(macroArg2, thisNameEnd);

if (TokenMatches2(macroArg, thisNameEnd, curAbbrev, curAbbrevEnd) && !Macros_ParserError) {
keymapLayerChangeMacro[layerId] = i;
}
}

if (TokenMatches(thisName, thisNameEnd, "$onLayerChange")) {
const char* macroArg = NextTok(thisName,thisNameEnd);
if (TokenMatches(macroArg, thisNameEnd, "any") && !Macros_ParserError) {
anyLayerChangeMacro = i;
} else {
const layer_id_t layerId = Macros_ParseLayerId(macroArg, thisNameEnd);
if (!Macros_ParserError) {
layerChangeMacro[layerId] = i;
}
}
}
Macros_ParserError = false;
}

Macros_ParserError = oldParserStatus;
}

void MacroEvent_OnLayerChange(layer_id_t layerId)
{
macro_index_t macrosToTry[3] = {
anyLayerChangeMacro,
layerChangeMacro[layerId],
keymapLayerChangeMacro[layerId],
};

for (uint8_t i = 0; i < sizeof macrosToTry; i++) {
startMacroInSlot(macrosToTry[i], &previousEventMacroSlot);
}

previousEventMacroSlot = 255;
}
2 changes: 2 additions & 0 deletions right/src/macro_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@

void MacroEvent_OnInit();
void MacroEvent_OnKeymapChange(uint8_t keymapIdx);
void MacroEvent_OnLayerChange(layer_id_t layerId);
void MacroEvent_RegisterLayerMacros();

#endif
8 changes: 7 additions & 1 deletion right/src/macro_set_command.c
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#include "macro_set_command.h"
#include "layer.h"
#include "ledmap.h"
#include "macros.h"
#include "timer.h"
Expand Down Expand Up @@ -35,6 +36,11 @@ static void moduleNavigationMode(const char* arg1, const char *textEnd, module_c
layer_id_t layerId = Macros_ParseLayerId(arg1, textEnd);
navigation_mode_t modeId = ParseNavigationModeId(NextTok(arg1, textEnd), textEnd);

if (IS_MODIFIER_LAYER(layerId)) {
Macros_ReportError("Navigation mode cannot be changed for modifier layers!", NULL, NULL);
return;
}

if (Macros_ParserError) {
return;
}
Expand Down Expand Up @@ -237,7 +243,7 @@ static void leds(const char* arg1, const char *textEnd)
{
const char* value = NextTok(arg1, textEnd);
if (TokenMatches(arg1, textEnd, "fadeTimeout")) {
LedSleepTimeout = 1000*60*Macros_ParseInt(value, textEnd, NULL);
LedSleepTimeout = 1000*Macros_ParseInt(value, textEnd, NULL);
} else if (TokenMatches(arg1, textEnd, "brightness")) {
LedBrightnessMultiplier = ParseFloat(value, textEnd);
} else if (TokenMatches(arg1, textEnd, "enabled")) {
Expand Down
72 changes: 57 additions & 15 deletions right/src/macros.c
Original file line number Diff line number Diff line change
Expand Up @@ -622,17 +622,20 @@ static macro_result_t dispatchText(const char* text, uint16_t textLen)

// If all characters have been sent, finish.
if (s->as.dispatchData.textIdx == textLen) {
s->as.dispatchData.textIdx = 0;
s->as.dispatchData.reportState = REPORT_FULL;
memset(&s->ms.macroBasicKeyboardReport, 0, sizeof s->ms.macroBasicKeyboardReport);
dispatchMutex = NULL;
return MacroResult_Finished;
if (s->as.dispatchData.reportState != REPORT_EMPTY) {
s->as.dispatchData.reportState = REPORT_EMPTY;
memset(&s->ms.macroBasicKeyboardReport, 0, sizeof s->ms.macroBasicKeyboardReport);
return MacroResult_Blocking;
} else {
s->as.dispatchData.textIdx = 0;
dispatchMutex = NULL;
return MacroResult_Finished;
}
}

// Whenever the report is full, we clear the report and send it empty before continuing.
if (s->as.dispatchData.reportState == REPORT_FULL) {
s->as.dispatchData.reportState = REPORT_EMPTY;

memset(&s->ms.macroBasicKeyboardReport, 0, sizeof s->ms.macroBasicKeyboardReport);
return MacroResult_Blocking;
}
Expand Down Expand Up @@ -2141,10 +2144,27 @@ static bool processIfKeyDefinedCommand(bool negate, const char* arg1, const char
static macro_result_t processActivateKeyPostponedCommand(const char* arg1, const char* argEnd)
{
uint8_t layer = 255;
if (TokenMatches(arg1, argEnd, "atLayer")) {
const char* arg2 = NextTok(arg1, argEnd);
layer = Macros_ParseLayerId(arg2, argEnd);
arg1 = NextTok(arg2, argEnd);
bool options = true;
bool append = true;

while (options) {
options = false;
if (TokenMatches(arg1, argEnd, "atLayer")) {
const char* arg2 = NextTok(arg1, argEnd);
layer = Macros_ParseLayerId(arg2, argEnd);
arg1 = NextTok(arg2, argEnd);
options = true;
}
if (TokenMatches(arg1, argEnd, "append")) {
arg1 = NextTok(arg1, argEnd);
append = true;
options = true;
}
if (TokenMatches(arg1, argEnd, "prepend")) {
arg1 = NextTok(arg1, argEnd);
append = false;
options = true;
}
}

if (Macros_ParserError) {
Expand All @@ -2153,12 +2173,24 @@ static macro_result_t processActivateKeyPostponedCommand(const char* arg1, const

uint16_t keyid = parseNUM(arg1, argEnd);
key_state_t* key = Utils_KeyIdToKeyState(keyid);
if (PostponerQuery_IsActiveEventually(key)) {
PostponerCore_TrackKeyEvent(key, false, layer);
PostponerCore_TrackKeyEvent(key, true, layer);

if (append) {
if (PostponerQuery_IsActiveEventually(key)) {
PostponerCore_TrackKeyEvent(key, false, layer);
PostponerCore_TrackKeyEvent(key, true, layer);
} else {
PostponerCore_TrackKeyEvent(key, true, layer);
PostponerCore_TrackKeyEvent(key, false, layer);
}
} else {
PostponerCore_TrackKeyEvent(key, true, layer);
PostponerCore_TrackKeyEvent(key, false, layer);
if (KeyState_Active(key)) {
//reverse order when prepending
PostponerCore_PrependKeyEvent(key, true, layer);
PostponerCore_PrependKeyEvent(key, false, layer);
} else {
PostponerCore_PrependKeyEvent(key, false, layer);
PostponerCore_PrependKeyEvent(key, true, layer);
}
}
return MacroResult_Finished;
}
Expand Down Expand Up @@ -3410,3 +3442,13 @@ void Macros_ClearStatus(void)
{
processClearStatusCommand();
}

bool Macros_MacroHasActiveInstance(macro_index_t macroIdx)
{
for(uint8_t j = 0; j < MACRO_STATE_POOL_SIZE; j++) {
if(MacroState[j].ms.macroPlaying && MacroState[j].ms.currentMacroIndex == MacroIndex_UsbCmdReserved) {
return true;
}
}
return false;
}
1 change: 1 addition & 0 deletions right/src/macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,7 @@
void Macros_Initialize();
void Macros_ClearStatus();
bool Macros_IsLayerHeld();
bool Macros_MacroHasActiveInstance(macro_index_t macroIdx);
uint8_t Macros_ParseLayerId(const char* arg1, const char* cmdEnd);
int32_t Macros_ParseInt(const char *a, const char *aEnd, const char* *parsedTill);
bool Macros_ParseBoolean(const char *a, const char *aEnd);
Expand Down
Loading

0 comments on commit 9d6414c

Please sign in to comment.