diff --git a/README.md b/README.md index 5a4a912..5d71342 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ Afterwards you can execute the script with `pipenv run`. Use the `-h` / `--help` ``` $ pipenv run python squeek2lvgl.py --help -usage: squeek2lvgl.py [-h] --input INPUT [--generate-scancodes] [--output OUTPUT] +usage: squeek2lvgl.py [-h] --input INPUT [--surround-space-with-arrows] [--generate-scancodes] --output OUTPUT Convert squeekboard layouts to LVGL-compatible C code. @@ -24,6 +24,8 @@ optional arguments: -h, --help show this help message and exit --input INPUT squeekboard layout to use as input for generation. Has to be a YAML file path relative to data/keyboards. Can be specified multiple times. + --surround-space-with-arrows + insert left / right arrow before / after space key --generate-scancodes also generate scancode tables (only works for US layout currently) --output OUTPUT output directory for generated files ``` diff --git a/examples/us-terminal-with-scancodes/sq2lv_layouts.c b/examples/us-terminal-with-scancodes/sq2lv_layouts.c index c235790..e82b8a3 100644 --- a/examples/us-terminal-with-scancodes/sq2lv_layouts.c +++ b/examples/us-terminal-with-scancodes/sq2lv_layouts.c @@ -18,7 +18,7 @@ static const char * const keycaps_lower_terminal_us[] = { \ "q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\n", \ "a", "s", "d", "f", "g", "h", "j", "k", "l", "\n", \ "ABC", "z", "x", "c", "v", "b", "n", "m", LV_SYMBOL_BACKSPACE, "\n", \ - "1#", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, "" \ + "1#", " ", LV_SYMBOL_OK, "" \ }; static const lv_btnmatrix_ctrl_t attributes_lower_terminal_us[] = { \ @@ -26,7 +26,17 @@ static const lv_btnmatrix_ctrl_t attributes_lower_terminal_us[] = { \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, 2, 2, \ LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \ - LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ + LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ +}; + +static const int num_switchers_lower_terminal_us = 2; + +static const int switcher_idxs_lower_terminal_us[] = { \ + 25, 34 \ +}; + +static const int switcher_dests_lower_terminal_us[] = { \ + 1, 2 \ }; static const int num_scancodes_lower_terminal_us = 5; @@ -36,7 +46,7 @@ static const int scancodes_lower_terminal_us[] = { \ KEY_Q, KEY_W, KEY_E, KEY_R, KEY_T, KEY_Y, KEY_U, KEY_I, KEY_O, KEY_P, \ KEY_A, KEY_S, KEY_D, KEY_F, KEY_G, KEY_H, KEY_J, KEY_K, KEY_L, \ KEY_Z, KEY_X, KEY_C, KEY_V, KEY_B, KEY_N, KEY_M, KEY_BACKSPACE, \ - KEY_LEFT, KEY_SPACE, KEY_RIGHT, KEY_ENTER \ + KEY_SPACE, KEY_ENTER \ }; static const int scancode_idxs_lower_terminal_us[] = { \ @@ -44,7 +54,7 @@ static const int scancode_idxs_lower_terminal_us[] = { \ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ 16, 17, 18, 19, 20, 21, 22, 23, 24, \ -1, 25, 26, 27, 28, 29, 30, 31, 32, \ - -1, 33, 34, 35, 36 \ + -1, 33, 34 \ }; static const int scancode_nums_lower_terminal_us[] = { \ @@ -52,7 +62,7 @@ static const int scancode_nums_lower_terminal_us[] = { \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 0, 1, 1, 1, 1, 1, 1, 1, 1, \ - 0, 1, 1, 1, 1 \ + 0, 1, 1 \ }; /* Layer: Uppercase letters - generated from upper */ @@ -62,7 +72,7 @@ static const char * const keycaps_upper_terminal_us[] = { \ "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\n", \ "A", "S", "D", "F", "G", "H", "J", "K", "L", "\n", \ "abc", "Z", "X", "C", "V", "B", "N", "M", LV_SYMBOL_BACKSPACE, "\n", \ - "1#", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, LV_SYMBOL_OK, "" \ + "1#", " ", LV_SYMBOL_OK, "" \ }; static const lv_btnmatrix_ctrl_t attributes_upper_terminal_us[] = { \ @@ -70,7 +80,17 @@ static const lv_btnmatrix_ctrl_t attributes_upper_terminal_us[] = { \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, 2, 2, \ LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \ - LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ + LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ +}; + +static const int num_switchers_upper_terminal_us = 2; + +static const int switcher_idxs_upper_terminal_us[] = { \ + 25, 34 \ +}; + +static const int switcher_dests_upper_terminal_us[] = { \ + 1, 2 \ }; static const int num_scancodes_upper_terminal_us = 5; @@ -80,7 +100,7 @@ static const int scancodes_upper_terminal_us[] = { \ KEY_LEFTSHIFT, KEY_Q, KEY_LEFTSHIFT, KEY_W, KEY_LEFTSHIFT, KEY_E, KEY_LEFTSHIFT, KEY_R, KEY_LEFTSHIFT, KEY_T, KEY_LEFTSHIFT, KEY_Y, KEY_LEFTSHIFT, KEY_U, KEY_LEFTSHIFT, KEY_I, KEY_LEFTSHIFT, KEY_O, KEY_LEFTSHIFT, KEY_P, \ KEY_LEFTSHIFT, KEY_A, KEY_LEFTSHIFT, KEY_S, KEY_LEFTSHIFT, KEY_D, KEY_LEFTSHIFT, KEY_F, KEY_LEFTSHIFT, KEY_G, KEY_LEFTSHIFT, KEY_H, KEY_LEFTSHIFT, KEY_J, KEY_LEFTSHIFT, KEY_K, KEY_LEFTSHIFT, KEY_L, \ KEY_LEFTSHIFT, KEY_Z, KEY_LEFTSHIFT, KEY_X, KEY_LEFTSHIFT, KEY_C, KEY_LEFTSHIFT, KEY_V, KEY_LEFTSHIFT, KEY_B, KEY_LEFTSHIFT, KEY_N, KEY_LEFTSHIFT, KEY_M, KEY_BACKSPACE, \ - KEY_LEFT, KEY_SPACE, KEY_RIGHT, KEY_ENTER \ + KEY_SPACE, KEY_ENTER \ }; static const int scancode_idxs_upper_terminal_us[] = { \ @@ -88,7 +108,7 @@ static const int scancode_idxs_upper_terminal_us[] = { \ 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, \ 26, 28, 30, 32, 34, 36, 38, 40, 42, \ -1, 44, 46, 48, 50, 52, 54, 56, 58, \ - -1, 59, 60, 61, 62 \ + -1, 59, 60 \ }; static const int scancode_nums_upper_terminal_us[] = { \ @@ -96,7 +116,7 @@ static const int scancode_nums_upper_terminal_us[] = { \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 0, 2, 2, 2, 2, 2, 2, 2, 1, \ - 0, 1, 1, 1, 1 \ + 0, 1, 1 \ }; /* Layer: Numbers / symbols - generated from numbers */ @@ -106,7 +126,7 @@ static const char * const keycaps_numbers_terminal_us[] = { \ "1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\n", \ "*", "#", "$", "/", "&", "-", "_", "+", "(", ")", "\n", \ ",", "\"", "'", ":", ";", "!", "?", LV_SYMBOL_BACKSPACE, "\n", \ - "abc", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, ".", LV_SYMBOL_OK, "" \ + "abc", " ", ".", LV_SYMBOL_OK, "" \ }; static const lv_btnmatrix_ctrl_t attributes_numbers_terminal_us[] = { \ @@ -114,7 +134,17 @@ static const lv_btnmatrix_ctrl_t attributes_numbers_terminal_us[] = { \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \ - LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ + LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ +}; + +static const int num_switchers_numbers_terminal_us = 1; + +static const int switcher_idxs_numbers_terminal_us[] = { \ + 34 \ +}; + +static const int switcher_dests_numbers_terminal_us[] = { \ + 0 \ }; static const int num_scancodes_numbers_terminal_us = 5; @@ -124,7 +154,7 @@ static const int scancodes_numbers_terminal_us[] = { \ KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, KEY_0, \ KEY_LEFTSHIFT, KEY_8, KEY_LEFTSHIFT, KEY_3, KEY_LEFTSHIFT, KEY_4, KEY_LEFTSHIFT, KEY_QUESTION, KEY_LEFTSHIFT, KEY_7, KEY_MINUS, KEY_LEFTSHIFT, KEY_MINUS, KEY_LEFTSHIFT, KEY_EQUAL, KEY_LEFTSHIFT, KEY_9, KEY_LEFTSHIFT, KEY_0, \ KEY_COMMA, KEY_LEFTSHIFT, KEY_APOSTROPHE, KEY_APOSTROPHE, KEY_LEFTSHIFT, KEY_SEMICOLON, KEY_SEMICOLON, KEY_LEFTSHIFT, KEY_1, KEY_QUESTION, KEY_BACKSPACE, \ - KEY_LEFT, KEY_SPACE, KEY_RIGHT, KEY_DOT, KEY_ENTER \ + KEY_SPACE, KEY_DOT, KEY_ENTER \ }; static const int scancode_idxs_numbers_terminal_us[] = { \ @@ -132,7 +162,7 @@ static const int scancode_idxs_numbers_terminal_us[] = { \ 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, \ 16, 18, 20, 22, 24, 26, 27, 29, 31, 33, \ 35, 36, 38, 39, 41, 42, 44, 45, \ - -1, 46, 47, 48, 49, 50 \ + -1, 46, 47, 48 \ }; static const int scancode_nums_numbers_terminal_us[] = { \ @@ -140,7 +170,7 @@ static const int scancode_nums_numbers_terminal_us[] = { \ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, \ 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, \ 1, 2, 1, 2, 1, 2, 1, 1, \ - 0, 1, 1, 1, 1, 1 \ + 0, 1, 1, 1 \ }; /** @@ -154,6 +184,9 @@ const sq2lv_layout_t sq2lv_layouts[] = { { .keycaps = keycaps_lower_terminal_us, .attributes = attributes_lower_terminal_us, + .num_switchers = num_switchers_lower_terminal_us, + .switcher_idxs = switcher_idxs_lower_terminal_us, + .switcher_dests = switcher_dests_lower_terminal_us, .num_scancodes = num_scancodes_lower_terminal_us, .scancodes = scancodes_lower_terminal_us, .scancode_idxs = scancode_idxs_lower_terminal_us, @@ -162,6 +195,9 @@ const sq2lv_layout_t sq2lv_layouts[] = { { .keycaps = keycaps_upper_terminal_us, .attributes = attributes_upper_terminal_us, + .num_switchers = num_switchers_upper_terminal_us, + .switcher_idxs = switcher_idxs_upper_terminal_us, + .switcher_dests = switcher_dests_upper_terminal_us, .num_scancodes = num_scancodes_upper_terminal_us, .scancodes = scancodes_upper_terminal_us, .scancode_idxs = scancode_idxs_upper_terminal_us, @@ -170,6 +206,9 @@ const sq2lv_layout_t sq2lv_layouts[] = { { .keycaps = keycaps_numbers_terminal_us, .attributes = attributes_numbers_terminal_us, + .num_switchers = num_switchers_numbers_terminal_us, + .switcher_idxs = switcher_idxs_numbers_terminal_us, + .switcher_dests = switcher_dests_numbers_terminal_us, .num_scancodes = num_scancodes_numbers_terminal_us, .scancodes = scancodes_numbers_terminal_us, .scancode_idxs = scancode_idxs_numbers_terminal_us, diff --git a/examples/us-terminal-with-scancodes/sq2lv_layouts.h b/examples/us-terminal-with-scancodes/sq2lv_layouts.h index 1fe044e..c999de5 100644 --- a/examples/us-terminal-with-scancodes/sq2lv_layouts.h +++ b/examples/us-terminal-with-scancodes/sq2lv_layouts.h @@ -26,6 +26,12 @@ typedef struct { const char ** const keycaps; /* Button matrix attributes */ const lv_btnmatrix_ctrl_t * const attributes; + /* Number of buttons that trigger a layer switch */ + const int num_switchers; + /* Button indexes that trigger a layer switch */ + const int * const switcher_idxs; + /* Indexes of layers to jump to when triggering layer switch buttons */ + const int * const switcher_dests; /* Total number of scancodes */ const int const num_scancodes; /* Flat array of scancodes */ diff --git a/examples/us/sq2lv_layouts.c b/examples/us/sq2lv_layouts.c index ed209d5..2d119c2 100644 --- a/examples/us/sq2lv_layouts.c +++ b/examples/us/sq2lv_layouts.c @@ -23,7 +23,17 @@ static const lv_btnmatrix_ctrl_t attributes_lower_us[] = { \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, 2, 2, \ LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \ - LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ + LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ +}; + +static const int num_switchers_lower_us = 2; + +static const int switcher_idxs_lower_us[] = { \ + 19, 28 \ +}; + +static const int switcher_dests_lower_us[] = { \ + 1, 2 \ }; /* Layer: Uppercase letters - generated from upper */ @@ -39,7 +49,17 @@ static const lv_btnmatrix_ctrl_t attributes_upper_us[] = { \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, 2, 2, \ LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \ - LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ + LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ +}; + +static const int num_switchers_upper_us = 2; + +static const int switcher_idxs_upper_us[] = { \ + 19, 28 \ +}; + +static const int switcher_dests_upper_us[] = { \ + 1, 2 \ }; /* Layer: Numbers / symbols - generated from numbers */ @@ -55,7 +75,17 @@ static const lv_btnmatrix_ctrl_t attributes_numbers_us[] = { \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, \ 2, 2, 2, 2, 2, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3, \ - LV_KEYBOARD_CTRL_BTN_FLAGS | 3, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ + LV_KEYBOARD_CTRL_BTN_FLAGS | 3, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 7, 2, 2, LV_KEYBOARD_CTRL_BTN_FLAGS | 3 \ +}; + +static const int num_switchers_numbers_us = 1; + +static const int switcher_idxs_numbers_us[] = { \ + 28 \ +}; + +static const int switcher_dests_numbers_us[] = { \ + 0 \ }; /** @@ -68,15 +98,24 @@ const sq2lv_layout_t sq2lv_layouts[] = { .layers = (sq2lv_layer_t[]){ { .keycaps = keycaps_lower_us, - .attributes = attributes_lower_us + .attributes = attributes_lower_us, + .num_switchers = num_switchers_lower_us, + .switcher_idxs = switcher_idxs_lower_us, + .switcher_dests = switcher_dests_lower_us }, { .keycaps = keycaps_upper_us, - .attributes = attributes_upper_us + .attributes = attributes_upper_us, + .num_switchers = num_switchers_upper_us, + .switcher_idxs = switcher_idxs_upper_us, + .switcher_dests = switcher_dests_upper_us }, { .keycaps = keycaps_numbers_us, - .attributes = attributes_numbers_us + .attributes = attributes_numbers_us, + .num_switchers = num_switchers_numbers_us, + .switcher_idxs = switcher_idxs_numbers_us, + .switcher_dests = switcher_dests_numbers_us } }, .num_layers = 3 diff --git a/examples/us/sq2lv_layouts.h b/examples/us/sq2lv_layouts.h index 540ecdd..d68141f 100644 --- a/examples/us/sq2lv_layouts.h +++ b/examples/us/sq2lv_layouts.h @@ -26,14 +26,12 @@ typedef struct { const char ** const keycaps; /* Button matrix attributes */ const lv_btnmatrix_ctrl_t * const attributes; - /* Total number of scancodes */ - const int const num_scancodes; - /* Flat array of scancodes */ - const int * const scancodes; - /* Start index in scancodes array for key cap */ - const int * const scancode_idxs; - /* Number of scancodes for key cap */ - const int * const scancode_nums; + /* Number of buttons that trigger a layer switch */ + const int num_switchers; + /* Button indexes that trigger a layer switch */ + const int * const switcher_idxs; + /* Indexes of layers to jump to when triggering layer switch buttons */ + const int * const switcher_dests; } sq2lv_layer_t; /* Layouts */ diff --git a/regenerate-examples.sh b/regenerate-examples.sh index 91132dc..a84c978 100755 --- a/regenerate-examples.sh +++ b/regenerate-examples.sh @@ -21,7 +21,8 @@ pipenv install pipenv run python squeek2lvgl.py \ --input us.yaml \ - --output examples/us + --output examples/us \ + --surround-space-with-arrows pipenv run python squeek2lvgl.py \ --input terminal/us.yaml \ diff --git a/squeek2lvgl.py b/squeek2lvgl.py index 8336773..77cba59 100644 --- a/squeek2lvgl.py +++ b/squeek2lvgl.py @@ -34,38 +34,6 @@ outfile_h = 'sq2lv_layouts.h' repository_url = 'https://gitlab.gnome.org/World/Phosh/squeekboard.git' rel_layouts_dir = 'data/keyboards' -typedef_layer_t = [ - 'typedef struct {', - ' /* Key caps */', - ' const char ** const keycaps;', - ' /* Button matrix attributes */', - ' const lv_btnmatrix_ctrl_t * const attributes;', - # ' /* Number of buttons that trigger a layer switch */', - # ' const int num_triggers;', - # ' /* Button indexes that trigger a layer switch */', - # ' const int * const trigger_idxs;', - # ' /* Indexes of layers to jump to when hitting trigger */', - # ' const int * const trigger_targets;', - ' /* Total number of scancodes */', - ' const int const num_scancodes;', - ' /* Flat array of scancodes */', - ' const int * const scancodes;', - ' /* Start index in scancodes array for key cap */', - ' const int * const scancode_idxs;', - ' /* Number of scancodes for key cap */', - ' const int * const scancode_nums;', - '} sq2lv_layer_t;' -] - -typedef_layout_t = [ - 'typedef struct {', - ' /* Layers array */', - ' const sq2lv_layer_t * const layers;', - ' /* Total number of layers */', - ' const int num_layers;', - '} sq2lv_layout_t;' -] - ### # General helpers @@ -95,9 +63,12 @@ def parse_arguments(): parser.add_argument('--input', dest='input', action='append', required=True, help='squeekboard layout to ' + 'use as input for generation. Has to be a YAML file path relative to data/keyboards. ' + 'Can be specified multiple times.') + parser.add_argument('--surround-space-with-arrows', action='store_true', dest='arrows_around_space', + help='insert left / right arrow before / after space key') parser.add_argument('--generate-scancodes', action='store_true', dest='generate_scancodes', help='also ' + 'generate scancode tables (only works for US layout currently)') - parser.add_argument('--output', dest='output', type=str, help='output directory for generated files') + parser.add_argument('--output', dest='output', type=str, required=True, help='output directory for generated ' + + 'files') args = parser.parse_args() if not args.output or not os.path.isdir(args.output): @@ -114,7 +85,7 @@ def clone_squeekboard_repo(destination): git.Repo.clone_from(repository_url, destination, depth=1) -def load_yaml(rel_path): +def load_yaml(layouts_dir, rel_path): """ Load a YAML file and return its dictionary representation. rel_path -- path of the YAML file relative to the layouts root directory @@ -241,7 +212,7 @@ class SourceFileBuilder(object): return self def add_array(self, static, type, identifier, values, row_terminator, array_terminator): - """Add a C array and return the builder. + """Add a row-based C array and return the builder. static -- True if the variable is static type -- variable type @@ -263,6 +234,17 @@ class SourceFileBuilder(object): self.add_line('};') return self + def add_flat_array(self, static, type, identifier, values, array_terminator): + """Add a flat C array and return the builder. + + static -- True if the variable is static + type -- variable type + identifier -- variable identifier + values -- list of values, + array_terminator -- element to append after the last element + """ + return self.add_array(static, type, identifier, [values], '', array_terminator) + ### # Layout processing @@ -347,12 +329,12 @@ keycap_for_key = { 'show_numbers': '1#', 'show_numbers_from_symbols': '1#', 'show_symbols': None, - 'space': ['LV_SYMBOL_LEFT', ' ', 'LV_SYMBOL_RIGHT'], + 'space': ' ', 'Return': 'LV_SYMBOL_OK', } def key_to_keycap(key, view_id, layout_id): - """Return the list of keycaps for a key + """Return the keycap for a key key -- the key view_id -- ID of the view the key appears on @@ -366,11 +348,7 @@ def key_to_keycap(key, view_id, layout_id): keycap = keycap[layout_id] else: keycap = None - if not keycap: - return [] - if isinstance(keycap, list): - return keycap - return [keycap] + return keycap def key_to_attributes(key, data_buttons): @@ -500,34 +478,73 @@ def keycap_to_scancodes(keycap): return scancodes_for_keycap[keycap] -def get_keycaps_attrs_scancodes(layout_id, view_id, data_views, data_buttons, include_scancodes): - """Return keycaps, LVGL button attributes and scancodes for a view +def get_keycaps_attrs_switchers_scancodes(args, layout_id, view_id, data_views, data_buttons): + """Return keycaps, LVGL button attributes, layer switching key indexes, layer switching key + destinations and scancodes for a view + args -- Commandline arguments layout_id -- ID of the layout view_id -- ID of the view data_views -- the "views" object from the layout's YAML file data_buttons -- the "buttons" object from the layout's YAML file - include_scancodes -- True if scancodes should be included """ keycaps = [] attrs = [] + switcher_idxs = [] + switcher_dests = [] scancodes = [] + idx = 0 + for row in data_views[view_id]: keycaps_in_row = [] attrs_in_row = [] scancodes_in_row = [] - for key in row.split(): - for keycap in key_to_keycap(key, view_id, layout_id): - keycaps_in_row.append(keycap_to_c_value(keycap)) - attrs_in_row.append(key_to_attributes(key, data_buttons)) - if include_scancodes: - scancodes_in_row.append(keycap_to_scancodes(keycap)) + + keys = row.split() + + if args.arrows_around_space: + space_idx = None + try: + space_idx = keys.index('space') + except ValueError: + pass + if space_idx != None: + keys.insert(space_idx, '←') + keys.insert(space_idx + 2, '→') + + + for key in keys: + keycap = key_to_keycap(key, view_id, layout_id) + if not keycap: + continue + + keycaps_in_row.append(keycap_to_c_value(keycap)) + attrs_in_row.append(key_to_attributes(key, data_buttons)) + + if key in data_buttons and 'action' in data_buttons[key]: + action = data_buttons[key]['action'] + dest = None + + if 'set_view' in action: + dest = action['set_view'] + elif 'locking' in action and 'lock_view' in action['locking']: + dest = action['locking']['lock_view'] + + if dest: + switcher_idxs.append(idx) + switcher_dests.append(dest) + + if args.generate_scancodes: + scancodes_in_row.append(keycap_to_scancodes(keycap)) + + idx += 1 + keycaps.append(keycaps_in_row) attrs.append(attrs_in_row) scancodes.append(scancodes_in_row) - return keycaps, attrs, scancodes + return keycaps, attrs, switcher_idxs, switcher_dests, scancodes def flatten_scancodes(scancodes): @@ -590,7 +607,7 @@ if __name__ == '__main__': layout_id, _ = os.path.splitext(file) layout_identifier = layout_id_to_c_identifier(layout_id) - data = load_yaml(file) + data = load_yaml(layouts_dir, file) data_views = data['views'] data_buttons = data['buttons'] if 'buttons' in data else {} @@ -601,6 +618,8 @@ if __name__ == '__main__': layer_identifiers = [] + view_ids = [view_id for view_id in data_views if view_id_to_layer_name(view_id) != None] + for view_id in data_views: layer_name = view_id_to_layer_name(view_id) if not layer_name: @@ -613,13 +632,27 @@ if __name__ == '__main__': c_builder.add_subsection_comment(f'Layer: {layer_name} - generated from {view_id}') c_builder.add_line() - keycaps, attrs, scancodes = get_keycaps_attrs_scancodes(layout_id, view_id, data_views, data_buttons, args.generate_scancodes) + keycaps, attrs, switcher_idxs, switcher_dests, scancodes = get_keycaps_attrs_switchers_scancodes( + args, layout_id, view_id, data_views, data_buttons) + + for dest in switcher_dests: + if dest not in view_ids: + die(f'Unhandled layer switch destination {dest}') + switcher_dests = [view_ids.index(d) for d in switcher_dests if d in view_ids] c_builder.add_array(True, 'const char * const', f'keycaps_{layer_identifier}', keycaps, '"\\n"', '""') c_builder.add_line() c_builder.add_array(True, 'const lv_btnmatrix_ctrl_t', f'attributes_{layer_identifier}', attrs, '', '') c_builder.add_line() + + c_builder.add_line(f'static const int num_switchers_{layer_identifier} = {len(switcher_idxs)};') + c_builder.add_line() + c_builder.add_flat_array(True, 'const int', f'switcher_idxs_{layer_identifier}', switcher_idxs, '') + c_builder.add_line() + c_builder.add_flat_array(True, 'const int', f'switcher_dests_{layer_identifier}', switcher_dests, '') + c_builder.add_line() + if args.generate_scancodes: scancodes_flat, scancode_idxs, scancode_nums = flatten_scancodes(scancodes) @@ -647,11 +680,36 @@ if __name__ == '__main__': h_builder.add_line() h_builder.add_line('/* Layout type */') - h_builder.add_lines(typedef_layout_t) + h_builder.add_line('typedef struct {') + h_builder.add_line(' /* Layers array */') + h_builder.add_line(' const sq2lv_layer_t * const layers;') + h_builder.add_line(' /* Total number of layers */') + h_builder.add_line(' const int num_layers;') + h_builder.add_line('} sq2lv_layout_t;') h_builder.add_line() h_builder.add_line('/* Layer type */') - h_builder.add_lines(typedef_layer_t) + h_builder.add_line('typedef struct {') + h_builder.add_line(' /* Key caps */') + h_builder.add_line(' const char ** const keycaps;') + h_builder.add_line(' /* Button matrix attributes */') + h_builder.add_line(' const lv_btnmatrix_ctrl_t * const attributes;') + h_builder.add_line(' /* Number of buttons that trigger a layer switch */') + h_builder.add_line(' const int num_switchers;') + h_builder.add_line(' /* Button indexes that trigger a layer switch */') + h_builder.add_line(' const int * const switcher_idxs;') + h_builder.add_line(' /* Indexes of layers to jump to when triggering layer switch buttons */') + h_builder.add_line(' const int * const switcher_dests;') + if args.generate_scancodes: + h_builder.add_line(' /* Total number of scancodes */') + h_builder.add_line(' const int const num_scancodes;') + h_builder.add_line(' /* Flat array of scancodes */') + h_builder.add_line(' const int * const scancodes;') + h_builder.add_line(' /* Start index in scancodes array for key cap */') + h_builder.add_line(' const int * const scancode_idxs;') + h_builder.add_line(' /* Number of scancodes for key cap */') + h_builder.add_line(' const int * const scancode_nums;') + h_builder.add_line('} sq2lv_layer_t;') h_builder.add_line() h_builder.add_line('/* Layouts */') @@ -672,7 +730,7 @@ if __name__ == '__main__': c_builder.add_line(' .layers = (sq2lv_layer_t[]){') for j, identifier in enumerate(layout['layer_identifiers']): c_builder.add_line(' {') - fields = ['keycaps', 'attributes'] + fields = ['keycaps', 'attributes', 'num_switchers', 'switcher_idxs', 'switcher_dests'] if args.generate_scancodes: fields += ['num_scancodes', 'scancodes', 'scancode_idxs', 'scancode_nums'] for k, field in enumerate(fields):