wrote the ui-info generating script for Ben (aka OrangeJewce)
- also changed the kbfun function comments to be easier to parse - also added running the generating script to the toplevel build processpartial-rewrite
parent
ee6481d97d
commit
fe603948a9
|
@ -0,0 +1,355 @@
|
||||||
|
#! /usr/bin/env python3
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
"""
|
||||||
|
Generate UI info file (in JSON) (format version: 0)
|
||||||
|
|
||||||
|
The file will contain:
|
||||||
|
{
|
||||||
|
".meta-data": {
|
||||||
|
"version": <number>,
|
||||||
|
"date-generated": <string>,
|
||||||
|
},
|
||||||
|
"keyboard-functions": {
|
||||||
|
<(function name)>: {
|
||||||
|
"position": <number>,
|
||||||
|
"length": <number>,
|
||||||
|
"comments": {
|
||||||
|
"name": <string>,
|
||||||
|
"description": <string>,
|
||||||
|
"notes": [
|
||||||
|
<string>,
|
||||||
|
...
|
||||||
|
],
|
||||||
|
...
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"layout-matrices": {
|
||||||
|
<(matrix name)>: {
|
||||||
|
"position": <number>,
|
||||||
|
"length": <number>
|
||||||
|
},
|
||||||
|
...
|
||||||
|
},
|
||||||
|
"miscellaneous": {
|
||||||
|
"git-commit-date": <string>,
|
||||||
|
"git-commit-id": <string>,
|
||||||
|
"number-of-layers": <number>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Depends on:
|
||||||
|
- the project source code
|
||||||
|
- the project '.map' file (generated by the compiler)
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
Copyright (c) 2012 Ben Blazak <benblazak.dev@gmail.com>
|
||||||
|
Released under The MIT License (MIT) (see "license.md")
|
||||||
|
Project located at <https://github.com/benblazak/ergodox-firmware>
|
||||||
|
-----------------------------------------------------------------------------
|
||||||
|
"""
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
import json
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def gen_static(git_commit_date=None, git_commit_id=None):
|
||||||
|
"""Generate static information"""
|
||||||
|
|
||||||
|
date = None
|
||||||
|
if os.name == 'posix':
|
||||||
|
date = subprocess.getoutput('date --rfc-3339 s')
|
||||||
|
|
||||||
|
return {
|
||||||
|
'.meta-data': {
|
||||||
|
'version': 0, # the format version number
|
||||||
|
'date-generated': date,
|
||||||
|
},
|
||||||
|
'miscellaneous': {
|
||||||
|
'git-commit-date': git_commit_date, # should be passed by makefile
|
||||||
|
'git-commit-id': git_commit_id, # should be passed by makefile
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def gen_derived(data):
|
||||||
|
"""
|
||||||
|
Generate derived information
|
||||||
|
Should be called last
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
'miscellaneous': {
|
||||||
|
'number-of-layers':
|
||||||
|
int( data['layout-matrices']['_kb_layout']['length']/(6*14) ),
|
||||||
|
# because 6*14 is the number of bytes/layer for '_kb_layout'
|
||||||
|
# (which is a uint8_t matrix)
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def parse_mapfile(map_file_path):
|
||||||
|
"""Parse the '.map' file"""
|
||||||
|
|
||||||
|
def parse_keyboard_function(f, line):
|
||||||
|
"""Parse keyboard-functions in the '.map' file"""
|
||||||
|
|
||||||
|
search = re.search(r'(0x\S+)\s+(0x\S+)', next(f))
|
||||||
|
position = int( search.group(1), 16 )
|
||||||
|
length = int( search.group(2), 16 )
|
||||||
|
|
||||||
|
search = re.search(r'0x\S+\s+(\S+)', next(f))
|
||||||
|
name = search.group(1)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'keyboard-functions': {
|
||||||
|
name: {
|
||||||
|
'position': position,
|
||||||
|
'length': length,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
def parse_layout_matrices(f, line):
|
||||||
|
"""Parse (all 3) layout matrices"""
|
||||||
|
|
||||||
|
search = re.search(r'0x\S+\s+(0x\S+)', line)
|
||||||
|
# (length for (size of, in bytes) a layer of 1 byte objects)
|
||||||
|
base_length = int( int( search.group(1), 16 ) / 5 )
|
||||||
|
|
||||||
|
next_lines = ''.join([next(f), next(f), next(f)])
|
||||||
|
layout_position = re.search(
|
||||||
|
r'(0x\S+)\s+_kb_layout'+'\n', next_lines ) . group(1)
|
||||||
|
layout_press_position = re.search(
|
||||||
|
r'(0x\S+)\s+_kb_layout_press'+'\n', next_lines ) . group(1)
|
||||||
|
layout_release_position = re.search(
|
||||||
|
r'(0x\S+)\s+_kb_layout_release'+'\n', next_lines ) . group(1)
|
||||||
|
layout_position = int(layout_position, 16)
|
||||||
|
layout_press_position = int(layout_press_position, 16)
|
||||||
|
layout_release_position = int(layout_release_position, 16)
|
||||||
|
|
||||||
|
if not ( layout_position
|
||||||
|
and layout_press_position
|
||||||
|
and layout_release_position ):
|
||||||
|
raise Exception(
|
||||||
|
"parse_mapfile: not all layout matrices were found" )
|
||||||
|
|
||||||
|
return {
|
||||||
|
'layout-matrices': {
|
||||||
|
'_kb_layout': {
|
||||||
|
'position': layout_position,
|
||||||
|
'length': base_length,
|
||||||
|
},
|
||||||
|
'_kb_layout_press': {
|
||||||
|
'position': layout_press_position,
|
||||||
|
'length': base_length * 2,
|
||||||
|
},
|
||||||
|
'_kb_layout_release': {
|
||||||
|
'position': layout_release_position,
|
||||||
|
'length': base_length * 2,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- parse_mapfile() ---
|
||||||
|
|
||||||
|
# normalize paths
|
||||||
|
map_file_path = os.path.abspath(map_file_path)
|
||||||
|
# check paths
|
||||||
|
if not os.path.exists(map_file_path):
|
||||||
|
raise ValueError("invalid 'map_file_path' given")
|
||||||
|
|
||||||
|
output = {}
|
||||||
|
|
||||||
|
f = open(map_file_path)
|
||||||
|
|
||||||
|
for line in f:
|
||||||
|
if re.search(r'^\s*\.text\.kbfun_', line):
|
||||||
|
dict_merge(output, parse_keyboard_function(f, line))
|
||||||
|
elif re.search(r'^\s*\.progmem\.data.*layout', line):
|
||||||
|
dict_merge(output, parse_layout_matrices(f, line))
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
def parse_source_code(source_code_path):
|
||||||
|
"""Parse all files in the source directory"""
|
||||||
|
|
||||||
|
def read_comments(f, line):
|
||||||
|
"""
|
||||||
|
Read in properly formatted multi-line comments
|
||||||
|
- Comments must start with '/*' and end with '*/', each on their own
|
||||||
|
line
|
||||||
|
"""
|
||||||
|
comments = ''
|
||||||
|
while(line.strip() != r'*/'):
|
||||||
|
comments += line[2:].strip()+'\n'
|
||||||
|
line = next(f)
|
||||||
|
return comments
|
||||||
|
|
||||||
|
def parse_comments(comments):
|
||||||
|
"""
|
||||||
|
Parse an INI style comment string
|
||||||
|
- Fields begin with '[field-name]', and continue until the next field,
|
||||||
|
or the end of the comment
|
||||||
|
- Fields '[name]', '[description]', and '[note]' are treated specially
|
||||||
|
"""
|
||||||
|
|
||||||
|
def add_field(output, field, value):
|
||||||
|
"""Put a field+value pair in 'output', the way we want it, if the
|
||||||
|
pair is valid"""
|
||||||
|
|
||||||
|
value = value.strip()
|
||||||
|
|
||||||
|
if field is not None:
|
||||||
|
if field in ('name', 'description'):
|
||||||
|
if field not in output:
|
||||||
|
output[field] = value
|
||||||
|
else:
|
||||||
|
if field == 'note':
|
||||||
|
field = 'notes'
|
||||||
|
|
||||||
|
if field not in output:
|
||||||
|
output[field] = []
|
||||||
|
|
||||||
|
output[field] += [value]
|
||||||
|
|
||||||
|
# --- parse_comments() ---
|
||||||
|
|
||||||
|
output = {}
|
||||||
|
|
||||||
|
field = None
|
||||||
|
value = None
|
||||||
|
for line in comments.split('\n'):
|
||||||
|
line = line.strip()
|
||||||
|
|
||||||
|
if re.search(r'^\[.*\]$', line):
|
||||||
|
add_field(output, field, value)
|
||||||
|
field = line[1:-1]
|
||||||
|
value = None
|
||||||
|
|
||||||
|
else:
|
||||||
|
if value is None:
|
||||||
|
value = ''
|
||||||
|
if len(value) > 0 and value[-1] == '.':
|
||||||
|
line = ' '+line
|
||||||
|
value += ' '+line
|
||||||
|
|
||||||
|
add_field(output, field, value)
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
def parse_keyboard_function(f, line, comments):
|
||||||
|
"""Parse keyboard-functions in the source code"""
|
||||||
|
|
||||||
|
search = re.search(r'void\s+(kbfun_\S+)\s*\(void\)', line)
|
||||||
|
name = search.group(1)
|
||||||
|
|
||||||
|
return {
|
||||||
|
'keyboard-functions': {
|
||||||
|
name: {
|
||||||
|
'comments': parse_comments(comments),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- parse_source_code() ---
|
||||||
|
|
||||||
|
# normalize paths
|
||||||
|
source_dir_path = os.path.abspath(source_code_path)
|
||||||
|
# check paths
|
||||||
|
if not os.path.exists(source_code_path):
|
||||||
|
raise ValueError("invalid 'source_dir_path' given")
|
||||||
|
|
||||||
|
output = {}
|
||||||
|
|
||||||
|
for tup in os.walk(source_code_path):
|
||||||
|
for file_name in tup[2]:
|
||||||
|
# normalize paths
|
||||||
|
file_name = os.path.abspath( os.path.join( tup[0], file_name ) )
|
||||||
|
|
||||||
|
# ignore non '.c' files
|
||||||
|
if file_name[-2:] != '.c':
|
||||||
|
continue
|
||||||
|
|
||||||
|
f = open(file_name)
|
||||||
|
|
||||||
|
comments = ''
|
||||||
|
for line in f:
|
||||||
|
if line.strip() == r'/*':
|
||||||
|
comments = read_comments(f, line)
|
||||||
|
elif re.search(r'void\s+kbfun_\S+\s*\(void\)', line):
|
||||||
|
dict_merge(
|
||||||
|
output,
|
||||||
|
parse_keyboard_function(f, line, comments) )
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def dict_merge(a, b):
|
||||||
|
"""
|
||||||
|
Recursively merge two dictionaries
|
||||||
|
- I was looking around for an easy way to do this, and found something
|
||||||
|
[here]
|
||||||
|
(http://www.xormedia.com/recursively-merge-dictionaries-in-python.html).
|
||||||
|
This is pretty close, but i didn't copy it exactly.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if not isinstance(a, dict) or not isinstance(b, dict):
|
||||||
|
return b
|
||||||
|
|
||||||
|
for (key, value) in b.items():
|
||||||
|
if key in a:
|
||||||
|
a[key] = dict_merge(a[key], value)
|
||||||
|
else:
|
||||||
|
a[key] = value
|
||||||
|
|
||||||
|
return a
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def main():
|
||||||
|
arg_parser = argparse.ArgumentParser(
|
||||||
|
description = 'Generate project data for use with the UI' )
|
||||||
|
|
||||||
|
arg_parser.add_argument(
|
||||||
|
'--git-commit-date',
|
||||||
|
help = ( "should be in the format rfc-3339 "
|
||||||
|
+ "(e.g. 2006-08-07 12:34:56-06:00)" ),
|
||||||
|
required = True )
|
||||||
|
arg_parser.add_argument(
|
||||||
|
'--git-commit-id',
|
||||||
|
help = "the git commit ID",
|
||||||
|
required = True )
|
||||||
|
arg_parser.add_argument(
|
||||||
|
'--map-file-path',
|
||||||
|
help = "the path to the '.map' file",
|
||||||
|
required = True )
|
||||||
|
arg_parser.add_argument(
|
||||||
|
'--source-code-path',
|
||||||
|
help = "the path to the source code directory",
|
||||||
|
required = True )
|
||||||
|
|
||||||
|
args = arg_parser.parse_args(sys.argv[1:])
|
||||||
|
|
||||||
|
output = {}
|
||||||
|
dict_merge(output, gen_static(args.git_commit_date, args.git_commit_id))
|
||||||
|
dict_merge(output, parse_mapfile(args.map_file_path))
|
||||||
|
dict_merge(output, parse_source_code(args.source_code_path))
|
||||||
|
dict_merge(output, gen_derived(output))
|
||||||
|
|
||||||
|
print(json.dumps(output, sort_keys=True, indent=4))
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main()
|
||||||
|
|
19
makefile
19
makefile
|
@ -20,13 +20,13 @@
|
||||||
|
|
||||||
# the base name of the file or package to distribute
|
# the base name of the file or package to distribute
|
||||||
NAME := ergodox-firmware
|
NAME := ergodox-firmware
|
||||||
# the branch of the git repo we're currently on
|
# git info
|
||||||
BRANCH := $(shell git branch -l | grep '*' | cut -c 3-)
|
GIT_BRANCH := $(shell git branch -l | grep '*' | cut -c 3-)
|
||||||
# a version identifier
|
GIT_COMMIT_DATE := $(shell git log -n 1 --pretty --date=iso | grep 'Date' | cut -c 9- )
|
||||||
VERSION := $(shell git log -n 1 | grep 'commit' | cut -c 8-14)--$(shell date +'%Y%m%dT%H%M%S')
|
GIT_COMMIT_ID := $(shell git log -n 1 | grep 'commit' | cut -c 8-)
|
||||||
|
|
||||||
# name to use for the final distribution file or package
|
# name to use for the final distribution file or package
|
||||||
TARGET := $(NAME)--$(BRANCH)--$(VERSION)
|
TARGET := $(NAME)--$(GIT_BRANCH)--$(shell date -d "$(GIT_COMMIT_DATE)" +'%Y%m%dT%H%M%S')--$(shell echo $(GIT_COMMIT_ID) | cut -c 1-7)
|
||||||
|
|
||||||
# the build dir
|
# the build dir
|
||||||
BUILD := build
|
BUILD := build
|
||||||
|
@ -43,6 +43,8 @@ clean:
|
||||||
-rm -r '$(BUILD)'
|
-rm -r '$(BUILD)'
|
||||||
|
|
||||||
dist:
|
dist:
|
||||||
|
# make sure we're checked in
|
||||||
|
git commit -a
|
||||||
# set up the build dir
|
# set up the build dir
|
||||||
-rm -r '$(BUILD)/$(TARGET)'*
|
-rm -r '$(BUILD)/$(TARGET)'*
|
||||||
-mkdir -p '$(BUILD)/$(TARGET)'
|
-mkdir -p '$(BUILD)/$(TARGET)'
|
||||||
|
@ -53,6 +55,13 @@ dist:
|
||||||
( cd src; \
|
( cd src; \
|
||||||
cp firmware.hex firmware.eep firmware.map \
|
cp firmware.hex firmware.eep firmware.map \
|
||||||
'../$(BUILD)/$(TARGET)' )
|
'../$(BUILD)/$(TARGET)' )
|
||||||
|
# run secondary build scripts
|
||||||
|
( ./build-scripts/gen-ui-info.py \
|
||||||
|
--git-commit-date '$(GIT_COMMIT_DATE)' \
|
||||||
|
--git-commit-id '$(GIT_COMMIT_ID)' \
|
||||||
|
--map-file-path '$(BUILD)/$(TARGET)/firmware.map' \
|
||||||
|
--source-code-path 'src' \
|
||||||
|
) > '$(BUILD)/$(TARGET)/firmware--ui-info.json'
|
||||||
# make into a zip archive
|
# make into a zip archive
|
||||||
( cd '$(BUILD)/$(TARGET)'; \
|
( cd '$(BUILD)/$(TARGET)'; \
|
||||||
zip '../$(TARGET).zip' \
|
zip '../$(TARGET).zip' \
|
||||||
|
|
5
src/TODO
5
src/TODO
|
@ -1,7 +1,4 @@
|
||||||
- write the python script for Ben, to extract all that useful stuff from the
|
- think about how to implement variable length arrays, and write some
|
||||||
.map file and comments
|
|
||||||
|
|
||||||
- then i'll think about how to implement variable length arrays, and write some
|
|
||||||
|
|
||||||
- then i'll think about how to use them as stacks, to deal with layer issues
|
- then i'll think about how to use them as stacks, to deal with layer issues
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,11 @@
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Press|Release
|
* [name]
|
||||||
* - Generate a normal keypress or keyrelease
|
* Press|Release
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Generate a normal keypress or keyrelease
|
||||||
*/
|
*/
|
||||||
void kbfun_press_release(void) {
|
void kbfun_press_release(void) {
|
||||||
uint8_t keycode = kb_layout_get(layer, row, col);
|
uint8_t keycode = kb_layout_get(layer, row, col);
|
||||||
|
@ -33,8 +36,11 @@ void kbfun_press_release(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Toggle
|
* [name]
|
||||||
* - Toggle the key pressed or unpressed
|
* Toggle
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Toggle the key pressed or unpressed
|
||||||
*/
|
*/
|
||||||
void kbfun_toggle(void) {
|
void kbfun_toggle(void) {
|
||||||
uint8_t keycode = kb_layout_get(layer, row, col);
|
uint8_t keycode = kb_layout_get(layer, row, col);
|
||||||
|
@ -46,8 +52,11 @@ void kbfun_toggle(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Increase layer
|
* [name]
|
||||||
* - Increment the current layer by the value specified in the keymap (for all
|
* Increase layer
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Increment the current layer by the value specified in the keymap (for all
|
||||||
* non-masked keys)
|
* non-masked keys)
|
||||||
*/
|
*/
|
||||||
void kbfun_layer_inc(void) {
|
void kbfun_layer_inc(void) {
|
||||||
|
@ -56,8 +65,11 @@ void kbfun_layer_inc(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decrease layer
|
* [name]
|
||||||
* - Decrement the current layer by the value specified in the keymap (for all
|
* Decrease layer
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Decrement the current layer by the value specified in the keymap (for all
|
||||||
* non-masked keys)
|
* non-masked keys)
|
||||||
*/
|
*/
|
||||||
void kbfun_layer_dec(void) {
|
void kbfun_layer_dec(void) {
|
||||||
|
|
|
@ -12,6 +12,20 @@
|
||||||
#include "../public.h"
|
#include "../public.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// descriptions
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/*
|
||||||
|
* [name]
|
||||||
|
* Jump to Bootloader
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* For reflashing the controller
|
||||||
|
*/
|
||||||
|
void kbfun_jump_to_bootloader(void);
|
||||||
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
#if MAKEFILE_BOARD == teensy-2-0
|
#if MAKEFILE_BOARD == teensy-2-0
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -110,8 +110,11 @@ static void _toggle_numpad(uint8_t numpad_layer) {
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Numpad toggle
|
* [name]
|
||||||
* - Toggles the numpad and sets numlock on (for active) or off (for inactive)
|
* Numpad toggle
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Toggles the numpad and sets numlock on (for active) or off (for inactive)
|
||||||
* with it, if it's not already in that state
|
* with it, if it's not already in that state
|
||||||
*/
|
*/
|
||||||
void kbfun_layermask_numpad_toggle(void) {
|
void kbfun_layermask_numpad_toggle(void) {
|
||||||
|
@ -120,8 +123,11 @@ void kbfun_layermask_numpad_toggle(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Numpad on
|
* [name]
|
||||||
* - Set the numpad on (along with numlock, if it's not already)
|
* Numpad on
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Set the numpad on (along with numlock, if it's not already)
|
||||||
*/
|
*/
|
||||||
void kbfun_layermask_numpad_on(void) {
|
void kbfun_layermask_numpad_on(void) {
|
||||||
uint8_t keycode = kb_layout_get(layer, row, col);
|
uint8_t keycode = kb_layout_get(layer, row, col);
|
||||||
|
@ -130,8 +136,11 @@ void kbfun_layermask_numpad_on(void) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Numpad off
|
* [name]
|
||||||
* - Set the numpad off (along with numlock, if it's not already)
|
* Numpad off
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Set the numpad off (along with numlock, if it's not already)
|
||||||
*/
|
*/
|
||||||
void kbfun_layermask_numpad_off(void) {
|
void kbfun_layermask_numpad_off(void) {
|
||||||
uint8_t keycode = kb_layout_get(layer, row, col);
|
uint8_t keycode = kb_layout_get(layer, row, col);
|
||||||
|
|
|
@ -28,13 +28,16 @@
|
||||||
// ----------------------------------------------------------------------------
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Increase layer, Execute key
|
* [name]
|
||||||
* - Increment the current layer by the value specified in the keymap (for all
|
* Increase layer, Execute key
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Increment the current layer by the value specified in the keymap (for all
|
||||||
* non-masked keys), and execute (usually press|release) the key in the same
|
* non-masked keys), and execute (usually press|release) the key in the same
|
||||||
* position on that new layer
|
* position on that new layer
|
||||||
*
|
*
|
||||||
* Note
|
* [note]
|
||||||
* - Meant to be paired with `kbfun_layer_dec_exec()`
|
* Meant to be paired with `kbfun_layer_dec_exec()`
|
||||||
*/
|
*/
|
||||||
void kbfun_layer_inc_exec(void) {
|
void kbfun_layer_inc_exec(void) {
|
||||||
uint8_t keycode = kb_layout_get(layer, row, col);
|
uint8_t keycode = kb_layout_get(layer, row, col);
|
||||||
|
@ -51,13 +54,16 @@ void kbfun_layer_inc_exec(void) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Decrease layer, Execute key
|
* [name]
|
||||||
* - Decrement the current layer by the value specified in the keymap (for all
|
* Decrease layer, Execute key
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* Decrement the current layer by the value specified in the keymap (for all
|
||||||
* non-masked keys), and execute (usually press|release) the key in the same
|
* non-masked keys), and execute (usually press|release) the key in the same
|
||||||
* position on that new layer
|
* position on that new layer
|
||||||
*
|
*
|
||||||
* Note
|
* [note]
|
||||||
* - Meant to be paired with `kbfun_layer_inc_exec()`
|
* Meant to be paired with `kbfun_layer_inc_exec()`
|
||||||
*/
|
*/
|
||||||
void kbfun_layer_dec_exec(void) {
|
void kbfun_layer_dec_exec(void) {
|
||||||
uint8_t keycode = kb_layout_get(layer, row, col);
|
uint8_t keycode = kb_layout_get(layer, row, col);
|
||||||
|
@ -74,13 +80,16 @@ void kbfun_layer_dec_exec(void) {
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Two keys => capslock
|
* [name]
|
||||||
* - When assigned to two keys (e.g. the physical left and right shift keys)
|
* Two keys => capslock
|
||||||
|
*
|
||||||
|
* [description]
|
||||||
|
* When assigned to two keys (e.g. the physical left and right shift keys)
|
||||||
* (in both the press and release matrices), pressing and holding down one of
|
* (in both the press and release matrices), pressing and holding down one of
|
||||||
* the keys will make the second key toggle capslock
|
* the keys will make the second key toggle capslock
|
||||||
*
|
*
|
||||||
* Note
|
* [note]
|
||||||
* - If either of the shifts are pressed when the second key is pressed, they
|
* If either of the shifts are pressed when the second key is pressed, they
|
||||||
* wil be released so that capslock will register properly when pressed.
|
* wil be released so that capslock will register properly when pressed.
|
||||||
* Capslock will then be pressed and released, and the original state of the
|
* Capslock will then be pressed and released, and the original state of the
|
||||||
* shifts will be restored
|
* shifts will be restored
|
||||||
|
|
Loading…
Reference in New Issue