Allow runtime selection of the lvgl display driver ("backend"), enable DRM backend
This commit is contained in:
parent
0c00af71be
commit
e4edfa3d64
12 changed files with 208 additions and 18 deletions
|
|
@ -14,6 +14,8 @@
|
|||
- fix: Prevent scrolling when keyboard hides (#21)
|
||||
- feat!: Do not show last typed character when typing (#25)
|
||||
- feat: Update lvgl & lv_drivers to git master (2022-02-21)
|
||||
- feat: allow runtime selection of the lvgl display driver ("backend")
|
||||
- feat: allow overriding dpi with the --dpi command line parameter
|
||||
|
||||
## 0.1.0 (2021-11-15)
|
||||
|
||||
|
|
|
|||
27
README.md
27
README.md
|
|
@ -1,7 +1,7 @@
|
|||
Unl0kr
|
||||
======
|
||||
|
||||
Framebuffer-based disk unlocker for the initramfs based on [LVGL].
|
||||
Disk unlocker for the initramfs based on [LVGL].
|
||||
|
||||
[[_TOC_]]
|
||||
|
||||
|
|
@ -72,6 +72,7 @@ Mandatory arguments to long options are mandatory for short options too.
|
|||
order.
|
||||
-g, --geometry=NxM Force a display size of N horizontal times M
|
||||
vertical pixels
|
||||
-d --dpi=N Overrides the DPI
|
||||
-h, --help Print this message and exit
|
||||
-v, --verbose Enable more detailed logging output on STDERR
|
||||
-V, --version Print the unl0kr version and exit
|
||||
|
|
@ -89,6 +90,7 @@ For an example configuration file, see [unl0kr.conf].
|
|||
- [squeek2lvgl] (git submodule / linked statically)
|
||||
- [libinput]
|
||||
- [libxkbcommon]
|
||||
- [libdrm] (optional, required for the DRM backend)
|
||||
- evdev kernel module
|
||||
|
||||
## Building & running
|
||||
|
|
@ -104,6 +106,28 @@ $ sudo ./_build/unl0kr
|
|||
|
||||
With meson <0\.55 use `ninja` instead of `meson compile`\.
|
||||
|
||||
### Optional features
|
||||
|
||||
If [libdrm] is installed, the DRM backend will be compiled automatically. It's possible to
|
||||
change this behaviour using the `with-drm` meson feature. For example,
|
||||
|
||||
```
|
||||
$ meson _build -Dwith-drm=disabled
|
||||
```
|
||||
|
||||
will forcibly disable the DRM backend regardless if libdrm is installed or not.
|
||||
|
||||
## Backends
|
||||
|
||||
Unl0kr supports multiple lvgl display drivers, which are herein referred as "backends".
|
||||
|
||||
Currently supported backends:
|
||||
|
||||
- fbdev
|
||||
- drm (optional)
|
||||
|
||||
The backend can be switched at runtime by modifying the `general.backend` configuration.
|
||||
|
||||
## Fonts
|
||||
|
||||
In order to work with [LVGL], fonts need to be converted to bitmaps, stored as C arrays. Unl0kr currently uses a combination of the [OpenSans] font for text and the [FontAwesome] font for pictograms. For both fonts only limited character ranges are included to reduce the binary size. To (re)generate the C file containing the combined font, run the following command
|
||||
|
|
@ -200,6 +224,7 @@ The [FontAwesome] font is licensed under the Open Font License version 1.1.
|
|||
[inih]: https://github.com/benhoyt/inih
|
||||
[libinput]: https://gitlab.freedesktop.org/libinput/libinput
|
||||
[libxkbcommon]: https://github.com/xkbcommon/libxkbcommon
|
||||
[libdrm]: https://gitlab.freedesktop.org/mesa/drm
|
||||
[lv_drivers]: https://github.com/lvgl/lv_drivers
|
||||
[lv_port_linux_frame_buffer]: https://github.com/lvgl/lv_port_linux_frame_buffer
|
||||
[lv_sim_emscripten]: https://github.com/lvgl/lv_sim_emscripten/blob/master/mouse_cursor_icon.c
|
||||
|
|
|
|||
48
backends.c
Normal file
48
backends.c
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
/**
|
||||
* Copyright 2022 Eugenio Paolantonio (g7)
|
||||
*
|
||||
* This file is part of unl0kr, hereafter referred to as the program.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "backends.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/**
|
||||
* Public interface
|
||||
*/
|
||||
|
||||
const char *ul_backends_backends[] = {
|
||||
#if USE_FBDEV
|
||||
"fbdev",
|
||||
#endif /* USE_FBDEV */
|
||||
#if USE_DRM
|
||||
"drm",
|
||||
#endif /* USE_DRM */
|
||||
NULL
|
||||
};
|
||||
|
||||
ul_backends_backend_id_t ul_backends_find_backend_with_name(const char *name) {
|
||||
for (int i = 0; ul_backends_backends[i] != NULL; ++i) {
|
||||
if (strcmp(ul_backends_backends[i], name) == 0) {
|
||||
ul_log(UL_LOG_LEVEL_VERBOSE, "Found backend: %s\n", name);
|
||||
return i;
|
||||
}
|
||||
}
|
||||
ul_log(UL_LOG_LEVEL_WARNING, "Backend %s not found\n", name);
|
||||
return UL_BACKENDS_BACKEND_NONE;
|
||||
}
|
||||
50
backends.h
Normal file
50
backends.h
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/**
|
||||
* Copyright 2022 Eugenio Paolantonio (g7)
|
||||
*
|
||||
* This file is part of unl0kr, hereafter referred to as the program.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef UL_BACKENDS_H
|
||||
#define UL_BACKENDS_H
|
||||
|
||||
#include "lv_drv_conf.h"
|
||||
|
||||
#include "log.h"
|
||||
|
||||
/* NOTE: Only UL_BACKENDS_BACKEND_NONE is ought to have an explicit value assigned */
|
||||
typedef enum {
|
||||
UL_BACKENDS_BACKEND_NONE = -1,
|
||||
#if USE_FBDEV
|
||||
UL_BACKENDS_BACKEND_FBDEV,
|
||||
#endif /* USE_FBDEV */
|
||||
#if USE_DRM
|
||||
UL_BACKENDS_BACKEND_DRM,
|
||||
#endif /* USE_DRM */
|
||||
} ul_backends_backend_id_t;
|
||||
|
||||
/* Backends */
|
||||
extern const char *ul_backends_backends[];
|
||||
|
||||
/**
|
||||
* Find the first backend with a given name.
|
||||
*
|
||||
* @param name backend name
|
||||
* @return ID of the first matching backend or UL_BACKENDS_BACKEND_NONE if no backend matched
|
||||
*/
|
||||
ul_backends_backend_id_t ul_backends_find_backend_with_name(const char *name);
|
||||
|
||||
#endif /* UL_BACKENDS_H */
|
||||
|
|
@ -82,6 +82,7 @@ static void print_usage() {
|
|||
" order.\n"
|
||||
" -g, --geometry=NxM Force a display size of N horizontal times M\n"
|
||||
" vertical pixels\n"
|
||||
" -d --dpi=N Overrides the DPI\n"
|
||||
" -h, --help Print this message and exit\n"
|
||||
" -v, --verbose Enable more detailed logging output on STDERR\n"
|
||||
" -V, --version Print the unl0kr version and exit\n");
|
||||
|
|
@ -100,6 +101,7 @@ void ul_cli_parse_opts(int argc, char *argv[], ul_cli_opts *opts) {
|
|||
{ "config", required_argument, NULL, 'c' },
|
||||
{ "config-override", required_argument, NULL, 'C' },
|
||||
{ "geometry", required_argument, NULL, 'g' },
|
||||
{ "dpi", required_argument, NULL, 'd' },
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "verbose", no_argument, NULL, 'v' },
|
||||
{ "version", no_argument, NULL, 'V' },
|
||||
|
|
@ -108,7 +110,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:hvV", long_opts, &index)) != -1) {
|
||||
while ((opt = getopt_long(argc, argv, "c:C:g:d:hvV", long_opts, &index)) != -1) {
|
||||
switch (opt) {
|
||||
case 'c':
|
||||
opts->config_files[0] = optarg;
|
||||
|
|
@ -128,6 +130,12 @@ void ul_cli_parse_opts(int argc, char *argv[], ul_cli_opts *opts) {
|
|||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'd':
|
||||
if (sscanf(optarg, "%i", &(opts->dpi)) != 1) {
|
||||
ul_log(UL_LOG_LEVEL_ERROR, "Invalid dpi argument \"%s\"\n", optarg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
print_usage();
|
||||
exit(EXIT_SUCCESS);
|
||||
|
|
|
|||
|
|
@ -35,6 +35,8 @@ typedef struct {
|
|||
int hor_res;
|
||||
/* Vertical display resolution */
|
||||
int ver_res;
|
||||
/* DPI */
|
||||
int dpi;
|
||||
/* Verbose mode. If true, provide more detailed logging output on STDERR. */
|
||||
bool verbose;
|
||||
} ul_cli_opts;
|
||||
|
|
|
|||
7
config.c
7
config.c
|
|
@ -73,6 +73,7 @@ static bool parse_bool(const char *value, bool *result);
|
|||
|
||||
static void init_opts(ul_config_opts *opts) {
|
||||
opts->general.animations = false;
|
||||
opts->general.backend = ul_backends_backends[0] == NULL ? UL_BACKENDS_BACKEND_NONE : 0;
|
||||
opts->keyboard.autohide = true;
|
||||
opts->keyboard.layout_id = SQ2LV_LAYOUT_US;
|
||||
opts->keyboard.popovers = false;
|
||||
|
|
@ -95,6 +96,12 @@ static int parsing_handler(void* user_data, const char* section, const char* key
|
|||
if (parse_bool(value, &(opts->general.animations))) {
|
||||
return 1;
|
||||
}
|
||||
} else if (strcmp(key, "backend") == 0) {
|
||||
ul_backends_backend_id_t id = ul_backends_find_backend_with_name(value);
|
||||
if (id != UL_BACKENDS_BACKEND_NONE) {
|
||||
opts->general.backend = id;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
} else if (strcmp(section, "keyboard") == 0) {
|
||||
if (strcmp(key, "autohide") == 0) {
|
||||
|
|
|
|||
4
config.h
4
config.h
|
|
@ -21,6 +21,8 @@
|
|||
#ifndef UL_CONFIG_H
|
||||
#define UL_CONFIG_H
|
||||
|
||||
#include "backends.h"
|
||||
|
||||
#include "themes.h"
|
||||
|
||||
#include "sq2lv_layouts.h"
|
||||
|
|
@ -31,6 +33,8 @@
|
|||
* General options
|
||||
*/
|
||||
typedef struct {
|
||||
/* Backend to use */
|
||||
ul_backends_backend_id_t backend;
|
||||
/* If true, use animations */
|
||||
bool animations;
|
||||
} ul_config_opts_general;
|
||||
|
|
|
|||
53
main.c
53
main.c
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
|
||||
#include "backends.h"
|
||||
#include "command_line.h"
|
||||
#include "config.h"
|
||||
#include "indev.h"
|
||||
|
|
@ -27,7 +28,14 @@
|
|||
#include "theme.h"
|
||||
#include "themes.h"
|
||||
|
||||
#include "lv_drv_conf.h"
|
||||
|
||||
#if USE_FBDEV
|
||||
#include "lv_drivers/display/fbdev.h"
|
||||
#endif /* USE_FBDEV */
|
||||
#if USE_DRM
|
||||
#include "lv_drivers/display/drm.h"
|
||||
#endif /* USE_DRM */
|
||||
|
||||
#include "lvgl/lvgl.h"
|
||||
|
||||
|
|
@ -338,19 +346,45 @@ int main(int argc, char *argv[]) {
|
|||
lv_init();
|
||||
lv_log_register_print_cb(ul_log_print_cb);
|
||||
|
||||
/* Initialise framebuffer driver and query display size */
|
||||
fbdev_init();
|
||||
uint32_t hor_res;
|
||||
uint32_t ver_res;
|
||||
fbdev_get_sizes(&hor_res, &ver_res);
|
||||
/* Initialise display driver */
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
|
||||
/* Override display size with command line options if necessary */
|
||||
/* Initialise framebuffer driver and query display size */
|
||||
uint32_t hor_res = 0;
|
||||
uint32_t ver_res = 0;
|
||||
uint32_t dpi = 0;
|
||||
|
||||
switch (conf_opts.general.backend) {
|
||||
#if USE_FBDEV
|
||||
case UL_BACKENDS_BACKEND_FBDEV:
|
||||
fbdev_init();
|
||||
fbdev_get_sizes(&hor_res, &ver_res);
|
||||
disp_drv.flush_cb = fbdev_flush;
|
||||
break;
|
||||
#endif /* USE_FBDEV */
|
||||
#if USE_DRM
|
||||
case UL_BACKENDS_BACKEND_DRM:
|
||||
drm_init();
|
||||
drm_get_sizes((lv_coord_t *)&hor_res, (lv_coord_t *)&ver_res, &dpi);
|
||||
disp_drv.flush_cb = drm_flush;
|
||||
break;
|
||||
#endif /* USE_DRM */
|
||||
default:
|
||||
ul_log(UL_LOG_LEVEL_ERROR, "Unable to find suitable backend");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/* Override display parameters with command line options if necessary */
|
||||
if (cli_opts.hor_res > 0) {
|
||||
hor_res = LV_MIN(hor_res, cli_opts.hor_res);
|
||||
}
|
||||
if (cli_opts.ver_res > 0) {
|
||||
ver_res = LV_MIN(ver_res, cli_opts.ver_res);
|
||||
}
|
||||
if (cli_opts.dpi > 0) {
|
||||
dpi = cli_opts.dpi;
|
||||
}
|
||||
|
||||
/* Prepare display buffer */
|
||||
const size_t buf_size = hor_res * ver_res / 10; /* At least 1/10 of the display size is recommended */
|
||||
|
|
@ -358,13 +392,12 @@ int main(int argc, char *argv[]) {
|
|||
lv_color_t *buf = (lv_color_t *)malloc(buf_size * sizeof(lv_color_t));
|
||||
lv_disp_draw_buf_init(&disp_buf, buf, NULL, buf_size);
|
||||
|
||||
/* Initialise display driver */
|
||||
static lv_disp_drv_t disp_drv;
|
||||
lv_disp_drv_init(&disp_drv);
|
||||
|
||||
/* Register display driver */
|
||||
disp_drv.draw_buf = &disp_buf;
|
||||
disp_drv.flush_cb = fbdev_flush;
|
||||
disp_drv.hor_res = hor_res;
|
||||
disp_drv.ver_res = ver_res;
|
||||
disp_drv.dpi = dpi;
|
||||
lv_disp_drv_register(&disp_drv);
|
||||
|
||||
/* Connect input devices */
|
||||
|
|
|
|||
21
meson.build
21
meson.build
|
|
@ -27,6 +27,7 @@ project(
|
|||
add_project_arguments('-DUL_VERSION="@0@"'.format(meson.project_version()), language: ['c'])
|
||||
|
||||
unl0kr_sources = [
|
||||
'backends.c',
|
||||
'command_line.c',
|
||||
'config.c',
|
||||
'cursor.c',
|
||||
|
|
@ -37,13 +38,25 @@ unl0kr_sources = [
|
|||
'sq2lv_layouts.c',
|
||||
'terminal.c',
|
||||
'theme.c',
|
||||
'themes.c'
|
||||
'themes.c',
|
||||
]
|
||||
|
||||
squeek2lvgl_sources = [
|
||||
'squeek2lvgl/sq2lv.c',
|
||||
]
|
||||
|
||||
unl0kr_dependencies = [
|
||||
dependency('inih'),
|
||||
dependency('libinput'),
|
||||
dependency('xkbcommon'),
|
||||
]
|
||||
|
||||
libdrm_dep = dependency('libdrm', required: get_option('with-drm'))
|
||||
if libdrm_dep.found()
|
||||
unl0kr_dependencies += [libdrm_dep]
|
||||
add_project_arguments('-DUSE_DRM=1', language: ['c'])
|
||||
endif
|
||||
|
||||
lvgl_sources = run_command('find-lvgl-sources.sh', 'lvgl', check: true).stdout().strip().split('\n')
|
||||
|
||||
lv_drivers_sources = run_command('find-lvgl-sources.sh', 'lv_drivers', check: true).stdout().strip().split('\n')
|
||||
|
|
@ -54,10 +67,6 @@ executable(
|
|||
'unl0kr',
|
||||
sources: unl0kr_sources + squeek2lvgl_sources + lvgl_sources + lv_drivers_sources,
|
||||
include_directories: ['lvgl', 'lv_drivers'],
|
||||
dependencies: [
|
||||
dependency('inih'),
|
||||
dependency('libinput'),
|
||||
dependency('xkbcommon')
|
||||
],
|
||||
dependencies: unl0kr_dependencies,
|
||||
install: true
|
||||
)
|
||||
|
|
|
|||
1
meson_options.txt
Normal file
1
meson_options.txt
Normal file
|
|
@ -0,0 +1 @@
|
|||
option('with-drm', type : 'feature', value : 'auto', description : 'Enable DRM backend')
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
[general]
|
||||
animations=true
|
||||
#backend=fbdev
|
||||
|
||||
[keyboard]
|
||||
autohide=true
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue