Add themes and fbdev force-refresh quirk via config

This commit is contained in:
Johannes Marbach
2024-03-30 08:06:29 +01:00
parent a4a4734317
commit 2987305546
29 changed files with 636 additions and 287 deletions

View File

@@ -10,6 +10,8 @@ If a change only affects particular applications, they are listed in parentheses
## Unreleased ## 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 - feat(buffyboard): Handle input device connection/disconnection at runtime; adds new dependency libudev
## 3.0.0 (2024-03-22) ## 3.0.0 (2024-03-22)

View File

@@ -29,6 +29,7 @@ For a growing collection of demo videos, see the [wiki].
## Dependencies ## Dependencies
- [inih]
- [lvgl] (git submodule / linked statically) - [lvgl] (git submodule / linked statically)
- [squeek2lvgl] (git submodule / linked statically) - [squeek2lvgl] (git submodule / linked statically)
- [libinput] - [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 [OpenSans]: https://fonts.google.com/specimen/Open+Sans
[arrow-alt-circle-up]: https://fontawesome.com/v5.15/icons/arrow-alt-circle-up?style=solid [arrow-alt-circle-up]: https://fontawesome.com/v5.15/icons/arrow-alt-circle-up?style=solid
[fbkeyboard]: https://github.com/bakonyiferenc/fbkeyboard [fbkeyboard]: https://github.com/bakonyiferenc/fbkeyboard
[inih]: https://github.com/benhoyt/inih
[libinput]: https://gitlab.freedesktop.org/libinput/libinput [libinput]: https://gitlab.freedesktop.org/libinput/libinput
[libudev]: https://github.com/systemd/systemd/tree/main/src/libudev [libudev]: https://github.com/systemd/systemd/tree/main/src/libudev
[lv_port_linux_frame_buffer]: https://github.com/lvgl/lv_port_linux_frame_buffer [lv_port_linux_frame_buffer]: https://github.com/lvgl/lv_port_linux_frame_buffer

View File

@@ -0,0 +1,5 @@
[general]
theme=breezy-light
#[quirks]
#fbdev_force_refresh=true

View File

@@ -13,11 +13,4 @@
#define BB_VERSION "?" /* Just to silence IDE warning. Real version injected by meson during build. */ #define BB_VERSION "?" /* Just to silence IDE warning. Real version injected by meson during build. */
#endif #endif
/**
* Fonts
*/
LV_FONT_DECLARE(font_32);
#endif /* BB_BUFFYBOARD_H */ #endif /* BB_BUFFYBOARD_H */

View File

@@ -8,6 +8,8 @@
#include "buffyboard.h" #include "buffyboard.h"
#include "../shared/log.h"
#include <getopt.h> #include <getopt.h>
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@@ -44,13 +46,19 @@ static void print_usage() {
"Usage: buffyboard [OPTION]\n" "Usage: buffyboard [OPTION]\n"
"\n" "\n"
"Mandatory arguments to long options are mandatory for short options too.\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" " -C, --config-override Path to a config override file. Can be supplied\n"
" 0 - normal orientation (0 degree)\n" " multiple times. Config files are merged in the\n"
" 1 - clockwise orientation (90 degrees)\n" " following order:\n"
" 2 - upside down orientation (180 degrees)\n" " * /etc/buffyboard.conf\n"
" 3 - counterclockwise orientation (270 degrees)\n" " * /etc/buffyboard.conf.d/* (alphabetically)\n"
" The values match the ones provided by the kernel in\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" " /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" " -h, --help Print this message and exit\n"
" -V, --version Print the buffyboard version and exit\n"); " -V, --version Print the buffyboard version and exit\n");
/*-------------------------------- 78 CHARS --------------------------------*/ /*-------------------------------- 78 CHARS --------------------------------*/
@@ -65,6 +73,7 @@ void bb_cli_parse_opts(int argc, char *argv[], bb_cli_opts *opts) {
init_opts(opts); init_opts(opts);
struct option long_opts[] = { struct option long_opts[] = {
{ "config-override", required_argument, NULL, 'C' },
{ "rotate", required_argument, NULL, 'r' }, { "rotate", required_argument, NULL, 'r' },
{ "help", no_argument, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, 'V' }, { "version", no_argument, NULL, 'V' },
@@ -73,8 +82,17 @@ void bb_cli_parse_opts(int argc, char *argv[], bb_cli_opts *opts) {
int opt, index = 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) { 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': { case 'r': {
int orientation; int orientation;
if (sscanf(optarg, "%i", &orientation) != 1 || orientation < 0 || orientation > 3) { if (sscanf(optarg, "%i", &orientation) != 1 || orientation < 0 || orientation > 3) {

View File

@@ -13,6 +13,10 @@
* Options parsed from command line arguments * Options parsed from command line arguments
*/ */
typedef struct { typedef struct {
/* Number of config files */
int num_config_files;
/* Paths of config file */
const char **config_files;
/* Display rotation */ /* Display rotation */
lv_display_rotation_t rotation; lv_display_rotation_t rotation;
} bb_cli_opts; } bb_cli_opts;

218
buffyboard/config.c Normal file
View File

@@ -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 <dirent.h>
#include <ini.h>
#include <stdlib.h>
#include <string.h>
/**
* 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);
}
}

72
buffyboard/config.h Normal file
View File

@@ -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 */

View File

@@ -1,7 +1,7 @@
/******************************************************************************* /*******************************************************************************
* Size: 32 px * Size: 32 px
* Bpp: 4 * 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 #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, 0x8, 0xef, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x80, 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 "" */ /* U+F043 "" */
0x0, 0x0, 0x0, 0x0, 0x4, 0xee, 0x40, 0x0, 0x0, 0x0, 0x0, 0x0, 0x4, 0xee, 0x40, 0x0,
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0xd, 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 = 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 = 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 = 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 = 90044, .adv_w = 512, .box_w = 32, .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 = 90556, .adv_w = 352, .box_w = 22, .box_h = 32, .ofs_x = 0, .ofs_y = -4},
{.bitmap_index = 90696, .adv_w = 448, .box_w = 28, .box_h = 34, .ofs_x = 0, .ofs_y = -5}, {.bitmap_index = 90908, .adv_w = 448, .box_w = 20, .box_h = 30, .ofs_x = 4, .ofs_y = -3},
{.bitmap_index = 91172, .adv_w = 448, .box_w = 28, .box_h = 29, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 91208, .adv_w = 448, .box_w = 28, .box_h = 34, .ofs_x = 0, .ofs_y = -5},
{.bitmap_index = 91578, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 91684, .adv_w = 448, .box_w = 28, .box_h = 29, .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 = 92090, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 92270, .adv_w = 448, .box_w = 30, .box_h = 28, .ofs_x = -1, .ofs_y = -2}, {.bitmap_index = 92482, .adv_w = 448, .box_w = 20, .box_h = 30, .ofs_x = 4, .ofs_y = -3},
{.bitmap_index = 92690, .adv_w = 320, .box_w = 18, .box_h = 28, .ofs_x = 1, .ofs_y = -2}, {.bitmap_index = 92782, .adv_w = 448, .box_w = 30, .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 = 93202, .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 = 93454, .adv_w = 320, .box_w = 18, .box_h = 28, .ofs_x = 1, .ofs_y = -2},
{.bitmap_index = 93586, .adv_w = 448, .box_w = 28, .box_h = 6, .ofs_x = 0, .ofs_y = 9}, {.bitmap_index = 93706, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 93670, .adv_w = 576, .box_w = 36, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 94098, .adv_w = 448, .box_w = 28, .box_h = 6, .ofs_x = 0, .ofs_y = 9},
{.bitmap_index = 94102, .adv_w = 640, .box_w = 40, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, {.bitmap_index = 94182, .adv_w = 576, .box_w = 36, .box_h = 24, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 94742, .adv_w = 576, .box_w = 38, .box_h = 32, .ofs_x = -1, .ofs_y = -4}, {.bitmap_index = 94614, .adv_w = 640, .box_w = 40, .box_h = 32, .ofs_x = 0, .ofs_y = -4},
{.bitmap_index = 95350, .adv_w = 512, .box_w = 32, .box_h = 30, .ofs_x = 0, .ofs_y = -3}, {.bitmap_index = 95254, .adv_w = 576, .box_w = 38, .box_h = 32, .ofs_x = -1, .ofs_y = -4},
{.bitmap_index = 95830, .adv_w = 448, .box_w = 28, .box_h = 18, .ofs_x = 0, .ofs_y = 3}, {.bitmap_index = 95862, .adv_w = 512, .box_w = 32, .box_h = 30, .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 = 96342, .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 = 96594, .adv_w = 448, .box_w = 28, .box_h = 18, .ofs_x = 0, .ofs_y = 3},
{.bitmap_index = 96854, .adv_w = 512, .box_w = 32, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 96846, .adv_w = 640, .box_w = 40, .box_h = 26, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 97238, .adv_w = 512, .box_w = 32, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, {.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 = 33, .box_h = 33, .ofs_x = -1, .ofs_y = -4}, {.bitmap_index = 97750, .adv_w = 512, .box_w = 32, .box_h = 32, .ofs_x = 0, .ofs_y = -4},
{.bitmap_index = 98295, .adv_w = 448, .box_w = 29, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 98262, .adv_w = 512, .box_w = 33, .box_h = 33, .ofs_x = -1, .ofs_y = -4},
{.bitmap_index = 98701, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, {.bitmap_index = 98807, .adv_w = 448, .box_w = 29, .box_h = 28, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 99149, .adv_w = 448, .box_w = 28, .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 = 99541, .adv_w = 448, .box_w = 28, .box_h = 26, .ofs_x = 0, .ofs_y = -1}, {.bitmap_index = 99661, .adv_w = 448, .box_w = 28, .box_h = 28, .ofs_x = 0, .ofs_y = -2},
{.bitmap_index = 99905, .adv_w = 512, .box_w = 32, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 100053, .adv_w = 448, .box_w = 28, .box_h = 26, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 100289, .adv_w = 320, .box_w = 22, .box_h = 32, .ofs_x = -1, .ofs_y = -4}, {.bitmap_index = 100417, .adv_w = 512, .box_w = 32, .box_h = 24, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 100641, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, {.bitmap_index = 100801, .adv_w = 320, .box_w = 22, .box_h = 32, .ofs_x = -1, .ofs_y = -4},
{.bitmap_index = 101089, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, {.bitmap_index = 101153, .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 = 101601, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4},
{.bitmap_index = 101969, .adv_w = 512, .box_w = 34, .box_h = 34, .ofs_x = -1, .ofs_y = -5}, {.bitmap_index = 102049, .adv_w = 576, .box_w = 36, .box_h = 24, .ofs_x = 0, .ofs_y = 0},
{.bitmap_index = 102547, .adv_w = 384, .box_w = 24, .box_h = 28, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 102481, .adv_w = 512, .box_w = 34, .box_h = 34, .ofs_x = -1, .ofs_y = -5},
{.bitmap_index = 102883, .adv_w = 640, .box_w = 40, .box_h = 29, .ofs_x = 0, .ofs_y = -2}, {.bitmap_index = 103059, .adv_w = 384, .box_w = 24, .box_h = 28, .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 = 103395, .adv_w = 640, .box_w = 40, .box_h = 29, .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 = 103975, .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 = 104375, .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 = 104775, .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 = 105175, .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 = 105575, .adv_w = 640, .box_w = 40, .box_h = 20, .ofs_x = 0, .ofs_y = 2},
{.bitmap_index = 105996, .adv_w = 448, .box_w = 24, .box_h = 32, .ofs_x = 2, .ofs_y = -4}, {.bitmap_index = 105975, .adv_w = 640, .box_w = 41, .box_h = 26, .ofs_x = 0, .ofs_y = -1},
{.bitmap_index = 106380, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4}, {.bitmap_index = 106508, .adv_w = 448, .box_w = 24, .box_h = 32, .ofs_x = 2, .ofs_y = -4},
{.bitmap_index = 106828, .adv_w = 512, .box_w = 33, .box_h = 33, .ofs_x = -1, .ofs_y = -5}, {.bitmap_index = 106892, .adv_w = 448, .box_w = 28, .box_h = 32, .ofs_x = 0, .ofs_y = -4},
{.bitmap_index = 107373, .adv_w = 512, .box_w = 32, .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 = 640, .box_w = 40, .box_h = 24, .ofs_x = 0, .ofs_y = 0}, {.bitmap_index = 107885, .adv_w = 512, .box_w = 32, .box_h = 32, .ofs_x = 0, .ofs_y = -4},
{.bitmap_index = 108365, .adv_w = 384, .box_w = 24, .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 = 108749, .adv_w = 515, .box_w = 33, .box_h = 21, .ofs_x = 0, .ofs_y = 2} {.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, 0x1cd9, 0x1cda, 0x1cdb, 0x1e31, 0x1e35, 0x1e3e, 0x1e40, 0x1e41,
0x1e44, 0x1e49, 0x1e4d, 0x1e5a, 0x1e77, 0x1e8f, 0x1e93, 0x1e94, 0x1e44, 0x1e49, 0x1e4d, 0x1e5a, 0x1e77, 0x1e8f, 0x1e93, 0x1e94,
0xec30, 0xec37, 0xec3a, 0xec3b, 0xec3c, 0xec40, 0xec42, 0xec44, 0xec30, 0xec37, 0xec3a, 0xec3b, 0xec3c, 0xec40, 0xec42, 0xec44,
0xec48, 0xec4b, 0xec50, 0xec55, 0xec56, 0xec57, 0xec6d, 0xec72, 0xec48, 0xec4b, 0xec50, 0xec55, 0xec56, 0xec57, 0xec6d, 0xec71,
0xec77, 0xec7a, 0xec7b, 0xec7c, 0xec80, 0xec81, 0xec82, 0xec83, 0xec72, 0xec77, 0xec7a, 0xec7b, 0xec7c, 0xec80, 0xec81, 0xec82,
0xec96, 0xec97, 0xec9d, 0xec9f, 0xeca0, 0xeca3, 0xeca6, 0xeca7, 0xec83, 0xec96, 0xec97, 0xec9d, 0xec9f, 0xeca0, 0xeca3, 0xeca6,
0xeca8, 0xecaa, 0xecc2, 0xecc4, 0xecf3, 0xecf4, 0xecf6, 0xecf8, 0xeca7, 0xeca8, 0xecaa, 0xecc2, 0xecc4, 0xecf3, 0xecf4, 0xecf6,
0xed0f, 0xed16, 0xed19, 0xed22, 0xed4b, 0xed53, 0xed87, 0xee1a, 0xecf8, 0xed0f, 0xed16, 0xed19, 0xed22, 0xed4b, 0xed53, 0xed87,
0xee6f, 0xee70, 0xee71, 0xee72, 0xee73, 0xeeb6, 0xeec2, 0xef1c, 0xee1a, 0xee6f, 0xee70, 0xee71, 0xee72, 0xee73, 0xeeb6, 0xeec2,
0xef33, 0xef8a, 0xf189, 0xf3f1, 0xf4d1 0xef1c, 0xef33, 0xef8a, 0xf189, 0xf3f1, 0xf4d1
}; };
/*Collect the unicode lists and glyph_id offsets*/ /*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, .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) #if LV_VERSION_CHECK(8, 0, 0)
const lv_font_t font_32 = { const lv_font_t font_32 = {
#else #else
lv_font_t font_32 = { const lv_font_t font_32 = {
#endif #endif
.get_glyph_dsc = lv_font_get_glyph_dsc_fmt_txt, /*Function pointer to get glyph's data*/ .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*/ .get_glyph_bitmap = lv_font_get_bitmap_fmt_txt, /*Function pointer to get glyph's bitmap*/

View File

@@ -392,10 +392,10 @@ e.g. "stm32f769xx.h" or "stm32f429xx.h"*/
/*Optionally declare custom fonts here. /*Optionally declare custom fonts here.
*You can use these fonts as default font too and they will be available globally. *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)*/ *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*/ /*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. /*Enable handling large font and/or fonts with a lot of characters.
*The limit depends on the font size, font face and bpp. *The limit depends on the font size, font face and bpp.

View File

@@ -6,6 +6,7 @@
#include "buffyboard.h" #include "buffyboard.h"
#include "command_line.h" #include "command_line.h"
#include "config.h"
#include "sq2lv_layouts.h" #include "sq2lv_layouts.h"
#include "terminal.h" #include "terminal.h"
#include "uinput_device.h" #include "uinput_device.h"
@@ -13,6 +14,8 @@
#include "lvgl/lvgl.h" #include "lvgl/lvgl.h"
#include "../shared/indev.h" #include "../shared/indev.h"
#include "../shared/theme.h"
#include "../shared/themes.h"
#include "../squeek2lvgl/sq2lv.h" #include "../squeek2lvgl/sq2lv.h"
#include <limits.h> #include <limits.h>
@@ -29,10 +32,10 @@
*/ */
bb_cli_opts cli_opts; bb_cli_opts cli_opts;
bb_config_opts conf_opts;
static bool resize_terminals = false; static bool resize_terminals = false;
static lv_obj_t *keyboard = NULL; 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); 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. * 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) { static void keyboard_value_changed_cb(lv_event_t *event) {
lv_obj_t *kb = lv_event_get_target(event); lv_obj_t *kb = lv_event_get_target(event);
@@ -233,6 +180,12 @@ int main(int argc, char *argv[]) {
/* Parse command line options */ /* Parse command line options */
bb_cli_parse_opts(argc, argv, &cli_opts); 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 */ /* Prepare for terminal resizing and reset */
resize_terminals = bb_terminal_init(2.0f / 3.0f); resize_terminals = bb_terminal_init(2.0f / 3.0f);
if (resize_terminals) { if (resize_terminals) {
@@ -258,6 +211,9 @@ int main(int argc, char *argv[]) {
/* Initialise display */ /* Initialise display */
lv_display_t *disp = lv_linux_fbdev_create(); lv_display_t *disp = lv_linux_fbdev_create();
lv_linux_fbdev_set_file(disp, "/dev/fb0"); 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 hor_res_phys = lv_display_get_horizontal_resolution(disp);
int32_t ver_res_phys = lv_display_get_vertical_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); 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 */ /* Start input device monitor and auto-connect available devices */
bb_indev_start_monitor_and_autoconnect(false, true, true); bb_indev_start_monitor_and_autoconnect(false, true, true);
/* Initialise theme and styles */ /* Initialise theme */
set_theme(true); bb_theme_apply(bb_themes_themes[conf_opts.general.theme_id]);
lv_style_init(&style_text_normal);
lv_style_set_text_font(&style_text_normal, &font_32);
/* Add keyboard */ /* Add keyboard */
keyboard = lv_keyboard_create(lv_scr_act()); 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_pos(keyboard, 0, 0);
lv_obj_set_size(keyboard, LV_HOR_RES, LV_VER_RES); lv_obj_set_size(keyboard, LV_HOR_RES, LV_VER_RES);
lv_obj_add_style(keyboard, &style_text_normal, 0); bb_theme_prepare_keyboard(keyboard);
/* 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);
/* Apply default keyboard layout */ /* Apply default keyboard layout */
sq2lv_switch_layout(keyboard, SQ2LV_LAYOUT_TERMINAL_US); sq2lv_switch_layout(keyboard, SQ2LV_LAYOUT_TERMINAL_US);
@@ -306,10 +261,9 @@ int main(int argc, char *argv[]) {
/* Start timer for periodically resizing terminals */ /* Start timer for periodically resizing terminals */
lv_timer_create(terminal_resize_timer_cb, 1000, NULL); lv_timer_create(terminal_resize_timer_cb, 1000, NULL);
/* Run lvgl in "tickless" mode */ /* Periodically run timer / task handler */
while(1) { while(1) {
lv_task_handler(); lv_timer_periodic_handler();
usleep(5000);
} }
return 0; return 0;

View File

@@ -14,6 +14,7 @@ add_project_arguments('-DBB_VERSION="@0@"'.format(meson.project_version()), lang
buffyboard_sources = [ buffyboard_sources = [
'command_line.c', 'command_line.c',
'config.c',
'font_32.c', 'font_32.c',
'main.c', 'main.c',
'sq2lv_layouts.c', 'sq2lv_layouts.c',
@@ -25,6 +26,8 @@ shared_sources = [
'../shared/cursor/cursor.c', '../shared/cursor/cursor.c',
'../shared/indev.c', '../shared/indev.c',
'../shared/log.c', '../shared/log.c',
'../shared/theme.c',
'../shared/themes.c',
] ]
squeek2lvgl_sources = [ squeek2lvgl_sources = [
@@ -38,6 +41,7 @@ executable(
sources: buffyboard_sources + shared_sources + squeek2lvgl_sources + lvgl_sources, sources: buffyboard_sources + shared_sources + squeek2lvgl_sources + lvgl_sources,
include_directories: ['..'], include_directories: ['..'],
dependencies: [ dependencies: [
dependency('inih'),
dependency('libinput'), dependency('libinput'),
dependency('libudev'), dependency('libudev'),
meson.get_compiler('c').find_library('m', required: false), meson.get_compiler('c').find_library('m', required: false),

19
buffyboard/regenerate-fonts.sh Executable file
View File

@@ -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'

View File

@@ -3,6 +3,7 @@
**/ **/
#include "sq2lv_layouts.h" #include "sq2lv_layouts.h"
#include "../squeek2lvgl/sq2lv.h"
#include <linux/input.h> #include <linux/input.h>
#define SQ2LV_SYMBOL_SHIFT "\xef\x8d\x9b" #define SQ2LV_SYMBOL_SHIFT "\xef\x8d\x9b"

View File

@@ -9,11 +9,6 @@
#define SQ2LV_SCANCODES_ENABLED 1 #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 */ /* Layout IDs, values can be used as indexes into the sq2lv_layouts array */
typedef enum { typedef enum {
SQ2LV_LAYOUT_NONE = -1, SQ2LV_LAYOUT_NONE = -1,

View File

@@ -6,10 +6,8 @@
#include "theme.h" #include "theme.h"
#include "sq2lv_layouts.h" #include "log.h"
#include "unl0kr.h" #include "../squeek2lvgl/sq2lv.h"
#include "../shared/log.h"
#include "lvgl/lvgl.h" #include "lvgl/lvgl.h"
@@ -238,7 +236,7 @@ static void apply_theme_cb(lv_theme_t *theme, lv_obj_t *obj) {
return; 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); lv_obj_add_style(obj, &(styles.header), 0);
return; return;
} }
@@ -331,7 +329,7 @@ static void keyboard_draw_task_added_cb(lv_event_t *event) {
return; 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) { if ((btnm->ctrl_bits[dsc->id1] & SQ2LV_CTRL_MOD_INACTIVE) == SQ2LV_CTRL_MOD_INACTIVE) {
key = &(current_theme.keyboard.keys.key_mod_inact); 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 * 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_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); 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) { if (!theme) {
bb_log(BB_LOG_LEVEL_ERROR, "Could not apply theme from NULL pointer"); bb_log(BB_LOG_LEVEL_ERROR, "Could not apply theme from NULL pointer");
return; return;

View File

@@ -4,15 +4,15 @@
*/ */
#ifndef UL_THEME_H #ifndef BB_THEME_H
#define UL_THEME_H #define BB_THEME_H
#include "lvgl/lvgl.h" #include "lvgl/lvgl.h"
#include <stdbool.h> #include <stdbool.h>
#include <stdint.h> #include <stdint.h>
#define UL_WIDGET_HEADER LV_OBJ_FLAG_USER_1 #define BB_WIDGET_HEADER LV_OBJ_FLAG_USER_1
/** /**
* Theming structs * Theming structs
@@ -21,7 +21,7 @@
/* Window theme */ /* Window theme */
typedef struct { typedef struct {
uint32_t bg_color; uint32_t bg_color;
} ul_theme_window; } bb_theme_window;
/* Header theme */ /* Header theme */
typedef struct { typedef struct {
@@ -30,30 +30,30 @@ typedef struct {
uint32_t border_color; uint32_t border_color;
lv_coord_t pad; lv_coord_t pad;
lv_coord_t gap; lv_coord_t gap;
} ul_theme_header; } bb_theme_header;
/* Key theme for one specific key type and state */ /* Key theme for one specific key type and state */
typedef struct { typedef struct {
uint32_t fg_color; uint32_t fg_color;
uint32_t bg_color; uint32_t bg_color;
uint32_t border_color; uint32_t border_color;
} ul_theme_key_state; } bb_theme_key_state;
/* Key theme for one specific key type and all states */ /* Key theme for one specific key type and all states */
typedef struct { typedef struct {
ul_theme_key_state normal; bb_theme_key_state normal;
ul_theme_key_state pressed; bb_theme_key_state pressed;
} ul_theme_key; } bb_theme_key;
/* Key theme */ /* Key theme */
typedef struct { typedef struct {
lv_coord_t border_width; lv_coord_t border_width;
lv_coord_t corner_radius; lv_coord_t corner_radius;
ul_theme_key key_char; bb_theme_key key_char;
ul_theme_key key_non_char; bb_theme_key key_non_char;
ul_theme_key key_mod_act; bb_theme_key key_mod_act;
ul_theme_key key_mod_inact; bb_theme_key key_mod_inact;
} ul_theme_keys; } bb_theme_keys;
/* Keyboard theme */ /* Keyboard theme */
typedef struct { typedef struct {
@@ -62,31 +62,31 @@ typedef struct {
uint32_t border_color; uint32_t border_color;
lv_coord_t pad; lv_coord_t pad;
lv_coord_t gap; lv_coord_t gap;
ul_theme_keys keys; bb_theme_keys keys;
} ul_theme_keyboard; } bb_theme_keyboard;
/* Button theme for one specific button state */ /* Button theme for one specific button state */
typedef struct { typedef struct {
uint32_t fg_color; uint32_t fg_color;
uint32_t bg_color; uint32_t bg_color;
uint32_t border_color; uint32_t border_color;
} ul_theme_button_state; } bb_theme_button_state;
/* Button theme */ /* Button theme */
typedef struct { typedef struct {
lv_coord_t border_width; lv_coord_t border_width;
lv_coord_t corner_radius; lv_coord_t corner_radius;
lv_coord_t pad; lv_coord_t pad;
ul_theme_button_state normal; bb_theme_button_state normal;
ul_theme_button_state pressed; bb_theme_button_state pressed;
} ul_theme_button; } bb_theme_button;
/* Text area cursor theme */ /* Text area cursor theme */
typedef struct { typedef struct {
lv_coord_t width; lv_coord_t width;
uint32_t color; uint32_t color;
int period; int period;
} ul_theme_textarea_cursor; } bb_theme_textarea_cursor;
/* Text area theme */ /* Text area theme */
typedef struct { typedef struct {
@@ -97,8 +97,8 @@ typedef struct {
lv_coord_t corner_radius; lv_coord_t corner_radius;
lv_coord_t pad; lv_coord_t pad;
uint32_t placeholder_color; uint32_t placeholder_color;
ul_theme_textarea_cursor cursor; bb_theme_textarea_cursor cursor;
} ul_theme_textarea; } bb_theme_textarea;
/* Dropdown list theme */ /* Dropdown list theme */
typedef struct { typedef struct {
@@ -110,29 +110,29 @@ typedef struct {
uint32_t border_color; uint32_t border_color;
lv_coord_t corner_radius; lv_coord_t corner_radius;
lv_coord_t pad; lv_coord_t pad;
} ul_theme_dropdown_list; } bb_theme_dropdown_list;
/* Dropdown theme */ /* Dropdown theme */
typedef struct { typedef struct {
ul_theme_button button; bb_theme_button button;
ul_theme_dropdown_list list; bb_theme_dropdown_list list;
} ul_theme_dropdown; } bb_theme_dropdown;
/* Label */ /* Label */
typedef struct { typedef struct {
uint32_t fg_color; uint32_t fg_color;
} ul_theme_label; } bb_theme_label;
/* Message box buttons theme */ /* Message box buttons theme */
typedef struct { typedef struct {
lv_coord_t gap; lv_coord_t gap;
} ul_theme_msgbox_buttons; } bb_theme_msgbox_buttons;
/* Message box dimming theme */ /* Message box dimming theme */
typedef struct { typedef struct {
uint32_t color; uint32_t color;
short opacity; short opacity;
} ul_theme_msgbox_dimming; } bb_theme_msgbox_dimming;
/* Message box theme */ /* Message box theme */
typedef struct { typedef struct {
@@ -143,35 +143,35 @@ typedef struct {
lv_coord_t corner_radius; lv_coord_t corner_radius;
lv_coord_t pad; lv_coord_t pad;
lv_coord_t gap; lv_coord_t gap;
ul_theme_msgbox_buttons buttons; bb_theme_msgbox_buttons buttons;
ul_theme_msgbox_dimming dimming; bb_theme_msgbox_dimming dimming;
} ul_theme_msgbox; } bb_theme_msgbox;
/* Progress bar indicator theme */ /* Progress bar indicator theme */
typedef struct { typedef struct {
uint32_t bg_color; uint32_t bg_color;
} ul_theme_bar_indicator; } bb_theme_bar_indicator;
/* Progress bar theme */ /* Progress bar theme */
typedef struct { typedef struct {
lv_coord_t border_width; lv_coord_t border_width;
uint32_t border_color; uint32_t border_color;
lv_coord_t corner_radius; lv_coord_t corner_radius;
ul_theme_bar_indicator indicator; bb_theme_bar_indicator indicator;
} ul_theme_bar; } bb_theme_bar;
/* Full theme */ /* Full theme */
typedef struct { typedef struct {
char *name; char *name;
ul_theme_window window; bb_theme_window window;
ul_theme_header header; bb_theme_header header;
ul_theme_keyboard keyboard; bb_theme_keyboard keyboard;
ul_theme_button button; bb_theme_button button;
ul_theme_textarea textarea; bb_theme_textarea textarea;
ul_theme_dropdown dropdown; bb_theme_dropdown dropdown;
ul_theme_label label; bb_theme_label label;
ul_theme_msgbox msgbox; bb_theme_msgbox msgbox;
ul_theme_bar bar; bb_theme_bar bar;
} ul_theme; } ul_theme;
/** /**
@@ -179,13 +179,13 @@ typedef struct {
* *
* @param keyboard keyboard widget * @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. * Apply a UI theme.
* *
* @param theme the theme to apply * @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 */

View File

@@ -6,7 +6,7 @@
#include "themes.h" #include "themes.h"
#include "../shared/log.h" #include "log.h"
#include <string.h> #include <string.h>
@@ -16,7 +16,7 @@
*/ */
/* Breezy light (based on KDE Breeze color palette, see https://develop.kde.org/hig/style/color/default/) */ /* 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", .name = "breezy-light",
.window = { .window = {
.bg_color = 0xeff0f1 .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/) */ /* 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", .name = "breezy-dark",
.window = { .window = {
.bg_color = 0x31363b .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) */ /* 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", .name = "pmos-light",
.window = { .window = {
.bg_color = 0xf2f7f8, .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) */ /* 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", .name = "pmos-dark",
.window = { .window = {
.bg_color = 0x070c0d .bg_color = 0x070c0d
@@ -648,21 +648,21 @@ static const ul_theme ul_themes_pmos_dark = {
* Public interface * Public interface
*/ */
const int ul_themes_num_themes = 4; const int bb_themes_num_themes = 4;
const ul_theme *ul_themes_themes[] = { const ul_theme *bb_themes_themes[] = {
&ul_themes_breezy_light, &bb_themes_breezy_light,
&ul_themes_breezy_dark, &bb_themes_breezy_dark,
&ul_themes_pmos_light, &bb_themes_pmos_light,
&ul_themes_pmos_dark &bb_themes_pmos_dark
}; };
ul_themes_theme_id_t ul_themes_find_theme_with_name(const char *name) { bb_themes_theme_id_t bb_themes_find_theme_with_name(const char *name) {
for (int i = 0; i < ul_themes_num_themes; ++i) { for (int i = 0; i < bb_themes_num_themes; ++i) {
if (strcmp(ul_themes_themes[i]->name, name) == 0) { if (strcmp(bb_themes_themes[i]->name, name) == 0) {
bb_log(BB_LOG_LEVEL_VERBOSE, "Found theme: %s\n", name); bb_log(BB_LOG_LEVEL_VERBOSE, "Found theme: %s\n", name);
return i; return i;
} }
} }
bb_log(BB_LOG_LEVEL_WARNING, "Theme %s not found\n", name); bb_log(BB_LOG_LEVEL_WARNING, "Theme %s not found\n", name);
return UL_THEMES_THEME_NONE; return BB_THEMES_THEME_NONE;
} }

33
shared/themes.h Normal file
View File

@@ -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 */

View File

@@ -9,6 +9,11 @@
#include "../sq2lv_layouts.h" #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. * Find the first layout with a given short name.
* *

View File

@@ -712,6 +712,7 @@ if __name__ == '__main__':
c_builder = SourceFileBuilder() c_builder = SourceFileBuilder()
c_builder.add_include(outfile_h) c_builder.add_include(outfile_h)
c_builder.add_include('../squeek2lvgl/sq2lv.h')
if args.generate_scancodes: if args.generate_scancodes:
c_builder.add_system_include('linux/input.h') c_builder.add_system_include('linux/input.h')
c_builder.add_line() c_builder.add_line()
@@ -725,11 +726,6 @@ if __name__ == '__main__':
h_builder.add_line() h_builder.add_line()
h_builder.add_line(f'#define SQ2LV_SCANCODES_ENABLED {1 if args.generate_scancodes else 0}') h_builder.add_line(f'#define SQ2LV_SCANCODES_ENABLED {1 if args.generate_scancodes else 0}')
h_builder.add_line() 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 = [] layouts = []
unique_scancodes = {} unique_scancodes = {}

View File

@@ -92,7 +92,7 @@ void ul_cli_parse_opts(int argc, char *argv[], ul_cli_opts *opts) {
int opt, index = 0; 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) { switch (opt) {
case 'C': case 'C':
opts->config_files = realloc(opts->config_files, (opts->num_config_files + 1) * sizeof(char *)); opts->config_files = realloc(opts->config_files, (opts->num_config_files + 1) * sizeof(char *));

View File

@@ -189,14 +189,14 @@ static int parsing_handler(void* user_data, const char* section, const char* key
} }
} else if (strcmp(section, "theme") == 0) { } else if (strcmp(section, "theme") == 0) {
if (strcmp(key, "default") == 0) { if (strcmp(key, "default") == 0) {
ul_themes_theme_id_t id = ul_themes_find_theme_with_name(value); bb_themes_theme_id_t id = bb_themes_find_theme_with_name(value);
if (id != UL_THEMES_THEME_NONE) { if (id != BB_THEMES_THEME_NONE) {
opts->theme.default_id = id; opts->theme.default_id = id;
return 1; return 1;
} }
} else if (strcmp(key, "alternate") == 0) { } else if (strcmp(key, "alternate") == 0) {
ul_themes_theme_id_t id = ul_themes_find_theme_with_name(value); bb_themes_theme_id_t id = bb_themes_find_theme_with_name(value);
if (id != UL_THEMES_THEME_NONE) { if (id != BB_THEMES_THEME_NONE) {
opts->theme.alternate_id = id; opts->theme.alternate_id = id;
return 1; return 1;
} }
@@ -263,8 +263,8 @@ void ul_config_init_opts(ul_config_opts *opts) {
opts->keyboard.popovers = true; opts->keyboard.popovers = true;
opts->textarea.obscured = true; opts->textarea.obscured = true;
opts->textarea.bullet = LV_SYMBOL_BULLET; opts->textarea.bullet = LV_SYMBOL_BULLET;
opts->theme.default_id = UL_THEMES_THEME_BREEZY_DARK; opts->theme.default_id = BB_THEMES_THEME_BREEZY_DARK;
opts->theme.alternate_id = UL_THEMES_THEME_BREEZY_LIGHT; opts->theme.alternate_id = BB_THEMES_THEME_BREEZY_LIGHT;
opts->input.keyboard = true; opts->input.keyboard = true;
opts->input.pointer = true; opts->input.pointer = true;
opts->input.touchscreen = true; opts->input.touchscreen = true;

View File

@@ -9,7 +9,7 @@
#include "backends.h" #include "backends.h"
#include "themes.h" #include "../shared/themes.h"
#include "sq2lv_layouts.h" #include "sq2lv_layouts.h"
@@ -55,9 +55,9 @@ typedef struct {
*/ */
typedef struct { typedef struct {
/* Default theme */ /* Default theme */
ul_themes_theme_id_t default_id; bb_themes_theme_id_t default_id;
/* Alternate theme */ /* Alternate theme */
ul_themes_theme_id_t alternate_id; bb_themes_theme_id_t alternate_id;
} ul_config_opts_theme; } ul_config_opts_theme;
/** /**

View File

@@ -9,11 +9,11 @@
#include "config.h" #include "config.h"
#include "unl0kr.h" #include "unl0kr.h"
#include "terminal.h" #include "terminal.h"
#include "theme.h"
#include "themes.h"
#include "../shared/indev.h" #include "../shared/indev.h"
#include "../shared/log.h" #include "../shared/log.h"
#include "../shared/theme.h"
#include "../shared/themes.h"
#include "../squeek2lvgl/sq2lv.h" #include "../squeek2lvgl/sq2lv.h"
#include "lvgl/lvgl.h" #include "lvgl/lvgl.h"
@@ -220,11 +220,11 @@ static void toggle_theme(void) {
} }
static void set_theme(bool is_alternate) { 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) { 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) { static void toggle_pw_btn_clicked_cb(lv_event_t *event) {
@@ -462,7 +462,7 @@ int main(int argc, char *argv[]) {
/* Header flexbox */ /* Header flexbox */
lv_obj_t *header = lv_obj_create(container); 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_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_flow(header, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(header, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER); 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_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_pos(keyboard, 0, is_keyboard_hidden ? keyboard_height : 0);
lv_obj_set_size(keyboard, hor_res, keyboard_height); lv_obj_set_size(keyboard, hor_res, keyboard_height);
ul_theme_prepare_keyboard(keyboard); bb_theme_prepare_keyboard(keyboard);
/* Apply textarea options */ /* Apply textarea options */
set_password_obscured(conf_opts.textarea.obscured); set_password_obscured(conf_opts.textarea.obscured);

View File

@@ -20,14 +20,14 @@ unl0kr_sources = [
'main.c', 'main.c',
'sq2lv_layouts.c', 'sq2lv_layouts.c',
'terminal.c', 'terminal.c',
'theme.c',
'themes.c',
] ]
shared_sources = [ shared_sources = [
'../shared/cursor/cursor.c', '../shared/cursor/cursor.c',
'../shared/indev.c', '../shared/indev.c',
'../shared/log.c', '../shared/log.c',
'../shared/theme.c',
'../shared/themes.c',
] ]
squeek2lvgl_sources = [ squeek2lvgl_sources = [

View File

@@ -3,6 +3,7 @@
**/ **/
#include "sq2lv_layouts.h" #include "sq2lv_layouts.h"
#include "../squeek2lvgl/sq2lv.h"
#define SQ2LV_SYMBOL_SHIFT "\xef\x8d\x9b" #define SQ2LV_SYMBOL_SHIFT "\xef\x8d\x9b"

View File

@@ -9,11 +9,6 @@
#define SQ2LV_SCANCODES_ENABLED 0 #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 */ /* Layout IDs, values can be used as indexes into the sq2lv_layouts array */
typedef enum { typedef enum {
SQ2LV_LAYOUT_NONE = -1, SQ2LV_LAYOUT_NONE = -1,

View File

@@ -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 */