Browse Source

Adding keyBlock capability to support Programmmer's Dvorak

- Useful for partial redefinitions of keys
  Such as redefining Shift, which, as per the USB spec is handled by the OS
  This means we have to careful select which USB Codes to send to the OS to simulate Shift not being pressed (while it is)
- KLL capabilities only work with numerical arguments (KLL 0.3d)
- Each key must be explicitly block for each combination (e.g. LShift and RShift are handled separately)

- Adding example configuration for the Infinity 60%
- Adding example configuration for the Infinity Ergodox
- Requires kll.git 1a078b2b94 or higher
blockKey
Jacob Alexander 7 years ago
parent
commit
a5203da1d4

+ 95
- 0
Keyboards/ergodox_programmers_dvorak.bash View File

@@ -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



+ 71
- 0
Keyboards/infinity_programmers_dvorak.bash View File

@@ -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


+ 19
- 2
Macro/PartialMap/capabilities.kll View File

@@ -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;


+ 60
- 0
Macro/PartialMap/macro.c View File

@@ -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 );