diff options
Diffstat (limited to 'lib/python/qmk')
| -rw-r--r-- | lib/python/qmk/cli/__init__.py | 1 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/config_h.py | 4 | ||||
| -rwxr-xr-x | lib/python/qmk/cli/generate/keyboard_c.py | 38 | ||||
| -rw-r--r-- | lib/python/qmk/cli/generate/keymap_h.py | 51 | ||||
| -rw-r--r-- | lib/python/qmk/commands.py | 4 | ||||
| -rw-r--r-- | lib/python/qmk/constants.py | 2 | ||||
| -rw-r--r-- | lib/python/qmk/info.py | 19 | ||||
| -rw-r--r-- | lib/python/qmk/keymap.py | 34 | 
8 files changed, 114 insertions, 39 deletions
| diff --git a/lib/python/qmk/cli/__init__.py b/lib/python/qmk/cli/__init__.py index f331445870..0baf19a629 100644 --- a/lib/python/qmk/cli/__init__.py +++ b/lib/python/qmk/cli/__init__.py @@ -58,6 +58,7 @@ subcommands = [      'qmk.cli.generate.keyboard_h',      'qmk.cli.generate.keycodes',      'qmk.cli.generate.keycodes_tests', +    'qmk.cli.generate.keymap_h',      'qmk.cli.generate.make_dependencies',      'qmk.cli.generate.rgb_breathe_table',      'qmk.cli.generate.rules_mk', diff --git a/lib/python/qmk/cli/generate/config_h.py b/lib/python/qmk/cli/generate/config_h.py index fc681300a3..d613f7b92c 100755 --- a/lib/python/qmk/cli/generate/config_h.py +++ b/lib/python/qmk/cli/generate/config_h.py @@ -135,8 +135,8 @@ def generate_encoder_config(encoder_json, config_h_lines, postfix=''):          b_pads.append(encoder["pin_b"])          resolutions.append(encoder.get("resolution", None)) -    config_h_lines.append(generate_define(f'ENCODERS_PAD_A{postfix}', f'{{ {", ".join(a_pads)} }}')) -    config_h_lines.append(generate_define(f'ENCODERS_PAD_B{postfix}', f'{{ {", ".join(b_pads)} }}')) +    config_h_lines.append(generate_define(f'ENCODER_A_PINS{postfix}', f'{{ {", ".join(a_pads)} }}')) +    config_h_lines.append(generate_define(f'ENCODER_B_PINS{postfix}', f'{{ {", ".join(b_pads)} }}'))      if None in resolutions:          cli.log.debug(f"Unable to generate ENCODER_RESOLUTION{postfix} configuration") diff --git a/lib/python/qmk/cli/generate/keyboard_c.py b/lib/python/qmk/cli/generate/keyboard_c.py index 5a6c967486..228b320942 100755 --- a/lib/python/qmk/cli/generate/keyboard_c.py +++ b/lib/python/qmk/cli/generate/keyboard_c.py @@ -6,7 +6,7 @@ from qmk.info import info_json  from qmk.commands import dump_lines  from qmk.keyboard import keyboard_completer, keyboard_folder  from qmk.path import normpath -from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE +from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, JOYSTICK_AXES  def _gen_led_configs(info_data): @@ -91,6 +91,41 @@ def _gen_matrix_mask(info_data):      return lines +def _gen_joystick_axes(info_data): +    """Convert info.json content to joystick_axes +    """ +    if 'axes' not in info_data.get('joystick', {}): +        return [] + +    axes = info_data['joystick']['axes'] +    axes_keys = list(axes.keys()) + +    lines = [] +    lines.append('#ifdef JOYSTICK_ENABLE') +    lines.append('joystick_config_t joystick_axes[JOYSTICK_AXIS_COUNT] = {') + +    # loop over all available axes - injecting virtual axis for those not specified +    for index, cur in enumerate(JOYSTICK_AXES): +        # bail out if we have generated all requested axis +        if len(axes_keys) == 0: +            break + +        axis = 'virtual' +        if cur in axes: +            axis = axes[cur] +            axes_keys.remove(cur) + +        if axis == 'virtual': +            lines.append(f"    [{index}] = JOYSTICK_AXIS_VIRTUAL,") +        else: +            lines.append(f"    [{index}] = JOYSTICK_AXIS_IN({axis['input_pin']}, {axis['low']}, {axis['rest']}, {axis['high']}),") + +    lines.append('};') +    lines.append('#endif') + +    return lines + +  @cli.argument('-o', '--output', arg_only=True, type=normpath, help='File to write to')  @cli.argument('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages")  @cli.argument('-kb', '--keyboard', arg_only=True, type=keyboard_folder, completer=keyboard_completer, required=True, help='Keyboard to generate keyboard.c for.') @@ -105,6 +140,7 @@ def generate_keyboard_c(cli):      keyboard_h_lines.extend(_gen_led_configs(kb_info_json))      keyboard_h_lines.extend(_gen_matrix_mask(kb_info_json)) +    keyboard_h_lines.extend(_gen_joystick_axes(kb_info_json))      # Show the results      dump_lines(cli.args.output, keyboard_h_lines, cli.args.quiet) diff --git a/lib/python/qmk/cli/generate/keymap_h.py b/lib/python/qmk/cli/generate/keymap_h.py new file mode 100644 index 0000000000..a3aaa405c0 --- /dev/null +++ b/lib/python/qmk/cli/generate/keymap_h.py @@ -0,0 +1,51 @@ +from argcomplete.completers import FilesCompleter + +from milc import cli + +import qmk.path +from qmk.commands import dump_lines +from qmk.commands import parse_configurator_json +from qmk.constants import GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE + + +def _generate_keycodes_function(keymap_json): +    """Generates keymap level keycodes. +    """ +    lines = [] +    lines.append('enum keymap_keycodes {') + +    for index, item in enumerate(keymap_json.get('keycodes', [])): +        key = item["key"] +        if index == 0: +            lines.append(f'  {key} = QK_USER_0,') +        else: +            lines.append(f'  {key},') + +    lines.append('};') + +    for item in keymap_json.get('keycodes', []): +        key = item["key"] +        for alias in item.get("aliases", []): +            lines.append(f'#define {alias} {key}') + +    return lines + + [email protected]('-o', '--output', arg_only=True, type=qmk.path.normpath, help='File to write to') [email protected]('-q', '--quiet', arg_only=True, action='store_true', help="Quiet mode, only output error messages") [email protected]('filename', type=qmk.path.FileType('r'), arg_only=True, completer=FilesCompleter('.json'), help='Configurator JSON file') [email protected]('Creates a keymap.h from a QMK Configurator export.') +def generate_keymap_h(cli): +    """Creates a keymap.h from a QMK Configurator export +    """ +    if cli.args.output and cli.args.output.name == '-': +        cli.args.output = None + +    keymap_h_lines = [GPL2_HEADER_C_LIKE, GENERATED_HEADER_C_LIKE, '#pragma once', '// clang-format off'] + +    keymap_json = parse_configurator_json(cli.args.filename) + +    if 'keycodes' in keymap_json and keymap_json['keycodes'] is not None: +        keymap_h_lines += _generate_keycodes_function(keymap_json) + +    dump_lines(cli.args.output, keymap_h_lines, cli.args.quiet) diff --git a/lib/python/qmk/commands.py b/lib/python/qmk/commands.py index 3db8353bfd..873380c28b 100644 --- a/lib/python/qmk/commands.py +++ b/lib/python/qmk/commands.py @@ -102,7 +102,9 @@ def dump_lines(output_file, lines, quiet=True):          output_file.parent.mkdir(parents=True, exist_ok=True)          if output_file.exists():              output_file.replace(output_file.parent / (output_file.name + '.bak')) -        output_file.write_text(generated, encoding='utf-8') +        with open(output_file, 'w', encoding='utf-8', newline='\n') as f: +            f.write(generated) +        # output_file.write_text(generated, encoding='utf-8', newline='\n') # `newline` needs Python 3.10          if not quiet:              cli.log.info(f'Wrote {output_file.name} to {output_file}.') diff --git a/lib/python/qmk/constants.py b/lib/python/qmk/constants.py index 90e4452f2b..b6f46180b2 100644 --- a/lib/python/qmk/constants.py +++ b/lib/python/qmk/constants.py @@ -320,3 +320,5 @@ LICENSE_TEXTS = [          you may not use this file except in compliance with the License.          """]),  ] + +JOYSTICK_AXES = ['x', 'y', 'z', 'rx', 'ry', 'rz'] diff --git a/lib/python/qmk/info.py b/lib/python/qmk/info.py index 833271c09c..5b3b249015 100644 --- a/lib/python/qmk/info.py +++ b/lib/python/qmk/info.py @@ -7,7 +7,7 @@ from dotty_dict import dotty  from milc import cli -from qmk.constants import COL_LETTERS, ROW_LETTERS, CHIBIOS_PROCESSORS, LUFA_PROCESSORS, VUSB_PROCESSORS +from qmk.constants import COL_LETTERS, ROW_LETTERS, CHIBIOS_PROCESSORS, LUFA_PROCESSORS, VUSB_PROCESSORS, JOYSTICK_AXES  from qmk.c_parse import find_layouts, parse_config_h_file, find_led_config  from qmk.json_schema import deep_update, json_load, validate  from qmk.keyboard import config_h, rules_mk @@ -249,8 +249,9 @@ def info_json(keyboard):      info_data = _extract_rules_mk(info_data, rules_mk(str(keyboard)))      info_data = _extract_config_h(info_data, config_h(str(keyboard))) -    # Ensure that we have matrix row and column counts +    # Ensure that we have various calculated values      info_data = _matrix_size(info_data) +    info_data = _joystick_axis_count(info_data)      # Merge in data from <keyboard.c>      info_data = _extract_led_config(info_data, str(keyboard)) @@ -374,8 +375,8 @@ def _extract_audio(info_data, config_c):  def _extract_encoders_values(config_c, postfix=''):      """Common encoder extraction logic      """ -    a_pad = config_c.get(f'ENCODERS_PAD_A{postfix}', '').replace(' ', '')[1:-1] -    b_pad = config_c.get(f'ENCODERS_PAD_B{postfix}', '').replace(' ', '')[1:-1] +    a_pad = config_c.get(f'ENCODER_A_PINS{postfix}', '').replace(' ', '')[1:-1] +    b_pad = config_c.get(f'ENCODER_B_PINS{postfix}', '').replace(' ', '')[1:-1]      resolutions = config_c.get(f'ENCODER_RESOLUTIONS{postfix}', '').replace(' ', '')[1:-1]      default_resolution = config_c.get('ENCODER_RESOLUTION', None) @@ -800,6 +801,16 @@ def _matrix_size(info_data):      return info_data +def _joystick_axis_count(info_data): +    """Add info_data['joystick.axis_count'] if required +    """ +    if 'axes' in info_data.get('joystick', {}): +        axes_keys = info_data['joystick']['axes'].keys() +        info_data['joystick']['axis_count'] = max(JOYSTICK_AXES.index(a) for a in axes_keys) + 1 if axes_keys else 0 + +    return info_data + +  def _check_matrix(info_data):      """Check the matrix to ensure that row/column count is consistent.      """ diff --git a/lib/python/qmk/keymap.py b/lib/python/qmk/keymap.py index b7bf897377..ca76f1b288 100644 --- a/lib/python/qmk/keymap.py +++ b/lib/python/qmk/keymap.py @@ -19,6 +19,9 @@ from qmk.info import info_json  # The `keymap.c` template to use when a keyboard doesn't have its own  DEFAULT_KEYMAP_C = """#include QMK_KEYBOARD_H +#if __has_include("keymap.h") +#    include "keymap.h" +#endif  __INCLUDES__  /* THIS FILE WAS GENERATED! @@ -26,8 +29,6 @@ __INCLUDES__   * This file was generated by qmk json2c. You may or may not want to   * edit it directly.   */ -__KEYCODE_OUTPUT_GOES_HERE__ -  const uint16_t PROGMEM keymaps[][MATRIX_ROWS][MATRIX_COLS] = {  __KEYMAP_GOES_HERE__  }; @@ -125,29 +126,6 @@ def _generate_macros_function(keymap_json):      return macro_txt -def _generate_keycodes_function(keymap_json): -    """Generates keymap level keycodes. -    """ -    lines = [] -    lines.append('enum keymap_keycodes {') - -    for index, item in enumerate(keymap_json.get('keycodes', [])): -        key = item["key"] -        if index == 0: -            lines.append(f'  {key} = QK_USER_0,') -        else: -            lines.append(f'  {key},') - -    lines.append('};') - -    for item in keymap_json.get('keycodes', []): -        key = item["key"] -        for alias in item.get("aliases", []): -            lines.append(f'#define {alias} {key}') - -    return lines - -  def template_json(keyboard):      """Returns a `keymap.json` template for a keyboard. @@ -350,12 +328,6 @@ def generate_c(keymap_json):          hostlang = f'#include "keymap_{keymap_json["host_language"]}.h"\n#include "sendstring_{keymap_json["host_language"]}.h"\n'      new_keymap = new_keymap.replace('__INCLUDES__', hostlang) -    keycodes = '' -    if 'keycodes' in keymap_json and keymap_json['keycodes'] is not None: -        keycodes_txt = _generate_keycodes_function(keymap_json) -        keycodes = '\n'.join(keycodes_txt) -    new_keymap = new_keymap.replace('__KEYCODE_OUTPUT_GOES_HERE__', keycodes) -      return new_keymap | 
