diff --git a/Keyboards/ergodox_programmers_dvorak.bash b/Keyboards/ergodox_programmers_dvorak.bash new file mode 100755 index 0000000..a691d67 --- /dev/null +++ b/Keyboards/ergodox_programmers_dvorak.bash @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +# This script shows how to use a complex multi-file layout such as Programmer's Dvorak +# Jacob Alexander 2015-2016 + + + +################# +# Configuration # +################# + +######## Left Side ######## + +# Feel free to change the variables in this section to configure your keyboard + +BuildPath="ICED-L" + +## KLL Configuration ## + +# Generally shouldn't be changed, this will affect every layer +BaseMap="scancode_map leftHand slave1 rightHand" + +# This is the default layer of the keyboard +# NOTE: To combine kll files into a single layout, separate them by spaces +# e.g. DefaultMap="mylayout mylayoutmod" +DefaultMap="programmers_dvorak_default lcdFuncMap" + +# This is where you set the additional layers +# NOTE: Indexing starts at 1 +# NOTE: Each new layer is another array entry +# e.g. PartialMaps[1]="layer1 layer1mod" +# PartialMaps[2]="layer2" +# PartialMaps[3]="layer3" +PartialMaps[1]="programmers_dvorak_shift" + + + +########################## +# Advanced Configuration # +########################## + +# Don't change the variables in this section unless you know what you're doing +# These are useful for completely custom keyboards +# NOTE: Changing any of these variables will require a force build to compile correctly + +# Keyboard Module Configuration +ScanModule="Infinity_Ergodox" +MacroModule="PartialMap" +OutputModule="pjrcUSB" +DebugModule="full" + +# Microcontroller +Chip="mk20dx256vlh7" + +# Compiler Selection +Compiler="gcc" + + + +######################## +# Bash Library Include # +######################## + +# Shouldn't need to touch this section + +# Check if the library can be found +if [ ! -f cmake.bash ]; then + echo "ERROR: Cannot find 'cmake.bash'" + exit 1 +fi + +# Load the library +source cmake.bash + + + +######################### +# Re-run for right side # +######################### + +######## Right Side ######## + +# Feel free to change the variables in this section to configure your keyboard + +BuildPath="ICED-R" + +## KLL Configuration ## + +# Only changing the basemap (everything else is the same) +# Generally shouldn't be changed, this will affect every layer +BaseMap="defaultMap rightHand slave1 leftHand" + +# Load the library (starts the build) +source cmake.bash + + diff --git a/Keyboards/infinity_programmers_dvorak.bash b/Keyboards/infinity_programmers_dvorak.bash new file mode 100755 index 0000000..e9062cc --- /dev/null +++ b/Keyboards/infinity_programmers_dvorak.bash @@ -0,0 +1,71 @@ +#!/usr/bin/env bash +# This script shows how to use a complex multi-file layout such as Programmer's Dvorak +# Jacob Alexander 2016 + + + +################# +# Configuration # +################# + +# Feel free to change the variables in this section to configure your keyboard + +BuildPath="IC60" + +## KLL Configuration ## + +# Generally shouldn't be changed, this will affect every layer +BaseMap="scancode_map" + +# This is the default layer of the keyboard +# NOTE: To combine kll files into a single layout, separate them by spaces +# e.g. DefaultMap="mylayout mylayoutmod" +DefaultMap="programmers_dvorak_default stdFuncMap" + +# This is where you set the additional layers +# NOTE: Indexing starts at 1 +# NOTE: Each new layer is another array entry +# e.g. PartialMaps[1]="layer1 layer1mod" +# PartialMaps[2]="layer2" +# PartialMaps[3]="layer3" +PartialMaps[1]="programmers_dvorak_shift" + + + +########################## +# Advanced Configuration # +########################## + +# Don't change the variables in this section unless you know what you're doing +# These are useful for completely custom keyboards +# NOTE: Changing any of these variables will require a force build to compile correctly + +# Keyboard Module Configuration +ScanModule="Infinity_60%" +MacroModule="PartialMap" +OutputModule="pjrcUSB" +DebugModule="full" + +# Microcontroller +Chip="mk20dx128vlf5" + +# Compiler Selection +Compiler="gcc" + + + +######################## +# Bash Library Include # +######################## + +# Shouldn't need to touch this section + +# Check if the library can be found +if [ ! -f cmake.bash ]; then + echo "ERROR: Cannot find 'cmake.bash'" + exit 1 +fi + +# Load the library +source cmake.bash + diff --git a/Macro/PartialMap/capabilities.kll b/Macro/PartialMap/capabilities.kll index 5261754..5e182c0 100644 --- a/Macro/PartialMap/capabilities.kll +++ b/Macro/PartialMap/capabilities.kll @@ -1,10 +1,10 @@ Name = PartialMapCapabilities; -Version = 0.3; +Version = 0.4; Author = "HaaTa (Jacob Alexander) 2014-2016"; KLL = 0.3d; # Modified Date -Date = 2016-04-08; +Date = 2016-08-06; # Capabilties available to the PartialMap module @@ -25,3 +25,20 @@ stateWordSize = 8; # Default for now, increase to 16 or 32 for higher limits indexWordSize => IndexWordSize_define; indexWordSize = 16; # Default for now, increase to 32 for higher limits (8 for less resource usage) +# Block Key Capability +# Add this capability as a combo to any key you want to explicitly block another +# For example: +# To turn Shift+1 into q +# U"Shift" + U"1" : U"Q" + blockKey( 0xE1 ) + blockKey( 0x1E ); +# +# 0xE1 - Left Shift (0xE5 is Right Shift) +# 0x1E - 1 +# +# NOTE: KLL is limited to using numbers for key blocking instead of the symbolic names +# A future version of KLL will address this +blockKey => Macro_blockUSBKey_capability( usbCode : 1 ); + +# This defines the maximum number of keys that can be blocked in a single processing loop +maxBlockCount => Macro_maxBlockCount_define; +maxBlockCount = 4; + diff --git a/Macro/PartialMap/macro.c b/Macro/PartialMap/macro.c index 68eb42a..6ec480f 100644 --- a/Macro/PartialMap/macro.c +++ b/Macro/PartialMap/macro.c @@ -131,6 +131,10 @@ TriggerGuide macroInterconnectCache[ MaxScanCode ]; uint8_t macroInterconnectCacheSize = 0; #endif +// Key blocking buffer +uint8_t macroHidBlockList[ Macro_maxBlockCount_define ]; +uint8_t macroHidBlockListSize; + // ----- Capabilities ----- @@ -370,6 +374,39 @@ void Macro_layerRotate_capability( uint8_t state, uint8_t stateType, uint8_t *ar } +// Block USB Key +// During the next processing cycle, queue up a key to be ignored +// e.g. If Shift is assigned to both Shift and Layer 1 +// Then if the 1 key on Layer 1 is assigned 2 +// Block the Shift key so a USB 2 can be sent via the Output channel +// This works by having a queue of keys to "unset" if they are triggered during the next processing loop +void Macro_blockUSBKey_capability( uint8_t state, uint8_t stateType, uint8_t *args ) +{ + // Display capability name + if ( stateType == 0xFF && state == 0xFF ) + { + print("Macro_blockUSBKey(usbCode)"); + return; + } + + // Get usb key from arguments + // Access argument directly as it's already uint8_t + uint8_t usbCode = args[0]; + + // Add to the hid block list + if ( macroHidBlockListSize < Macro_maxBlockCount_define ) + { + macroHidBlockList[ macroHidBlockListSize++ ] = usbCode; + } + else + { + warn_print("USB Key Block buffer is full!: "); + printHex( usbCode ); + print( NL ); + } +} + + // ----- Functions ----- @@ -681,6 +718,26 @@ void Macro_appendResultMacroToPendingList( const TriggerMacro *triggerMacro ) } +// Block any of the keys that may be in the buffer +// These keys may not be pressed during the processing loop, but block them anyways +// See Macro_blockUSBKey_capability for more details on usage +inline void Macro_processKeyBlocking() +{ + // Iterate over list of USB keys + for ( uint8_t key = 0; key < Macro_maxBlockCount_define; key++ ) + { + // This capability will always unset (doesn't toggle) + + // First we need to generate the argument + uint8_t args[] = { macroHidBlockList[ key ] }; + + // XXX Only handles normal keys (no analog, yet) + // 0x03 is release, which always unsets a key from the USB buffer, even if it's not there + Output_usbCodeSend_capability( 0x03, 0x00, args ); + } +} + + // Macro Procesing Loop // Called once per USB buffer send inline void Macro_process() @@ -758,6 +815,9 @@ inline void Macro_process() // Process result macros Result_process(); + // Process Key Blocking + Macro_processKeyBlocking(); + // Signal buffer that we've used it Scan_finishedWithMacro( macroTriggerListBufferSize );