Skip to content
Snippets Groups Projects
Commit b98b8d1b authored by Johannes Marbach's avatar Johannes Marbach
Browse files

Move indev to shared component

parent f81f4587
No related branches found
No related tags found
No related merge requests found
......@@ -10,7 +10,7 @@ If a change only affects particular applications, they are listed in parentheses
## Unreleased
Nothing at the moment
- feat(buffyboard): Handle input device connection/disconnection at runtime; adds new dependency libudev
## 3.0.0 (2024-03-22)
......
......@@ -32,6 +32,7 @@ For a growing collection of demo videos, see the [wiki].
- [lvgl] (git submodule / linked statically)
- [squeek2lvgl] (git submodule / linked statically)
- [libinput]
- [libudev]
- evdev kernel module
- uinput kernel module
......@@ -129,6 +130,7 @@ The [FontAwesome] font is licensed under the Open Font License version 1.1.
[arrow-alt-circle-up]: https://fontawesome.com/v5.15/icons/arrow-alt-circle-up?style=solid
[fbkeyboard]: https://github.com/bakonyiferenc/fbkeyboard
[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
[lv_sim_emscripten]: https://github.com/lvgl/lv_sim_emscripten/blob/master/mouse_cursor_icon.c
[lvgl]: https://github.com/lvgl/lvgl
......
/**
* Copyright 2021 Johannes Marbach
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "indev.h"
#include "../shared/cursor/cursor.h"
#include "lvgl/lvgl.h"
#include <limits.h>
/**
* Defines
*/
#define MAX_POINTER_DEVS 4
#define MAX_TOUCHSCREEN_DEVS 1
/**
* Static variables
*/
static int num_pointer_devs = 0;
static char *pointer_devs[MAX_POINTER_DEVS];
static lv_indev_t *pointer_indevs[MAX_POINTER_DEVS];
static int num_touchscreen_devs = 0;
static char *touchscreen_devs[MAX_TOUCHSCREEN_DEVS];
static lv_indev_t *touchscreen_indevs[MAX_TOUCHSCREEN_DEVS];
/**
* Static prototypes
*/
/**
* Auto-connect available input devices having a specific capability.
*
* @param capability capability to filter devices by
* @param max_num_devs maximum number of devices to connect
* @param num_devs pointer for writing the actual number of connected devices into
* @param devs array for storing device paths
* @param indevs array for storing LVGL indevs
*/
static void auto_connect(lv_libinput_capability capability, int max_num_devs, int *num_devs, char *devs[], lv_indev_t *indevs[]);
/**
* Static functions
*/
static void auto_connect(lv_libinput_capability capability, int max_num_devs, int *num_devs, char *devs[], lv_indev_t *indevs[]) {
lv_memset(devs, 0, max_num_devs * sizeof(char *));
lv_memset(indevs, 0, max_num_devs * sizeof(lv_indev_t *));
*num_devs = lv_libinput_find_devs(capability, devs, max_num_devs, false);
for (int i = 0; i < *num_devs; ++i) {
indevs[i] = lv_libinput_create(capability & LV_LIBINPUT_CAPABILITY_KEYBOARD ? LV_INDEV_TYPE_KEYPAD : LV_INDEV_TYPE_POINTER, devs[i]);
}
}
/**
* Public functions
*/
void bb_indev_auto_connect() {
auto_connect(LV_LIBINPUT_CAPABILITY_POINTER, MAX_POINTER_DEVS, &num_pointer_devs, pointer_devs, pointer_indevs);
auto_connect(LV_LIBINPUT_CAPABILITY_TOUCH, MAX_TOUCHSCREEN_DEVS, &num_touchscreen_devs, touchscreen_devs, touchscreen_indevs);
}
void bb_indev_set_up_mouse_cursor() {
lv_obj_t *cursor_obj = lv_img_create(lv_scr_act());
lv_img_set_src(cursor_obj, &bb_cursor_img_dsc);
for (int i = 0; i < num_pointer_devs; ++i) {
lv_indev_set_cursor(pointer_indevs[i], cursor_obj);
}
}
/**
* Copyright 2021 Johannes Marbach
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#ifndef BB_INDEV_H
#define BB_INDEV_H
/**
* Auto-connect currently available keyboard, pointer and touchscreen input devices.
*/
void bb_indev_auto_connect();
/**
* Set up the mouse cursor image for currently connected pointer devices.
*/
void bb_indev_set_up_mouse_cursor();
#endif /* BB_INDEV_H */
......@@ -6,13 +6,13 @@
#include "buffyboard.h"
#include "command_line.h"
#include "indev.h"
#include "sq2lv_layouts.h"
#include "terminal.h"
#include "uinput_device.h"
#include "lvgl/lvgl.h"
#include "../shared/indev.h"
#include "../squeek2lvgl/sq2lv.h"
#include <limits.h>
......@@ -279,9 +279,8 @@ int main(int argc, char *argv[]) {
}
}
/* Connect input devices */
bb_indev_auto_connect();
bb_indev_set_up_mouse_cursor();
/* 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);
......
......@@ -15,7 +15,6 @@ add_project_arguments('-DBB_VERSION="@0@"'.format(meson.project_version()), lang
buffyboard_sources = [
'command_line.c',
'font_32.c',
'indev.c',
'main.c',
'sq2lv_layouts.c',
'terminal.c',
......@@ -23,7 +22,9 @@ buffyboard_sources = [
]
shared_sources = [
'../shared/cursor/cursor.c'
'../shared/cursor/cursor.c',
'../shared/indev.c',
'../shared/log.c',
]
squeek2lvgl_sources = [
......@@ -38,6 +39,7 @@ executable(
include_directories: ['..'],
dependencies: [
dependency('libinput'),
dependency('libudev'),
meson.get_compiler('c').find_library('m', required: false),
],
install: true
......
......@@ -6,8 +6,8 @@
#include "indev.h"
#include "../shared/cursor/cursor.h"
#include "../shared/log.h"
#include "cursor/cursor.h"
#include "log.h"
#include "lvgl/src/indev/lv_indev_private.h"
......@@ -361,12 +361,17 @@ static void set_mouse_cursor(struct input_device *device) {
lv_indev_set_cursor(device->indev, cursor_obj);
}
static void query_device_monitor(lv_timer_t *timer) {
LV_UNUSED(timer);
bb_indev_query_monitor();
}
/**
* Public functions
*/
void ul_indev_set_allowed_device_capability(bool keyboard, bool pointer, bool touchscreen) {
void bb_indev_set_allowed_device_capability(bool keyboard, bool pointer, bool touchscreen) {
allowed_capability = LV_LIBINPUT_CAPABILITY_NONE;
if (keyboard) {
allowed_capability |= LV_LIBINPUT_CAPABILITY_KEYBOARD;
......@@ -379,7 +384,7 @@ void ul_indev_set_allowed_device_capability(bool keyboard, bool pointer, bool to
}
}
void ul_indev_set_keyboard_input_group(lv_group_t *group) {
void bb_indev_set_keyboard_input_group(lv_group_t *group) {
/* Store the group */
keyboard_input_group = group;
......@@ -391,7 +396,14 @@ void ul_indev_set_keyboard_input_group(lv_group_t *group) {
}
}
void ul_indev_auto_connect() {
void bb_indev_start_monitor_and_autoconnect(bool keyboard, bool pointer, bool touchscreen) {
bb_indev_set_allowed_device_capability(keyboard, pointer, touchscreen);
bb_indev_start_monitor();
lv_timer_create(query_device_monitor, 1000, NULL);
bb_indev_auto_connect();
}
void bb_indev_auto_connect() {
bb_log(BB_LOG_LEVEL_VERBOSE, "Auto-connecting supported input devices");
/* Make sure udev context is initialised */
......@@ -434,7 +446,7 @@ void ul_indev_auto_connect() {
udev_enumerate_unref(enumerate);
}
void ul_indev_start_monitor() {
void bb_indev_start_monitor() {
/* Make sure udev context is initialised */
if (!context) {
context = udev_new();
......@@ -454,7 +466,7 @@ void ul_indev_start_monitor() {
monitor = udev_monitor_new_from_netlink(context, "udev");
if (!monitor) {
bb_log(BB_LOG_LEVEL_WARNING, "Could not create udev monitor");
ul_indev_stop_monitor();
bb_indev_stop_monitor();
return;
}
......@@ -466,19 +478,19 @@ void ul_indev_start_monitor() {
/* Start monitor */
if (udev_monitor_enable_receiving(monitor) < 0) {
bb_log(BB_LOG_LEVEL_WARNING, "Could not enable udev monitor");
ul_indev_stop_monitor();
bb_indev_stop_monitor();
return;
}
/* Obtain monitor file descriptor */
if ((monitor_fd = udev_monitor_get_fd(monitor)) < 0) {
bb_log(BB_LOG_LEVEL_WARNING, "Could not acquire file descriptor for udev monitor");
ul_indev_stop_monitor();
bb_indev_stop_monitor();
return;
}
}
void ul_indev_stop_monitor() {
void bb_indev_stop_monitor() {
/* Unreference monitor */
if (monitor) {
udev_monitor_unref(monitor);
......@@ -497,7 +509,7 @@ void ul_indev_stop_monitor() {
}
}
void ul_indev_query_monitor() {
void bb_indev_query_monitor() {
/* Make sure the monitor is running */
if (!monitor) {
bb_log(BB_LOG_LEVEL_ERROR, "Cannot query udev monitor because it is not running");
......@@ -535,7 +547,7 @@ void ul_indev_query_monitor() {
}
}
bool ul_indev_is_keyboard_connected() {
bool bb_indev_is_keyboard_connected() {
for (int i = 0; i < num_connected_devices; ++i) {
if (is_keyboard_device(devices[i])) {
return true;
......
......@@ -4,8 +4,8 @@
*/
#ifndef UL_INDEV_H
#define UL_INDEV_H
#ifndef BB_INDEV_H
#define BB_INDEV_H
#include "lvgl/lvgl.h"
......@@ -18,40 +18,49 @@
* @param pointer if true, allow connection of pointer devices
* @param touchscreen if true, allow connection of touchscreen devices
*/
void ul_indev_set_allowed_device_capability(bool keyboard, bool pointer, bool touchscreen);
void bb_indev_set_allowed_device_capability(bool keyboard, bool pointer, bool touchscreen);
/**
* Set the group for receiving input from keyboard devices.
*
* @param group group that should receive input
*/
void ul_indev_set_keyboard_input_group(lv_group_t *group);
void bb_indev_set_keyboard_input_group(lv_group_t *group);
/**
* Start the udev device monitor and auto-connect currently available devices.
*
* @param keyboard if true, allow connection of keyboard devices
* @param pointer if true, allow connection of pointer devices
* @param touchscreen if true, allow connection of touchscreen devices
*/
void bb_indev_start_monitor_and_autoconnect(bool keyboard, bool pointer, bool touchscreen);
/**
* Auto-connect currently available keyboard, pointer and touchscreen input devices.
*/
void ul_indev_auto_connect();
void bb_indev_auto_connect();
/**
* Start the udev device monitor.
*/
void ul_indev_start_monitor();
void bb_indev_start_monitor();
/**
* Stop the udev device monitor.
*/
void ul_indev_stop_monitor();
void bb_indev_stop_monitor();
/**
* Query the udev device monitor and (dis)connect added or removed devices
*/
void ul_indev_query_monitor();
void bb_indev_query_monitor();
/**
* Check if any keyboard devices are connected.
*
* @return true if at least one keyboard device is connected, false otherwise
*/
bool ul_indev_is_keyboard_connected();
bool bb_indev_is_keyboard_connected();
#endif /* UL_INDEV_H */
#endif /* BB_INDEV_H */
......@@ -7,12 +7,12 @@
#include "backends.h"
#include "command_line.h"
#include "config.h"
#include "indev.h"
#include "unl0kr.h"
#include "terminal.h"
#include "theme.h"
#include "themes.h"
#include "../shared/indev.h"
#include "../shared/log.h"
#include "../squeek2lvgl/sq2lv.h"
......@@ -54,13 +54,6 @@ lv_obj_t *keyboard = NULL;
*/
static void *tick_thread (void *args);
/**
* Query the device monitor and handle updates.
*
* @param timer the timer object
*/
static void query_device_monitor(lv_timer_t *timer);
/**
* Handle LV_EVENT_CLICKED events from the theme toggle button.
*
......@@ -216,11 +209,6 @@ static void *tick_thread (void *args) {
return NULL;
}
static void query_device_monitor(lv_timer_t *timer) {
LV_UNUSED(timer);
ul_indev_query_monitor();
}
static void toggle_theme_btn_clicked_cb(lv_event_t *event) {
LV_UNUSED(event);
toggle_theme();
......@@ -442,16 +430,13 @@ int main(int argc, char *argv[]) {
/* Prepare for routing physical keyboard input into the textarea */
lv_group_t *keyboard_input_group = lv_group_create();
ul_indev_set_keyboard_input_group(keyboard_input_group);
bb_indev_set_keyboard_input_group(keyboard_input_group);
/* Start input device monitor and auto-connect available devices */
ul_indev_set_allowed_device_capability(conf_opts.input.keyboard, conf_opts.input.pointer, conf_opts.input.touchscreen);
ul_indev_start_monitor();
lv_timer_create(query_device_monitor, 1000, NULL);
ul_indev_auto_connect();
bb_indev_start_monitor_and_autoconnect(conf_opts.input.keyboard, conf_opts.input.pointer, conf_opts.input.touchscreen);
/* Hide the on-screen keyboard by default if a physical keyboard is connected */
if (conf_opts.keyboard.autohide && ul_indev_is_keyboard_connected()) {
if (conf_opts.keyboard.autohide && bb_indev_is_keyboard_connected()) {
is_keyboard_hidden = true;
}
......
......@@ -17,7 +17,6 @@ unl0kr_sources = [
'command_line.c',
'config.c',
'font_32.c',
'indev.c',
'main.c',
'sq2lv_layouts.c',
'terminal.c',
......@@ -27,6 +26,7 @@ unl0kr_sources = [
shared_sources = [
'../shared/cursor/cursor.c',
'../shared/indev.c',
'../shared/log.c',
]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment