f0rmz: new subproject to create a form/wizard setup thing
This commit is contained in:
parent
b12ce978b1
commit
47b046da73
36 changed files with 4693 additions and 241 deletions
|
|
@ -10,6 +10,8 @@ BuffyBox is a suite of graphical applications for the terminal.
|
|||
|
||||
**[unl0kr]** – Disk unlocking UI for the initramfs
|
||||
|
||||
**[f0rmz]** – A form/setup wizard for the initramfs
|
||||
|
||||
### Utilities
|
||||
|
||||
**[squeek2lvgl]** – Converter for transforming [Squeekboard] layouts into [LVGL]-compatible C code
|
||||
|
|
|
|||
|
|
@ -39,15 +39,10 @@ static void print_usage();
|
|||
*/
|
||||
|
||||
static void init_opts(bb_cli_opts *opts) {
|
||||
bbx_cli_init_common_opts(&opts->common);
|
||||
opts->num_config_files = 0;
|
||||
opts->config_files = NULL;
|
||||
opts->hor_res = -1;
|
||||
opts->ver_res = -1;
|
||||
opts->x_offset = 0;
|
||||
opts->y_offset = 0;
|
||||
opts->dpi = 0;
|
||||
opts->rotation = LV_DISPLAY_ROTATION_0;
|
||||
opts->verbose = false;
|
||||
|
||||
int fd_rotate = open("/sys/class/graphics/fbcon/rotate", O_RDONLY);
|
||||
if (fd_rotate < 0) {
|
||||
|
|
@ -148,16 +143,12 @@ void bb_cli_parse_opts(int argc, char *argv[], bb_cli_opts *opts) {
|
|||
opts->num_config_files++;
|
||||
break;
|
||||
case 'g':
|
||||
if (sscanf(optarg, "%ix%i@%i,%i", &(opts->hor_res), &(opts->ver_res), &(opts->x_offset), &(opts->y_offset)) != 4) {
|
||||
if (sscanf(optarg, "%ix%i", &(opts->hor_res), &(opts->ver_res)) != 2) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Invalid geometry argument \"%s\"\n", optarg);
|
||||
if (bbx_cli_parse_geometry(optarg, &opts->common) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (sscanf(optarg, "%i", &(opts->dpi)) != 1) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Invalid dpi argument \"%s\"\n", optarg);
|
||||
if (bbx_cli_parse_dpi(optarg, &opts->common) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
|
@ -187,11 +178,11 @@ void bb_cli_parse_opts(int argc, char *argv[], bb_cli_opts *opts) {
|
|||
print_usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'v':
|
||||
opts->verbose = true;
|
||||
opts->common.verbose = true;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr, "buffyboard %s\n", PROJECT_VERSION);
|
||||
exit(0);
|
||||
bbx_cli_print_version_and_exit("unl0kr");
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
|||
|
|
@ -8,29 +8,20 @@
|
|||
#define BB_COMMAND_LINE_H
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
#include "../shared/cli_common.h"
|
||||
|
||||
/**
|
||||
* Options parsed from command line arguments
|
||||
*/
|
||||
typedef struct {
|
||||
/* Common cli options */
|
||||
bbx_cli_common_opts common;
|
||||
/* Number of config files */
|
||||
int num_config_files;
|
||||
/* Paths of config file */
|
||||
const char **config_files;
|
||||
/* Horizontal display resolution */
|
||||
int hor_res;
|
||||
/* Vertical display resolution */
|
||||
int ver_res;
|
||||
/* Horizontal display offset */
|
||||
int x_offset;
|
||||
/* Vertical display offset */
|
||||
int y_offset;
|
||||
/* DPI */
|
||||
int dpi;
|
||||
/* Display rotation */
|
||||
lv_display_rotation_t rotation;
|
||||
/* Verbose mode. If true, provide more detailed logging output on STDERR. */
|
||||
bool verbose;
|
||||
} bb_cli_opts;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -158,7 +158,7 @@ int main(int argc, char *argv[]) {
|
|||
bb_cli_parse_opts(argc, argv, &cli_opts);
|
||||
|
||||
/* Set up log level */
|
||||
if (cli_opts.verbose) {
|
||||
if (cli_opts.common.verbose) {
|
||||
bbx_log_set_level(BBX_LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
|
||||
|
|
@ -194,12 +194,12 @@ int main(int argc, char *argv[]) {
|
|||
lv_display_get_vertical_resolution(disp));
|
||||
|
||||
/* Override display properties with command line options if necessary */
|
||||
lv_display_set_offset(disp, cli_opts.x_offset, cli_opts.y_offset);
|
||||
if (cli_opts.hor_res > 0 && cli_opts.ver_res > 0) {
|
||||
lv_display_set_resolution(disp, cli_opts.hor_res, cli_opts.ver_res);
|
||||
lv_display_set_offset(disp, cli_opts.common.x_offset, cli_opts.common.y_offset);
|
||||
if (cli_opts.common.hor_res > 0 && cli_opts.common.ver_res > 0) {
|
||||
lv_display_set_resolution(disp, cli_opts.common.hor_res, cli_opts.common.ver_res);
|
||||
}
|
||||
if (cli_opts.dpi > 0) {
|
||||
lv_display_set_dpi(disp, cli_opts.dpi);
|
||||
if (cli_opts.common.dpi > 0) {
|
||||
lv_display_set_dpi(disp, cli_opts.common.dpi);
|
||||
}
|
||||
|
||||
/* Set up display rotation */
|
||||
|
|
|
|||
147
f0rmz/README.md
Normal file
147
f0rmz/README.md
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
f0rmz
|
||||
=====
|
||||
|
||||
Form collection tool for the initramfs based on [LVGL].
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
# About
|
||||
|
||||
f0rmz is a standalone form collection tool built on [LVGL], with rendering directly to the Linux framebuffer. It shares the same look and feel as [unl0kr] while providing a way to collect structured user input through configurable forms.
|
||||
|
||||
f0rmz was created for use cases like prompting for username, passphrases, and hostname during "first boot" in the initramfs, before creating LUKS partitions or generating configuration files.
|
||||
|
||||
# Status
|
||||
|
||||
f0rmz provides a complete form collection workflow:
|
||||
|
||||
- **Intro Page**: Configurable welcome screen with title and body text
|
||||
- **Multi-field Forms**: Runtime-configurable forms via INI files using the same format as unl0kr
|
||||
- **Touch-optimized UI**: One field per page for simplified display on small screens
|
||||
- **Field Types**: Text and password input fields with validation
|
||||
- **Summary Screen**: Review all values with click-to-edit capability
|
||||
- **Input Support**: On-screen keyboard with layout switching, physical keyboard, mouse, and touchscreen
|
||||
- **Theming**: Light and dark themes with runtime switching (shared with unl0kr)
|
||||
- **Structured Output**: Key=value pairs printed to stdout for easy parsing
|
||||
|
||||
# Usage
|
||||
|
||||
f0rmz can be invoked with various command line options:
|
||||
|
||||
```
|
||||
$ f0rmz --help
|
||||
Usage: f0rmz [OPTION]
|
||||
|
||||
-C, --config Path to form configuration file
|
||||
-g, --geometry=NxM[@X,Y] Force display size and offset
|
||||
-d, --dpi=N Override display DPI
|
||||
-h, --help Show this help
|
||||
-v, --verbose Enable verbose logging
|
||||
-V, --version Show version
|
||||
```
|
||||
|
||||
f0rmz reads configuration files in the following order:
|
||||
- `/usr/share/f0rmz/f0rmz.conf`
|
||||
- `/usr/share/f0rmz/f0rmz.conf.d/*` (alphabetically)
|
||||
- `/etc/f0rmz.conf`
|
||||
- `/etc/f0rmz.conf.d/*` (alphabetically)
|
||||
- Custom config file (specified with `-C`)
|
||||
|
||||
## Configuration
|
||||
|
||||
### Basic Example
|
||||
|
||||
```ini
|
||||
[intro]
|
||||
title=Welcome to postmarketOS!
|
||||
body=Let's set up your device with a few quick questions.
|
||||
|
||||
[form.username]
|
||||
type=text
|
||||
label=Username
|
||||
required=true
|
||||
|
||||
[form.password]
|
||||
type=password
|
||||
label=Password
|
||||
required=true
|
||||
|
||||
[form.hostname]
|
||||
type=text
|
||||
label=Hostname
|
||||
required=false
|
||||
```
|
||||
|
||||
### Configuration Sections
|
||||
|
||||
#### `[intro]`
|
||||
- `title` - Welcome screen title text
|
||||
- `body` - Welcome screen body text
|
||||
|
||||
#### `[form.fieldname]`
|
||||
Define form fields where `fieldname` is the output key name.
|
||||
|
||||
- `type` - Field type: `text` or `password`
|
||||
- `label` - Display label for the field
|
||||
- `required` - Whether field is required: `true` or `false` (default: `true`)
|
||||
|
||||
#### Shared Sections
|
||||
f0rmz supports the same configuration sections as unl0kr for theming, keyboard, and input device settings. See [unl0kr.conf] for examples of `[general]`, `[keyboard]`, `[textarea]`, `[theme]`, `[input]`, and `[quirks]` sections.
|
||||
|
||||
## Navigation Flow
|
||||
|
||||
1. **Intro Page** - Welcome screen with "Get Started" button
|
||||
2. **Field Pages** - One field per page with Previous/Next navigation
|
||||
3. **Summary Screen** - Review all values, click any field to edit
|
||||
4. **Output** - Print `key=value` pairs to stdout and exit
|
||||
|
||||
## Output Format
|
||||
|
||||
f0rmz outputs structured data as key=value pairs:
|
||||
|
||||
```
|
||||
username=alice
|
||||
password=secretpass
|
||||
hostname=mydevice
|
||||
```
|
||||
|
||||
# Development
|
||||
|
||||
## Dependencies
|
||||
|
||||
- [inih] - INI file parsing
|
||||
- [lvgl] (git submodule / linked statically)
|
||||
- [squeek2lvgl] (linked statically)
|
||||
- [libinput] - Input device handling
|
||||
- [libudev] - Device enumeration
|
||||
- [libxkbcommon] - Keyboard layout support
|
||||
- evdev kernel module
|
||||
|
||||
## Backends
|
||||
|
||||
f0rmz uses the same backend system as unl0kr:
|
||||
|
||||
- fbdev (default)
|
||||
- drm (optional, if [libdrm] is available)
|
||||
|
||||
The active backend can be selected via the `general.backend` option in the configuration file.
|
||||
|
||||
## Keyboard layouts
|
||||
|
||||
f0rmz uses [squeekboard layouts] converted to C via [squeek2lvgl], the same as unl0kr. To regenerate the layouts, ensure that you have pipenv installed and run:
|
||||
|
||||
```
|
||||
$ ./regenerate-layouts.sh
|
||||
```
|
||||
|
||||
[LVGL]: https://lvgl.io
|
||||
[unl0kr]: ../unl0kr
|
||||
[inih]: https://github.com/benhoyt/inih
|
||||
[lvgl]: https://github.com/lvgl/lvgl
|
||||
[squeek2lvgl]: ../squeek2lvgl
|
||||
[libinput]: https://gitlab.freedesktop.org/libinput/libinput
|
||||
[libudev]: https://github.com/systemd/systemd/tree/main/src/libudev
|
||||
[libxkbcommon]: https://github.com/xkbcommon/libxkbcommon
|
||||
[libdrm]: https://gitlab.freedesktop.org/mesa/drm
|
||||
[squeekboard layouts]: https://gitlab.gnome.org/World/Phosh/squeekboard/-/tree/master/data/keyboards
|
||||
[unl0kr.conf]: ../unl0kr/unl0kr.conf
|
||||
73
f0rmz/command_line.c
Normal file
73
f0rmz/command_line.c
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/**
|
||||
* Copyright 2025 Clayton Craft
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "command_line.h"
|
||||
#include "../shared/log.h"
|
||||
|
||||
#include <getopt.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static void init_opts(f0_cli_opts *opts) {
|
||||
bbx_cli_init_common_opts(&opts->common);
|
||||
opts->config_file = NULL;
|
||||
}
|
||||
|
||||
static void print_usage() {
|
||||
fprintf(stderr,
|
||||
"Usage: f0rmz [OPTION]\n"
|
||||
"\n"
|
||||
" -C, --config Path to form configuration file\n"
|
||||
" -g, --geometry=NxM[@X,Y] Force display size and offset\n"
|
||||
" -d, --dpi=N Override display DPI\n"
|
||||
" -h, --help Show this help\n"
|
||||
" -v, --verbose Enable verbose logging\n"
|
||||
" -V, --version Show version\n");
|
||||
}
|
||||
|
||||
void f0_cli_parse_opts(int argc, char *argv[], f0_cli_opts *opts) {
|
||||
init_opts(opts);
|
||||
|
||||
struct option long_opts[] = {
|
||||
{ "config", required_argument, NULL, 'C' },
|
||||
{ "geometry", required_argument, NULL, 'g' },
|
||||
{ "dpi", required_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
int opt;
|
||||
while ((opt = getopt_long(argc, argv, "C:g:d:hvV", long_opts, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'C':
|
||||
opts->config_file = optarg;
|
||||
break;
|
||||
case 'g':
|
||||
if (bbx_cli_parse_geometry(optarg, &opts->common) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (bbx_cli_parse_dpi(optarg, &opts->common) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
print_usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
case 'v':
|
||||
opts->common.verbose = true;
|
||||
break;
|
||||
case 'V':
|
||||
bbx_cli_print_version_and_exit("f0rmz");
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
18
f0rmz/command_line.h
Normal file
18
f0rmz/command_line.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Copyright 2025 Clayton Craft
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef F0_COMMAND_LINE_H
|
||||
#define F0_COMMAND_LINE_H
|
||||
|
||||
#include "../shared/cli_common.h"
|
||||
|
||||
typedef struct {
|
||||
bbx_cli_common_opts common;
|
||||
const char *config_file;
|
||||
} f0_cli_opts;
|
||||
|
||||
void f0_cli_parse_opts(int argc, char *argv[], f0_cli_opts *opts);
|
||||
|
||||
#endif /* F0_COMMAND_LINE_H */
|
||||
216
f0rmz/config.c
Normal file
216
f0rmz/config.c
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/**
|
||||
* Copyright 2025 Clayton Craft
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "../shared/config.h"
|
||||
#include "../shared/log.h"
|
||||
#include "../squeek2lvgl/sq2lv.h"
|
||||
|
||||
#include <ini.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Static prototypes
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle parsing events from INIH.
|
||||
*
|
||||
* @param user_data pointer to user data
|
||||
* @param section current section name
|
||||
* @param key option key
|
||||
* @param value option value
|
||||
* @return 0 on error, non-0 otherwise
|
||||
*/
|
||||
static int parsing_handler(void* user_data, const char* section, const char* key, const char* value);
|
||||
|
||||
/**
|
||||
* Static functions
|
||||
*/
|
||||
|
||||
static int parsing_handler(void* user_data, const char* section, const char* key, const char* value) {
|
||||
f0_config_opts *opts = (f0_config_opts *)user_data;
|
||||
|
||||
if (strcmp(section, "general") == 0) {
|
||||
if (strcmp(key, "backend") == 0) {
|
||||
bbx_backends_backend_id_t id = bbx_backends_find_backend_with_name(value);
|
||||
if (id != BBX_BACKENDS_BACKEND_NONE) {
|
||||
opts->general.backend = id;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(section, "keyboard") == 0) {
|
||||
if (strcmp(key, "autohide") == 0) {
|
||||
if (bbx_config_parse_bool(value, &(opts->keyboard.autohide))) {
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "layout") == 0) {
|
||||
sq2lv_layout_id_t id = sq2lv_find_layout_with_short_name(value);
|
||||
if (id != SQ2LV_LAYOUT_NONE) {
|
||||
opts->keyboard.layout_id = id;
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "popovers") == 0) {
|
||||
if (bbx_config_parse_bool(value, &(opts->keyboard.popovers))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(section, "theme") == 0) {
|
||||
if (strcmp(key, "default") == 0) {
|
||||
bbx_themes_theme_id_t id = bbx_themes_find_theme_with_name(value);
|
||||
if (id != BBX_THEMES_THEME_NONE) {
|
||||
opts->theme.default_id = id;
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "alternate") == 0) {
|
||||
bbx_themes_theme_id_t id = bbx_themes_find_theme_with_name(value);
|
||||
if (id != BBX_THEMES_THEME_NONE) {
|
||||
opts->theme.alternate_id = id;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(section, "input") == 0) {
|
||||
if (strcmp(key, "keyboard") == 0) {
|
||||
if (bbx_config_parse_bool(value, &(opts->input.keyboard))) {
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "pointer") == 0) {
|
||||
if (bbx_config_parse_bool(value, &(opts->input.pointer))) {
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "touchscreen") == 0) {
|
||||
if (bbx_config_parse_bool(value, &(opts->input.touchscreen))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(section, "quirks") == 0) {
|
||||
if (strcmp(key, "fbdev_force_refresh") == 0) {
|
||||
if (bbx_config_parse_bool(value, &(opts->quirks.fbdev_force_refresh))) {
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "terminal_prevent_graphics_mode") == 0) {
|
||||
if (bbx_config_parse_bool(value, &(opts->quirks.terminal_prevent_graphics_mode))) {
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "terminal_allow_keyboard_input") == 0) {
|
||||
if (bbx_config_parse_bool(value, &(opts->quirks.terminal_allow_keyboard_input))) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(section, "intro") == 0) {
|
||||
if (strcmp(key, "title") == 0) {
|
||||
char *title = strdup(value);
|
||||
if (title) {
|
||||
opts->intro.title = title;
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "body") == 0) {
|
||||
char *body = strdup(value);
|
||||
if (body) {
|
||||
opts->intro.body = body;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if (strncmp(section, "form.", 5) == 0) {
|
||||
/* Extract field name */
|
||||
const char *field_name = section + 5;
|
||||
|
||||
/* Find or create field */
|
||||
f0_form_field_t *field = NULL;
|
||||
for (int i = 0; i < opts->num_fields; i++) {
|
||||
if (strcmp(opts->fields[i].name, field_name) == 0) {
|
||||
field = &opts->fields[i];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!field) {
|
||||
/* Create new field */
|
||||
opts->fields = realloc(opts->fields, (opts->num_fields + 1) * sizeof(f0_form_field_t));
|
||||
field = &opts->fields[opts->num_fields];
|
||||
lv_memzero(field, sizeof(f0_form_field_t));
|
||||
field->name = strdup(field_name);
|
||||
opts->num_fields++;
|
||||
}
|
||||
|
||||
/* Parse field properties */
|
||||
if (strcmp(key, "type") == 0) {
|
||||
if (strcmp(value, "text") == 0) {
|
||||
field->type = F0_FIELD_TYPE_TEXT;
|
||||
return 1;
|
||||
} else if (strcmp(value, "password") == 0) {
|
||||
field->type = F0_FIELD_TYPE_PASSWORD;
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "label") == 0) {
|
||||
field->label = strdup(value);
|
||||
return 1;
|
||||
} else if (strcmp(key, "required") == 0) {
|
||||
if (bbx_config_parse_bool(value, &field->required)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Ignoring invalid config value \"%s\" for key \"%s\" in section \"%s\"", value, key, section);
|
||||
return 1; /* Return 1 (true) so that we can use the return value of ini_parse exclusively for file-level errors */
|
||||
}
|
||||
|
||||
/**
|
||||
* Public functions
|
||||
*/
|
||||
|
||||
void f0_config_init_opts(f0_config_opts *opts) {
|
||||
opts->general.backend = bbx_backends_backends[0] == NULL ? BBX_BACKENDS_BACKEND_NONE : 0;
|
||||
opts->intro.title = "A Form!";
|
||||
opts->intro.body = "Please complete the following form.";
|
||||
opts->theme.default_id = BBX_THEMES_THEME_BREEZY_DARK;
|
||||
opts->theme.alternate_id = BBX_THEMES_THEME_BREEZY_LIGHT;
|
||||
opts->keyboard.autohide = true;
|
||||
opts->keyboard.layout_id = SQ2LV_LAYOUT_US;
|
||||
opts->keyboard.popovers = true;
|
||||
opts->textarea.obscured = true;
|
||||
opts->textarea.bullet = LV_SYMBOL_BULLET;
|
||||
opts->input.keyboard = true;
|
||||
opts->input.pointer = true;
|
||||
opts->input.touchscreen = true;
|
||||
opts->quirks.fbdev_force_refresh = false;
|
||||
opts->quirks.terminal_prevent_graphics_mode = false;
|
||||
opts->quirks.terminal_allow_keyboard_input = false;
|
||||
opts->fields = NULL;
|
||||
opts->num_fields = 0;
|
||||
}
|
||||
|
||||
void f0_config_parse_directory(const char *path, f0_config_opts *opts) {
|
||||
/* Find files in directory */
|
||||
char **found = NULL;
|
||||
int num_found = 0;
|
||||
bbx_config_find_files(path, &found, &num_found);
|
||||
|
||||
/* Sort and parse files */
|
||||
qsort(found, num_found, sizeof(char *), bbx_config_compare_strings);
|
||||
f0_config_parse_files((const char **)found, num_found, opts);
|
||||
|
||||
/* Free memory */
|
||||
for (int i = 0; i < num_found; ++i) {
|
||||
free(found[i]);
|
||||
}
|
||||
free(found);
|
||||
}
|
||||
|
||||
void f0_config_parse_files(const char **files, int num_files, f0_config_opts *opts) {
|
||||
for (int i = 0; i < num_files; ++i) {
|
||||
f0_config_parse_file(files[i], opts);
|
||||
}
|
||||
}
|
||||
|
||||
void f0_config_parse_file(const char *path, f0_config_opts *opts) {
|
||||
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Parsing config file %s", path);
|
||||
if (ini_parse(path, parsing_handler, opts) != 0) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Ignoring invalid config file %s", path);
|
||||
}
|
||||
}
|
||||
167
f0rmz/config.h
Normal file
167
f0rmz/config.h
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
/**
|
||||
* Copyright 2025 Clayton Craft
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef F0_CONFIG_H
|
||||
#define F0_CONFIG_H
|
||||
|
||||
#include "../shared/backends.h"
|
||||
#include "../shared/config.h"
|
||||
#include "../shared/themes.h"
|
||||
|
||||
#include "sq2lv_layouts.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
/**
|
||||
* General options
|
||||
*/
|
||||
typedef struct {
|
||||
/* Backend to use */
|
||||
bbx_backends_backend_id_t backend;
|
||||
} f0_config_opts_general;
|
||||
|
||||
/**
|
||||
* Options related to the keyboard
|
||||
*/
|
||||
typedef struct {
|
||||
/* If true, hide the keyboard on launch when a hardware keyboard is connected */
|
||||
bool autohide;
|
||||
/* Keyboard layout */
|
||||
sq2lv_layout_id_t layout_id;
|
||||
/* If true, display key popovers on press */
|
||||
bool popovers;
|
||||
} f0_config_opts_keyboard;
|
||||
|
||||
/**
|
||||
* Options related to the theme
|
||||
*/
|
||||
typedef struct {
|
||||
/* Default theme */
|
||||
bbx_themes_theme_id_t default_id;
|
||||
/* Alternate theme */
|
||||
bbx_themes_theme_id_t alternate_id;
|
||||
} f0_config_opts_theme;
|
||||
|
||||
/**
|
||||
* Options related to the password textarea
|
||||
*/
|
||||
typedef struct {
|
||||
/* If true, disguise the entered text with dots */
|
||||
bool obscured;
|
||||
/* The character to use for disguising the entered text */
|
||||
const char *bullet;
|
||||
} f0_config_opts_textarea;
|
||||
|
||||
/**
|
||||
* Options related to input devices
|
||||
*/
|
||||
typedef struct {
|
||||
/* If true and a keyboard device is connected, use it for input */
|
||||
bool keyboard;
|
||||
/* If true and a pointer device is connected, use it for input */
|
||||
bool pointer;
|
||||
/* If true and a touchscreen device is connected, use it for input */
|
||||
bool touchscreen;
|
||||
} f0_config_opts_input;
|
||||
|
||||
/**
|
||||
* (Normally unneeded) quirky options
|
||||
*/
|
||||
typedef struct {
|
||||
/* If true and using the framebuffer backend, force a refresh on every draw operation */
|
||||
bool fbdev_force_refresh;
|
||||
/* If true, do *not* switch terminal into graphics mode (will show terminal command prompt) */
|
||||
bool terminal_prevent_graphics_mode;
|
||||
/* If true, do *not* turn off terminal keyboard input (will show entered characters) */
|
||||
bool terminal_allow_keyboard_input;
|
||||
} f0_config_opts_quirks;
|
||||
|
||||
/**
|
||||
* Form configuration options
|
||||
*/
|
||||
|
||||
/**
|
||||
* Intro section configuration
|
||||
*/
|
||||
typedef struct {
|
||||
/* Welcome screen title */
|
||||
const char *title;
|
||||
/* Welcome screen body text */
|
||||
const char *body;
|
||||
} f0_config_intro;
|
||||
|
||||
/**
|
||||
* Form field types
|
||||
*/
|
||||
typedef enum {
|
||||
F0_FIELD_TYPE_TEXT,
|
||||
F0_FIELD_TYPE_PASSWORD
|
||||
} f0_field_type_t;
|
||||
|
||||
/**
|
||||
* Form field definition
|
||||
*/
|
||||
typedef struct {
|
||||
char *name;
|
||||
f0_field_type_t type;
|
||||
char *label;
|
||||
bool required;
|
||||
} f0_form_field_t;
|
||||
|
||||
typedef struct {
|
||||
/* General options */
|
||||
f0_config_opts_general general;
|
||||
/* Options related to the keyboard */
|
||||
f0_config_opts_keyboard keyboard;
|
||||
/* Options related to the theme */
|
||||
f0_config_opts_theme theme;
|
||||
/* Options related to the password textarea */
|
||||
f0_config_opts_textarea textarea;
|
||||
/* Options related to input devices */
|
||||
f0_config_opts_input input;
|
||||
/* Options related to (normally unneeded) quirks */
|
||||
f0_config_opts_quirks quirks;
|
||||
/* Intro section */
|
||||
f0_config_intro intro;
|
||||
/* Form fields */
|
||||
f0_form_field_t *fields;
|
||||
/* Number of form fields/pages */
|
||||
int num_fields;
|
||||
} f0_config_opts;
|
||||
|
||||
/**
|
||||
* Initialize config options with default values.
|
||||
*
|
||||
* @param opts pointer to the options struct
|
||||
*/
|
||||
void f0_config_init_opts(f0_config_opts *opts);
|
||||
|
||||
/**
|
||||
* Find configuration files in a directory and parse them in alphabetic order.
|
||||
*
|
||||
* @param path directory path
|
||||
* @param opts pointer for writing the parsed options into
|
||||
*/
|
||||
void f0_config_parse_directory(const char *path, f0_config_opts *opts);
|
||||
|
||||
/**
|
||||
* Parse one or more configuration files.
|
||||
*
|
||||
* @param files paths to configuration files
|
||||
* @param num_files number of configuration files
|
||||
* @param opts pointer for writing the parsed options into
|
||||
*/
|
||||
void f0_config_parse_files(const char **files, int num_files, f0_config_opts *opts);
|
||||
|
||||
/**
|
||||
* Parse a configuration file.
|
||||
*
|
||||
* @param path path to configuration file
|
||||
* @param opts pointer for writing the parsed options into
|
||||
*/
|
||||
void f0_config_parse_file(const char *path, f0_config_opts *opts);
|
||||
|
||||
#endif /* F0_CONFIG_H */
|
||||
117
f0rmz/lv_conf.defaults
Normal file
117
f0rmz/lv_conf.defaults
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# Manual post-processing steps for the generated lv_conf.h
|
||||
# 1. Comment LV_USE_LINUX_DRM (handled by meson.build)
|
||||
# 2. Remove LV_BIG_ENDIAN_SYSTEM (handled by meson.build)
|
||||
# 3. Add `#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(bbx_font_32)` (a bug in generate_lv_conf.py)
|
||||
|
||||
LV_COLOR_DEPTH 32
|
||||
LV_USE_STDLIB_MALLOC LV_STDLIB_CLIB
|
||||
LV_USE_STDLIB_STRING LV_STDLIB_CLIB
|
||||
LV_USE_STDLIB_SPRINTF LV_STDLIB_CLIB
|
||||
|
||||
LV_USE_DRAW_SW 1
|
||||
LV_DRAW_SW_COMPLEX 1
|
||||
LV_DRAW_SW_SUPPORT_RGB565 0
|
||||
LV_DRAW_SW_SUPPORT_RGB565_SWAPPED 0
|
||||
LV_DRAW_SW_SUPPORT_RGB565A8 0
|
||||
LV_DRAW_SW_SUPPORT_RGB888 1
|
||||
LV_DRAW_SW_SUPPORT_XRGB8888 1
|
||||
LV_DRAW_SW_SUPPORT_ARGB8888 1
|
||||
LV_DRAW_SW_SUPPORT_ARGB8888_PREMULTIPLIED 0
|
||||
LV_DRAW_SW_SUPPORT_L8 0
|
||||
LV_DRAW_SW_SUPPORT_AL88 0
|
||||
LV_DRAW_SW_SUPPORT_A8 0
|
||||
LV_DRAW_SW_SUPPORT_I1 0
|
||||
|
||||
LV_USE_LOG 1
|
||||
LV_LOG_LEVEL LV_LOG_LEVEL_WARN
|
||||
LV_USE_PRIVATE_API 1
|
||||
|
||||
LV_FONT_MONTSERRAT_8 0
|
||||
LV_FONT_MONTSERRAT_10 0
|
||||
LV_FONT_MONTSERRAT_12 0
|
||||
LV_FONT_MONTSERRAT_14 0
|
||||
LV_FONT_MONTSERRAT_16 0
|
||||
LV_FONT_MONTSERRAT_18 0
|
||||
LV_FONT_MONTSERRAT_20 0
|
||||
LV_FONT_MONTSERRAT_22 0
|
||||
LV_FONT_MONTSERRAT_24 0
|
||||
LV_FONT_MONTSERRAT_26 0
|
||||
LV_FONT_MONTSERRAT_28 0
|
||||
LV_FONT_MONTSERRAT_30 0
|
||||
LV_FONT_MONTSERRAT_32 0
|
||||
LV_FONT_MONTSERRAT_34 0
|
||||
LV_FONT_MONTSERRAT_36 0
|
||||
LV_FONT_MONTSERRAT_38 0
|
||||
LV_FONT_MONTSERRAT_40 0
|
||||
LV_FONT_MONTSERRAT_42 0
|
||||
LV_FONT_MONTSERRAT_44 0
|
||||
LV_FONT_MONTSERRAT_46 0
|
||||
LV_FONT_MONTSERRAT_48 0
|
||||
LV_FONT_MONTSERRAT_28_COMPRESSED 0
|
||||
LV_FONT_DEJAVU_16_PERSIAN_HEBREW 0
|
||||
LV_FONT_SIMSUN_14_CJK 0
|
||||
LV_FONT_SIMSUN_16_CJK 0
|
||||
LV_FONT_UNSCII_8 0
|
||||
LV_FONT_UNSCII_16 0
|
||||
|
||||
#LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(bbx_font_32)
|
||||
LV_FONT_DEFAULT &bbx_font_32
|
||||
|
||||
LV_WIDGETS_HAS_DEFAULT_VALUE 0
|
||||
LV_USE_ANIMIMG 0
|
||||
LV_USE_ARC 0
|
||||
LV_USE_BAR 0
|
||||
LV_USE_BUTTON 1
|
||||
LV_USE_BUTTONMATRIX 1
|
||||
LV_USE_CALENDAR 0
|
||||
LV_USE_CANVAS 0
|
||||
LV_USE_CHART 0
|
||||
LV_USE_CHECKBOX 0
|
||||
LV_USE_DROPDOWN 1
|
||||
LV_USE_IMAGE 1
|
||||
LV_USE_IMAGEBUTTON 0
|
||||
LV_USE_KEYBOARD 1
|
||||
LV_USE_LABEL 1
|
||||
LV_LABEL_TEXT_SELECTION 0
|
||||
LV_LABEL_LONG_TXT_HINT 0
|
||||
LV_USE_LED 0
|
||||
LV_USE_LINE 0
|
||||
LV_USE_LIST 0
|
||||
LV_USE_LOTTIE 0
|
||||
LV_USE_MENU 0
|
||||
LV_USE_MSGBOX 1
|
||||
LV_USE_ROLLER 0
|
||||
LV_USE_SCALE 0
|
||||
LV_USE_SLIDER 0
|
||||
LV_USE_SPAN 0
|
||||
LV_USE_SPINBOX 0
|
||||
LV_USE_SPINNER 0
|
||||
LV_USE_SWITCH 0
|
||||
LV_USE_TEXTAREA 1
|
||||
LV_TEXTAREA_DEF_PWD_SHOW_TIME 0 /*ms*/
|
||||
LV_USE_TABLE 0
|
||||
LV_USE_TABVIEW 0
|
||||
LV_USE_TILEVIEW 0
|
||||
LV_USE_WIN 0
|
||||
|
||||
LV_USE_THEME_DEFAULT 0
|
||||
LV_USE_THEME_SIMPLE 0
|
||||
LV_USE_THEME_MONO 0
|
||||
|
||||
LV_USE_FLEX 1
|
||||
LV_USE_GRID 0
|
||||
|
||||
LV_USE_LINUX_FBDEV 1
|
||||
LV_LINUX_FBDEV_BSD 0
|
||||
LV_LINUX_FBDEV_RENDER_MODE LV_DISPLAY_RENDER_MODE_PARTIAL
|
||||
|
||||
LV_USE_LINUX_DRM 0
|
||||
|
||||
LV_USE_LIBINPUT 1
|
||||
LV_LIBINPUT_BSD 0
|
||||
LV_LIBINPUT_XKB 1
|
||||
|
||||
LV_BUILD_EXAMPLES 0
|
||||
LV_BUILD_DEMOS 0
|
||||
1392
f0rmz/lv_conf.h
Normal file
1392
f0rmz/lv_conf.h
Normal file
File diff suppressed because it is too large
Load diff
908
f0rmz/main.c
Normal file
908
f0rmz/main.c
Normal file
|
|
@ -0,0 +1,908 @@
|
|||
/**
|
||||
* Copyright 2025 Clayton Craft
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "command_line.h"
|
||||
#include "config.h"
|
||||
|
||||
#include "../shared/backends.h"
|
||||
#include "../shared/display.h"
|
||||
#include "../shared/header.h"
|
||||
#include "../shared/indev.h"
|
||||
#include "../shared/keyboard.h"
|
||||
#include "../shared/log.h"
|
||||
#include "../shared/theme.h"
|
||||
#include "../shared/themes.h"
|
||||
#include "../shared/terminal.h"
|
||||
#include "../squeek2lvgl/sq2lv.h"
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <sys/reboot.h>
|
||||
|
||||
#define F0_PASSWORD_HIDDEN_DOTS "••••••••"
|
||||
|
||||
/**
|
||||
* Static variables
|
||||
*/
|
||||
|
||||
f0_cli_opts cli_opts;
|
||||
f0_config_opts conf_opts;
|
||||
|
||||
bool is_alternate_theme = false;
|
||||
bool is_keyboard_hidden = false;
|
||||
|
||||
static char **field_values = NULL;
|
||||
|
||||
int current_field_index = 0;
|
||||
|
||||
lv_obj_t *form_container = NULL;
|
||||
lv_obj_t *form_textarea = NULL;
|
||||
lv_obj_t *keyboard = NULL;
|
||||
|
||||
int32_t content_height_with_kb;
|
||||
int32_t content_height_without_kb;
|
||||
|
||||
/**
|
||||
* Static prototypes
|
||||
*/
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from the theme toggle button.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void toggle_theme_btn_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Toggle between the light and dark theme.
|
||||
*/
|
||||
static void toggle_theme(void);
|
||||
|
||||
/**
|
||||
* Set the UI theme.
|
||||
*
|
||||
* @param is_alternate true if the alternate theme should be applied, false if the default theme should be applied
|
||||
*/
|
||||
static void set_theme(bool is_alternate);
|
||||
|
||||
/**
|
||||
* Get the UI theme.
|
||||
*
|
||||
* @param is_alternate true if the alternate theme should be selected, false if the default theme should be selected
|
||||
*/
|
||||
static const bbx_theme * get_theme(bool is_alternate);
|
||||
|
||||
/**
|
||||
* Show the intro screen.
|
||||
*
|
||||
*/
|
||||
static void show_intro_screen(void);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_KEY events from the intro 'get started' button.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void get_started_btn_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_KEY events on intro screen.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void intro_key_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Show form screen with a field
|
||||
*/
|
||||
static void show_form_screen(void);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from the form field submit.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void field_submit_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from the form 'previous' button.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void prev_btn_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from the form 'next' button.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void next_btn_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Validate a form field according to its requirements.
|
||||
*
|
||||
* @param field_index index of the field to validate
|
||||
* @return true if field is valid, false otherwise
|
||||
*/
|
||||
static bool validate_field(int field_index);
|
||||
|
||||
/**
|
||||
* Set visual validation error state on the current textarea.
|
||||
*
|
||||
* @param has_error true to show error styling, false to clear it
|
||||
*/
|
||||
static void set_field_validation_error(bool has_error);
|
||||
|
||||
/**
|
||||
* Save current textarea content and validate the field.
|
||||
*
|
||||
* @return true if field is valid, false if validation failed
|
||||
*/
|
||||
static bool save_and_validate_current_field(void);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from the show/hide keyboard toggle button.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void toggle_kb_btn_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Toggle between showing and hiding the keyboard.
|
||||
*/
|
||||
static void toggle_keyboard_hidden(void);
|
||||
|
||||
/**
|
||||
* Show / hide the keyboard.
|
||||
*
|
||||
* @param is_hidden true if the keyboard should be hidden, false if it should be shown
|
||||
*/
|
||||
static void set_keyboard_hidden(bool is_hidden);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from password visibility toggle button.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void toggle_password_btn_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from password visibility toggle button in
|
||||
* summary.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void toggle_password_summary_btn_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_VALUE_CHANGED events from the keyboard layout dropdown.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void layout_dropdown_value_changed_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from the shutdown button.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void shutdown_btn_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle confirmation events from the shutdown message box.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void shutdown_mbox_confirmed_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle declination events from the shutdown message box.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void shutdown_mbox_declined_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_VALUE_CHANGED events from the keyboard widget.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void keyboard_value_changed_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_READY events from the keyboard widget.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void keyboard_ready_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Show summary screen with all field values.
|
||||
*/
|
||||
static void show_summary_screen(void);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from summary field items.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void summary_field_clicked_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Handle LV_EVENT_CLICKED events from finish button.
|
||||
*
|
||||
* @param event the event object
|
||||
*/
|
||||
static void finish_cb(lv_event_t *event);
|
||||
|
||||
/**
|
||||
* Shuts down the device.
|
||||
*/
|
||||
static void shutdown(void);
|
||||
|
||||
/**
|
||||
* Handle termination signals sent to the process.
|
||||
*
|
||||
* @param signum the signal's number
|
||||
*/
|
||||
static void sigaction_handler(int signum);
|
||||
|
||||
/**
|
||||
* Restore the terminal and exit from the program with EXIT_FAILURE.
|
||||
*/
|
||||
static void exit_failure();
|
||||
|
||||
/**
|
||||
* Static functions
|
||||
*/
|
||||
|
||||
static void intro_key_cb(lv_event_t *event) {
|
||||
uint32_t key = lv_indev_get_key(lv_indev_active());
|
||||
if (key == LV_KEY_ENTER) {
|
||||
get_started_btn_clicked_cb(event);
|
||||
}
|
||||
}
|
||||
|
||||
static void toggle_theme_btn_clicked_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
toggle_theme();
|
||||
}
|
||||
|
||||
static void sigaction_handler(int signum) {
|
||||
bbx_terminal_reset_current_terminal();
|
||||
exit(signum);
|
||||
}
|
||||
|
||||
static void exit_failure() {
|
||||
bbx_terminal_reset_current_terminal();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
||||
static void toggle_theme(void) {
|
||||
is_alternate_theme = !is_alternate_theme;
|
||||
set_theme(is_alternate_theme);
|
||||
}
|
||||
|
||||
static void set_theme(bool is_alternate) {
|
||||
bbx_theme_apply(get_theme(is_alternate));
|
||||
}
|
||||
|
||||
static const bbx_theme * get_theme(bool is_alternate) {
|
||||
return bbx_themes_themes[is_alternate ? conf_opts.theme.alternate_id : conf_opts.theme.default_id];
|
||||
}
|
||||
|
||||
static void toggle_kb_btn_clicked_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
toggle_keyboard_hidden();
|
||||
}
|
||||
|
||||
static void toggle_keyboard_hidden(void) {
|
||||
is_keyboard_hidden = !is_keyboard_hidden;
|
||||
set_keyboard_hidden(is_keyboard_hidden);
|
||||
}
|
||||
|
||||
static void set_keyboard_hidden(bool is_hidden) {
|
||||
if (!form_container) return;
|
||||
|
||||
lv_anim_t container_anim;
|
||||
lv_anim_init(&container_anim);
|
||||
lv_anim_set_var(&container_anim, form_container);
|
||||
lv_anim_set_exec_cb(&container_anim, (lv_anim_exec_xcb_t) lv_obj_set_height);
|
||||
lv_anim_set_path_cb(&container_anim, lv_anim_path_ease_out);
|
||||
lv_anim_set_time(&container_anim, 500);
|
||||
|
||||
lv_anim_set_values(&container_anim,
|
||||
is_hidden? content_height_with_kb : content_height_without_kb,
|
||||
is_hidden? content_height_without_kb : content_height_with_kb);
|
||||
|
||||
lv_anim_start(&container_anim);
|
||||
}
|
||||
|
||||
static void toggle_password_btn_clicked_cb(lv_event_t *event) {
|
||||
lv_obj_t *btn = lv_event_get_target(event);
|
||||
lv_obj_t *textarea = (lv_obj_t *)lv_obj_get_user_data(btn);
|
||||
lv_obj_t *btn_label = lv_obj_get_child(btn, 0);
|
||||
|
||||
bool is_obscured = lv_textarea_get_password_mode(textarea);
|
||||
lv_textarea_set_password_mode(textarea, !is_obscured);
|
||||
lv_label_set_text(btn_label, is_obscured ? LV_SYMBOL_EYE_CLOSE : LV_SYMBOL_EYE_OPEN);
|
||||
}
|
||||
|
||||
static void toggle_password_summary_btn_clicked_cb(lv_event_t *event) {
|
||||
lv_obj_t *btn = lv_event_get_target(event);
|
||||
lv_obj_t *value_label = (lv_obj_t *)lv_obj_get_user_data(btn);
|
||||
lv_obj_t *btn_label = lv_obj_get_child(btn, 0);
|
||||
|
||||
const char *current_text = lv_label_get_text(value_label);
|
||||
bool is_obscured = (strcmp(current_text, F0_PASSWORD_HIDDEN_DOTS) == 0);
|
||||
|
||||
if (is_obscured) {
|
||||
/* Show actual password - need field index to get real value */
|
||||
int field_index = (int)(intptr_t)lv_obj_get_user_data(value_label);
|
||||
const char *real_value = field_values[field_index] ? field_values[field_index] : "";
|
||||
lv_label_set_text(value_label, real_value);
|
||||
lv_label_set_text(btn_label, LV_SYMBOL_EYE_CLOSE);
|
||||
} else {
|
||||
lv_label_set_text(value_label, F0_PASSWORD_HIDDEN_DOTS);
|
||||
lv_label_set_text(btn_label, LV_SYMBOL_EYE_OPEN);
|
||||
}
|
||||
}
|
||||
|
||||
static void layout_dropdown_value_changed_cb(lv_event_t *event) {
|
||||
lv_obj_t *dropdown = lv_event_get_target(event);
|
||||
uint16_t idx = lv_dropdown_get_selected(dropdown);
|
||||
sq2lv_switch_layout(keyboard, idx);
|
||||
}
|
||||
|
||||
static void shutdown_btn_clicked_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
lv_obj_t *mbox = lv_msgbox_create(NULL);
|
||||
lv_msgbox_add_title(mbox, "Shutdown device?");
|
||||
lv_obj_t *confirm_btn = lv_msgbox_add_footer_button(mbox, "Yes");
|
||||
lv_obj_add_event_cb(confirm_btn, shutdown_mbox_confirmed_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_t *decline_btn = lv_msgbox_add_footer_button(mbox, "No");
|
||||
lv_obj_add_event_cb(decline_btn, shutdown_mbox_declined_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_set_size(mbox, 400, LV_SIZE_CONTENT);
|
||||
lv_obj_center(mbox);
|
||||
}
|
||||
|
||||
static void shutdown_mbox_confirmed_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
shutdown();
|
||||
}
|
||||
|
||||
static void shutdown_mbox_declined_cb(lv_event_t *event) {
|
||||
/* Find the containing message box for the clicked button */
|
||||
lv_obj_t *obj = lv_event_get_target(event);
|
||||
while (obj && !lv_obj_check_type(obj, &lv_msgbox_class)) {
|
||||
obj = lv_obj_get_parent(obj);
|
||||
}
|
||||
|
||||
if (!obj) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Could not find containing message box for clicked button");
|
||||
return;
|
||||
}
|
||||
|
||||
lv_msgbox_close(obj);
|
||||
}
|
||||
|
||||
static void keyboard_value_changed_cb(lv_event_t *event) {
|
||||
lv_obj_t *kb = lv_event_get_target(event);
|
||||
|
||||
uint16_t btn_id = lv_buttonmatrix_get_selected_button(kb);
|
||||
if (btn_id == LV_BUTTONMATRIX_BUTTON_NONE) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (sq2lv_is_layer_switcher(kb, btn_id)) {
|
||||
sq2lv_switch_layer(kb, btn_id);
|
||||
return;
|
||||
}
|
||||
|
||||
lv_keyboard_def_event_cb(event);
|
||||
}
|
||||
|
||||
static void keyboard_ready_cb(lv_event_t *event) {
|
||||
field_submit_cb(event);
|
||||
}
|
||||
|
||||
static void get_started_btn_clicked_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
current_field_index = 0;
|
||||
show_form_screen();
|
||||
}
|
||||
|
||||
static void field_submit_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
if (save_and_validate_current_field()) {
|
||||
current_field_index++;
|
||||
if (current_field_index >= conf_opts.num_fields) {
|
||||
show_summary_screen();
|
||||
} else {
|
||||
show_form_screen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void prev_btn_clicked_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
if (current_field_index > 0 && save_and_validate_current_field()) {
|
||||
current_field_index--;
|
||||
show_form_screen();
|
||||
}
|
||||
}
|
||||
|
||||
static void next_btn_clicked_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
if (save_and_validate_current_field()) {
|
||||
current_field_index++;
|
||||
if (current_field_index >= conf_opts.num_fields) {
|
||||
show_summary_screen();
|
||||
} else {
|
||||
show_form_screen();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void summary_field_clicked_cb(lv_event_t *event) {
|
||||
lv_obj_t *target = lv_event_get_target(event);
|
||||
int field_index = (int)(intptr_t)lv_obj_get_user_data(target);
|
||||
|
||||
current_field_index = field_index;
|
||||
show_form_screen();
|
||||
}
|
||||
|
||||
static void finish_cb(lv_event_t *event) {
|
||||
LV_UNUSED(event);
|
||||
|
||||
/* Output key=value pairs */
|
||||
for (int i = 0; i < conf_opts.num_fields; i++) {
|
||||
const f0_form_field_t *field = &conf_opts.fields[i];
|
||||
const char *value = field_values[i] ? field_values[i] : "";
|
||||
printf("%s=%s\n", field->name, value);
|
||||
}
|
||||
|
||||
/* Clear the screen so that form data cannot leak via stale display buffers */
|
||||
lv_obj_t *rect = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(rect, LV_PCT(100), LV_PCT(100));
|
||||
lv_obj_set_pos(rect, 0, 0);
|
||||
lv_obj_set_style_bg_opa(rect, LV_OPA_COVER, LV_PART_MAIN);
|
||||
lv_obj_set_style_bg_color(rect, lv_color_hex(get_theme(is_alternate_theme)->window.bg_color), LV_PART_MAIN);
|
||||
lv_refr_now(lv_display_get_default()); /* Force the screen to be drawn */
|
||||
|
||||
/* Trigger SIGTERM to exit */
|
||||
sigaction_handler(SIGTERM);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static bool validate_field(int field_index) {
|
||||
if (field_index >= conf_opts.num_fields) return true;
|
||||
|
||||
const f0_form_field_t *field = &conf_opts.fields[field_index];
|
||||
const char *value = field_values[field_index] ? field_values[field_index] : "";
|
||||
|
||||
// Required field validation
|
||||
if (field->required && strlen(value) == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Future validation rules here, e.g.:
|
||||
// if (field->min_length > 0 && strlen(value) < field->min_length) return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void set_field_validation_error(bool has_error) {
|
||||
if (!form_textarea) return;
|
||||
|
||||
if (has_error) {
|
||||
lv_obj_set_style_border_color(form_textarea, lv_color_hex(0xFF0000), LV_PART_MAIN);
|
||||
lv_obj_set_style_border_width(form_textarea, 2, LV_PART_MAIN);
|
||||
} else {
|
||||
lv_obj_set_style_border_color(form_textarea, lv_color_hex(0x000000), LV_PART_MAIN);
|
||||
lv_obj_set_style_border_width(form_textarea, 1, LV_PART_MAIN);
|
||||
}
|
||||
}
|
||||
|
||||
static bool save_and_validate_current_field() {
|
||||
if (!form_textarea || !field_values) return true;
|
||||
|
||||
// Save current content
|
||||
char *new_value = strdup(lv_textarea_get_text(form_textarea));
|
||||
if (new_value) {
|
||||
if (field_values[current_field_index]) {
|
||||
free(field_values[current_field_index]);
|
||||
}
|
||||
field_values[current_field_index] = new_value;
|
||||
}
|
||||
|
||||
// Validate and show/clear error
|
||||
bool is_valid = validate_field(current_field_index);
|
||||
set_field_validation_error(!is_valid);
|
||||
|
||||
return is_valid;
|
||||
}
|
||||
|
||||
static void show_intro_screen(void) {
|
||||
lv_obj_t *screen = lv_screen_active();
|
||||
|
||||
/* Header config */
|
||||
bbx_header_config_t header_config;
|
||||
bbx_header_init_config(&header_config);
|
||||
/* No OSK needed on intro */
|
||||
header_config.show_keyboard_toggle = false;
|
||||
header_config.show_layout_dropdown = false;
|
||||
|
||||
bbx_header_widgets_t header_widgets;
|
||||
lv_obj_t *header = bbx_header_create(screen, &header_config, &header_widgets);
|
||||
lv_obj_add_flag(header, BBX_WIDGET_HEADER);
|
||||
lv_theme_apply(header);
|
||||
|
||||
/* Attach callbacks */
|
||||
lv_obj_add_event_cb(header_widgets.theme_toggle_btn, toggle_theme_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
/* Container for intro content */
|
||||
lv_obj_t *container = lv_obj_create(screen);
|
||||
lv_obj_set_size(container, LV_PCT(100), LV_PCT(100));
|
||||
lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(container, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_set_style_pad_all(container, 40, LV_PART_MAIN);
|
||||
|
||||
/* Title */
|
||||
lv_obj_t *title = lv_label_create(container);
|
||||
lv_label_set_text(title, conf_opts.intro.title);
|
||||
lv_obj_set_style_text_align(title, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_bottom(title, 20, LV_PART_MAIN);
|
||||
|
||||
/* Body */
|
||||
lv_obj_t *body = lv_label_create(container);
|
||||
lv_label_set_text(body, conf_opts.intro.body);
|
||||
lv_label_set_long_mode(body, LV_LABEL_LONG_WRAP);
|
||||
lv_obj_set_width(body, LV_PCT(80));
|
||||
lv_obj_set_style_text_align(body, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN);
|
||||
lv_obj_set_style_pad_bottom(body, 30, LV_PART_MAIN);
|
||||
|
||||
/* Get Started button */
|
||||
lv_obj_t *btn = lv_button_create(container);
|
||||
lv_obj_t *btn_label = lv_label_create(btn);
|
||||
lv_label_set_text(btn_label, "Get Started");
|
||||
lv_obj_center(btn_label);
|
||||
lv_obj_add_event_cb(btn, get_started_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
/* Set up keyboard input for intro screen */
|
||||
lv_group_t *intro_input_group = lv_group_create();
|
||||
bbx_indev_set_keyboard_input_group(intro_input_group);
|
||||
lv_group_add_obj(intro_input_group, btn);
|
||||
lv_obj_add_event_cb(btn, intro_key_cb, LV_EVENT_KEY, NULL);
|
||||
}
|
||||
|
||||
static void show_form_screen(void) {
|
||||
if (current_field_index >= conf_opts.num_fields) {
|
||||
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Form complete");
|
||||
return;
|
||||
}
|
||||
|
||||
if (field_values == NULL) {
|
||||
field_values = calloc(conf_opts.num_fields, sizeof(char*));
|
||||
}
|
||||
|
||||
f0_form_field_t *field = &conf_opts.fields[current_field_index];
|
||||
|
||||
/* Clear screen */
|
||||
lv_obj_clean(lv_screen_active());
|
||||
|
||||
/* Recreate header */
|
||||
bbx_header_config_t header_config;
|
||||
bbx_header_init_config(&header_config);
|
||||
header_config.show_keyboard_toggle = true;
|
||||
header_config.show_layout_dropdown = true;
|
||||
header_config.dropdown_options = sq2lv_layout_short_names;
|
||||
|
||||
bbx_header_widgets_t header_widgets;
|
||||
lv_obj_t *header = bbx_header_create(lv_screen_active(), &header_config, &header_widgets);
|
||||
lv_obj_add_flag(header, BBX_WIDGET_HEADER);
|
||||
lv_theme_apply(header);
|
||||
|
||||
/* Attach callbacks */
|
||||
lv_obj_add_event_cb(header_widgets.theme_toggle_btn, toggle_theme_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_event_cb(header_widgets.keyboard_toggle_btn, toggle_kb_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_event_cb(header_widgets.layout_dropdown, layout_dropdown_value_changed_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_event_cb(header_widgets.shutdown_btn, shutdown_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
/* Calculate keyboard dimensions and container heights */
|
||||
lv_obj_update_layout(header);
|
||||
const int32_t hor_res = lv_display_get_horizontal_resolution(lv_display_get_default());
|
||||
const int32_t ver_res = lv_display_get_vertical_resolution(lv_display_get_default());
|
||||
const int32_t keyboard_height = ver_res > hor_res ? ver_res / 2.5 : ver_res / 1.8;
|
||||
|
||||
content_height_without_kb = ver_res - lv_obj_get_height(header);
|
||||
content_height_with_kb = content_height_without_kb - keyboard_height;
|
||||
|
||||
/* Form container - vertical layout */
|
||||
form_container = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_flex_flow(form_container, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_flex_align(form_container, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
lv_obj_set_style_pad_all(form_container, 40, LV_PART_MAIN);
|
||||
lv_obj_remove_flag(form_container, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
/* Field label */
|
||||
lv_obj_t *label = lv_label_create(form_container);
|
||||
lv_label_set_text(label, field->label ? field->label : field->name);
|
||||
lv_obj_set_style_pad_bottom(label, 20, LV_PART_MAIN);
|
||||
|
||||
/* Textarea container */
|
||||
lv_obj_t *textarea_container = lv_obj_create(form_container);
|
||||
lv_obj_set_size(textarea_container, LV_PCT(80), LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_flow(textarea_container, LV_FLEX_FLOW_ROW);
|
||||
|
||||
/* Create textarea and restore content */
|
||||
form_textarea = lv_textarea_create(textarea_container);
|
||||
lv_textarea_set_one_line(form_textarea, true);
|
||||
if (field->type == F0_FIELD_TYPE_PASSWORD) {
|
||||
lv_textarea_set_password_mode(form_textarea, true);
|
||||
lv_textarea_set_password_bullet(form_textarea, conf_opts.textarea.bullet);
|
||||
}
|
||||
lv_obj_add_event_cb(form_textarea, field_submit_cb, LV_EVENT_READY, NULL);
|
||||
lv_obj_set_flex_grow(form_textarea, 1);
|
||||
lv_obj_add_state(form_textarea, LV_STATE_FOCUSED);
|
||||
|
||||
/* Reveal / obscure password button */
|
||||
if (field->type == F0_FIELD_TYPE_PASSWORD) {
|
||||
lv_obj_update_layout(form_textarea);
|
||||
const int32_t textarea_height = lv_obj_get_height(form_textarea);
|
||||
|
||||
lv_obj_t *toggle_pw_btn = lv_button_create(textarea_container);
|
||||
lv_obj_set_size(toggle_pw_btn, textarea_height, textarea_height);
|
||||
lv_obj_t *toggle_pw_btn_label = lv_label_create(toggle_pw_btn);
|
||||
lv_obj_center(toggle_pw_btn_label);
|
||||
lv_label_set_text(toggle_pw_btn_label, LV_SYMBOL_EYE_OPEN);
|
||||
lv_obj_set_user_data(toggle_pw_btn, form_textarea);
|
||||
lv_obj_add_event_cb(toggle_pw_btn, toggle_password_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
}
|
||||
|
||||
/* Restore saved content */
|
||||
if (field_values[current_field_index]) {
|
||||
lv_textarea_set_text(form_textarea, field_values[current_field_index]);
|
||||
/* Prevent text from being scrolled off to the left of the textarea */
|
||||
lv_obj_update_layout(form_textarea);
|
||||
lv_obj_scroll_to_x(form_textarea, 0, LV_ANIM_OFF);
|
||||
}
|
||||
|
||||
/* Navigation bar at bottom */
|
||||
lv_obj_t *nav_container = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(nav_container, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_flow(nav_container, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_style_pad_all(nav_container, 10, LV_PART_MAIN);
|
||||
|
||||
/* Previous button */
|
||||
lv_obj_t *prev_btn = lv_button_create(nav_container);
|
||||
lv_obj_t *prev_label = lv_label_create(prev_btn);
|
||||
lv_label_set_text(prev_label, "Previous");
|
||||
lv_obj_center(prev_label);
|
||||
lv_obj_add_event_cb(prev_btn, prev_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
if (current_field_index == 0) {
|
||||
lv_obj_add_flag(prev_btn, LV_OBJ_FLAG_HIDDEN);
|
||||
} else {
|
||||
lv_obj_remove_flag(prev_btn, LV_OBJ_FLAG_HIDDEN);
|
||||
}
|
||||
|
||||
/* Spacer to push Next to the right */
|
||||
lv_obj_t *spacer = lv_obj_create(nav_container);
|
||||
lv_obj_set_flex_grow(spacer, 1);
|
||||
lv_obj_set_height(spacer, 0);
|
||||
|
||||
/* Next button */
|
||||
lv_obj_t *next_btn = lv_button_create(nav_container);
|
||||
lv_obj_t *next_label = lv_label_create(next_btn);
|
||||
lv_label_set_text(next_label, current_field_index >= conf_opts.num_fields - 1 ? "Submit" : "Next");
|
||||
lv_obj_center(next_label);
|
||||
lv_obj_add_event_cb(next_btn, next_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
/* Update layout to get nav bar height */
|
||||
lv_obj_update_layout(nav_container);
|
||||
const int32_t nav_height = lv_obj_get_height(nav_container);
|
||||
|
||||
/* Adjust content heights for nav bar */
|
||||
content_height_without_kb -= nav_height;
|
||||
content_height_with_kb -= nav_height;
|
||||
|
||||
/* Update form container size to account for nav bar */
|
||||
lv_obj_set_size(form_container, LV_PCT(100), is_keyboard_hidden ? content_height_without_kb : content_height_with_kb);
|
||||
|
||||
/* Create keyboard widget */
|
||||
bbx_keyboard_config_t keyboard_config;
|
||||
bbx_keyboard_init_config(&keyboard_config);
|
||||
keyboard_config.layout_id = (int)conf_opts.keyboard.layout_id;
|
||||
keyboard_config.height = keyboard_height;
|
||||
keyboard_config.popovers = conf_opts.keyboard.popovers;
|
||||
keyboard_config.value_changed_callback = keyboard_value_changed_cb;
|
||||
keyboard_config.ready_callback = keyboard_ready_cb;
|
||||
keyboard = bbx_keyboard_create(lv_screen_active(), form_textarea, &keyboard_config);
|
||||
|
||||
/* Configuring routing for physical keyboard input into the textarea */
|
||||
lv_group_t *keyboard_input_group = lv_group_create();
|
||||
bbx_indev_set_keyboard_input_group(keyboard_input_group);
|
||||
lv_group_add_obj(keyboard_input_group, form_textarea);
|
||||
}
|
||||
|
||||
static void show_summary_screen(void) {
|
||||
/* Clear screen */
|
||||
lv_obj_clean(lv_screen_active());
|
||||
|
||||
/* Header */
|
||||
bbx_header_config_t header_config;
|
||||
bbx_header_init_config(&header_config);
|
||||
header_config.show_keyboard_toggle = false;
|
||||
header_config.show_layout_dropdown = false;
|
||||
|
||||
bbx_header_widgets_t header_widgets;
|
||||
lv_obj_t *header = bbx_header_create(lv_screen_active(), &header_config, &header_widgets);
|
||||
lv_obj_add_flag(header, BBX_WIDGET_HEADER);
|
||||
lv_theme_apply(header);
|
||||
lv_obj_add_event_cb(header_widgets.theme_toggle_btn, toggle_theme_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
/* Summary container */
|
||||
lv_obj_t *container = lv_obj_create(lv_screen_active());
|
||||
lv_obj_set_size(container, LV_PCT(100), LV_PCT(80));
|
||||
lv_obj_set_flex_flow(container, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_style_pad_all(container, 20, LV_PART_MAIN);
|
||||
|
||||
/* Title */
|
||||
lv_obj_t *title = lv_label_create(container);
|
||||
lv_label_set_text(title, "Summary");
|
||||
lv_obj_set_style_pad_bottom(title, 20, LV_PART_MAIN);
|
||||
|
||||
/* Field list */
|
||||
for (int i = 0; i < conf_opts.num_fields; i++) {
|
||||
f0_form_field_t *field = &conf_opts.fields[i];
|
||||
const char *value = field_values[i] ? field_values[i] : "";
|
||||
|
||||
lv_obj_t *item_btn = lv_button_create(container);
|
||||
lv_obj_set_width(item_btn, LV_PCT(100));
|
||||
lv_obj_set_user_data(item_btn, (void*)(intptr_t)i);
|
||||
lv_obj_add_event_cb(item_btn, summary_field_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
lv_obj_t *item_container = lv_obj_create(item_btn);
|
||||
lv_obj_set_flex_flow(item_container, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_set_width(item_container, LV_PCT(100));
|
||||
lv_obj_add_flag(item_container, LV_OBJ_FLAG_EVENT_BUBBLE);
|
||||
|
||||
lv_obj_t *label = lv_label_create(item_container);
|
||||
lv_label_set_text(label, field->label ? field->label : field->name);
|
||||
lv_obj_set_style_text_decor(label, LV_TEXT_DECOR_UNDERLINE, LV_PART_MAIN);
|
||||
|
||||
lv_obj_t *value_label = lv_label_create(item_container);
|
||||
if (strlen(value) > 0) {
|
||||
if (field->type == F0_FIELD_TYPE_PASSWORD) {
|
||||
lv_label_set_text(value_label, F0_PASSWORD_HIDDEN_DOTS);
|
||||
|
||||
/* Add toggle button for password */
|
||||
lv_obj_t *toggle_btn = lv_button_create(item_container);
|
||||
lv_obj_set_size(toggle_btn, 40, 30);
|
||||
lv_obj_set_user_data(toggle_btn, value_label);
|
||||
|
||||
lv_obj_t *toggle_label = lv_label_create(toggle_btn);
|
||||
lv_label_set_text(toggle_label, LV_SYMBOL_EYE_OPEN);
|
||||
lv_obj_center(toggle_label);
|
||||
lv_obj_add_event_cb(toggle_btn, toggle_password_summary_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
} else {
|
||||
lv_label_set_text(value_label, value);
|
||||
}
|
||||
} else {
|
||||
lv_label_set_text(value_label, "(empty)");
|
||||
}
|
||||
|
||||
/* Save field index to obj to reference later in summary_field_click_cb */
|
||||
lv_obj_set_user_data(item_container, (void*)(intptr_t)i);
|
||||
lv_obj_set_user_data(label, (void*)(intptr_t)i);
|
||||
lv_obj_set_user_data(value_label, (void*)(intptr_t)i);
|
||||
}
|
||||
|
||||
/* Spacer for button positioning */
|
||||
lv_obj_t *spacer = lv_obj_create(container);
|
||||
lv_obj_set_height(spacer, 20);
|
||||
lv_obj_set_width(spacer, 0);
|
||||
|
||||
/* Button container for centering */
|
||||
lv_obj_t *button_container = lv_obj_create(container);
|
||||
lv_obj_set_size(button_container, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
lv_obj_set_flex_flow(button_container, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_flex_align(button_container, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
|
||||
|
||||
/* Finish button */
|
||||
lv_obj_t *finish_btn = lv_button_create(button_container);
|
||||
lv_obj_t *finish_label = lv_label_create(finish_btn);
|
||||
lv_label_set_text(finish_label, "Finish");
|
||||
lv_obj_center(finish_label);
|
||||
lv_obj_add_event_cb(finish_btn, finish_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
/* Set up keyboard input for summary screen */
|
||||
lv_group_t *summary_input_group = lv_group_create();
|
||||
bbx_indev_set_keyboard_input_group(summary_input_group);
|
||||
lv_group_add_obj(summary_input_group, finish_btn);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
f0_cli_parse_opts(argc, argv, &cli_opts);
|
||||
|
||||
if (cli_opts.common.verbose) {
|
||||
bbx_log_set_level(BBX_LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
|
||||
/* Parse config files */
|
||||
f0_config_init_opts(&conf_opts);
|
||||
f0_config_parse_file("/usr/share/f0rmz/f0rmz.conf", &conf_opts);
|
||||
f0_config_parse_directory("/usr/share/f0rmz/f0rmz.conf.d", &conf_opts);
|
||||
f0_config_parse_file("/etc/f0rmz.conf", &conf_opts);
|
||||
f0_config_parse_directory("/etc/f0rmz.conf.d", &conf_opts);
|
||||
f0_config_parse_file(cli_opts.config_file, &conf_opts);
|
||||
|
||||
/* Prepare current TTY and clean up on termination */
|
||||
bbx_terminal_prepare_current_terminal(!conf_opts.quirks.terminal_prevent_graphics_mode, !conf_opts.quirks.terminal_allow_keyboard_input);
|
||||
struct sigaction action;
|
||||
memset(&action, 0, sizeof(action));
|
||||
action.sa_handler = sigaction_handler;
|
||||
sigaction(SIGINT, &action, NULL);
|
||||
sigaction(SIGTERM, &action, NULL);
|
||||
|
||||
/* Initialize LVGL */
|
||||
lv_init();
|
||||
lv_log_register_print_cb(bbx_log_print_cb);
|
||||
|
||||
/* Populate display config */
|
||||
bbx_display_config_t display_config = {
|
||||
.hor_res = cli_opts.common.hor_res,
|
||||
.ver_res = cli_opts.common.ver_res,
|
||||
.x_offset = cli_opts.common.x_offset,
|
||||
.y_offset = cli_opts.common.y_offset,
|
||||
.dpi = cli_opts.common.dpi,
|
||||
.fbdev_force_refresh = conf_opts.quirks.fbdev_force_refresh
|
||||
};
|
||||
|
||||
/* Initialize display */
|
||||
lv_display_t *disp = bbx_display_create(conf_opts.general.backend, &display_config);
|
||||
if (!disp) {
|
||||
exit_failure();
|
||||
}
|
||||
|
||||
/* Prepare for routing physical keyboard input into the textarea */
|
||||
lv_group_t *keyboard_input_group = lv_group_create();
|
||||
bbx_indev_set_keyboard_input_group(keyboard_input_group);
|
||||
|
||||
/* Start input device monitor and auto-connect available devices */
|
||||
bbx_indev_start_monitor_and_autoconnect(conf_opts.input.keyboard, conf_opts.input.pointer, conf_opts.input.touchscreen);
|
||||
|
||||
/* Hide the on-screen keyboard by default if a physical keyboard is connected */
|
||||
if (conf_opts.keyboard.autohide && bbx_indev_is_keyboard_connected()) {
|
||||
is_keyboard_hidden = true;
|
||||
}
|
||||
|
||||
/* Prevent scrolling when keyboard is off-screen */
|
||||
lv_obj_t *screen = lv_screen_active();
|
||||
lv_theme_apply(screen);
|
||||
lv_obj_set_flex_flow(screen, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_remove_flag(screen, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
/* Initialise theme */
|
||||
set_theme(is_alternate_theme);
|
||||
|
||||
/* Create header */
|
||||
show_intro_screen();
|
||||
|
||||
/* Main loop */
|
||||
while(1) {
|
||||
uint32_t time_till_next = lv_timer_handler();
|
||||
usleep(time_till_next * 1000);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
34
f0rmz/meson.build
Normal file
34
f0rmz/meson.build
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
# Copyright 2025 buffybox contributors
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
f0rmz_sources = files(
|
||||
'command_line.c',
|
||||
'config.c',
|
||||
'main.c',
|
||||
'sq2lv_layouts.c'
|
||||
)
|
||||
|
||||
f0rmz_dependencies = [
|
||||
common_dependencies,
|
||||
depinih,
|
||||
depxkbcommon
|
||||
]
|
||||
|
||||
f0rmz_args = []
|
||||
|
||||
deplibdrm = dependency('libdrm', required: get_option('with-drm'))
|
||||
if deplibdrm.found()
|
||||
f0rmz_dependencies += deplibdrm
|
||||
f0rmz_args += '-DLV_USE_LINUX_DRM=1'
|
||||
else
|
||||
f0rmz_args += '-DLV_USE_LINUX_DRM=0'
|
||||
endif
|
||||
|
||||
executable('f0rmz',
|
||||
include_directories: common_include_dirs,
|
||||
sources: f0rmz_sources + shared_sources + squeek2lvgl_sources + lvgl_sources + header_sources,
|
||||
dependencies: f0rmz_dependencies,
|
||||
c_args: f0rmz_args,
|
||||
install: true,
|
||||
install_tag: 'f0rmz'
|
||||
)
|
||||
949
f0rmz/sq2lv_layouts.c
Normal file
949
f0rmz/sq2lv_layouts.c
Normal file
|
|
@ -0,0 +1,949 @@
|
|||
/**
|
||||
* Auto-generated with squeek2lvgl
|
||||
**/
|
||||
|
||||
#include "sq2lv_layouts.h"
|
||||
#include "../squeek2lvgl/sq2lv.h"
|
||||
|
||||
#define SQ2LV_SYMBOL_SHIFT "\xef\x8d\x9b"
|
||||
|
||||
/**
|
||||
* Layout: US English - generated from us
|
||||
**/
|
||||
|
||||
static const char * const name_us = "US English";
|
||||
static const char * const short_name_us = "us";
|
||||
|
||||
/* Layer: Lowercase letters - generated from base */
|
||||
|
||||
static const int num_keys_lower_us = 44;
|
||||
|
||||
static const char * const keycaps_lower_us[] = { \
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\n", \
|
||||
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\n", \
|
||||
"a", "s", "d", "f", "g", "h", "j", "k", "l", "\n", \
|
||||
SQ2LV_SYMBOL_SHIFT, "z", "x", "c", "v", "b", "n", "m", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"123", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, ".", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_lower_us[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_lower_us = 0;
|
||||
|
||||
static const int * const modifier_idxs_lower_us = NULL;
|
||||
|
||||
static const int num_switchers_lower_us = 2;
|
||||
|
||||
static const int switcher_idxs_lower_us[] = { \
|
||||
29, 38 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_lower_us[] = { \
|
||||
1, 2 \
|
||||
};
|
||||
|
||||
/* Layer: Uppercase letters - generated from upper */
|
||||
|
||||
static const int num_keys_upper_us = 44;
|
||||
|
||||
static const char * const keycaps_upper_us[] = { \
|
||||
"!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "\n", \
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\n", \
|
||||
"A", "S", "D", "F", "G", "H", "J", "K", "L", "\n", \
|
||||
SQ2LV_SYMBOL_SHIFT, "Z", "X", "C", "V", "B", "N", "M", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"123", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, ".", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_upper_us[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_MOD_ACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_upper_us = 0;
|
||||
|
||||
static const int * const modifier_idxs_upper_us = NULL;
|
||||
|
||||
static const int num_switchers_upper_us = 2;
|
||||
|
||||
static const int switcher_idxs_upper_us[] = { \
|
||||
29, 38 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_upper_us[] = { \
|
||||
0, 2 \
|
||||
};
|
||||
|
||||
/* Layer: Numbers / symbols - generated from numbers */
|
||||
|
||||
static const int num_keys_numbers_us = 36;
|
||||
|
||||
static const char * const keycaps_numbers_us[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"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, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_numbers_us[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_numbers_us = 0;
|
||||
|
||||
static const int * const modifier_idxs_numbers_us = NULL;
|
||||
|
||||
static const int num_switchers_numbers_us = 2;
|
||||
|
||||
static const int switcher_idxs_numbers_us[] = { \
|
||||
21, 30 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_numbers_us[] = { \
|
||||
3, 0 \
|
||||
};
|
||||
|
||||
/* Layer: Symbols - generated from symbols */
|
||||
|
||||
static const int num_keys_symbols_us = 36;
|
||||
|
||||
static const char * const keycaps_symbols_us[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"~", "`", "|", "·", "√", "π", "τ", "÷", "×", "¶", "\n", \
|
||||
"©", "®", "£", "€", "¥", "^", "°", "*", "{", "}", "\n", \
|
||||
"123", "\\", "/", "<", ">", "=", "[", "]", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"ABC", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, ".", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_symbols_us[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_symbols_us = 0;
|
||||
|
||||
static const int * const modifier_idxs_symbols_us = NULL;
|
||||
|
||||
static const int num_switchers_symbols_us = 2;
|
||||
|
||||
static const int switcher_idxs_symbols_us[] = { \
|
||||
21, 30 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_symbols_us[] = { \
|
||||
2, 0 \
|
||||
};
|
||||
|
||||
/* Layer array */
|
||||
|
||||
static const int num_layers_us = 4;
|
||||
|
||||
static const sq2lv_layer_t layers_us[] = {
|
||||
{
|
||||
.num_keys = num_keys_lower_us,
|
||||
.keycaps = keycaps_lower_us,
|
||||
.attributes = attributes_lower_us,
|
||||
.num_modifiers = num_modifiers_lower_us,
|
||||
.modifier_idxs = modifier_idxs_lower_us,
|
||||
.num_switchers = num_switchers_lower_us,
|
||||
.switcher_idxs = switcher_idxs_lower_us,
|
||||
.switcher_dests = switcher_dests_lower_us
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_upper_us,
|
||||
.keycaps = keycaps_upper_us,
|
||||
.attributes = attributes_upper_us,
|
||||
.num_modifiers = num_modifiers_upper_us,
|
||||
.modifier_idxs = modifier_idxs_upper_us,
|
||||
.num_switchers = num_switchers_upper_us,
|
||||
.switcher_idxs = switcher_idxs_upper_us,
|
||||
.switcher_dests = switcher_dests_upper_us
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_numbers_us,
|
||||
.keycaps = keycaps_numbers_us,
|
||||
.attributes = attributes_numbers_us,
|
||||
.num_modifiers = num_modifiers_numbers_us,
|
||||
.modifier_idxs = modifier_idxs_numbers_us,
|
||||
.num_switchers = num_switchers_numbers_us,
|
||||
.switcher_idxs = switcher_idxs_numbers_us,
|
||||
.switcher_dests = switcher_dests_numbers_us
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_symbols_us,
|
||||
.keycaps = keycaps_symbols_us,
|
||||
.attributes = attributes_symbols_us,
|
||||
.num_modifiers = num_modifiers_symbols_us,
|
||||
.modifier_idxs = modifier_idxs_symbols_us,
|
||||
.num_switchers = num_switchers_symbols_us,
|
||||
.switcher_idxs = switcher_idxs_symbols_us,
|
||||
.switcher_dests = switcher_dests_symbols_us
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Layout: Deutsch - generated from de
|
||||
**/
|
||||
|
||||
static const char * const name_de = "Deutsch";
|
||||
static const char * const short_name_de = "de";
|
||||
|
||||
/* Layer: Lowercase letters - generated from base */
|
||||
|
||||
static const int num_keys_lower_de = 46;
|
||||
|
||||
static const char * const keycaps_lower_de[] = { \
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\n", \
|
||||
"q", "w", "e", "r", "t", "z", "u", "i", "o", "p", "\n", \
|
||||
"a", "s", "d", "f", "g", "h", "j", "k", "l", "\n", \
|
||||
SQ2LV_SYMBOL_SHIFT, "y", "x", "c", "v", "b", "n", "m", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"123", "äÄ", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, ",", ".", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_lower_de[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_lower_de = 0;
|
||||
|
||||
static const int * const modifier_idxs_lower_de = NULL;
|
||||
|
||||
static const int num_switchers_lower_de = 3;
|
||||
|
||||
static const int switcher_idxs_lower_de[] = { \
|
||||
29, 38, 39 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_lower_de[] = { \
|
||||
1, 2, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Uppercase letters - generated from upper */
|
||||
|
||||
static const int num_keys_upper_de = 46;
|
||||
|
||||
static const char * const keycaps_upper_de[] = { \
|
||||
"!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "\n", \
|
||||
"Q", "W", "E", "R", "T", "Z", "U", "I", "O", "P", "\n", \
|
||||
"A", "S", "D", "F", "G", "H", "J", "K", "L", "\n", \
|
||||
SQ2LV_SYMBOL_SHIFT, "Y", "X", "C", "V", "B", "N", "M", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"123", "äÄ", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "!", "?", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_upper_de[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_MOD_ACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_upper_de = 0;
|
||||
|
||||
static const int * const modifier_idxs_upper_de = NULL;
|
||||
|
||||
static const int num_switchers_upper_de = 3;
|
||||
|
||||
static const int switcher_idxs_upper_de[] = { \
|
||||
29, 38, 39 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_upper_de[] = { \
|
||||
0, 2, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Numbers / symbols - generated from numbers */
|
||||
|
||||
static const int num_keys_numbers_de = 38;
|
||||
|
||||
static const char * const keycaps_numbers_de[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"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, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_numbers_de[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_numbers_de = 0;
|
||||
|
||||
static const int * const modifier_idxs_numbers_de = NULL;
|
||||
|
||||
static const int num_switchers_numbers_de = 3;
|
||||
|
||||
static const int switcher_idxs_numbers_de[] = { \
|
||||
21, 30, 31 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_numbers_de[] = { \
|
||||
3, 0, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Symbols - generated from symbols */
|
||||
|
||||
static const int num_keys_symbols_de = 38;
|
||||
|
||||
static const char * const keycaps_symbols_de[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"~", "`", "´", "|", "·", "√", "µ", "÷", "×", "¶", "\n", \
|
||||
"©", "®", "£", "$", "¥", "^", "°", "*", "{", "}", "\n", \
|
||||
"123", "\\", "/", "§", "π", "τ", "[", "]", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"abc", "äÄ", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, ",", ".", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_symbols_de[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_symbols_de = 0;
|
||||
|
||||
static const int * const modifier_idxs_symbols_de = NULL;
|
||||
|
||||
static const int num_switchers_symbols_de = 3;
|
||||
|
||||
static const int switcher_idxs_symbols_de[] = { \
|
||||
21, 30, 31 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_symbols_de[] = { \
|
||||
2, 0, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Special characters - generated from eschars */
|
||||
|
||||
static const int num_keys_special_de = 38;
|
||||
|
||||
static const char * const keycaps_special_de[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"ä", "è", "é", "ö", "ü", "Ä", "È", "É", "Ö", "Ü", "\n", \
|
||||
"à", "â", "ê", "î", "ô", "À", "Â", "È", "Î", "Ô", "\n", \
|
||||
"123", "«", "»", "ç", "Ç", "æ", "œ", "ß", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"abc", "äÄ", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "„", "“", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_special_de[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_ACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_special_de = 0;
|
||||
|
||||
static const int * const modifier_idxs_special_de = NULL;
|
||||
|
||||
static const int num_switchers_special_de = 3;
|
||||
|
||||
static const int switcher_idxs_special_de[] = { \
|
||||
21, 30, 31 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_special_de[] = { \
|
||||
2, 0, 0 \
|
||||
};
|
||||
|
||||
/* Layer array */
|
||||
|
||||
static const int num_layers_de = 5;
|
||||
|
||||
static const sq2lv_layer_t layers_de[] = {
|
||||
{
|
||||
.num_keys = num_keys_lower_de,
|
||||
.keycaps = keycaps_lower_de,
|
||||
.attributes = attributes_lower_de,
|
||||
.num_modifiers = num_modifiers_lower_de,
|
||||
.modifier_idxs = modifier_idxs_lower_de,
|
||||
.num_switchers = num_switchers_lower_de,
|
||||
.switcher_idxs = switcher_idxs_lower_de,
|
||||
.switcher_dests = switcher_dests_lower_de
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_upper_de,
|
||||
.keycaps = keycaps_upper_de,
|
||||
.attributes = attributes_upper_de,
|
||||
.num_modifiers = num_modifiers_upper_de,
|
||||
.modifier_idxs = modifier_idxs_upper_de,
|
||||
.num_switchers = num_switchers_upper_de,
|
||||
.switcher_idxs = switcher_idxs_upper_de,
|
||||
.switcher_dests = switcher_dests_upper_de
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_numbers_de,
|
||||
.keycaps = keycaps_numbers_de,
|
||||
.attributes = attributes_numbers_de,
|
||||
.num_modifiers = num_modifiers_numbers_de,
|
||||
.modifier_idxs = modifier_idxs_numbers_de,
|
||||
.num_switchers = num_switchers_numbers_de,
|
||||
.switcher_idxs = switcher_idxs_numbers_de,
|
||||
.switcher_dests = switcher_dests_numbers_de
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_symbols_de,
|
||||
.keycaps = keycaps_symbols_de,
|
||||
.attributes = attributes_symbols_de,
|
||||
.num_modifiers = num_modifiers_symbols_de,
|
||||
.modifier_idxs = modifier_idxs_symbols_de,
|
||||
.num_switchers = num_switchers_symbols_de,
|
||||
.switcher_idxs = switcher_idxs_symbols_de,
|
||||
.switcher_dests = switcher_dests_symbols_de
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_special_de,
|
||||
.keycaps = keycaps_special_de,
|
||||
.attributes = attributes_special_de,
|
||||
.num_modifiers = num_modifiers_special_de,
|
||||
.modifier_idxs = modifier_idxs_special_de,
|
||||
.num_switchers = num_switchers_special_de,
|
||||
.switcher_idxs = switcher_idxs_special_de,
|
||||
.switcher_dests = switcher_dests_special_de
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Layout: Español - generated from es
|
||||
**/
|
||||
|
||||
static const char * const name_es = "Español";
|
||||
static const char * const short_name_es = "es";
|
||||
|
||||
/* Layer: Lowercase letters - generated from base */
|
||||
|
||||
static const int num_keys_lower_es = 47;
|
||||
|
||||
static const char * const keycaps_lower_es[] = { \
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\n", \
|
||||
"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", "\n", \
|
||||
"a", "s", "d", "f", "g", "h", "j", "k", "l", "ñ", "\n", \
|
||||
SQ2LV_SYMBOL_SHIFT, "z", "x", "c", "v", "b", "n", "m", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"123", "áÁ", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "?", ".", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_lower_es[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_lower_es = 0;
|
||||
|
||||
static const int * const modifier_idxs_lower_es = NULL;
|
||||
|
||||
static const int num_switchers_lower_es = 3;
|
||||
|
||||
static const int switcher_idxs_lower_es[] = { \
|
||||
30, 39, 40 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_lower_es[] = { \
|
||||
1, 2, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Uppercase letters - generated from upper */
|
||||
|
||||
static const int num_keys_upper_es = 47;
|
||||
|
||||
static const char * const keycaps_upper_es[] = { \
|
||||
"!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "\n", \
|
||||
"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", "\n", \
|
||||
"A", "S", "D", "F", "G", "H", "J", "K", "L", "Ñ", "\n", \
|
||||
SQ2LV_SYMBOL_SHIFT, "Z", "X", "C", "V", "B", "N", "M", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"123", "áÁ", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "¿", ".", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_upper_es[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_MOD_ACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_upper_es = 0;
|
||||
|
||||
static const int * const modifier_idxs_upper_es = NULL;
|
||||
|
||||
static const int num_switchers_upper_es = 3;
|
||||
|
||||
static const int switcher_idxs_upper_es[] = { \
|
||||
30, 39, 40 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_upper_es[] = { \
|
||||
0, 2, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Numbers / symbols - generated from numbers */
|
||||
|
||||
static const int num_keys_numbers_es = 38;
|
||||
|
||||
static const char * const keycaps_numbers_es[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"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, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_numbers_es[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_numbers_es = 0;
|
||||
|
||||
static const int * const modifier_idxs_numbers_es = NULL;
|
||||
|
||||
static const int num_switchers_numbers_es = 3;
|
||||
|
||||
static const int switcher_idxs_numbers_es[] = { \
|
||||
21, 30, 31 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_numbers_es[] = { \
|
||||
3, 0, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Symbols - generated from symbols */
|
||||
|
||||
static const int num_keys_symbols_es = 38;
|
||||
|
||||
static const char * const keycaps_symbols_es[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"~", "`", "|", "·", "√", "π", "τ", "÷", "×", "¶", "\n", \
|
||||
"©", "®", "£", "$", "¥", "^", "°", "*", "{", "}", "\n", \
|
||||
"123", "\\", "/", "<", ">", "=", "[", "]", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"abc", "áÁ", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "?", ".", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_symbols_es[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_symbols_es = 0;
|
||||
|
||||
static const int * const modifier_idxs_symbols_es = NULL;
|
||||
|
||||
static const int num_switchers_symbols_es = 3;
|
||||
|
||||
static const int switcher_idxs_symbols_es[] = { \
|
||||
21, 30, 31 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_symbols_es[] = { \
|
||||
2, 0, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Special characters - generated from eschars */
|
||||
|
||||
static const int num_keys_special_es = 38;
|
||||
|
||||
static const char * const keycaps_special_es[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"á", "é", "í", "ó", "ú", "Á", "É", "Í", "Ó", "Ú", "\n", \
|
||||
"à", "è", "ì", "ò", "ù", "À", "È", "Ì", "Ò", "Ù", "\n", \
|
||||
"123", "ü", "ç", "ï", "Ü", "Ç", "Ï", "¡", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"abc", "áÁ", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "«", "»", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_special_es[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_MOD_ACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_special_es = 0;
|
||||
|
||||
static const int * const modifier_idxs_special_es = NULL;
|
||||
|
||||
static const int num_switchers_special_es = 3;
|
||||
|
||||
static const int switcher_idxs_special_es[] = { \
|
||||
21, 30, 31 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_special_es[] = { \
|
||||
2, 0, 0 \
|
||||
};
|
||||
|
||||
/* Layer array */
|
||||
|
||||
static const int num_layers_es = 5;
|
||||
|
||||
static const sq2lv_layer_t layers_es[] = {
|
||||
{
|
||||
.num_keys = num_keys_lower_es,
|
||||
.keycaps = keycaps_lower_es,
|
||||
.attributes = attributes_lower_es,
|
||||
.num_modifiers = num_modifiers_lower_es,
|
||||
.modifier_idxs = modifier_idxs_lower_es,
|
||||
.num_switchers = num_switchers_lower_es,
|
||||
.switcher_idxs = switcher_idxs_lower_es,
|
||||
.switcher_dests = switcher_dests_lower_es
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_upper_es,
|
||||
.keycaps = keycaps_upper_es,
|
||||
.attributes = attributes_upper_es,
|
||||
.num_modifiers = num_modifiers_upper_es,
|
||||
.modifier_idxs = modifier_idxs_upper_es,
|
||||
.num_switchers = num_switchers_upper_es,
|
||||
.switcher_idxs = switcher_idxs_upper_es,
|
||||
.switcher_dests = switcher_dests_upper_es
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_numbers_es,
|
||||
.keycaps = keycaps_numbers_es,
|
||||
.attributes = attributes_numbers_es,
|
||||
.num_modifiers = num_modifiers_numbers_es,
|
||||
.modifier_idxs = modifier_idxs_numbers_es,
|
||||
.num_switchers = num_switchers_numbers_es,
|
||||
.switcher_idxs = switcher_idxs_numbers_es,
|
||||
.switcher_dests = switcher_dests_numbers_es
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_symbols_es,
|
||||
.keycaps = keycaps_symbols_es,
|
||||
.attributes = attributes_symbols_es,
|
||||
.num_modifiers = num_modifiers_symbols_es,
|
||||
.modifier_idxs = modifier_idxs_symbols_es,
|
||||
.num_switchers = num_switchers_symbols_es,
|
||||
.switcher_idxs = switcher_idxs_symbols_es,
|
||||
.switcher_dests = switcher_dests_symbols_es
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_special_es,
|
||||
.keycaps = keycaps_special_es,
|
||||
.attributes = attributes_special_es,
|
||||
.num_modifiers = num_modifiers_special_es,
|
||||
.modifier_idxs = modifier_idxs_special_es,
|
||||
.num_switchers = num_switchers_special_es,
|
||||
.switcher_idxs = switcher_idxs_special_es,
|
||||
.switcher_dests = switcher_dests_special_es
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Layout: Français - generated from fr
|
||||
**/
|
||||
|
||||
static const char * const name_fr = "Français";
|
||||
static const char * const short_name_fr = "fr";
|
||||
|
||||
/* Layer: Lowercase letters - generated from base */
|
||||
|
||||
static const int num_keys_lower_fr = 45;
|
||||
|
||||
static const char * const keycaps_lower_fr[] = { \
|
||||
"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", "\n", \
|
||||
"a", "z", "e", "r", "t", "y", "u", "i", "o", "p", "\n", \
|
||||
"q", "s", "d", "f", "g", "h", "j", "k", "l", "m", "\n", \
|
||||
SQ2LV_SYMBOL_SHIFT, "w", "x", "c", "v", "b", "n", ".", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"123", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "âÂ", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_lower_fr[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_lower_fr = 0;
|
||||
|
||||
static const int * const modifier_idxs_lower_fr = NULL;
|
||||
|
||||
static const int num_switchers_lower_fr = 3;
|
||||
|
||||
static const int switcher_idxs_lower_fr[] = { \
|
||||
30, 39, 43 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_lower_fr[] = { \
|
||||
1, 2, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Uppercase letters - generated from upper */
|
||||
|
||||
static const int num_keys_upper_fr = 45;
|
||||
|
||||
static const char * const keycaps_upper_fr[] = { \
|
||||
"!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "\n", \
|
||||
"A", "Z", "E", "R", "T", "Y", "U", "I", "O", "P", "\n", \
|
||||
"Q", "S", "D", "F", "G", "H", "J", "K", "L", "M", "\n", \
|
||||
SQ2LV_SYMBOL_SHIFT, "W", "X", "C", "V", "B", "N", ",", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"123", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "âÂ", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_upper_fr[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_MOD_ACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_upper_fr = 0;
|
||||
|
||||
static const int * const modifier_idxs_upper_fr = NULL;
|
||||
|
||||
static const int num_switchers_upper_fr = 3;
|
||||
|
||||
static const int switcher_idxs_upper_fr[] = { \
|
||||
30, 39, 43 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_upper_fr[] = { \
|
||||
0, 2, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Numbers / symbols - generated from numbers */
|
||||
|
||||
static const int num_keys_numbers_fr = 36;
|
||||
|
||||
static const char * const keycaps_numbers_fr[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"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, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_numbers_fr[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_numbers_fr = 0;
|
||||
|
||||
static const int * const modifier_idxs_numbers_fr = NULL;
|
||||
|
||||
static const int num_switchers_numbers_fr = 3;
|
||||
|
||||
static const int switcher_idxs_numbers_fr[] = { \
|
||||
21, 30, 34 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_numbers_fr[] = { \
|
||||
3, 0, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Symbols - generated from symbols */
|
||||
|
||||
static const int num_keys_symbols_fr = 36;
|
||||
|
||||
static const char * const keycaps_symbols_fr[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"~", "`", "|", "·", "√", "π", "τ", "÷", "×", "¶", "\n", \
|
||||
"©", "®", "£", "$", "¥", "^", "°", "*", "{", "}", "\n", \
|
||||
"123", "\\", "/", "<", ">", "=", "[", "]", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"abc", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "âÂ", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_symbols_fr[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, SQ2LV_CTRL_MOD_INACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_symbols_fr = 0;
|
||||
|
||||
static const int * const modifier_idxs_symbols_fr = NULL;
|
||||
|
||||
static const int num_switchers_symbols_fr = 3;
|
||||
|
||||
static const int switcher_idxs_symbols_fr[] = { \
|
||||
21, 30, 34 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_symbols_fr[] = { \
|
||||
2, 0, 4 \
|
||||
};
|
||||
|
||||
/* Layer: Special characters - generated from eschars */
|
||||
|
||||
static const int num_keys_special_fr = 36;
|
||||
|
||||
static const char * const keycaps_special_fr[] = { \
|
||||
"<hidden>", "\n", \
|
||||
"à", "â", "ç", "é", "è", "ê", "î", "ô", "ù", "û", "\n", \
|
||||
"À", "Â", "Ç", "É", "È", "Ê", "Î", "Ô", "Ù", "Û", "\n", \
|
||||
"123", "æ", "œ", "ä", "ë", "ï", "ö", "ü", LV_SYMBOL_BACKSPACE, "\n", \
|
||||
"abc", LV_SYMBOL_LEFT, " ", LV_SYMBOL_RIGHT, "âÂ", LV_SYMBOL_OK, "" \
|
||||
};
|
||||
|
||||
static const lv_buttonmatrix_ctrl_t attributes_special_fr[] = { \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_HIDDEN | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, LV_BUTTONMATRIX_CTRL_POPOVER | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 2, SQ2LV_CTRL_NON_CHAR | 3, \
|
||||
SQ2LV_CTRL_NON_CHAR | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 2, 7, SQ2LV_CTRL_NON_CHAR | 2, SQ2LV_CTRL_MOD_ACTIVE | LV_BUTTONMATRIX_CTRL_NO_REPEAT | 3, SQ2LV_CTRL_NON_CHAR | 3 \
|
||||
};
|
||||
|
||||
static const int num_modifiers_special_fr = 0;
|
||||
|
||||
static const int * const modifier_idxs_special_fr = NULL;
|
||||
|
||||
static const int num_switchers_special_fr = 3;
|
||||
|
||||
static const int switcher_idxs_special_fr[] = { \
|
||||
21, 30, 34 \
|
||||
};
|
||||
|
||||
static const int switcher_dests_special_fr[] = { \
|
||||
2, 0, 0 \
|
||||
};
|
||||
|
||||
/* Layer array */
|
||||
|
||||
static const int num_layers_fr = 5;
|
||||
|
||||
static const sq2lv_layer_t layers_fr[] = {
|
||||
{
|
||||
.num_keys = num_keys_lower_fr,
|
||||
.keycaps = keycaps_lower_fr,
|
||||
.attributes = attributes_lower_fr,
|
||||
.num_modifiers = num_modifiers_lower_fr,
|
||||
.modifier_idxs = modifier_idxs_lower_fr,
|
||||
.num_switchers = num_switchers_lower_fr,
|
||||
.switcher_idxs = switcher_idxs_lower_fr,
|
||||
.switcher_dests = switcher_dests_lower_fr
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_upper_fr,
|
||||
.keycaps = keycaps_upper_fr,
|
||||
.attributes = attributes_upper_fr,
|
||||
.num_modifiers = num_modifiers_upper_fr,
|
||||
.modifier_idxs = modifier_idxs_upper_fr,
|
||||
.num_switchers = num_switchers_upper_fr,
|
||||
.switcher_idxs = switcher_idxs_upper_fr,
|
||||
.switcher_dests = switcher_dests_upper_fr
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_numbers_fr,
|
||||
.keycaps = keycaps_numbers_fr,
|
||||
.attributes = attributes_numbers_fr,
|
||||
.num_modifiers = num_modifiers_numbers_fr,
|
||||
.modifier_idxs = modifier_idxs_numbers_fr,
|
||||
.num_switchers = num_switchers_numbers_fr,
|
||||
.switcher_idxs = switcher_idxs_numbers_fr,
|
||||
.switcher_dests = switcher_dests_numbers_fr
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_symbols_fr,
|
||||
.keycaps = keycaps_symbols_fr,
|
||||
.attributes = attributes_symbols_fr,
|
||||
.num_modifiers = num_modifiers_symbols_fr,
|
||||
.modifier_idxs = modifier_idxs_symbols_fr,
|
||||
.num_switchers = num_switchers_symbols_fr,
|
||||
.switcher_idxs = switcher_idxs_symbols_fr,
|
||||
.switcher_dests = switcher_dests_symbols_fr
|
||||
},
|
||||
{
|
||||
.num_keys = num_keys_special_fr,
|
||||
.keycaps = keycaps_special_fr,
|
||||
.attributes = attributes_special_fr,
|
||||
.num_modifiers = num_modifiers_special_fr,
|
||||
.modifier_idxs = modifier_idxs_special_fr,
|
||||
.num_switchers = num_switchers_special_fr,
|
||||
.switcher_idxs = switcher_idxs_special_fr,
|
||||
.switcher_dests = switcher_dests_special_fr
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
**/
|
||||
|
||||
const int sq2lv_num_layouts = 4;
|
||||
|
||||
const sq2lv_layout_t sq2lv_layouts[] = {
|
||||
/* US English */
|
||||
{
|
||||
.name = name_us,
|
||||
.short_name = short_name_us,
|
||||
.num_layers = num_layers_us,
|
||||
.layers = layers_us
|
||||
},
|
||||
/* Deutsch */
|
||||
{
|
||||
.name = name_de,
|
||||
.short_name = short_name_de,
|
||||
.num_layers = num_layers_de,
|
||||
.layers = layers_de
|
||||
},
|
||||
/* Español */
|
||||
{
|
||||
.name = name_es,
|
||||
.short_name = short_name_es,
|
||||
.num_layers = num_layers_es,
|
||||
.layers = layers_es
|
||||
},
|
||||
/* Français */
|
||||
{
|
||||
.name = name_fr,
|
||||
.short_name = short_name_fr,
|
||||
.num_layers = num_layers_fr,
|
||||
.layers = layers_fr
|
||||
}
|
||||
};
|
||||
|
||||
const char * const sq2lv_layout_names =
|
||||
"US English" "\n"
|
||||
"Deutsch" "\n"
|
||||
"Español" "\n"
|
||||
"Français";
|
||||
|
||||
const char * const sq2lv_layout_short_names =
|
||||
"us" "\n"
|
||||
"de" "\n"
|
||||
"es" "\n"
|
||||
"fr";
|
||||
61
f0rmz/sq2lv_layouts.h
Normal file
61
f0rmz/sq2lv_layouts.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/**
|
||||
* Auto-generated with squeek2lvgl
|
||||
**/
|
||||
|
||||
#ifndef SQ2LV_LAYOUTS_H
|
||||
#define SQ2LV_LAYOUTS_H
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
#define SQ2LV_SCANCODES_ENABLED 0
|
||||
|
||||
/* Layout IDs, values can be used as indexes into the sq2lv_layouts array */
|
||||
typedef enum {
|
||||
SQ2LV_LAYOUT_NONE = -1,
|
||||
SQ2LV_LAYOUT_US = 0,
|
||||
SQ2LV_LAYOUT_DE = 1,
|
||||
SQ2LV_LAYOUT_ES = 2,
|
||||
SQ2LV_LAYOUT_FR = 3
|
||||
} sq2lv_layout_id_t;
|
||||
|
||||
/* Layer type */
|
||||
typedef struct {
|
||||
/* Number of keys */
|
||||
const int num_keys;
|
||||
/* Key caps */
|
||||
const char * const * const keycaps;
|
||||
/* Key attributes */
|
||||
const lv_buttonmatrix_ctrl_t * const attributes;
|
||||
/* Number of modifier keys */
|
||||
const int num_modifiers;
|
||||
/* Button indexes of modifier keys */
|
||||
const int * const modifier_idxs;
|
||||
/* 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;
|
||||
|
||||
/* Layout type */
|
||||
typedef struct {
|
||||
/* Layout name */
|
||||
const char * const name;
|
||||
/* Layout short name */
|
||||
const char * const short_name;
|
||||
/* Total number of layers */
|
||||
const int num_layers;
|
||||
/* Layers array */
|
||||
const sq2lv_layer_t * const layers;
|
||||
} sq2lv_layout_t;
|
||||
|
||||
/* Layouts */
|
||||
extern const int sq2lv_num_layouts;
|
||||
extern const sq2lv_layout_t sq2lv_layouts[];
|
||||
|
||||
/* Layout names (suitable for use in lv_dropdown_t) */
|
||||
extern const char * const sq2lv_layout_names;
|
||||
extern const char * const sq2lv_layout_short_names;
|
||||
|
||||
#endif /* SQ2LV_LAYOUTS_H */
|
||||
|
|
@ -22,15 +22,22 @@ endif
|
|||
common_include_dirs = include_directories('.')
|
||||
|
||||
shared_sources = files(
|
||||
'shared/backends.c',
|
||||
'shared/cursor/cursor.c',
|
||||
'shared/cli_common.c',
|
||||
'shared/display.c',
|
||||
'shared/fonts/font_32.c',
|
||||
'shared/config.c',
|
||||
'shared/indev.c',
|
||||
'shared/keyboard.c',
|
||||
'shared/log.c',
|
||||
'shared/terminal.c',
|
||||
'shared/theme.c',
|
||||
'shared/themes.c'
|
||||
)
|
||||
|
||||
header_sources = files('shared/header.c')
|
||||
|
||||
squeek2lvgl_sources = files(
|
||||
'squeek2lvgl/sq2lv.c'
|
||||
)
|
||||
|
|
@ -47,6 +54,7 @@ common_dependencies = [
|
|||
|
||||
subdir('unl0kr')
|
||||
subdir('buffyboard')
|
||||
subdir('f0rmz')
|
||||
|
||||
if get_option('man')
|
||||
subdir('man')
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* Public interface
|
||||
*/
|
||||
|
||||
const char *ul_backends_backends[] = {
|
||||
const char *bbx_backends_backends[] = {
|
||||
#if LV_USE_LINUX_FBDEV
|
||||
"fbdev",
|
||||
#endif /* LV_USE_LINUX_FBDEV */
|
||||
|
|
@ -25,13 +25,13 @@ const char *ul_backends_backends[] = {
|
|||
NULL
|
||||
};
|
||||
|
||||
ul_backends_backend_id_t ul_backends_find_backend_with_name(const char *name) {
|
||||
for (int i = 0; ul_backends_backends[i] != NULL; ++i) {
|
||||
if (strcmp(ul_backends_backends[i], name) == 0) {
|
||||
bbx_backends_backend_id_t bbx_backends_find_backend_with_name(const char *name) {
|
||||
for (int i = 0; bbx_backends_backends[i] != NULL; ++i) {
|
||||
if (strcmp(bbx_backends_backends[i], name) == 0) {
|
||||
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Found backend: %s\n", name);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
bbx_log(BBX_LOG_LEVEL_WARNING, "Backend %s not found\n", name);
|
||||
return UL_BACKENDS_BACKEND_NONE;
|
||||
return BBX_BACKENDS_BACKEND_NONE;
|
||||
}
|
||||
40
shared/backends.h
Normal file
40
shared/backends.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/**
|
||||
* Copyright 2022 Eugenio Paolantonio (g7)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#ifndef BBX_BACKENDS_H
|
||||
#define BBX_BACKENDS_H
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/**
|
||||
* Backend identifiers
|
||||
*
|
||||
* Only BBX_BACKENDS_BACKEND_NONE should have an explicit value assigned
|
||||
*/
|
||||
typedef enum {
|
||||
BBX_BACKENDS_BACKEND_NONE = -1,
|
||||
#if LV_USE_LINUX_FBDEV
|
||||
BBX_BACKENDS_BACKEND_FBDEV,
|
||||
#endif /* LV_USE_LINUX_FBDEV */
|
||||
#if LV_USE_LINUX_DRM
|
||||
BBX_BACKENDS_BACKEND_DRM,
|
||||
#endif /* LV_USE_LINUX_DRM */
|
||||
} bbx_backends_backend_id_t;
|
||||
|
||||
/**
|
||||
* Actual backends
|
||||
*/
|
||||
extern const char *bbx_backends_backends[];
|
||||
|
||||
/**
|
||||
* Find the first backend with a given name.
|
||||
*
|
||||
* @param name backend name
|
||||
* @return ID of the first matching backend or BBX_BACKENDS_BACKEND_NONE if no backend matched
|
||||
*/
|
||||
bbx_backends_backend_id_t bbx_backends_find_backend_with_name(const char *name);
|
||||
|
||||
#endif /* BBX_BACKENDS_H */
|
||||
52
shared/cli_common.c
Normal file
52
shared/cli_common.c
Normal file
|
|
@ -0,0 +1,52 @@
|
|||
/**
|
||||
* Copyright 2025 buffybox contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "cli_common.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifndef PROJECT_VERSION
|
||||
#define PROJECT_VERSION "?" /* Real version injected by meson during build */
|
||||
#endif
|
||||
|
||||
void bbx_cli_init_common_opts(bbx_cli_common_opts *opts) {
|
||||
opts->hor_res = -1;
|
||||
opts->ver_res = -1;
|
||||
opts->x_offset = 0;
|
||||
opts->y_offset = 0;
|
||||
opts->dpi = 0;
|
||||
opts->verbose = false;
|
||||
}
|
||||
|
||||
int bbx_cli_parse_geometry(const char *optarg, bbx_cli_common_opts *opts) {
|
||||
/* Try parsing with offset first: NxM@X,Y */
|
||||
if (sscanf(optarg, "%ix%i@%i,%i", &(opts->hor_res), &(opts->ver_res),
|
||||
&(opts->x_offset), &(opts->y_offset)) == 4) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Try parsing without offset: NxM */
|
||||
if (sscanf(optarg, "%ix%i", &(opts->hor_res), &(opts->ver_res)) == 2) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Invalid geometry argument \"%s\"", optarg);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int bbx_cli_parse_dpi(const char *optarg, bbx_cli_common_opts *opts) {
|
||||
if (sscanf(optarg, "%i", &(opts->dpi)) != 1) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Invalid dpi argument \"%s\"", optarg);
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bbx_cli_print_version_and_exit(const char *program_name) {
|
||||
fprintf(stderr, "%s %s\n", program_name, PROJECT_VERSION);
|
||||
exit(0);
|
||||
}
|
||||
58
shared/cli_common.h
Normal file
58
shared/cli_common.h
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
/**
|
||||
* Copyright 2025 buffybox contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef BBX_CLI_COMMON_H
|
||||
#define BBX_CLI_COMMON_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* Common CLI options shared across buffybox tools
|
||||
*/
|
||||
typedef struct {
|
||||
/* Display geometry */
|
||||
int hor_res;
|
||||
int ver_res;
|
||||
int x_offset;
|
||||
int y_offset;
|
||||
/* DPI override */
|
||||
int dpi;
|
||||
/* Verbose logging */
|
||||
bool verbose;
|
||||
} bbx_cli_common_opts;
|
||||
|
||||
/**
|
||||
* Initialize common CLI options with default values.
|
||||
*
|
||||
* @param opts pointer to the options struct
|
||||
*/
|
||||
void bbx_cli_init_common_opts(bbx_cli_common_opts *opts);
|
||||
|
||||
/**
|
||||
* Parse geometry argument in format "NxM[@X,Y]".
|
||||
*
|
||||
* @param optarg the argument string
|
||||
* @param opts pointer to options struct to populate
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int bbx_cli_parse_geometry(const char *optarg, bbx_cli_common_opts *opts);
|
||||
|
||||
/**
|
||||
* Parse DPI argument.
|
||||
*
|
||||
* @param optarg the argument string
|
||||
* @param opts pointer to options struct to populate
|
||||
* @return 0 on success, -1 on failure
|
||||
*/
|
||||
int bbx_cli_parse_dpi(const char *optarg, bbx_cli_common_opts *opts);
|
||||
|
||||
/**
|
||||
* Print version information and exit.
|
||||
*
|
||||
* @param program_name name of the program
|
||||
*/
|
||||
void bbx_cli_print_version_and_exit(const char *program_name);
|
||||
|
||||
#endif /* BBX_CLI_COMMON_H */
|
||||
91
shared/display.c
Normal file
91
shared/display.c
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
/**
|
||||
* Copyright 2025 buffybox contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "display.h"
|
||||
#include "log.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <unistd.h>
|
||||
|
||||
lv_display_t *bbx_display_create(bbx_backends_backend_id_t backend_id, bbx_display_config_t *config) {
|
||||
lv_display_t *disp = NULL;
|
||||
|
||||
switch (backend_id) {
|
||||
#if LV_USE_LINUX_FBDEV
|
||||
case BBX_BACKENDS_BACKEND_FBDEV:
|
||||
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Using framebuffer backend");
|
||||
disp = lv_linux_fbdev_create();
|
||||
if (!disp) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Failed to create framebuffer display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (access("/dev/fb0", F_OK) != 0) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "/dev/fb0 is not available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_linux_fbdev_set_file(disp, "/dev/fb0");
|
||||
if (config && config->fbdev_force_refresh) {
|
||||
lv_linux_fbdev_set_force_refresh(disp, true);
|
||||
}
|
||||
break;
|
||||
#endif /* LV_USE_LINUX_FBDEV */
|
||||
|
||||
#if LV_USE_LINUX_DRM
|
||||
case BBX_BACKENDS_BACKEND_DRM:
|
||||
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Using DRM backend");
|
||||
disp = lv_linux_drm_create();
|
||||
if (!disp) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Failed to create DRM display");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
char drm_path[16];
|
||||
bool found = false;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
sprintf(drm_path, "/dev/dri/card%d", i);
|
||||
|
||||
if (access(drm_path, F_OK) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "/dev/dri/card* are not available");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
lv_linux_drm_set_file(disp, drm_path, -1);
|
||||
break;
|
||||
#endif /* LV_USE_LINUX_DRM */
|
||||
|
||||
default:
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Unable to find suitable backend");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Apply configuration overrides if provided */
|
||||
if (config) {
|
||||
/* Set display offset */
|
||||
lv_display_set_offset(disp, config->x_offset, config->y_offset);
|
||||
|
||||
/* Override resolution if specified */
|
||||
if (config->hor_res > 0 || config->ver_res > 0) {
|
||||
lv_display_set_physical_resolution(disp,
|
||||
lv_display_get_horizontal_resolution(disp),
|
||||
lv_display_get_vertical_resolution(disp));
|
||||
lv_display_set_resolution(disp, config->hor_res, config->ver_res);
|
||||
}
|
||||
|
||||
/* Override DPI if specified */
|
||||
if (config->dpi > 0) {
|
||||
lv_display_set_dpi(disp, config->dpi);
|
||||
}
|
||||
}
|
||||
|
||||
return disp;
|
||||
}
|
||||
37
shared/display.h
Normal file
37
shared/display.h
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
/**
|
||||
* Copyright 2025 buffybox contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef BBX_DISPLAY_H
|
||||
#define BBX_DISPLAY_H
|
||||
|
||||
#include "backends.h"
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/**
|
||||
* Display configuration options
|
||||
*/
|
||||
typedef struct {
|
||||
/* Display resolution override */
|
||||
int hor_res;
|
||||
int ver_res;
|
||||
/* Display offset */
|
||||
int x_offset;
|
||||
int y_offset;
|
||||
/* DPI override */
|
||||
int dpi;
|
||||
/* Framebuffer force refresh quirk */
|
||||
bool fbdev_force_refresh;
|
||||
} bbx_display_config_t;
|
||||
|
||||
/**
|
||||
* Initialize LVGL display with the specified backend and configuration.
|
||||
*
|
||||
* @param backend_id the backend to use
|
||||
* @param config display configuration options
|
||||
* @return initialized display or NULL on failure
|
||||
*/
|
||||
lv_display_t *bbx_display_create(bbx_backends_backend_id_t backend_id, bbx_display_config_t *config);
|
||||
|
||||
#endif /* BBX_DISPLAY_H */
|
||||
88
shared/header.c
Normal file
88
shared/header.c
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
/**
|
||||
* Copyright 2025 buffybox contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "header.h"
|
||||
|
||||
void bbx_header_init_config(bbx_header_config_t *config) {
|
||||
config->show_theme_toggle = true;
|
||||
config->show_keyboard_toggle = true;
|
||||
config->show_layout_dropdown = true;
|
||||
config->show_shutdown_button = true;
|
||||
config->dropdown_options = "Option 1\nOption 2\nOption 3";
|
||||
config->dropdown_width = 90;
|
||||
config->theme_symbol = LV_SYMBOL_SETTINGS;
|
||||
config->keyboard_symbol = LV_SYMBOL_KEYBOARD;
|
||||
config->shutdown_symbol = LV_SYMBOL_POWER;
|
||||
}
|
||||
|
||||
lv_obj_t *bbx_header_create(lv_obj_t *parent, bbx_header_config_t *config, bbx_header_widgets_t *widgets) {
|
||||
lv_memzero(widgets, sizeof(bbx_header_widgets_t));
|
||||
|
||||
/* Create header flexbox */
|
||||
lv_obj_t *header = lv_obj_create(parent);
|
||||
widgets->header = header;
|
||||
|
||||
/* Theme toggle button */
|
||||
if (config->show_theme_toggle) {
|
||||
lv_obj_t *btn = lv_button_create(header);
|
||||
widgets->theme_toggle_btn = btn;
|
||||
|
||||
lv_obj_t *label = lv_label_create(btn);
|
||||
lv_label_set_text(label, config->theme_symbol);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
/* Keyboard toggle button */
|
||||
if (config->show_keyboard_toggle) {
|
||||
lv_obj_t *btn = lv_button_create(header);
|
||||
widgets->keyboard_toggle_btn = btn;
|
||||
|
||||
lv_obj_t *label = lv_label_create(btn);
|
||||
lv_label_set_text(label, config->keyboard_symbol);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
/* Layout dropdown */
|
||||
if (config->show_layout_dropdown) {
|
||||
lv_obj_t *dropdown = lv_dropdown_create(header);
|
||||
widgets->layout_dropdown = dropdown;
|
||||
|
||||
lv_dropdown_set_options(dropdown, config->dropdown_options);
|
||||
lv_obj_set_width(dropdown, config->dropdown_width);
|
||||
}
|
||||
|
||||
/* Spacer */
|
||||
lv_obj_t *spacer = lv_obj_create(header);
|
||||
lv_obj_set_height(spacer, 0);
|
||||
lv_obj_set_flex_grow(spacer, 1);
|
||||
|
||||
/* Shutdown button */
|
||||
if (config->show_shutdown_button) {
|
||||
lv_obj_t *btn = lv_button_create(header);
|
||||
widgets->shutdown_btn = btn;
|
||||
|
||||
lv_obj_t *label = lv_label_create(btn);
|
||||
lv_label_set_text(label, config->shutdown_symbol);
|
||||
lv_obj_center(label);
|
||||
}
|
||||
|
||||
/* Size buttons to match dropdown height */
|
||||
if (widgets->layout_dropdown) {
|
||||
lv_obj_update_layout(widgets->layout_dropdown);
|
||||
const int32_t dropdown_height = lv_obj_get_height(widgets->layout_dropdown);
|
||||
|
||||
if (widgets->theme_toggle_btn) {
|
||||
lv_obj_set_size(widgets->theme_toggle_btn, dropdown_height, dropdown_height);
|
||||
}
|
||||
if (widgets->keyboard_toggle_btn) {
|
||||
lv_obj_set_size(widgets->keyboard_toggle_btn, dropdown_height, dropdown_height);
|
||||
}
|
||||
if (widgets->shutdown_btn) {
|
||||
lv_obj_set_size(widgets->shutdown_btn, dropdown_height, dropdown_height);
|
||||
}
|
||||
}
|
||||
|
||||
return header;
|
||||
}
|
||||
60
shared/header.h
Normal file
60
shared/header.h
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/**
|
||||
* Copyright 2025 buffybox contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef BBX_HEADER_H
|
||||
#define BBX_HEADER_H
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* Header configuration options
|
||||
*/
|
||||
typedef struct {
|
||||
/* Which elements to include */
|
||||
bool show_theme_toggle;
|
||||
bool show_keyboard_toggle;
|
||||
bool show_layout_dropdown;
|
||||
bool show_shutdown_button;
|
||||
|
||||
/* Dropdown options (if enabled) */
|
||||
const char *dropdown_options;
|
||||
int dropdown_width;
|
||||
|
||||
/* Button symbols */
|
||||
const char *theme_symbol;
|
||||
const char *keyboard_symbol;
|
||||
const char *shutdown_symbol;
|
||||
} bbx_header_config_t;
|
||||
|
||||
/**
|
||||
* Header widget references for attaching callbacks
|
||||
*/
|
||||
typedef struct {
|
||||
lv_obj_t *header;
|
||||
lv_obj_t *theme_toggle_btn;
|
||||
lv_obj_t *keyboard_toggle_btn;
|
||||
lv_obj_t *layout_dropdown;
|
||||
lv_obj_t *shutdown_btn;
|
||||
} bbx_header_widgets_t;
|
||||
|
||||
/**
|
||||
* Create a header bar with configurable elements.
|
||||
*
|
||||
* @param parent parent object (usually screen)
|
||||
* @param config header configuration
|
||||
* @param widgets output struct for widget references
|
||||
* @return header object
|
||||
*/
|
||||
lv_obj_t *bbx_header_create(lv_obj_t *parent, bbx_header_config_t *config, bbx_header_widgets_t *widgets);
|
||||
|
||||
/**
|
||||
* Initialize header config with default values.
|
||||
*
|
||||
* @param config config struct to initialize
|
||||
*/
|
||||
void bbx_header_init_config(bbx_header_config_t *config);
|
||||
|
||||
#endif /* BBX_HEADER_H */
|
||||
59
shared/keyboard.c
Normal file
59
shared/keyboard.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/**
|
||||
* Copyright 2025 buffybox contributors
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
#include "keyboard.h"
|
||||
#include "theme.h"
|
||||
#include "../squeek2lvgl/sq2lv.h"
|
||||
|
||||
void bbx_keyboard_init_config(bbx_keyboard_config_t *config) {
|
||||
config->mode = LV_KEYBOARD_MODE_TEXT_LOWER;
|
||||
config->layout_id = 0; /* Default to first layout */
|
||||
config->popovers = false;
|
||||
config->height = -1; /* Auto-calculate */
|
||||
config->value_changed_callback = NULL;
|
||||
config->ready_callback = NULL;
|
||||
}
|
||||
|
||||
lv_obj_t *bbx_keyboard_create(lv_obj_t *parent, lv_obj_t *textarea, bbx_keyboard_config_t *config) {
|
||||
lv_obj_t *keyboard = lv_keyboard_create(parent);
|
||||
|
||||
lv_keyboard_set_mode(keyboard, config->mode);
|
||||
lv_keyboard_set_textarea(keyboard, textarea);
|
||||
|
||||
/* Remove default event callback and add custom ones */
|
||||
uint32_t num_events = lv_obj_get_event_count(keyboard);
|
||||
for(uint32_t i = 0; i < num_events; ++i) {
|
||||
if(lv_event_dsc_get_cb(lv_obj_get_event_dsc(keyboard, i)) == lv_keyboard_def_event_cb) {
|
||||
lv_obj_remove_event(keyboard, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (config->value_changed_callback) {
|
||||
lv_obj_add_event_cb(keyboard, config->value_changed_callback, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
}
|
||||
|
||||
if (config->ready_callback) {
|
||||
lv_obj_add_event_cb(keyboard, config->ready_callback, LV_EVENT_READY, NULL);
|
||||
}
|
||||
|
||||
/* Set size */
|
||||
if (config->height > 0) {
|
||||
lv_obj_set_size(keyboard, LV_PCT(100), config->height);
|
||||
}
|
||||
|
||||
/* Apply theme preparation */
|
||||
bbx_theme_prepare_keyboard(keyboard);
|
||||
|
||||
/* Set layout */
|
||||
sq2lv_switch_layout(keyboard, config->layout_id);
|
||||
|
||||
/* Enable popovers if requested */
|
||||
if (config->popovers) {
|
||||
lv_keyboard_set_popovers(keyboard, true);
|
||||
}
|
||||
|
||||
return keyboard;
|
||||
}
|
||||
19
shared/keyboard.h
Normal file
19
shared/keyboard.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#ifndef BBX_KEYBOARD_H
|
||||
#define BBX_KEYBOARD_H
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct {
|
||||
lv_keyboard_mode_t mode;
|
||||
int layout_id;
|
||||
bool popovers;
|
||||
int32_t height;
|
||||
lv_event_cb_t value_changed_callback;
|
||||
lv_event_cb_t ready_callback;
|
||||
} bbx_keyboard_config_t;
|
||||
|
||||
lv_obj_t *bbx_keyboard_create(lv_obj_t *parent, lv_obj_t *textarea, bbx_keyboard_config_t *config);
|
||||
void bbx_keyboard_init_config(bbx_keyboard_config_t *config);
|
||||
|
||||
#endif /* BBX_KEYBOARD_H */
|
||||
|
|
@ -30,7 +30,7 @@ static int original_kb_mode = -1;
|
|||
* Public functions
|
||||
*/
|
||||
|
||||
void ul_terminal_prepare_current_terminal(bool enable_graphics_mode, bool disable_keyboard_input) {
|
||||
void bbx_terminal_prepare_current_terminal(bool enable_graphics_mode, bool disable_keyboard_input) {
|
||||
/* Exit early if there is nothing to do */
|
||||
if (!enable_graphics_mode && !disable_keyboard_input) {
|
||||
return;
|
||||
|
|
@ -66,7 +66,7 @@ void ul_terminal_prepare_current_terminal(bool enable_graphics_mode, bool disabl
|
|||
}
|
||||
}
|
||||
|
||||
void ul_terminal_reset_current_terminal(void) {
|
||||
void bbx_terminal_reset_current_terminal(void) {
|
||||
/* If we haven't previously opened the current terminal, exit */
|
||||
if (current_fd < 0) {
|
||||
bbx_log(BBX_LOG_LEVEL_WARNING, "Could not reset current terminal");
|
||||
|
|
@ -4,8 +4,8 @@
|
|||
*/
|
||||
|
||||
|
||||
#ifndef UL_TERMINAL_H
|
||||
#define UL_TERMINAL_H
|
||||
#ifndef BBX_TERMINAL_H
|
||||
#define BBX_TERMINAL_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
|
|
@ -15,11 +15,11 @@
|
|||
* @param enable_graphics_mode if true, switch terminal into graphics mode (hides command prompt)
|
||||
* @param disable_keyboard_input if true, disable terminal keyboard input (hides entered text)
|
||||
*/
|
||||
void ul_terminal_prepare_current_terminal(bool enable_graphics_mode, bool disable_keyboard_input);
|
||||
void bbx_terminal_prepare_current_terminal(bool enable_graphics_mode, bool disable_keyboard_input);
|
||||
|
||||
/**
|
||||
* Reset the current TTY to text output.
|
||||
*/
|
||||
void ul_terminal_reset_current_terminal(void);
|
||||
void bbx_terminal_reset_current_terminal(void);
|
||||
|
||||
#endif /* UL_TERMINAL_H */
|
||||
#endif /* BBX_TERMINAL_H */
|
||||
|
|
@ -230,6 +230,10 @@ static void apply_theme_cb(lv_theme_t *theme, lv_obj_t *obj) {
|
|||
|
||||
if (lv_obj_has_flag(obj, BBX_WIDGET_HEADER)) {
|
||||
lv_obj_add_style(obj, &(styles.header), 0);
|
||||
#if LV_USE_FLEX
|
||||
lv_obj_set_flex_flow(obj, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_size(obj, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,40 +0,0 @@
|
|||
/**
|
||||
* Copyright 2022 Eugenio Paolantonio (g7)
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UL_BACKENDS_H
|
||||
#define UL_BACKENDS_H
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
/**
|
||||
* Backend identifiers
|
||||
*
|
||||
* Only UL_BACKENDS_BACKEND_NONE should have an explicit value assigned
|
||||
*/
|
||||
typedef enum {
|
||||
UL_BACKENDS_BACKEND_NONE = -1,
|
||||
#if LV_USE_LINUX_FBDEV
|
||||
UL_BACKENDS_BACKEND_FBDEV,
|
||||
#endif /* LV_USE_LINUX_FBDEV */
|
||||
#if LV_USE_LINUX_DRM
|
||||
UL_BACKENDS_BACKEND_DRM,
|
||||
#endif /* LV_USE_LINUX_DRM */
|
||||
} ul_backends_backend_id_t;
|
||||
|
||||
/**
|
||||
* Actual backends
|
||||
*/
|
||||
extern const char *ul_backends_backends[];
|
||||
|
||||
/**
|
||||
* Find the first backend with a given name.
|
||||
*
|
||||
* @param name backend name
|
||||
* @return ID of the first matching backend or UL_BACKENDS_BACKEND_NONE if no backend matched
|
||||
*/
|
||||
ul_backends_backend_id_t ul_backends_find_backend_with_name(const char *name);
|
||||
|
||||
#endif /* UL_BACKENDS_H */
|
||||
|
|
@ -38,16 +38,11 @@ static void print_usage();
|
|||
*/
|
||||
|
||||
static void init_opts(ul_cli_opts *opts) {
|
||||
bbx_cli_init_common_opts(&opts->common);
|
||||
opts->num_config_files = 0;
|
||||
opts->config_files = NULL;
|
||||
opts->message = NULL;
|
||||
opts->hor_res = -1;
|
||||
opts->ver_res = -1;
|
||||
opts->x_offset = 0;
|
||||
opts->y_offset = 0;
|
||||
opts->dpi = 0;
|
||||
opts->newline = true;
|
||||
opts->verbose = false;
|
||||
}
|
||||
|
||||
static void print_usage() {
|
||||
|
|
@ -115,16 +110,12 @@ void ul_cli_parse_opts(int argc, char *argv[], ul_cli_opts *opts) {
|
|||
opts->num_config_files++;
|
||||
break;
|
||||
case 'g':
|
||||
if (sscanf(optarg, "%ix%i@%i,%i", &(opts->hor_res), &(opts->ver_res), &(opts->x_offset), &(opts->y_offset)) != 4) {
|
||||
if (sscanf(optarg, "%ix%i", &(opts->hor_res), &(opts->ver_res)) != 2) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Invalid geometry argument \"%s\"\n", optarg);
|
||||
if (bbx_cli_parse_geometry(optarg, &opts->common) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (sscanf(optarg, "%i", &(opts->dpi)) != 1) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Invalid dpi argument \"%s\"\n", optarg);
|
||||
if (bbx_cli_parse_dpi(optarg, &opts->common) != 0) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
|
@ -135,11 +126,11 @@ void ul_cli_parse_opts(int argc, char *argv[], ul_cli_opts *opts) {
|
|||
opts->newline = false;
|
||||
break;
|
||||
case 'v':
|
||||
opts->verbose = true;
|
||||
opts->common.verbose = true;
|
||||
break;
|
||||
case 'V':
|
||||
fprintf(stderr, "unl0kr %s\n", PROJECT_VERSION);
|
||||
exit(0);
|
||||
bbx_cli_print_version_and_exit("unl0kr");
|
||||
break;
|
||||
default:
|
||||
print_usage();
|
||||
exit(EXIT_FAILURE);
|
||||
|
|
|
|||
|
|
@ -7,32 +7,23 @@
|
|||
#ifndef UL_COMMAND_LINE_H
|
||||
#define UL_COMMAND_LINE_H
|
||||
|
||||
#include "../shared/cli_common.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
/**
|
||||
* Options parsed from command line arguments
|
||||
*/
|
||||
typedef struct {
|
||||
/* Common cli options */
|
||||
bbx_cli_common_opts common;
|
||||
/* Number of config files */
|
||||
int num_config_files;
|
||||
/* Paths of config file */
|
||||
const char **config_files;
|
||||
/* Message for a user */
|
||||
const char *message;
|
||||
/* Horizontal display resolution */
|
||||
int hor_res;
|
||||
/* Vertical display resolution */
|
||||
int ver_res;
|
||||
/* Horizontal display offset */
|
||||
int x_offset;
|
||||
/* Vertical display offset */
|
||||
int y_offset;
|
||||
/* DPI */
|
||||
int dpi;
|
||||
/* If true, append a newline character to a password */
|
||||
bool newline;
|
||||
/* Verbose mode. If true, provide more detailed logging output on STDERR. */
|
||||
bool verbose;
|
||||
} ul_cli_opts;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -46,8 +46,8 @@ static int parsing_handler(void* user_data, const char* section, const char* key
|
|||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "backend") == 0) {
|
||||
ul_backends_backend_id_t id = ul_backends_find_backend_with_name(value);
|
||||
if (id != UL_BACKENDS_BACKEND_NONE) {
|
||||
bbx_backends_backend_id_t id = bbx_backends_find_backend_with_name(value);
|
||||
if (id != BBX_BACKENDS_BACKEND_NONE) {
|
||||
opts->general.backend = id;
|
||||
return 1;
|
||||
}
|
||||
|
|
@ -139,7 +139,7 @@ static int parsing_handler(void* user_data, const char* section, const char* key
|
|||
|
||||
void ul_config_init_opts(ul_config_opts *opts) {
|
||||
opts->general.animations = false;
|
||||
opts->general.backend = ul_backends_backends[0] == NULL ? UL_BACKENDS_BACKEND_NONE : 0;
|
||||
opts->general.backend = bbx_backends_backends[0] == NULL ? BBX_BACKENDS_BACKEND_NONE : 0;
|
||||
opts->general.timeout = 0;
|
||||
opts->keyboard.autohide = true;
|
||||
opts->keyboard.layout_id = SQ2LV_LAYOUT_US;
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
#ifndef UL_CONFIG_H
|
||||
#define UL_CONFIG_H
|
||||
|
||||
#include "backends.h"
|
||||
|
||||
#include "../shared/backends.h"
|
||||
#include "../shared/themes.h"
|
||||
|
||||
#include "sq2lv_layouts.h"
|
||||
|
|
@ -23,7 +23,7 @@ typedef struct {
|
|||
/* If true, use animations */
|
||||
bool animations;
|
||||
/* Backend to use */
|
||||
ul_backends_backend_id_t backend;
|
||||
bbx_backends_backend_id_t backend;
|
||||
/* Timeout (in seconds) - once elapsed, the device will shutdown. 0 (default) to disable */
|
||||
uint16_t timeout;
|
||||
} ul_config_opts_general;
|
||||
|
|
|
|||
166
unl0kr/main.c
166
unl0kr/main.c
|
|
@ -4,14 +4,17 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "backends.h"
|
||||
#include "command_line.h"
|
||||
#include "config.h"
|
||||
#include "unl0kr.h"
|
||||
#include "terminal.h"
|
||||
|
||||
#include "../shared/backends.h"
|
||||
#include "../shared/display.h"
|
||||
#include "../shared/header.h"
|
||||
#include "../shared/indev.h"
|
||||
#include "../shared/keyboard.h"
|
||||
#include "../shared/log.h"
|
||||
#include "../shared/terminal.h"
|
||||
#include "../shared/theme.h"
|
||||
#include "../shared/themes.h"
|
||||
#include "../squeek2lvgl/sq2lv.h"
|
||||
|
|
@ -372,12 +375,12 @@ static void shutdown(void) {
|
|||
|
||||
static void sigaction_handler(int signum) {
|
||||
LV_UNUSED(signum);
|
||||
ul_terminal_reset_current_terminal();
|
||||
bbx_terminal_reset_current_terminal();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
static void exit_failure() {
|
||||
ul_terminal_reset_current_terminal();
|
||||
bbx_terminal_reset_current_terminal();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
|
|
@ -391,7 +394,7 @@ int main(int argc, char *argv[]) {
|
|||
ul_cli_parse_opts(argc, argv, &cli_opts);
|
||||
|
||||
/* Set up log level */
|
||||
if (cli_opts.verbose) {
|
||||
if (cli_opts.common.verbose) {
|
||||
bbx_log_set_level(BBX_LOG_LEVEL_VERBOSE);
|
||||
}
|
||||
|
||||
|
|
@ -414,7 +417,7 @@ int main(int argc, char *argv[]) {
|
|||
ul_config_parse_files(cli_opts.config_files, cli_opts.num_config_files, &conf_opts);
|
||||
|
||||
/* Prepare current TTY and clean up on termination */
|
||||
ul_terminal_prepare_current_terminal(!conf_opts.quirks.terminal_prevent_graphics_mode, !conf_opts.quirks.terminal_allow_keyboard_input);
|
||||
bbx_terminal_prepare_current_terminal(!conf_opts.quirks.terminal_prevent_graphics_mode, !conf_opts.quirks.terminal_allow_keyboard_input);
|
||||
struct sigaction action;
|
||||
memset(&action, 0, sizeof(action));
|
||||
action.sa_handler = sigaction_handler;
|
||||
|
|
@ -425,61 +428,21 @@ int main(int argc, char *argv[]) {
|
|||
lv_init();
|
||||
lv_log_register_print_cb(bbx_log_print_cb);
|
||||
|
||||
/* Initialise display */
|
||||
lv_display_t *disp = NULL;
|
||||
switch (conf_opts.general.backend) {
|
||||
#if LV_USE_LINUX_FBDEV
|
||||
case UL_BACKENDS_BACKEND_FBDEV:
|
||||
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Using framebuffer backend");
|
||||
disp = lv_linux_fbdev_create();
|
||||
if (access("/dev/fb0", F_OK) != 0) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "/dev/fb0 is not available");
|
||||
/* Populate display config */
|
||||
bbx_display_config_t display_config = {
|
||||
.hor_res = cli_opts.common.hor_res,
|
||||
.ver_res = cli_opts.common.ver_res,
|
||||
.x_offset = cli_opts.common.x_offset,
|
||||
.y_offset = cli_opts.common.y_offset,
|
||||
.dpi = cli_opts.common.dpi,
|
||||
.fbdev_force_refresh = conf_opts.quirks.fbdev_force_refresh
|
||||
};
|
||||
|
||||
/* Initialize display */
|
||||
lv_display_t *disp = bbx_display_create(conf_opts.general.backend, &display_config);
|
||||
if (!disp) {
|
||||
exit_failure();
|
||||
}
|
||||
lv_linux_fbdev_set_file(disp, "/dev/fb0");
|
||||
if (conf_opts.quirks.fbdev_force_refresh) {
|
||||
lv_linux_fbdev_set_force_refresh(disp, true);
|
||||
}
|
||||
break;
|
||||
#endif /* LV_USE_LINUX_FBDEV */
|
||||
#if LV_USE_LINUX_DRM
|
||||
case UL_BACKENDS_BACKEND_DRM:
|
||||
bbx_log(BBX_LOG_LEVEL_VERBOSE, "Using DRM backend");
|
||||
disp = lv_linux_drm_create();
|
||||
|
||||
char drm_path[16];
|
||||
bool found = false;
|
||||
for (int i = 0; i < 9; i++) {
|
||||
sprintf(drm_path, "/dev/dri/card%d", i);
|
||||
|
||||
if (access(drm_path, F_OK) == 0) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "/dev/dri/card* are not available");
|
||||
exit_failure();
|
||||
}
|
||||
|
||||
lv_linux_drm_set_file(disp, drm_path, -1);
|
||||
|
||||
break;
|
||||
#endif /* LV_USE_LINUX_DRM */
|
||||
default:
|
||||
bbx_log(BBX_LOG_LEVEL_ERROR, "Unable to find suitable backend");
|
||||
exit_failure();
|
||||
}
|
||||
|
||||
/* Override display properties with command line options if necessary */
|
||||
lv_display_set_offset(disp, cli_opts.x_offset, cli_opts.y_offset);
|
||||
if (cli_opts.hor_res > 0 || cli_opts.ver_res > 0) {
|
||||
lv_display_set_physical_resolution(disp, lv_display_get_horizontal_resolution(disp), lv_display_get_vertical_resolution(disp));
|
||||
lv_display_set_resolution(disp, cli_opts.hor_res, cli_opts.ver_res);
|
||||
}
|
||||
if (cli_opts.dpi > 0) {
|
||||
lv_display_set_dpi(disp, cli_opts.dpi);
|
||||
}
|
||||
|
||||
/* Prepare for routing physical keyboard input into the textarea */
|
||||
lv_group_t *keyboard_input_group = lv_group_create();
|
||||
|
|
@ -507,50 +470,25 @@ int main(int argc, char *argv[]) {
|
|||
lv_obj_set_flex_flow(screen, LV_FLEX_FLOW_COLUMN);
|
||||
lv_obj_remove_flag(screen, LV_OBJ_FLAG_SCROLLABLE);
|
||||
|
||||
/* Header flexbox */
|
||||
lv_obj_t *header = lv_obj_create(screen);
|
||||
/* Configure header */
|
||||
bbx_header_config_t header_config;
|
||||
bbx_header_init_config(&header_config);
|
||||
header_config.theme_symbol = UL_SYMBOL_ADJUST;
|
||||
header_config.dropdown_options = sq2lv_layout_short_names;
|
||||
|
||||
bbx_header_widgets_t header_widgets;
|
||||
lv_obj_t *header = bbx_header_create(screen, &header_config, &header_widgets);
|
||||
lv_obj_add_flag(header, BBX_WIDGET_HEADER);
|
||||
lv_theme_apply(header); /* Force re-apply theme after setting flag so that the widget can be identified */
|
||||
lv_obj_set_flex_flow(header, LV_FLEX_FLOW_ROW);
|
||||
lv_obj_set_size(header, LV_PCT(100), LV_SIZE_CONTENT);
|
||||
|
||||
/* Theme switcher button */
|
||||
lv_obj_t *toggle_theme_btn = lv_button_create(header);
|
||||
lv_obj_add_event_cb(toggle_theme_btn, toggle_theme_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_t *toggle_theme_btn_label = lv_label_create(toggle_theme_btn);
|
||||
lv_label_set_text(toggle_theme_btn_label, UL_SYMBOL_ADJUST);
|
||||
lv_obj_center(toggle_theme_btn_label);
|
||||
/* Add theme toggle to distinguish this widget type */
|
||||
lv_obj_add_flag(header, BBX_WIDGET_HEADER);
|
||||
lv_theme_apply(header);
|
||||
|
||||
/* Show / hide keyboard button */
|
||||
lv_obj_t *toggle_kb_btn = lv_button_create(header);
|
||||
lv_obj_add_event_cb(toggle_kb_btn, toggle_kb_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_t *toggle_kb_btn_label = lv_label_create(toggle_kb_btn);
|
||||
lv_label_set_text(toggle_kb_btn_label, LV_SYMBOL_KEYBOARD);
|
||||
lv_obj_center(toggle_kb_btn_label);
|
||||
|
||||
/* Keyboard layout dropdown */
|
||||
lv_obj_t *layout_dropdown = lv_dropdown_create(header);
|
||||
lv_dropdown_set_options(layout_dropdown, sq2lv_layout_short_names);
|
||||
lv_obj_add_event_cb(layout_dropdown, layout_dropdown_value_changed_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_set_width(layout_dropdown, 90);
|
||||
|
||||
/* Spacer */
|
||||
lv_obj_t *spacer = lv_obj_create(header);
|
||||
lv_obj_set_height(spacer, 0);
|
||||
lv_obj_set_flex_grow(spacer, 1);
|
||||
|
||||
/* Shutdown button */
|
||||
lv_obj_t *shutdown_btn = lv_button_create(header);
|
||||
lv_obj_add_event_cb(shutdown_btn, shutdown_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_t *shutdown_btn_label = lv_label_create(shutdown_btn);
|
||||
lv_label_set_text(shutdown_btn_label, LV_SYMBOL_POWER);
|
||||
lv_obj_center(shutdown_btn_label);
|
||||
|
||||
lv_obj_update_layout(layout_dropdown);
|
||||
const int32_t dropwdown_height = lv_obj_get_height(layout_dropdown);
|
||||
lv_obj_set_size(toggle_theme_btn, dropwdown_height, dropwdown_height);
|
||||
lv_obj_set_size(toggle_kb_btn, dropwdown_height, dropwdown_height);
|
||||
lv_obj_set_size(shutdown_btn, dropwdown_height, dropwdown_height);
|
||||
/* Attach callbacks */
|
||||
lv_obj_add_event_cb(header_widgets.theme_toggle_btn, toggle_theme_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_event_cb(header_widgets.keyboard_toggle_btn, toggle_kb_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
lv_obj_add_event_cb(header_widgets.layout_dropdown, layout_dropdown_value_changed_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_event_cb(header_widgets.shutdown_btn, shutdown_btn_clicked_cb, LV_EVENT_CLICKED, NULL);
|
||||
|
||||
lv_obj_update_layout(header);
|
||||
content_height_without_kb = ver_res - lv_obj_get_height(header);
|
||||
|
|
@ -633,30 +571,22 @@ int main(int argc, char *argv[]) {
|
|||
lv_obj_set_style_pad_bottom(container, is_keyboard_hidden? content_pad_bottom_without_kb : content_pad_bottom_with_kb, LV_PART_MAIN);
|
||||
|
||||
/* Keyboard (after textarea / label so that key popovers are not drawn over) */
|
||||
keyboard = lv_keyboard_create(screen);
|
||||
lv_keyboard_set_mode(keyboard, LV_KEYBOARD_MODE_TEXT_LOWER);
|
||||
lv_keyboard_set_textarea(keyboard, textarea);
|
||||
uint32_t num_keyboard_events = lv_obj_get_event_count(keyboard);
|
||||
for(uint32_t i = 0; i < num_keyboard_events; ++i) {
|
||||
if(lv_event_dsc_get_cb(lv_obj_get_event_dsc(keyboard, i)) == lv_keyboard_def_event_cb) {
|
||||
lv_obj_remove_event(keyboard, i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
lv_obj_add_event_cb(keyboard, keyboard_value_changed_cb, LV_EVENT_VALUE_CHANGED, NULL);
|
||||
lv_obj_add_event_cb(keyboard, keyboard_ready_cb, LV_EVENT_READY, NULL);
|
||||
lv_obj_set_size(keyboard, LV_PCT(100), keyboard_height);
|
||||
bbx_theme_prepare_keyboard(keyboard);
|
||||
bbx_keyboard_config_t keyboard_config;
|
||||
bbx_keyboard_init_config(&keyboard_config);
|
||||
keyboard_config.layout_id = (int)conf_opts.keyboard.layout_id;
|
||||
keyboard_config.height = keyboard_height;
|
||||
keyboard_config.popovers = conf_opts.keyboard.popovers;
|
||||
keyboard_config.value_changed_callback = keyboard_value_changed_cb;
|
||||
keyboard_config.ready_callback = keyboard_ready_cb;
|
||||
|
||||
keyboard = bbx_keyboard_create(screen, textarea, &keyboard_config);
|
||||
|
||||
/* Apply textarea options */
|
||||
set_password_obscured(conf_opts.textarea.obscured);
|
||||
|
||||
/* Apply keyboard options */
|
||||
sq2lv_switch_layout(keyboard, conf_opts.keyboard.layout_id);
|
||||
lv_dropdown_set_selected(layout_dropdown, conf_opts.keyboard.layout_id);
|
||||
if (conf_opts.keyboard.popovers) {
|
||||
lv_keyboard_set_popovers(keyboard, true);
|
||||
}
|
||||
lv_dropdown_set_selected(header_widgets.layout_dropdown, conf_opts.keyboard.layout_id);
|
||||
|
||||
/* Periodically run timer / task handler */
|
||||
uint32_t timeout = conf_opts.general.timeout * 1000; /* ms */
|
||||
|
|
|
|||
|
|
@ -2,12 +2,10 @@
|
|||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
unl0kr_sources = files(
|
||||
'backends.c',
|
||||
'command_line.c',
|
||||
'config.c',
|
||||
'main.c',
|
||||
'sq2lv_layouts.c',
|
||||
'terminal.c'
|
||||
)
|
||||
|
||||
unl0kr_dependencies = [
|
||||
|
|
@ -27,7 +25,7 @@ endif
|
|||
|
||||
executable('unl0kr',
|
||||
include_directories: common_include_dirs,
|
||||
sources: unl0kr_sources + shared_sources + squeek2lvgl_sources + lvgl_sources,
|
||||
sources: unl0kr_sources + shared_sources + squeek2lvgl_sources + lvgl_sources + header_sources,
|
||||
dependencies: unl0kr_dependencies,
|
||||
c_args: unl0kr_args,
|
||||
install: true,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue