diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c5e4a8..f44544e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,8 @@ If a change only affects particular applications, they are listed in parentheses ## Unreleased +- feat(buffyboard): Add fbdev force-refresh quirk via config +- feat(buffyboard): Allow choosing theme via config and add all themes from unl0kr - feat(buffyboard): Handle input device connection/disconnection at runtime; adds new dependency libudev ## 3.0.0 (2024-03-22) diff --git a/buffyboard/README.md b/buffyboard/README.md index a7adfc6..0fecd81 100644 --- a/buffyboard/README.md +++ b/buffyboard/README.md @@ -29,6 +29,7 @@ For a growing collection of demo videos, see the [wiki]. ## Dependencies +- [inih] - [lvgl] (git submodule / linked statically) - [squeek2lvgl] (git submodule / linked statically) - [libinput] @@ -129,6 +130,7 @@ The [FontAwesome] font is licensed under the Open Font License version 1.1. [OpenSans]: https://fonts.google.com/specimen/Open+Sans [arrow-alt-circle-up]: https://fontawesome.com/v5.15/icons/arrow-alt-circle-up?style=solid [fbkeyboard]: https://github.com/bakonyiferenc/fbkeyboard +[inih]: https://github.com/benhoyt/inih [libinput]: https://gitlab.freedesktop.org/libinput/libinput [libudev]: https://github.com/systemd/systemd/tree/main/src/libudev [lv_port_linux_frame_buffer]: https://github.com/lvgl/lv_port_linux_frame_buffer diff --git a/buffyboard/buffyboard.conf b/buffyboard/buffyboard.conf new file mode 100644 index 0000000..60d9157 --- /dev/null +++ b/buffyboard/buffyboard.conf @@ -0,0 +1,5 @@ +[general] +theme=breezy-light + +#[quirks] +#fbdev_force_refresh=true diff --git a/buffyboard/buffyboard.h b/buffyboard/buffyboard.h index b47c3f2..85ac9e5 100644 --- a/buffyboard/buffyboard.h +++ b/buffyboard/buffyboard.h @@ -13,11 +13,4 @@ #define BB_VERSION "?" /* Just to silence IDE warning. Real version injected by meson during build. */ #endif - -/** - * Fonts - */ - -LV_FONT_DECLARE(font_32); - #endif /* BB_BUFFYBOARD_H */ diff --git a/buffyboard/command_line.c b/buffyboard/command_line.c index 1cd5b5b..2cf1d34 100644 --- a/buffyboard/command_line.c +++ b/buffyboard/command_line.c @@ -8,6 +8,8 @@ #include "buffyboard.h" +#include "../shared/log.h" + #include #include #include @@ -44,15 +46,21 @@ static void print_usage() { "Usage: buffyboard [OPTION]\n" "\n" "Mandatory arguments to long options are mandatory for short options too.\n" - " -r, --rotate=[0-3] Rotate the UI to the given orientation.\n" - " 0 - normal orientation (0 degree)\n" - " 1 - clockwise orientation (90 degrees)\n" - " 2 - upside down orientation (180 degrees)\n" - " 3 - counterclockwise orientation (270 degrees)\n" - " The values match the ones provided by the kernel in\n" - " /sys/class/graphics/fbcon/rotate.\n" - " -h, --help Print this message and exit\n" - " -V, --version Print the buffyboard version and exit\n"); + " -C, --config-override Path to a config override file. Can be supplied\n" + " multiple times. Config files are merged in the\n" + " following order:\n" + " * /etc/buffyboard.conf\n" + " * /etc/buffyboard.conf.d/* (alphabetically)\n" + " * Override files (in supplied order)\n" + " -r, --rotate=[0-3] Rotate the UI to the given orientation. The\n" + " values match the ones provided by the kernel in\n" + " /sys/class/graphics/fbcon/rotate.\n" + " * 0 - normal orientation (0 degree)\n" + " * 1 - clockwise orientation (90 degrees)\n" + " * 2 - upside down orientation (180 degrees)\n" + " * 3 - counterclockwise orientation (270 degrees)\n" + " -h, --help Print this message and exit\n" + " -V, --version Print the buffyboard version and exit\n"); /*-------------------------------- 78 CHARS --------------------------------*/ } @@ -65,16 +73,26 @@ void bb_cli_parse_opts(int argc, char *argv[], bb_cli_opts *opts) { init_opts(opts); struct option long_opts[] = { - { "rotate", required_argument, NULL, 'r' }, - { "help", no_argument, NULL, 'h' }, - { "version", no_argument, NULL, 'V' }, + { "config-override", required_argument, NULL, 'C' }, + { "rotate", required_argument, NULL, 'r' }, + { "help", no_argument, NULL, 'h' }, + { "version", no_argument, NULL, 'V' }, { NULL, 0, NULL, 0 } }; int opt, index = 0; - while ((opt = getopt_long(argc, argv, "r:hV", long_opts, &index)) != -1) { + while ((opt = getopt_long(argc, argv, "C:r:hV", long_opts, &index)) != -1) { switch (opt) { + case 'C': + opts->config_files = realloc(opts->config_files, (opts->num_config_files + 1) * sizeof(char *)); + if (!opts->config_files) { + bb_log(BB_LOG_LEVEL_ERROR, "Could not allocate memory for config file paths"); + exit(EXIT_FAILURE); + } + opts->config_files[opts->num_config_files] = optarg; + opts->num_config_files++; + break; case 'r': { int orientation; if (sscanf(optarg, "%i", &orientation) != 1 || orientation < 0 || orientation > 3) { diff --git a/buffyboard/command_line.h b/buffyboard/command_line.h index 5316366..f04297a 100644 --- a/buffyboard/command_line.h +++ b/buffyboard/command_line.h @@ -13,6 +13,10 @@ * Options parsed from command line arguments */ typedef struct { + /* Number of config files */ + int num_config_files; + /* Paths of config file */ + const char **config_files; /* Display rotation */ lv_display_rotation_t rotation; } bb_cli_opts; diff --git a/buffyboard/config.c b/buffyboard/config.c new file mode 100644 index 0000000..9f18f91 --- /dev/null +++ b/buffyboard/config.c @@ -0,0 +1,218 @@ +/** + * Copyright 2021 Johannes Marbach + * SPDX-License-Identifier: GPL-3.0-or-later + */ + + +#include "config.h" + +#include "../shared/log.h" +#include "../squeek2lvgl/sq2lv.h" + +#include "lvgl/lvgl.h" + +#include +#include +#include +#include + + +/** + * Static prototypes + */ + +/** + * Compares two strings from opaque types. + * + * @param a first string as void pointer + * @param b second string as void pointer + * @return a positive integer if a > b, a negative integer if a < b and 0 otherwise + */ +static int compare_strings(const void* a, const void* b); + +/** + * Checks whether a string ends with a suffix + * + * @param string string to check + * @param suffix suffix to compare to + * @return true if the suffix matches at the end of the string, false otherwise + */ +static bool string_ends_with(const char *string, const char *suffix); + +/** + * Non-recursively searches a directory for configuration files. + * + * @param path folder to search in + * @param found pointer to write found configuration file names into (to be freed by the caller) + * @param num_found pointer to write number of found files into + */ +static void find_files(const char *path, char ***found, int *num_found); + +/** + * 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); + +/** + * Attempt to parse a boolean value. + * + * @param value string to parse + * @param result pointer to write result into if parsing is successful + * @return true on success, false otherwise + */ +static bool parse_bool(const char *value, bool *result); + + +/** + * Static functions + */ + +static int compare_strings(const void* a, const void* b) { + return strcmp(*(const char**)a, *(const char**)b); +} + +static bool string_ends_with(const char *string, const char *suffix) { + if (!string || !suffix || strlen(suffix) > strlen(string)) { + return false; + } + return strncmp(string + strlen(string) - strlen(suffix), suffix, strlen(suffix)) == 0; +} + +static void find_files(const char *path, char ***found, int *num_found) { + /* Initialise output variables */ + *found = NULL; + *num_found = 0; + + /* Count length of directory path */ + const int path_length = strlen(path); + + /* Open directory */ + DIR *d = opendir(path); + if (!d) { + bb_log(BB_LOG_LEVEL_WARNING, "Could not read contents of folder %s", path); + return; + } + + /* Loop over directory contents */ + struct dirent *dir; + while ((dir = readdir(d)) != NULL) { + /* Ignore anything except for .conf files */ + if (dir->d_type != DT_REG || !string_ends_with(dir->d_name, ".conf")) { + continue; + } + + /* Grow output array */ + char **tmp = realloc(*found, (*num_found + 1) * sizeof(char *)); + if (!tmp) { + bb_log(BB_LOG_LEVEL_ERROR, "Could not reallocate memory for configuration file paths"); + break; + } + *found = tmp; + + /* Extract file name and length */ + char *name = dir->d_name; + int name_length = strlen(name); + + /* Allocate memory for full path */ + char *found_path = malloc(path_length + name_length + 2); /* +1 for path separator and null terminator, respectively */ + if (!found_path) { + bb_log(BB_LOG_LEVEL_ERROR, "Could not allocate memory for configuration file path"); + break; + } + + /* Build full path */ + memcpy(found_path, path, path_length); + found_path[path_length] = '/'; + memcpy(found_path + path_length + 1, dir->d_name, name_length + 1); /* +1 for path separator and null terminator, respectively */ + + /* Store file path */ + (*found)[*num_found] = found_path; + *num_found += 1; + } + + /* Close directory */ + closedir(d); +} + +static int parsing_handler(void* user_data, const char* section, const char* key, const char* value) { + bb_config_opts *opts = (bb_config_opts *)user_data; + + if (strcmp(section, "general") == 0) { + if (strcmp(key, "theme") == 0) { + bb_themes_theme_id_t id = bb_themes_find_theme_with_name(value); + if (id != BB_THEMES_THEME_NONE) { + opts->general.theme_id = id; + return 1; + } + } + } else if (strcmp(section, "quirks") == 0) { + if (strcmp(key, "fbdev_force_refresh") == 0) { + if (parse_bool(value, &(opts->quirks.fbdev_force_refresh))) { + return 1; + } + } + } + + bb_log(BB_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 (e.g. file not found) */ +} + +static bool parse_bool(const char *value, bool *result) { + if (strcmp(value, "true") == 0) { + *result = true; + return true; + } + + if (strcmp(value, "false") == 0) { + *result = false; + return true; + } + + return false; +} + + +/** + * Public functions + */ + +void bb_config_init_opts(bb_config_opts *opts) { + opts->general.theme_id = BB_THEMES_THEME_BREEZY_DARK; + opts->quirks.fbdev_force_refresh = false; +} + +void bb_config_parse_directory(const char *path, bb_config_opts *opts) { + /* Find files in directory */ + char **found = NULL; + int num_found = 0; + find_files(path, &found, &num_found); + + /* Sort and parse files */ + qsort(found, num_found, sizeof(char *), compare_strings); + bb_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 bb_config_parse_files(const char **files, int num_files, bb_config_opts *opts) { + for (int i = 0; i < num_files; ++i) { + bb_config_parse_file(files[i], opts); + } +} + +void bb_config_parse_file(const char *path, bb_config_opts *opts) { + bb_log(BB_LOG_LEVEL_VERBOSE, "Parsing config file %s", path); + if (ini_parse(path, parsing_handler, opts) != 0) { + bb_log(BB_LOG_LEVEL_ERROR, "Ignoring invalid config file %s", path); + } +} diff --git a/buffyboard/config.h b/buffyboard/config.h new file mode 100644 index 0000000..eab2e02 --- /dev/null +++ b/buffyboard/config.h @@ -0,0 +1,72 @@ +/** + * Copyright 2021 Johannes Marbach + * SPDX-License-Identifier: GPL-3.0-or-later + */ + + +#ifndef BB_CONFIG_H +#define BB_CONFIG_H + +#include "../shared/themes.h" + +#include "sq2lv_layouts.h" + +/** + * General options + */ +typedef struct { + /* Theme */ + bb_themes_theme_id_t theme_id; +} bb_config_opts_general; + +/** + * (Normally unneeded) quirky options + */ +typedef struct { + /* If true and using the framebuffer backend, force a refresh on every draw operation */ + bool fbdev_force_refresh; +} bb_config_opts_quirks; + +/** + * Options parsed from config file(s) + */ +typedef struct { + /* General options */ + bb_config_opts_general general; + /* Options related to (normally unneeded) quirks */ + bb_config_opts_quirks quirks; +} bb_config_opts; + +/** + * Initialise a config options struct with default values. + * + * @param opts pointer to the options struct + */ +void bb_config_init_opts(bb_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 bb_config_parse_directory(const char *path, bb_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 bb_config_parse_files(const char **files, int num_files, bb_config_opts *opts); + +/** + * Parse a configuration file. + * + * @param path path to configuration file + * @param opts pointer for writing the parsed options into + */ +void bb_config_parse_file(const char *path, bb_config_opts *opts); + +#endif /* BB_CONFIG_H */ diff --git a/buffyboard/font_32.c b/buffyboard/font_32.c index 0180a02..09dc869 100644 --- a/buffyboard/font_32.c +++ b/buffyboard/font_32.c @@ -1,7 +1,7 @@ /******************************************************************************* * Size: 32 px * Bpp: 4 - * Opts: --bpp 4 --size 32 --no-compress -o font_32.c --format lvgl --font OpenSans-Regular.ttf --range 0x0020-0x007F --range 0x00A0-0x00FF --range 0x0100-0x017F --range 0x0370-0x03FF --range 0x2000-0x206F --range 0x20A0-0x20CF --range 0x2200-0x22FF --font FontAwesome5-Solid+Brands+Regular.woff --range 0xF001,0xF008,0xF00B,0xF00C,0xF00D,0xF011,0xF013,0xF015,0xF019,0xF01C,0xF021,0xF026,0xF027,0xF028,0xF03E,0xF0E0,0xF304,0xF043,0xF048,0xF04B,0xF04C,0xF04D,0xF051,0xF052,0xF053,0xF054,0xF067,0xF068,0xF06E,0xF070,0xF071,0xF074,0xF077,0xF078,0xF079,0xF07B,0xF093,0xF095,0xF0C4,0xF0C5,0xF0C7,0xF0C9,0xF0E7,0xF0EA,0xF0F3,0xF11C,0xF124,0xF158,0xF1EB,0xF240,0xF241,0xF242,0xF243,0xF244,0xF287,0xF293,0xF2ED,0xF55A,0xF7C2,0xF8A2 --range 0xF35B + * Opts: --bpp 4 --size 32 --no-compress -o font_32.c --format lvgl --font OpenSans-Regular.ttf --range 0x0020-0x007F --range 0x00A0-0x00FF --range 0x0100-0x017F --range 0x0370-0x03FF --range 0x2000-0x206F --range 0x20A0-0x20CF --range 0x2200-0x22FF --font FontAwesome5-Solid+Brands+Regular.woff --range 0xF001,0xF008,0xF00B,0xF00C,0xF00D,0xF011,0xF013,0xF015,0xF019,0xF01C,0xF021,0xF026,0xF027,0xF028,0xF03E,0xF0E0,0xF304,0xF043,0xF048,0xF04B,0xF04C,0xF04D,0xF051,0xF052,0xF053,0xF054,0xF067,0xF068,0xF06E,0xF070,0xF071,0xF074,0xF077,0xF078,0xF079,0xF07B,0xF093,0xF095,0xF0C4,0xF0C5,0xF0C7,0xF0C9,0xF0E7,0xF0EA,0xF0F3,0xF11C,0xF124,0xF158,0xF1EB,0xF240,0xF241,0xF242,0xF243,0xF244,0xF287,0xF293,0xF2ED,0xF55A,0xF7C2,0xF8A2 --range 0xF042 --range 0xF35B ******************************************************************************/ #ifdef LV_LVGL_H_INCLUDE_SIMPLE @@ -12341,6 +12341,72 @@ static LV_ATTRIBUTE_LARGE_CONST const uint8_t glyph_bitmap[] = { 0x8, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, + /* U+F042 "" */ + 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x34, + 0x43, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5a, 0xef, 0xff, + 0xff, 0xfd, 0x94, 0x0, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x6e, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xc4, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x2c, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xa0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x3, 0xef, 0xff, 0xff, 0xff, 0xff, + 0xcd, 0xff, 0xff, 0xff, 0xfd, 0x10, 0x0, 0x0, + 0x0, 0x0, 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x5, 0xaf, 0xff, 0xff, 0xe1, 0x0, 0x0, + 0x0, 0x2, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x3, 0xdf, 0xff, 0xfd, 0x0, 0x0, + 0x0, 0xd, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0xb, 0xff, 0xff, 0xa0, 0x0, + 0x0, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0xbf, 0xff, 0xf4, 0x0, + 0x1, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0xfc, 0x0, + 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x3, 0xff, 0xff, 0x30, + 0xc, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xbf, 0xff, 0x90, + 0x1f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, 0xd0, + 0x4f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1f, 0xff, 0xf0, + 0x6f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xe, 0xff, 0xf2, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0xf3, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xc, 0xff, 0xf4, + 0x7f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 0xff, 0xf3, + 0x5f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0xf, 0xff, 0xf1, + 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x3f, 0xff, 0xf0, + 0xe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x8f, 0xff, 0xb0, + 0x9, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x1, 0xff, 0xff, 0x60, + 0x3, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x9, 0xff, 0xff, 0x0, + 0x0, 0xbf, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x0, 0x5f, 0xff, 0xf8, 0x0, + 0x0, 0x2f, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x4, 0xff, 0xff, 0xe0, 0x0, + 0x0, 0x7, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x0, 0x6f, 0xff, 0xff, 0x30, 0x0, + 0x0, 0x0, 0x9f, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x0, 0x0, 0x3c, 0xff, 0xff, 0xf6, 0x0, 0x0, + 0x0, 0x0, 0xa, 0xff, 0xff, 0xff, 0xff, 0xff, + 0x56, 0x9d, 0xff, 0xff, 0xff, 0x70, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x8f, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xf5, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x4, 0xdf, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xfb, 0x20, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x5, 0xcf, 0xff, 0xff, + 0xff, 0xff, 0xfb, 0x40, 0x0, 0x0, 0x0, 0x0, + 0x0, 0x0, 0x0, 0x0, 0x0, 0x1, 0x58, 0xab, + 0xba, 0x84, 0x10, 0x0, 0x0, 0x0, 0x0, 0x0, + /* U+F043 "" */ 0x0, 0x0, 0x0, 0x0, 0x4, 0xee, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, @@ -15294,52 +15360,53 @@ static const lv_font_fmt_txt_glyph_dsc_t glyph_dsc[] = { {.bitmap_index = 88772, .adv_w = 384, .box_w = 24, .box_h = 26, .ofs_x = 0, .ofs_y = -1}, {.bitmap_index = 89084, .adv_w = 576, .box_w = 36, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, {.bitmap_index = 89660, .adv_w = 512, .box_w = 32, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 90044, .adv_w = 352, .box_w = 22, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 90396, .adv_w = 448, .box_w = 20, .box_h = 30, .ofs_x = 4, .ofs_y = -3}, - {.bitmap_index = 90696, .adv_w = 448, .box_w = 28, .box_h = 34, .ofs_x = 0, .ofs_y = -5}, - {.bitmap_index = 91172, .adv_w = 448, .box_w = 28, .box_h = 29, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91578, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 91970, .adv_w = 448, .box_w = 20, .box_h = 30, .ofs_x = 4, .ofs_y = -3}, - {.bitmap_index = 92270, .adv_w = 448, .box_w = 30, .box_h = 28, .ofs_x = -1, .ofs_y = -2}, - {.bitmap_index = 92690, .adv_w = 320, .box_w = 18, .box_h = 28, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 92942, .adv_w = 320, .box_w = 18, .box_h = 28, .ofs_x = 1, .ofs_y = -2}, - {.bitmap_index = 93194, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 93586, .adv_w = 448, .box_w = 28, .box_h = 6, .ofs_x = 0, .ofs_y = 9}, - {.bitmap_index = 93670, .adv_w = 576, .box_w = 36, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 94102, .adv_w = 640, .box_w = 40, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 94742, .adv_w = 576, .box_w = 38, .box_h = 32, .ofs_x = -1, .ofs_y = -4}, - {.bitmap_index = 95350, .adv_w = 512, .box_w = 32, .box_h = 30, .ofs_x = 0, .ofs_y = -3}, - {.bitmap_index = 95830, .adv_w = 448, .box_w = 28, .box_h = 18, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 96082, .adv_w = 448, .box_w = 28, .box_h = 18, .ofs_x = 0, .ofs_y = 3}, - {.bitmap_index = 96334, .adv_w = 640, .box_w = 40, .box_h = 26, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 96854, .adv_w = 512, .box_w = 32, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 97238, .adv_w = 512, .box_w = 32, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 97750, .adv_w = 512, .box_w = 33, .box_h = 33, .ofs_x = -1, .ofs_y = -4}, - {.bitmap_index = 98295, .adv_w = 448, .box_w = 29, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 98701, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 99149, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 99541, .adv_w = 448, .box_w = 28, .box_h = 26, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 99905, .adv_w = 512, .box_w = 32, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 100289, .adv_w = 320, .box_w = 22, .box_h = 32, .ofs_x = -1, .ofs_y = -4}, - {.bitmap_index = 100641, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 101089, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 101537, .adv_w = 576, .box_w = 36, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 101969, .adv_w = 512, .box_w = 34, .box_h = 34, .ofs_x = -1, .ofs_y = -5}, - {.bitmap_index = 102547, .adv_w = 384, .box_w = 24, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 102883, .adv_w = 640, .box_w = 40, .box_h = 29, .ofs_x = 0, .ofs_y = -2}, - {.bitmap_index = 103463, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 103863, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 104263, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 104663, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 105063, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, - {.bitmap_index = 105463, .adv_w = 640, .box_w = 41, .box_h = 26, .ofs_x = 0, .ofs_y = -1}, - {.bitmap_index = 105996, .adv_w = 448, .box_w = 24, .box_h = 32, .ofs_x = 2, .ofs_y = -4}, - {.bitmap_index = 106380, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 106828, .adv_w = 512, .box_w = 33, .box_h = 33, .ofs_x = -1, .ofs_y = -5}, - {.bitmap_index = 107373, .adv_w = 512, .box_w = 32, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 107885, .adv_w = 640, .box_w = 40, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, - {.bitmap_index = 108365, .adv_w = 384, .box_w = 24, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, - {.bitmap_index = 108749, .adv_w = 515, .box_w = 33, .box_h = 21, .ofs_x = 0, .ofs_y = 2} + {.bitmap_index = 90044, .adv_w = 512, .box_w = 32, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 90556, .adv_w = 352, .box_w = 22, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 90908, .adv_w = 448, .box_w = 20, .box_h = 30, .ofs_x = 4, .ofs_y = -3}, + {.bitmap_index = 91208, .adv_w = 448, .box_w = 28, .box_h = 34, .ofs_x = 0, .ofs_y = -5}, + {.bitmap_index = 91684, .adv_w = 448, .box_w = 28, .box_h = 29, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92090, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 92482, .adv_w = 448, .box_w = 20, .box_h = 30, .ofs_x = 4, .ofs_y = -3}, + {.bitmap_index = 92782, .adv_w = 448, .box_w = 30, .box_h = 28, .ofs_x = -1, .ofs_y = -2}, + {.bitmap_index = 93202, .adv_w = 320, .box_w = 18, .box_h = 28, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 93454, .adv_w = 320, .box_w = 18, .box_h = 28, .ofs_x = 1, .ofs_y = -2}, + {.bitmap_index = 93706, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 94098, .adv_w = 448, .box_w = 28, .box_h = 6, .ofs_x = 0, .ofs_y = 9}, + {.bitmap_index = 94182, .adv_w = 576, .box_w = 36, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 94614, .adv_w = 640, .box_w = 40, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 95254, .adv_w = 576, .box_w = 38, .box_h = 32, .ofs_x = -1, .ofs_y = -4}, + {.bitmap_index = 95862, .adv_w = 512, .box_w = 32, .box_h = 30, .ofs_x = 0, .ofs_y = -3}, + {.bitmap_index = 96342, .adv_w = 448, .box_w = 28, .box_h = 18, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 96594, .adv_w = 448, .box_w = 28, .box_h = 18, .ofs_x = 0, .ofs_y = 3}, + {.bitmap_index = 96846, .adv_w = 640, .box_w = 40, .box_h = 26, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 97366, .adv_w = 512, .box_w = 32, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 97750, .adv_w = 512, .box_w = 32, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 98262, .adv_w = 512, .box_w = 33, .box_h = 33, .ofs_x = -1, .ofs_y = -4}, + {.bitmap_index = 98807, .adv_w = 448, .box_w = 29, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 99213, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 99661, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 100053, .adv_w = 448, .box_w = 28, .box_h = 26, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 100417, .adv_w = 512, .box_w = 32, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 100801, .adv_w = 320, .box_w = 22, .box_h = 32, .ofs_x = -1, .ofs_y = -4}, + {.bitmap_index = 101153, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 101601, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 102049, .adv_w = 576, .box_w = 36, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 102481, .adv_w = 512, .box_w = 34, .box_h = 34, .ofs_x = -1, .ofs_y = -5}, + {.bitmap_index = 103059, .adv_w = 384, .box_w = 24, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103395, .adv_w = 640, .box_w = 40, .box_h = 29, .ofs_x = 0, .ofs_y = -2}, + {.bitmap_index = 103975, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 104375, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 104775, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 105175, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 105575, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2}, + {.bitmap_index = 105975, .adv_w = 640, .box_w = 41, .box_h = 26, .ofs_x = 0, .ofs_y = -1}, + {.bitmap_index = 106508, .adv_w = 448, .box_w = 24, .box_h = 32, .ofs_x = 2, .ofs_y = -4}, + {.bitmap_index = 106892, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 107340, .adv_w = 512, .box_w = 33, .box_h = 33, .ofs_x = -1, .ofs_y = -5}, + {.bitmap_index = 107885, .adv_w = 512, .box_w = 32, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 108397, .adv_w = 640, .box_w = 40, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, + {.bitmap_index = 108877, .adv_w = 384, .box_w = 24, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, + {.bitmap_index = 109261, .adv_w = 515, .box_w = 33, .box_h = 21, .ofs_x = 0, .ofs_y = 2} }; /*--------------------- @@ -15360,13 +15427,13 @@ static const uint16_t unicode_list_5[] = { 0x1cd9, 0x1cda, 0x1cdb, 0x1e31, 0x1e35, 0x1e3e, 0x1e40, 0x1e41, 0x1e44, 0x1e49, 0x1e4d, 0x1e5a, 0x1e77, 0x1e8f, 0x1e93, 0x1e94, 0xec30, 0xec37, 0xec3a, 0xec3b, 0xec3c, 0xec40, 0xec42, 0xec44, - 0xec48, 0xec4b, 0xec50, 0xec55, 0xec56, 0xec57, 0xec6d, 0xec72, - 0xec77, 0xec7a, 0xec7b, 0xec7c, 0xec80, 0xec81, 0xec82, 0xec83, - 0xec96, 0xec97, 0xec9d, 0xec9f, 0xeca0, 0xeca3, 0xeca6, 0xeca7, - 0xeca8, 0xecaa, 0xecc2, 0xecc4, 0xecf3, 0xecf4, 0xecf6, 0xecf8, - 0xed0f, 0xed16, 0xed19, 0xed22, 0xed4b, 0xed53, 0xed87, 0xee1a, - 0xee6f, 0xee70, 0xee71, 0xee72, 0xee73, 0xeeb6, 0xeec2, 0xef1c, - 0xef33, 0xef8a, 0xf189, 0xf3f1, 0xf4d1 + 0xec48, 0xec4b, 0xec50, 0xec55, 0xec56, 0xec57, 0xec6d, 0xec71, + 0xec72, 0xec77, 0xec7a, 0xec7b, 0xec7c, 0xec80, 0xec81, 0xec82, + 0xec83, 0xec96, 0xec97, 0xec9d, 0xec9f, 0xeca0, 0xeca3, 0xeca6, + 0xeca7, 0xeca8, 0xecaa, 0xecc2, 0xecc4, 0xecf3, 0xecf4, 0xecf6, + 0xecf8, 0xed0f, 0xed16, 0xed19, 0xed22, 0xed4b, 0xed53, 0xed87, + 0xee1a, 0xee6f, 0xee70, 0xee71, 0xee72, 0xee73, 0xeeb6, 0xeec2, + 0xef1c, 0xef33, 0xef8a, 0xf189, 0xf3f1, 0xf4d1 }; /*Collect the unicode lists and glyph_id offsets*/ @@ -15394,7 +15461,7 @@ static const lv_font_fmt_txt_cmap_t cmaps[] = }, { .range_start = 977, .range_length = 62674, .glyph_id_start = 392, - .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 117, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY + .unicode_list = unicode_list_5, .glyph_id_ofs_list = NULL, .list_length = 118, .type = LV_FONT_FMT_TXT_CMAP_SPARSE_TINY } }; @@ -15434,7 +15501,7 @@ static lv_font_fmt_txt_dsc_t font_dsc = { #if LV_VERSION_CHECK(8, 0, 0) const lv_font_t font_32 = { #else -lv_font_t font_32 = { +const lv_font_t font_32 = { #endif .get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/ diff --git a/buffyboard/lv_conf.h b/buffyboard/lv_conf.h index 02cd251..c1bc5a5 100644 --- a/buffyboard/lv_conf.h +++ b/buffyboard/lv_conf.h @@ -392,10 +392,10 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/ /*Optionally declare custom fonts here. *You can use these fonts as default font too and they will be available globally. *E.g. #define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(my_font_1) LV_FONT_DECLARE(my_font_2)*/ -#define LV_FONT_CUSTOM_DECLARE +#define LV_FONT_CUSTOM_DECLARE LV_FONT_DECLARE(font_32) /*Always set a default font*/ -#define LV_FONT_DEFAULT &lv_font_montserrat_14 +#define LV_FONT_DEFAULT &font_32 /*Enable handling large font and/or fonts with a lot of characters. *The limit depends on the font size, font face and bpp. diff --git a/buffyboard/main.c b/buffyboard/main.c index 3321d3a..6acd470 100644 --- a/buffyboard/main.c +++ b/buffyboard/main.c @@ -6,6 +6,7 @@ #include "buffyboard.h" #include "command_line.h" +#include "config.h" #include "sq2lv_layouts.h" #include "terminal.h" #include "uinput_device.h" @@ -13,6 +14,8 @@ #include "lvgl/lvgl.h" #include "../shared/indev.h" +#include "../shared/theme.h" +#include "../shared/themes.h" #include "../squeek2lvgl/sq2lv.h" #include @@ -29,10 +32,10 @@ */ bb_cli_opts cli_opts; +bb_config_opts conf_opts; static bool resize_terminals = false; static lv_obj_t *keyboard = NULL; -static lv_style_t style_text_normal; /** @@ -63,20 +66,6 @@ static void sigaction_handler(int signum); */ static void terminal_resize_timer_cb(lv_timer_t *timer); -/** - * Set the UI theme. - * - * @param is_dark true if the dark theme should be applied, false if the light theme should be applied - */ -static void set_theme(bool is_dark); - -/** - * Handle LV_EVENT_DRAW_TASK_ADDED events from the keyboard widget. - * - * @param event the event object - */ -static void keyboard_draw_task_added_cb(lv_event_t *event); - /** * Handle LV_EVENT_VALUE_CHANGED events from the keyboard widget. * @@ -120,48 +109,6 @@ static void terminal_resize_timer_cb(lv_timer_t *timer) { } } -static void set_theme(bool is_dark) { - lv_theme_default_init(NULL, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_CYAN), is_dark, &font_32); -} - -static void keyboard_draw_task_added_cb(lv_event_t *event) { - lv_obj_t *obj = lv_event_get_target(event); - lv_buttonmatrix_t *btnm = (lv_buttonmatrix_t *)obj; - lv_draw_task_t *draw_task = lv_event_get_draw_task(event); - lv_draw_dsc_base_t *dsc = draw_task->draw_dsc; - - if (dsc->part != LV_PART_ITEMS) { - return; - } - - lv_draw_fill_dsc_t *fill_dsc = lv_draw_task_get_fill_dsc(draw_task); - if (!fill_dsc) { - return; - } - - if (lv_btnmatrix_get_selected_btn(obj) == dsc->id1 && lv_obj_has_state(obj, LV_STATE_PRESSED)) { - if ((btnm->ctrl_bits[dsc->id1] & SQ2LV_CTRL_MOD_INACTIVE) == SQ2LV_CTRL_MOD_INACTIVE) { - fill_dsc->color = lv_palette_lighten(LV_PALETTE_TEAL, 1); - } else if ((btnm->ctrl_bits[dsc->id1] & SQ2LV_CTRL_MOD_ACTIVE) == SQ2LV_CTRL_MOD_ACTIVE) { - fill_dsc->color = lv_palette_lighten(LV_PALETTE_TEAL, 1); - } else if ((btnm->ctrl_bits[dsc->id1] & SQ2LV_CTRL_NON_CHAR) == SQ2LV_CTRL_NON_CHAR) { - fill_dsc->color = lv_palette_darken(LV_PALETTE_BLUE_GREY, 3); - } else { - fill_dsc->color = lv_palette_lighten(LV_PALETTE_BLUE_GREY, 1); - } - } else { - if ((btnm->ctrl_bits[dsc->id1] & SQ2LV_CTRL_MOD_INACTIVE) == SQ2LV_CTRL_MOD_INACTIVE) { - fill_dsc->color = lv_palette_darken(LV_PALETTE_BLUE_GREY, 4); - } else if ((btnm->ctrl_bits[dsc->id1] & SQ2LV_CTRL_MOD_ACTIVE) == SQ2LV_CTRL_MOD_ACTIVE) { - fill_dsc->color = lv_palette_main(LV_PALETTE_TEAL); - } else if ((btnm->ctrl_bits[dsc->id1] & SQ2LV_CTRL_NON_CHAR) == SQ2LV_CTRL_NON_CHAR) { - fill_dsc->color = lv_palette_darken(LV_PALETTE_BLUE_GREY, 4); - } else { - fill_dsc->color = lv_palette_main(LV_PALETTE_BLUE_GREY); - } - } -} - static void keyboard_value_changed_cb(lv_event_t *event) { lv_obj_t *kb = lv_event_get_target(event); @@ -233,6 +180,12 @@ int main(int argc, char *argv[]) { /* Parse command line options */ bb_cli_parse_opts(argc, argv, &cli_opts); + /* Parse config files */ + bb_config_init_opts(&conf_opts); + bb_config_parse_file("/etc/buffyboard.conf", &conf_opts); + bb_config_parse_directory("/etc/buffyboard.conf.d", &conf_opts); + bb_config_parse_files(cli_opts.config_files, cli_opts.num_config_files, &conf_opts); + /* Prepare for terminal resizing and reset */ resize_terminals = bb_terminal_init(2.0f / 3.0f); if (resize_terminals) { @@ -258,6 +211,9 @@ int main(int argc, char *argv[]) { /* Initialise display */ lv_display_t *disp = lv_linux_fbdev_create(); lv_linux_fbdev_set_file(disp, "/dev/fb0"); + if (conf_opts.quirks.fbdev_force_refresh) { + lv_linux_fbdev_set_force_refresh(disp, true); + } int32_t hor_res_phys = lv_display_get_horizontal_resolution(disp); int32_t ver_res_phys = lv_display_get_vertical_resolution(disp); lv_display_set_physical_resolution(disp, hor_res_phys, ver_res_phys); @@ -282,23 +238,22 @@ int main(int argc, char *argv[]) { /* Start input device monitor and auto-connect available devices */ bb_indev_start_monitor_and_autoconnect(false, true, true); - /* Initialise theme and styles */ - set_theme(true); - lv_style_init(&style_text_normal); - lv_style_set_text_font(&style_text_normal, &font_32); + /* Initialise theme */ + bb_theme_apply(bb_themes_themes[conf_opts.general.theme_id]); /* Add keyboard */ keyboard = lv_keyboard_create(lv_scr_act()); - // lv_buttonmatrix_set_popovers(keyboard, true); + 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_set_pos(keyboard, 0, 0); lv_obj_set_size(keyboard, LV_HOR_RES, LV_VER_RES); - lv_obj_add_style(keyboard, &style_text_normal, 0); - - /* Set up keyboard event handlers */ - lv_obj_remove_event_cb(keyboard, lv_keyboard_def_event_cb); - lv_obj_add_event_cb(keyboard, keyboard_value_changed_cb, LV_EVENT_VALUE_CHANGED, NULL); - lv_obj_add_event_cb(keyboard, keyboard_draw_task_added_cb, LV_EVENT_DRAW_TASK_ADDED, NULL); - lv_obj_add_flag(keyboard, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); + bb_theme_prepare_keyboard(keyboard); /* Apply default keyboard layout */ sq2lv_switch_layout(keyboard, SQ2LV_LAYOUT_TERMINAL_US); @@ -306,10 +261,9 @@ int main(int argc, char *argv[]) { /* Start timer for periodically resizing terminals */ lv_timer_create(terminal_resize_timer_cb, 1000, NULL); - /* Run lvgl in "tickless" mode */ + /* Periodically run timer / task handler */ while(1) { - lv_task_handler(); - usleep(5000); + lv_timer_periodic_handler(); } return 0; diff --git a/buffyboard/meson.build b/buffyboard/meson.build index aeee739..a1facb7 100644 --- a/buffyboard/meson.build +++ b/buffyboard/meson.build @@ -14,6 +14,7 @@ add_project_arguments('-DBB_VERSION="@0@"'.format(meson.project_version()), lang buffyboard_sources = [ 'command_line.c', + 'config.c', 'font_32.c', 'main.c', 'sq2lv_layouts.c', @@ -25,6 +26,8 @@ shared_sources = [ '../shared/cursor/cursor.c', '../shared/indev.c', '../shared/log.c', + '../shared/theme.c', + '../shared/themes.c', ] squeek2lvgl_sources = [ @@ -38,6 +41,7 @@ executable( sources: buffyboard_sources + shared_sources + squeek2lvgl_sources + lvgl_sources, include_directories: ['..'], dependencies: [ + dependency('inih'), dependency('libinput'), dependency('libudev'), meson.get_compiler('c').find_library('m', required: false), diff --git a/buffyboard/regenerate-fonts.sh b/buffyboard/regenerate-fonts.sh new file mode 100755 index 0000000..4ff1e0a --- /dev/null +++ b/buffyboard/regenerate-fonts.sh @@ -0,0 +1,19 @@ +#!/bin/sh -ex + +# Copyright 2022 Johannes Marbach +# SPDX-License-Identifier: GPL-3.0-or-later + + +npx lv_font_conv --bpp 4 --size 32 --no-compress -o font_32.c --format lvgl \ + --font OpenSans-Regular.ttf \ + --range '0x0020-0x007F' \ + --range '0x00A0-0x00FF' \ + --range '0x0100-0x017F' \ + --range '0x0370-0x03FF' \ + --range '0x2000-0x206F' \ + --range '0x20A0-0x20CF' \ + --range '0x2200-0x22FF' \ + --font FontAwesome5-Solid+Brands+Regular.woff \ + --range '0xF001,0xF008,0xF00B,0xF00C,0xF00D,0xF011,0xF013,0xF015,0xF019,0xF01C,0xF021,0xF026,0xF027,0xF028,0xF03E,0xF0E0,0xF304,0xF043,0xF048,0xF04B,0xF04C,0xF04D,0xF051,0xF052,0xF053,0xF054,0xF067,0xF068,0xF06E,0xF070,0xF071,0xF074,0xF077,0xF078,0xF079,0xF07B,0xF093,0xF095,0xF0C4,0xF0C5,0xF0C7,0xF0C9,0xF0E7,0xF0EA,0xF0F3,0xF11C,0xF124,0xF158,0xF1EB,0xF240,0xF241,0xF242,0xF243,0xF244,0xF287,0xF293,0xF2ED,0xF55A,0xF7C2,0xF8A2' \ + --range '0xF042' \ + --range '0xF35B' diff --git a/buffyboard/sq2lv_layouts.c b/buffyboard/sq2lv_layouts.c index b4dd2c4..0a62956 100644 --- a/buffyboard/sq2lv_layouts.c +++ b/buffyboard/sq2lv_layouts.c @@ -3,6 +3,7 @@ **/ #include "sq2lv_layouts.h" +#include "../squeek2lvgl/sq2lv.h" #include #define SQ2LV_SYMBOL_SHIFT "\xef\x8d\x9b" diff --git a/buffyboard/sq2lv_layouts.h b/buffyboard/sq2lv_layouts.h index 113d5ef..8afad75 100644 --- a/buffyboard/sq2lv_layouts.h +++ b/buffyboard/sq2lv_layouts.h @@ -9,11 +9,6 @@ #define SQ2LV_SCANCODES_ENABLED 1 -/* Key attributes */ -#define SQ2LV_CTRL_NON_CHAR (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKED) -#define SQ2LV_CTRL_MOD_ACTIVE (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKABLE) -#define SQ2LV_CTRL_MOD_INACTIVE (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKABLE | LV_BUTTONMATRIX_CTRL_CHECKED) - /* Layout IDs, values can be used as indexes into the sq2lv_layouts array */ typedef enum { SQ2LV_LAYOUT_NONE = -1, diff --git a/unl0kr/theme.c b/shared/theme.c similarity index 98% rename from unl0kr/theme.c rename to shared/theme.c index 347da61..d07df41 100644 --- a/unl0kr/theme.c +++ b/shared/theme.c @@ -6,10 +6,8 @@ #include "theme.h" -#include "sq2lv_layouts.h" -#include "unl0kr.h" - -#include "../shared/log.h" +#include "log.h" +#include "../squeek2lvgl/sq2lv.h" #include "lvgl/lvgl.h" @@ -238,7 +236,7 @@ static void apply_theme_cb(lv_theme_t *theme, lv_obj_t *obj) { return; } - if (lv_obj_has_flag(obj, UL_WIDGET_HEADER)) { + if (lv_obj_has_flag(obj, BB_WIDGET_HEADER)) { lv_obj_add_style(obj, &(styles.header), 0); return; } @@ -331,7 +329,7 @@ static void keyboard_draw_task_added_cb(lv_event_t *event) { return; } - ul_theme_key *key = NULL; + bb_theme_key *key = NULL; if ((btnm->ctrl_bits[dsc->id1] & SQ2LV_CTRL_MOD_INACTIVE) == SQ2LV_CTRL_MOD_INACTIVE) { key = &(current_theme.keyboard.keys.key_mod_inact); @@ -366,12 +364,12 @@ static void keyboard_draw_task_added_cb(lv_event_t *event) { * Public functions */ -void ul_theme_prepare_keyboard(lv_obj_t *keyboard) { +void bb_theme_prepare_keyboard(lv_obj_t *keyboard) { lv_obj_add_event_cb(keyboard, keyboard_draw_task_added_cb, LV_EVENT_DRAW_TASK_ADDED, NULL); lv_obj_add_flag(keyboard, LV_OBJ_FLAG_SEND_DRAW_TASK_EVENTS); } -void ul_theme_apply(const ul_theme *theme) { +void bb_theme_apply(const ul_theme *theme) { if (!theme) { bb_log(BB_LOG_LEVEL_ERROR, "Could not apply theme from NULL pointer"); return; diff --git a/unl0kr/theme.h b/shared/theme.h similarity index 66% rename from unl0kr/theme.h rename to shared/theme.h index 89a965a..62006c8 100644 --- a/unl0kr/theme.h +++ b/shared/theme.h @@ -4,15 +4,15 @@ */ -#ifndef UL_THEME_H -#define UL_THEME_H +#ifndef BB_THEME_H +#define BB_THEME_H #include "lvgl/lvgl.h" #include #include -#define UL_WIDGET_HEADER LV_OBJ_FLAG_USER_1 +#define BB_WIDGET_HEADER LV_OBJ_FLAG_USER_1 /** * Theming structs @@ -21,7 +21,7 @@ /* Window theme */ typedef struct { uint32_t bg_color; -} ul_theme_window; +} bb_theme_window; /* Header theme */ typedef struct { @@ -30,30 +30,30 @@ typedef struct { uint32_t border_color; lv_coord_t pad; lv_coord_t gap; -} ul_theme_header; +} bb_theme_header; /* Key theme for one specific key type and state */ typedef struct { uint32_t fg_color; uint32_t bg_color; uint32_t border_color; -} ul_theme_key_state; +} bb_theme_key_state; /* Key theme for one specific key type and all states */ typedef struct { - ul_theme_key_state normal; - ul_theme_key_state pressed; -} ul_theme_key; + bb_theme_key_state normal; + bb_theme_key_state pressed; +} bb_theme_key; /* Key theme */ typedef struct { lv_coord_t border_width; lv_coord_t corner_radius; - ul_theme_key key_char; - ul_theme_key key_non_char; - ul_theme_key key_mod_act; - ul_theme_key key_mod_inact; -} ul_theme_keys; + bb_theme_key key_char; + bb_theme_key key_non_char; + bb_theme_key key_mod_act; + bb_theme_key key_mod_inact; +} bb_theme_keys; /* Keyboard theme */ typedef struct { @@ -62,31 +62,31 @@ typedef struct { uint32_t border_color; lv_coord_t pad; lv_coord_t gap; - ul_theme_keys keys; -} ul_theme_keyboard; + bb_theme_keys keys; +} bb_theme_keyboard; /* Button theme for one specific button state */ typedef struct { uint32_t fg_color; uint32_t bg_color; uint32_t border_color; -} ul_theme_button_state; +} bb_theme_button_state; /* Button theme */ typedef struct { lv_coord_t border_width; lv_coord_t corner_radius; lv_coord_t pad; - ul_theme_button_state normal; - ul_theme_button_state pressed; -} ul_theme_button; + bb_theme_button_state normal; + bb_theme_button_state pressed; +} bb_theme_button; /* Text area cursor theme */ typedef struct { lv_coord_t width; uint32_t color; int period; -} ul_theme_textarea_cursor; +} bb_theme_textarea_cursor; /* Text area theme */ typedef struct { @@ -97,8 +97,8 @@ typedef struct { lv_coord_t corner_radius; lv_coord_t pad; uint32_t placeholder_color; - ul_theme_textarea_cursor cursor; -} ul_theme_textarea; + bb_theme_textarea_cursor cursor; +} bb_theme_textarea; /* Dropdown list theme */ typedef struct { @@ -110,29 +110,29 @@ typedef struct { uint32_t border_color; lv_coord_t corner_radius; lv_coord_t pad; -} ul_theme_dropdown_list; +} bb_theme_dropdown_list; /* Dropdown theme */ typedef struct { - ul_theme_button button; - ul_theme_dropdown_list list; -} ul_theme_dropdown; + bb_theme_button button; + bb_theme_dropdown_list list; +} bb_theme_dropdown; /* Label */ typedef struct { uint32_t fg_color; -} ul_theme_label; +} bb_theme_label; /* Message box buttons theme */ typedef struct { lv_coord_t gap; -} ul_theme_msgbox_buttons; +} bb_theme_msgbox_buttons; /* Message box dimming theme */ typedef struct { uint32_t color; short opacity; -} ul_theme_msgbox_dimming; +} bb_theme_msgbox_dimming; /* Message box theme */ typedef struct { @@ -143,35 +143,35 @@ typedef struct { lv_coord_t corner_radius; lv_coord_t pad; lv_coord_t gap; - ul_theme_msgbox_buttons buttons; - ul_theme_msgbox_dimming dimming; -} ul_theme_msgbox; + bb_theme_msgbox_buttons buttons; + bb_theme_msgbox_dimming dimming; +} bb_theme_msgbox; /* Progress bar indicator theme */ typedef struct { uint32_t bg_color; -} ul_theme_bar_indicator; +} bb_theme_bar_indicator; /* Progress bar theme */ typedef struct { lv_coord_t border_width; uint32_t border_color; lv_coord_t corner_radius; - ul_theme_bar_indicator indicator; -} ul_theme_bar; + bb_theme_bar_indicator indicator; +} bb_theme_bar; /* Full theme */ typedef struct { char *name; - ul_theme_window window; - ul_theme_header header; - ul_theme_keyboard keyboard; - ul_theme_button button; - ul_theme_textarea textarea; - ul_theme_dropdown dropdown; - ul_theme_label label; - ul_theme_msgbox msgbox; - ul_theme_bar bar; + bb_theme_window window; + bb_theme_header header; + bb_theme_keyboard keyboard; + bb_theme_button button; + bb_theme_textarea textarea; + bb_theme_dropdown dropdown; + bb_theme_label label; + bb_theme_msgbox msgbox; + bb_theme_bar bar; } ul_theme; /** @@ -179,13 +179,13 @@ typedef struct { * * @param keyboard keyboard widget */ -void ul_theme_prepare_keyboard(lv_obj_t *keyboard); +void bb_theme_prepare_keyboard(lv_obj_t *keyboard); /** * Apply a UI theme. * * @param theme the theme to apply */ -void ul_theme_apply(const ul_theme *theme); +void bb_theme_apply(const ul_theme *theme); -#endif /* UL_THEME_H */ +#endif /* BB_THEME_H */ diff --git a/unl0kr/themes.c b/shared/themes.c similarity index 96% rename from unl0kr/themes.c rename to shared/themes.c index 7d33882..d451290 100644 --- a/unl0kr/themes.c +++ b/shared/themes.c @@ -6,7 +6,7 @@ #include "themes.h" -#include "../shared/log.h" +#include "log.h" #include @@ -16,7 +16,7 @@ */ /* Breezy light (based on KDE Breeze color palette, see https://develop.kde.org/hig/style/color/default/) */ -static const ul_theme ul_themes_breezy_light = { +static const ul_theme bb_themes_breezy_light = { .name = "breezy-light", .window = { .bg_color = 0xeff0f1 @@ -174,7 +174,7 @@ static const ul_theme ul_themes_breezy_light = { /* Breezy dark (based on KDE Breeze Dark color palette, see https://develop.kde.org/hig/style/color/dark/) */ -static const ul_theme ul_themes_breezy_dark = { +static const ul_theme bb_themes_breezy_dark = { .name = "breezy-dark", .window = { .bg_color = 0x31363b @@ -331,7 +331,7 @@ static const ul_theme ul_themes_breezy_dark = { }; /* pmOS light (based on palette https://coolors.co/009900-395e66-db504a-e3b505-ebf5ee) */ -static const ul_theme ul_themes_pmos_light = { +static const ul_theme bb_themes_pmos_light = { .name = "pmos-light", .window = { .bg_color = 0xf2f7f8, @@ -488,7 +488,7 @@ static const ul_theme ul_themes_pmos_light = { }; /* pmOS dark (based on palette https://coolors.co/009900-395e66-db504a-e3b505-ebf5ee) */ -static const ul_theme ul_themes_pmos_dark = { +static const ul_theme bb_themes_pmos_dark = { .name = "pmos-dark", .window = { .bg_color = 0x070c0d @@ -648,21 +648,21 @@ static const ul_theme ul_themes_pmos_dark = { * Public interface */ -const int ul_themes_num_themes = 4; -const ul_theme *ul_themes_themes[] = { - &ul_themes_breezy_light, - &ul_themes_breezy_dark, - &ul_themes_pmos_light, - &ul_themes_pmos_dark +const int bb_themes_num_themes = 4; +const ul_theme *bb_themes_themes[] = { + &bb_themes_breezy_light, + &bb_themes_breezy_dark, + &bb_themes_pmos_light, + &bb_themes_pmos_dark }; -ul_themes_theme_id_t ul_themes_find_theme_with_name(const char *name) { - for (int i = 0; i < ul_themes_num_themes; ++i) { - if (strcmp(ul_themes_themes[i]->name, name) == 0) { +bb_themes_theme_id_t bb_themes_find_theme_with_name(const char *name) { + for (int i = 0; i < bb_themes_num_themes; ++i) { + if (strcmp(bb_themes_themes[i]->name, name) == 0) { bb_log(BB_LOG_LEVEL_VERBOSE, "Found theme: %s\n", name); return i; } } bb_log(BB_LOG_LEVEL_WARNING, "Theme %s not found\n", name); - return UL_THEMES_THEME_NONE; + return BB_THEMES_THEME_NONE; } diff --git a/shared/themes.h b/shared/themes.h new file mode 100644 index 0000000..957bf7c --- /dev/null +++ b/shared/themes.h @@ -0,0 +1,33 @@ +/** + * Copyright 2021 Johannes Marbach + * SPDX-License-Identifier: GPL-3.0-or-later + */ + + +#ifndef BB_THEMES_H +#define BB_THEMES_H + +#include "theme.h" + +/* Theme IDs, values can be used as indexes into the bb_themes_themes array */ +typedef enum { + BB_THEMES_THEME_NONE = -1, + BB_THEMES_THEME_BREEZY_LIGHT = 0, + BB_THEMES_THEME_BREEZY_DARK = 1, + BB_THEMES_THEME_PMOS_LIGHT = 2, + BB_THEMES_THEME_PMOS_DARK = 3 +} bb_themes_theme_id_t; + +/* Themes */ +extern const int bb_themes_num_themes; +extern const ul_theme *bb_themes_themes[]; + +/** + * Find the first theme with a given name. + * + * @param name theme name + * @return ID of the first matching theme or BB_THEMES_THEME_NONE if no theme matched + */ +bb_themes_theme_id_t bb_themes_find_theme_with_name(const char *name); + +#endif /* BB_THEMES_H */ diff --git a/squeek2lvgl/sq2lv.h b/squeek2lvgl/sq2lv.h index 6ea6c4c..e85b87b 100644 --- a/squeek2lvgl/sq2lv.h +++ b/squeek2lvgl/sq2lv.h @@ -9,6 +9,11 @@ #include "../sq2lv_layouts.h" +/* Key attributes */ +#define SQ2LV_CTRL_NON_CHAR (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKED) +#define SQ2LV_CTRL_MOD_ACTIVE (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKABLE) +#define SQ2LV_CTRL_MOD_INACTIVE (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKABLE | LV_BUTTONMATRIX_CTRL_CHECKED) + /** * Find the first layout with a given short name. * diff --git a/squeek2lvgl/squeek2lvgl.py b/squeek2lvgl/squeek2lvgl.py index 8595483..a66d5fa 100644 --- a/squeek2lvgl/squeek2lvgl.py +++ b/squeek2lvgl/squeek2lvgl.py @@ -712,6 +712,7 @@ if __name__ == '__main__': c_builder = SourceFileBuilder() c_builder.add_include(outfile_h) + c_builder.add_include('../squeek2lvgl/sq2lv.h') if args.generate_scancodes: c_builder.add_system_include('linux/input.h') c_builder.add_line() @@ -725,11 +726,6 @@ if __name__ == '__main__': h_builder.add_line() h_builder.add_line(f'#define SQ2LV_SCANCODES_ENABLED {1 if args.generate_scancodes else 0}') h_builder.add_line() - h_builder.add_subsection_comment('Key attributes') - h_builder.add_line('#define SQ2LV_CTRL_NON_CHAR (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKED)') - h_builder.add_line('#define SQ2LV_CTRL_MOD_ACTIVE (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKABLE)') - h_builder.add_line('#define SQ2LV_CTRL_MOD_INACTIVE (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKABLE | LV_BUTTONMATRIX_CTRL_CHECKED)') - h_builder.add_line() layouts = [] unique_scancodes = {} diff --git a/unl0kr/command_line.c b/unl0kr/command_line.c index 356953b..b1ecf0d 100644 --- a/unl0kr/command_line.c +++ b/unl0kr/command_line.c @@ -92,7 +92,7 @@ void ul_cli_parse_opts(int argc, char *argv[], ul_cli_opts *opts) { int opt, index = 0; - while ((opt = getopt_long(argc, argv, "c:C:g:d:hvV", long_opts, &index)) != -1) { + while ((opt = getopt_long(argc, argv, "C:g:d:hvV", long_opts, &index)) != -1) { switch (opt) { case 'C': opts->config_files = realloc(opts->config_files, (opts->num_config_files + 1) * sizeof(char *)); diff --git a/unl0kr/config.c b/unl0kr/config.c index 712732e..ea81ddc 100644 --- a/unl0kr/config.c +++ b/unl0kr/config.c @@ -189,14 +189,14 @@ static int parsing_handler(void* user_data, const char* section, const char* key } } else if (strcmp(section, "theme") == 0) { if (strcmp(key, "default") == 0) { - ul_themes_theme_id_t id = ul_themes_find_theme_with_name(value); - if (id != UL_THEMES_THEME_NONE) { + bb_themes_theme_id_t id = bb_themes_find_theme_with_name(value); + if (id != BB_THEMES_THEME_NONE) { opts->theme.default_id = id; return 1; } } else if (strcmp(key, "alternate") == 0) { - ul_themes_theme_id_t id = ul_themes_find_theme_with_name(value); - if (id != UL_THEMES_THEME_NONE) { + bb_themes_theme_id_t id = bb_themes_find_theme_with_name(value); + if (id != BB_THEMES_THEME_NONE) { opts->theme.alternate_id = id; return 1; } @@ -263,8 +263,8 @@ void ul_config_init_opts(ul_config_opts *opts) { opts->keyboard.popovers = true; opts->textarea.obscured = true; opts->textarea.bullet = LV_SYMBOL_BULLET; - opts->theme.default_id = UL_THEMES_THEME_BREEZY_DARK; - opts->theme.alternate_id = UL_THEMES_THEME_BREEZY_LIGHT; + opts->theme.default_id = BB_THEMES_THEME_BREEZY_DARK; + opts->theme.alternate_id = BB_THEMES_THEME_BREEZY_LIGHT; opts->input.keyboard = true; opts->input.pointer = true; opts->input.touchscreen = true; diff --git a/unl0kr/config.h b/unl0kr/config.h index 3ec5eab..30a251e 100644 --- a/unl0kr/config.h +++ b/unl0kr/config.h @@ -9,7 +9,7 @@ #include "backends.h" -#include "themes.h" +#include "../shared/themes.h" #include "sq2lv_layouts.h" @@ -55,9 +55,9 @@ typedef struct { */ typedef struct { /* Default theme */ - ul_themes_theme_id_t default_id; + bb_themes_theme_id_t default_id; /* Alternate theme */ - ul_themes_theme_id_t alternate_id; + bb_themes_theme_id_t alternate_id; } ul_config_opts_theme; /** diff --git a/unl0kr/main.c b/unl0kr/main.c index c586795..5613f42 100644 --- a/unl0kr/main.c +++ b/unl0kr/main.c @@ -9,11 +9,11 @@ #include "config.h" #include "unl0kr.h" #include "terminal.h" -#include "theme.h" -#include "themes.h" #include "../shared/indev.h" #include "../shared/log.h" +#include "../shared/theme.h" +#include "../shared/themes.h" #include "../squeek2lvgl/sq2lv.h" #include "lvgl/lvgl.h" @@ -220,11 +220,11 @@ static void toggle_theme(void) { } static void set_theme(bool is_alternate) { - ul_theme_apply(get_theme(is_alternate)); + bb_theme_apply(get_theme(is_alternate)); } static const ul_theme * get_theme(bool is_alternate) { - return ul_themes_themes[is_alternate ? conf_opts.theme.alternate_id : conf_opts.theme.default_id]; + return bb_themes_themes[is_alternate ? conf_opts.theme.alternate_id : conf_opts.theme.default_id]; } static void toggle_pw_btn_clicked_cb(lv_event_t *event) { @@ -462,7 +462,7 @@ int main(int argc, char *argv[]) { /* Header flexbox */ lv_obj_t *header = lv_obj_create(container); - lv_obj_add_flag(header, UL_WIDGET_HEADER); + lv_obj_add_flag(header, BB_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_flex_align(header, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); @@ -561,7 +561,7 @@ int main(int argc, char *argv[]) { lv_obj_add_event_cb(keyboard, keyboard_ready_cb, LV_EVENT_READY, NULL); lv_obj_set_pos(keyboard, 0, is_keyboard_hidden ? keyboard_height : 0); lv_obj_set_size(keyboard, hor_res, keyboard_height); - ul_theme_prepare_keyboard(keyboard); + bb_theme_prepare_keyboard(keyboard); /* Apply textarea options */ set_password_obscured(conf_opts.textarea.obscured); diff --git a/unl0kr/meson.build b/unl0kr/meson.build index 4e0de61..31ea46f 100644 --- a/unl0kr/meson.build +++ b/unl0kr/meson.build @@ -20,14 +20,14 @@ unl0kr_sources = [ 'main.c', 'sq2lv_layouts.c', 'terminal.c', - 'theme.c', - 'themes.c', ] shared_sources = [ '../shared/cursor/cursor.c', '../shared/indev.c', '../shared/log.c', + '../shared/theme.c', + '../shared/themes.c', ] squeek2lvgl_sources = [ diff --git a/unl0kr/sq2lv_layouts.c b/unl0kr/sq2lv_layouts.c index 6bb83c0..fb3c2e3 100644 --- a/unl0kr/sq2lv_layouts.c +++ b/unl0kr/sq2lv_layouts.c @@ -3,6 +3,7 @@ **/ #include "sq2lv_layouts.h" +#include "../squeek2lvgl/sq2lv.h" #define SQ2LV_SYMBOL_SHIFT "\xef\x8d\x9b" diff --git a/unl0kr/sq2lv_layouts.h b/unl0kr/sq2lv_layouts.h index 2d77ee2..b9b75c0 100644 --- a/unl0kr/sq2lv_layouts.h +++ b/unl0kr/sq2lv_layouts.h @@ -9,11 +9,6 @@ #define SQ2LV_SCANCODES_ENABLED 0 -/* Key attributes */ -#define SQ2LV_CTRL_NON_CHAR (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKED) -#define SQ2LV_CTRL_MOD_ACTIVE (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKABLE) -#define SQ2LV_CTRL_MOD_INACTIVE (LV_BUTTONMATRIX_CTRL_CLICK_TRIG | LV_BUTTONMATRIX_CTRL_CHECKABLE | LV_BUTTONMATRIX_CTRL_CHECKED) - /* Layout IDs, values can be used as indexes into the sq2lv_layouts array */ typedef enum { SQ2LV_LAYOUT_NONE = -1, diff --git a/unl0kr/themes.h b/unl0kr/themes.h deleted file mode 100644 index 0502d09..0000000 --- a/unl0kr/themes.h +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Copyright 2021 Johannes Marbach - * SPDX-License-Identifier: GPL-3.0-or-later - */ - - -#ifndef UL_THEMES_H -#define UL_THEMES_H - -#include "theme.h" - -/* Theme IDs, values can be used as indexes into the ul_themes_themes array */ -typedef enum { - UL_THEMES_THEME_NONE = -1, - UL_THEMES_THEME_BREEZY_LIGHT = 0, - UL_THEMES_THEME_BREEZY_DARK = 1, - UL_THEMES_THEME_PMOS_LIGHT = 2, - UL_THEMES_THEME_PMOS_DARK = 3 -} ul_themes_theme_id_t; - -/* Themes */ -extern const int ul_themes_num_themes; -extern const ul_theme *ul_themes_themes[]; - -/** - * Find the first theme with a given name. - * - * @param name theme name - * @return ID of the first matching theme or UL_THEMES_THEME_NONE if no theme matched - */ -ul_themes_theme_id_t ul_themes_find_theme_with_name(const char *name); - -#endif /* UL_THEMES_H */