| lv_drivers@8960d0fcd0 | ||
| lvgl@ab50f001a6 | ||
| squeek2lvgl@94e5cfa841 | ||
| .gitignore | ||
| .gitmodules | ||
| COPYING | ||
| cursor.c | ||
| cursor.h | ||
| FontAwesome5-Solid+Brands+Regular.woff | ||
| libinput_multi.c | ||
| libinput_multi.h | ||
| libinput_xkb.c | ||
| libinput_xkb.h | ||
| lv_conf.h | ||
| lv_drv_conf.h | ||
| main.c | ||
| Makefile | ||
| Montserrat-Regular.ttf | ||
| montserrat_extended_32.c | ||
| README.md | ||
| regenerate-layouts.sh | ||
| sq2lv_layouts.c | ||
| sq2lv_layouts.h | ||
Unl0kr
Proof-of-concept framebuffer-based disk unlocker for the initramfs based on lvgl.
Disclaimer: Doesn't actually unlock anything 😜
About
This is an experiment that attempts to evaluate the fitness of lvgl to build a graphical user interface on the Linux framebuffer for unlocking encrypted hard drives during boot. It's neither functional nor meant to replace postmarketOS/osk-sdl. For background see postmarketOS/osk-sdl#121.
Status
The biggest obstacle is input processing. lv_drivers provides an evdev interface (supporting touchscreens, pointer devices and keypads) and a libinput interface (supporting touchscreens only). Presently there is no support for full physical keyboards (short of using the SDL interface) and no automated device detection. Additonally, the drivers can currently not be used with multiple devices at the same time.
What works
- Password-entry UI including on-screen keyboard on the framebuffer
- Input device discovery for keyboards, mice and trackpads
- On-screen keyboard control via one or more mouse / trackpad (including cursor)
- On-screen keyboard control via one or more hardware keyboard (including support for multiple layouts using XKB)
- Works great on my laptop keyboard but occasionally drops keys on my Ergodox EZ)
- On-screen keyboard control via touchscreen (tested on PinePhone)
- Switching on-screen keyboard layout at runtime (layouts still to be refined, currently based on squeekboard subset)
- Switching between light and dark theme at runtime
- Disclosing and hiding entered password at runtime
- Powering off via soft button
- Toggling on-screen keyboard via soft button
To do
... everything else ...
Discovered shortcomings compared to SDL2
- Fonts cannot be loaded at runtime. In order for LVGL to render them, they have to be converted to static and font-size-dependent bitmaps first. That means osk-sdl's font configuration option cannot be replicated.
- A corollary of the above: Required font sizes need to be known at compile time. In order to support the larger and smaller end of the mobile screen spectrum, bitmaps of the same font at different font sizes might have to be included.
Upstreaming
As far as feasible and sensible, lvgl and lv_drivers fixes and enhancements are being upstreamed. Ideally all code outside of main.c should be contributed back but I'm not yet sure if that will be possible.
Upstreamed contributions so far:
lvgl
- fix(examples) don't compile assets unless needed (✅ merged)
- feat(btnmatrix): add option to show popovers on button press (⏳ in review)
- feat(msgbox): add function to get selected button index (✅ merged)
- feat(msgbox): omit title label unless needed (✅ merged)
- fix(btnmatrix): make ORed values work correctly with lv_btnmatrix_has_btn_ctrl (⏳ in review)
lv_drivers
- Add support for pointer devices to libinput driver (✅ merged)
- Add support for keypads to libinput driver (✅ merged)
- Add full keyboard support to libinput/evdev driver (✅ merged)
- Automatic device discovery via libinput (✅ merged)
- Make it possible to use multiple devices with the libinput and XKB drivers (⏳ in review)
Development
Dependencies
- lvgl (git submodule / linked statically)
- lv_drivers (git submodule / linked statically)
- libinput
- libxkbcommon
Building & running
For development and testing you can run the app in a VT. sudo is needed to access input device files.
$ make
$ sudo chvt 2
$ sudo ./unl0kr
Changing fonts
In order to work with lvgl, fonts need to be converted to C arrays. Buffyboard currently uses a combination of the [Montserrat] font for text and the [FontAwesome] font for pictograms. For both fonts only limited character ranges are included. To (re)generate the C file containing the combined font, run the following command
$ npx lv_font_conv --bpp 4 --size 32 --no-compress -o montserrat_extended_32.c --format lvgl \
--font Montserrat-Regular.ttf \
--range '0x0020-0x007F' \
--range '0x00A0-0x00FF' \
--range '0x0100-0x017F' \
--range '0x2000-0x206F' \
--range '0x20A0-0x20CF' \
--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'
The following is a summary of the meaning of the different unicode ranges used above
- [Montserrat]
- Basic Latin (
0x0020-0x007F) - Latin-1 supplement (
0x00A0-0x00FF) - Latin extended A (
0x0100-0x017F) - General punctuation (
0x2000-0x206F) - Currency symbols (
0x20A0-0x20CF)
- Basic Latin (
- [FontAwesome]
- Standard
LV_SYMBOL_*glyphs (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) - adjust (
0xF042) - arrow-alt-circle-up (
0xF35B)
- Standard
Changing layouts
Unl0kr uses squeekboard layouts converted to C via squeek2lvgl. To regenerate the layouts, run
$ ./regenerate-layouts.sh
from the root of the repository.
Screen recording
For demonstration purposes you can record the framebuffer device, e.g. with ffmpeg:
$ sudo ffmpeg -f fbdev -i /dev/fb0 -r 24 -c:v libx264 -b:v 500k demo.avi
Acknowledgements
The lv_port_linux_frame_buffer project served as a starting point for the codebase. The mouse cursor image was taken from lv_sim_emscripten.
License
Unl0kr is licensed under 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.
The Montserrat font is licensed under the Open Font License.
The Font Awesome font is licensed under the Open Font License version 1.1.