Skip to content

Commit

Permalink
Adding keyBlock capability to support Programmmer's Dvorak
Browse files Browse the repository at this point in the history
- 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%
- Requires kll.git 1a078b2 or higher
  • Loading branch information
haata committed Aug 7, 2016
1 parent 253d96a commit 8a9945b
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 2 deletions.
71 changes: 71 additions & 0 deletions Keyboards/infinity_programmers_dvorak.bash
Original file line number Diff line number Diff line change
@@ -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

21 changes: 19 additions & 2 deletions Macro/PartialMap/capabilities.kll
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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 changes: 60 additions & 0 deletions Macro/PartialMap/macro.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 -----
Expand Down Expand Up @@ -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 -----

Expand Down Expand Up @@ -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()
Expand Down Expand Up @@ -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 );

Expand Down

0 comments on commit 8a9945b

Please sign in to comment.