Skip to content
This repository has been archived by the owner on Dec 14, 2023. It is now read-only.

Commit

Permalink
Remove multiple anymod limitation.
Browse files Browse the repository at this point in the history
Closes #22
  • Loading branch information
humblehacker committed Jul 30, 2010
1 parent abcb2c4 commit 9714b47
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 48 deletions.
17 changes: 17 additions & 0 deletions firmware/kbgen/KbInternals.rb
Expand Up @@ -258,6 +258,23 @@ def initialize
:R_CTRL => 'RC', :R_SHFT => 'RS', :R_ALT => 'RA', :R_GUI => 'RG',
:A_CTRL => 'AC', :A_SHFT => 'AS', :A_ALT => 'AA', :A_GUI => 'AG' }

# returns the low byte of the argument 'modifiers' as 'stdmods',
# and the high nibble of 'modifiers' duplicated as the high and low
# nibbles of 'anymods'
def get_premods(modifiers)
stdmods = modifiers & 0x00FF
anymods = (modifiers & 0x0F00) >> 4;
anymods |= anymods >> 4;
return stdmods, anymods
end

# returns the low byte of 'modifiers', with the 'anymods' portion
# shifted down to the position of the right modifiers. For example,
# A_ALT would become R_ALT.
def get_mods(modifiers)
return modifiers & 0x00FF | ((modifiers & 0x0F00) >> 4);
end

def process_modifier(mod_text, convertanymods)
case mod_text
when "left_alt"
Expand Down
42 changes: 39 additions & 3 deletions firmware/kbgen/templates/binding.erb.c
Expand Up @@ -23,6 +23,41 @@

#include "binding.h"

/*
* PreMods
*/

static const uint8_t hi_mask = 0x00F0;
static const uint8_t lo_mask = 0x000F;

bool
PreMods__exact_match(const PreMods *this, uint8_t mods)
{
uint8_t br = (this->std & hi_mask) >> 4;
uint8_t pr = (mods & hi_mask) >> 4;
uint8_t bl = this->std & lo_mask;
uint8_t pl = mods & lo_mask;
uint8_t al = this->any & lo_mask;
return ((!this->std || ((mods&this->std)==this->std)) && ((((pl&~bl)|(pr&~br)))==al));
}

bool
PreMods__near_match(const PreMods *this, uint8_t mods)
{
uint8_t br = (this->std & hi_mask) >> 4;
uint8_t pr = (mods & hi_mask) >> 4;
uint8_t bl = this->std & lo_mask;
uint8_t pl = mods & lo_mask;
uint8_t al = this->any & lo_mask;
return ((!this->std || ((mods&this->std)==this->std)) && ((((pl&~bl)|(pr&~br))&al)==al));
}

bool
PreMods__is_empty(const PreMods *this)
{
return this->std == NONE && this->any == NONE;
}

/*
* KeyBinding
*/
Expand Down Expand Up @@ -92,12 +127,12 @@ MacroTarget__get_map_target(const MacroTarget *this, uint8_t index)
key.kbindings.each do |premods, kbinding|
ident = kbinding_identifier(keymap, key.location, premods, kbinding.class)
if kbinding.instance_of? Map %>
const MapTarget <%=ident%> PROGMEM = { <%=kbinding.modifiers%>, HID_USAGE_<%=normalize_identifier(kbinding.usage.name)%> };<%
const MapTarget <%=ident%> PROGMEM = { 0x<%= get_mods(kbinding.modifiers).to_s(16) %>, HID_USAGE_<%=normalize_identifier(kbinding.usage.name)%> };<%
elsif kbinding.instance_of? Macro %>
const MapTarget <%=ident%>Targets[] PROGMEM =
{
<% kbinding.kbindings.each do |macro_kbinding| %>
{ <%=macro_kbinding.modifiers%>, HID_USAGE_<%=normalize_identifier(macro_kbinding.usage.name)%> },
{ 0x<%= get_mods(macro_kbinding.modifiers).to_s(16) %>, HID_USAGE_<%=normalize_identifier(macro_kbinding.usage.name)%> },
<% end %>
};

Expand Down Expand Up @@ -129,7 +164,8 @@ const KeyBinding <%= "#{keymap.ids.last}_#{key.location}" %>[] PROGMEM =
else
%><%="/* What? */"%>, <%
end
%><%= premods %>, (void*)&<%= kbinding_identifier(keymap, key.location, premods, kbinding.class) %> }, <%
stdmods, anymods = get_premods(premods)
%>{ 0x<%=stdmods.to_s(16)%>, 0x<%=anymods.to_s(16)%> }, (void*)&<%= kbinding_identifier(keymap, key.location, premods, kbinding.class) %> }, <%
end %>
};
<%
Expand Down
19 changes: 17 additions & 2 deletions firmware/kbgen/templates/binding.erb.h
Expand Up @@ -32,16 +32,31 @@ typedef struct MacroTarget MacroTarget;
typedef struct MapTarget MapTarget;
typedef struct KeyBinding KeyBinding;
typedef struct KeyBindingArray KeyBindingArray;
typedef struct PreMods PreMods;
typedef const KeyBindingArray* KeyMap;

/*
* PreMods
*/

struct PreMods
{
uint8_t std;
uint8_t any;
};

bool PreMods__exact_match(const PreMods *this, uint8_t mods);
bool PreMods__near_match(const PreMods *this, uint8_t mods);
bool PreMods__is_empty(const PreMods *this);

/*
* KeyBinding
*/

struct KeyBinding
{
enum {NOMAP, MAP, MODE, MACRO} kind;
Modifiers premods;
PreMods premods;
void *target;
};

Expand Down Expand Up @@ -85,7 +100,7 @@ struct ModeTarget

struct MapTarget
{
Modifiers modifiers;
uint8_t modifiers;
Usage usage;
};

Expand Down
36 changes: 4 additions & 32 deletions firmware/src/bound_key.c
Expand Up @@ -22,34 +22,6 @@ BoundKey__deactivate(BoundKey *this)
this->cell = DEACTIVATED;
}

static const uint16_t hi_mask = 0x0F00;
static const uint16_t mid_mask = 0x00F0;
static const uint16_t lo_mask = 0x000F;

bool exact(uint16_t b, uint16_t p)
{
uint8_t a = (b & hi_mask) >> 8;
uint8_t br = (b & mid_mask) >> 4;
uint8_t pr = (p & mid_mask) >> 4;
uint8_t bl = b & lo_mask;
uint8_t pl = p & lo_mask;
b &= ~hi_mask;
p &= ~hi_mask;
return ((!b || ((p&b)==b)) && ((((pl&~bl)|(pr&~br)))==a));
}

bool near(uint16_t b, uint16_t p)
{
uint8_t a = (b & hi_mask) >> 8;
uint8_t br = (b & mid_mask) >> 4;
uint8_t pr = (p & mid_mask) >> 4;
uint8_t bl = b & lo_mask;
uint8_t pl = p & lo_mask;
b &= ~hi_mask;
p &= ~hi_mask;
return ((!b || ((p&b)==b)) && ((((pl&~bl)|(pr&~br))&a)==a));
}

void
BoundKey__update_binding(BoundKey *this, Modifiers mods, KeyMap keymap)
{
Expand All @@ -63,7 +35,7 @@ BoundKey__update_binding(BoundKey *this, Modifiers mods, KeyMap keymap)
for (int i = 0; i < bindings.length; ++i)
{
const KeyBinding *binding = KeyBindingArray__get_binding(&bindings, i);
if (exact(binding->premods, mods))
if (PreMods__exact_match(&binding->premods, mods))
{
KeyBinding__copy(binding, &this->binding);
return;
Expand All @@ -74,7 +46,7 @@ BoundKey__update_binding(BoundKey *this, Modifiers mods, KeyMap keymap)
for (int i = 0; i < bindings.length; ++i)
{
const KeyBinding *binding = KeyBindingArray__get_binding(&bindings, i);
if (near(binding->premods, mods))
if (PreMods__near_match(&binding->premods, mods))
{
KeyBinding__copy(binding, &this->binding);
return;
Expand All @@ -85,9 +57,9 @@ BoundKey__update_binding(BoundKey *this, Modifiers mods, KeyMap keymap)
// TODO: the code generator must ensure that the
// following assumption is correct, the first
// binding will be the one and only binding with
// premods == NONE.
// empty premods.
const KeyBinding *binding = KeyBindingArray__get_binding(&bindings, 0);
if (binding->premods == NONE)
if (PreMods__is_empty(&binding->premods))
{
KeyBinding__copy(binding, &this->binding);
return;
Expand Down
19 changes: 8 additions & 11 deletions firmware/src/keyboard_class.c
Expand Up @@ -248,7 +248,8 @@ modifier_keys_engaged(KeyboardReport *report)
if ((this_modifier = get_modifier(target->usage)) != NONE)
{
active_modifiers |= this_modifier;
KeyboardReport__reset_modifiers(report, key->binding.premods);
KeyboardReport__reset_modifiers(report, key->binding.premods.std);
KeyboardReport__reset_modifiers(report, key->binding.premods.any);
BoundKey__deactivate(key);
}
}
Expand Down Expand Up @@ -322,8 +323,8 @@ process_keys(KeyboardReport *report)
{
uint8_t current_mods = KeyboardReport__get_modifiers(report);
const MapTarget *target = KeyBinding__get_map_target(&key->binding);
if (ActiveKeys__count(&kb.active_keys) > 1 &&
((current_mods & ~key->binding.premods) | target->modifiers) != current_mods)
if (ActiveKeys__count(&kb.active_keys) > 1
&& (((current_mods & ~key->binding.premods.std) & ~key->binding.premods.any) | target->modifiers) != current_mods)
{
if (KeyboardReport__has_key(&kb.prev_report, target->usage))
{
Expand All @@ -336,10 +337,8 @@ process_keys(KeyboardReport *report)
// Key is arriving, assume others are leaving and block them
block_others = true;
KeyboardReport__add_key(report, target->usage);
uint8_t anymods = ((key->binding.premods & 0x0F00) >> 4)
| ((key->binding.premods & 0x0F00) >> 8);
KeyboardReport__reset_modifiers(report, anymods);
KeyboardReport__reset_modifiers(report, key->binding.premods);
KeyboardReport__reset_modifiers(report, key->binding.premods.std);
KeyboardReport__reset_modifiers(report, key->binding.premods.any);
KeyboardReport__set_modifiers(report, target->modifiers);
BoundKey__deactivate(key);
}
Expand All @@ -363,10 +362,8 @@ process_keys(KeyboardReport *report)
{
const MapTarget *target = KeyBinding__get_map_target(&key->binding);
KeyboardReport__add_key(report, target->usage);
uint8_t anymods = ((key->binding.premods & 0x0F00) >> 4)
| ((key->binding.premods & 0x0F00) >> 8);
KeyboardReport__reset_modifiers(report, anymods);
KeyboardReport__reset_modifiers(report, key->binding.premods);
KeyboardReport__reset_modifiers(report, key->binding.premods.std);
KeyboardReport__reset_modifiers(report, key->binding.premods.any);
KeyboardReport__set_modifiers(report, target->modifiers);
break;
}
Expand Down

0 comments on commit 9714b47

Please sign in to comment.