From 50463b27c2059b886a7107863d33e3456bb39663 Mon Sep 17 00:00:00 2001 From: Johannes Marbach Date: Fri, 24 Sep 2021 09:07:37 +0200 Subject: [PATCH] Eliminate libinput_multi* Fixes: #3 --- README.md | 2 +- indev.c | 189 +++++++++++++++++++++++++++++++++++ indev.h | 52 ++++++++++ libinput_multi.c | 249 ----------------------------------------------- libinput_multi.h | 81 --------------- libinput_xkb.c | 146 --------------------------- libinput_xkb.h | 58 ----------- lv_drivers | 2 +- main.c | 75 ++------------ meson.build | 3 +- 10 files changed, 250 insertions(+), 607 deletions(-) create mode 100644 indev.c create mode 100644 indev.h delete mode 100644 libinput_multi.c delete mode 100644 libinput_multi.h delete mode 100644 libinput_xkb.c delete mode 100644 libinput_xkb.h diff --git a/README.md b/README.md index 26dc996..64c2500 100644 --- a/README.md +++ b/README.md @@ -51,7 +51,7 @@ Below is a summary of contributions upstreamed thus far. - [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) +- [Make it possible to use multiple devices with the libinput and XKB drivers] (✅ merged) # Usage diff --git a/indev.c b/indev.c new file mode 100644 index 0000000..b1cb4a6 --- /dev/null +++ b/indev.c @@ -0,0 +1,189 @@ +/** + * Copyright 2021 Johannes Marbach + * + * 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 . + */ + + +#include "indev.h" + +#include "cursor.h" +#include "log.h" + +#include "lv_drivers/indev/libinput_drv.h" + +#include + + +/** + * Defines + */ + +#define MAX_KEYBOARD_DEVS 4 +#define MAX_POINTER_DEVS 4 +#define MAX_TOUCHSCREEN_DEVS 1 + + +/** + * Static variables + */ + +static int num_keyboard_devs = 0; +static char *keyboard_devs[MAX_KEYBOARD_DEVS]; +static lv_indev_t *keyboard_indevs[MAX_KEYBOARD_DEVS]; +static lv_indev_drv_t keyboard_indev_drvs[MAX_KEYBOARD_DEVS]; +static libinput_drv_state_t keyboard_drv_states[MAX_KEYBOARD_DEVS]; + +static int num_pointer_devs = 0; +static char *pointer_devs[MAX_POINTER_DEVS]; +static lv_indev_t *pointer_indevs[MAX_POINTER_DEVS]; +static lv_indev_drv_t pointer_indev_drvs[MAX_POINTER_DEVS]; +static libinput_drv_state_t pointer_drv_states[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 lv_indev_drv_t touchscreen_indev_drvs[MAX_TOUCHSCREEN_DEVS]; +static libinput_drv_state_t touchscreen_drv_states[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 + * @param indev_drvs array for storing LVGL indev drivers + * @param drv_states array for storing LVGL libinput driver states + */ +static void auto_connect(libinput_capability capability, int max_num_devs, int *num_devs, char *devs[], lv_indev_t *indevs[], + lv_indev_drv_t indev_drvs[], libinput_drv_state_t drv_states[]); + +/** + * Log a message announcing the connection of an input device. + * + * @param capability the device's capability + * @param dev the device path + */ +static void log_connection(libinput_capability capability, char *dev); + +/** + * Perform an input read on a device using the libinput driver. + * + * @param indev_drv input device driver + * @param data input device data to write into + */ +static void libinput_read_cb(lv_indev_drv_t *indev_drv, lv_indev_data_t *data); + + +/** + * Static functions + */ + +static void auto_connect(libinput_capability capability, int max_num_devs, int *num_devs, char *devs[], lv_indev_t *indevs[], + lv_indev_drv_t indev_drvs[], libinput_drv_state_t drv_states[]) { + + memset(devs, 0, max_num_devs * sizeof(char *)); + memset(indevs, 0, max_num_devs * sizeof(lv_indev_t)); + memset(indev_drvs, 0, max_num_devs * sizeof(lv_indev_drv_t)); + memset(drv_states, 0, max_num_devs * sizeof(libinput_drv_state_t)); + + *num_devs = libinput_find_devs(capability, devs, max_num_devs, false); + + for (int i = 0; i < *num_devs; ++i) { + log_connection(capability, devs[i]); + + libinput_init_state(&(drv_states[i]), devs[i]); + lv_indev_drv_init(&(indev_drvs[i])); + + indev_drvs[i].read_cb = libinput_read_cb; + indev_drvs[i].user_data = &(drv_states[i]); + + if (capability == LIBINPUT_CAPABILITY_KEYBOARD) { + indev_drvs[i].type = LV_INDEV_TYPE_KEYPAD; + } else { + indev_drvs[i].type = LV_INDEV_TYPE_POINTER; + indev_drvs[i].long_press_repeat_time = USHRT_MAX; + } + + indevs[i] = lv_indev_drv_register(&(indev_drvs[i])); + } +} + +static void log_connection(libinput_capability capability, char *dev) { + switch (capability) { + case LIBINPUT_CAPABILITY_KEYBOARD: + ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting keyboard device %s\n", dev); + break; + case LIBINPUT_CAPABILITY_POINTER: + ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting pointer device %s\n", dev); + break; + case LIBINPUT_CAPABILITY_TOUCH: + ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting touchscreen device %s\n", dev); + break; + case LIBINPUT_CAPABILITY_NONE: + break; + } +} + +static void libinput_read_cb(lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { + libinput_read_state(indev_drv->user_data, indev_drv, data); +} + + +/** + * Public functions + */ + +void ul_indev_auto_connect() { + auto_connect(LIBINPUT_CAPABILITY_KEYBOARD, MAX_KEYBOARD_DEVS, &num_keyboard_devs, keyboard_devs, keyboard_indevs, + keyboard_indev_drvs, keyboard_drv_states); + auto_connect(LIBINPUT_CAPABILITY_POINTER, MAX_POINTER_DEVS, &num_pointer_devs, pointer_devs, pointer_indevs, + pointer_indev_drvs, pointer_drv_states); + auto_connect(LIBINPUT_CAPABILITY_TOUCH, MAX_TOUCHSCREEN_DEVS, &num_touchscreen_devs, touchscreen_devs, touchscreen_indevs, + touchscreen_indev_drvs, touchscreen_drv_states); +} + +bool ul_indev_is_keyboard_connected() { + return num_keyboard_devs > 0; +} + +void ul_indev_set_up_textarea_for_keyboard_input(lv_obj_t *textarea) { + if (!ul_indev_is_keyboard_connected()) { + return; + } + + lv_group_t *group = lv_group_create(); + lv_group_add_obj(group, textarea); + + for (int i = 0; i < num_keyboard_devs; ++i) { + lv_indev_set_group(keyboard_indevs[i], group); + } +} + +void ul_indev_set_up_mouse_cursor() { + lv_obj_t *cursor_obj = lv_img_create(lv_scr_act()); + lv_img_set_src(cursor_obj, &ul_cursor_img_dsc); + for (int i = 0; i < num_pointer_devs; ++i) { + lv_indev_set_cursor(pointer_indevs[i], cursor_obj); + } +} diff --git a/indev.h b/indev.h new file mode 100644 index 0000000..e56afcc --- /dev/null +++ b/indev.h @@ -0,0 +1,52 @@ +/** + * Copyright 2021 Johannes Marbach + * + * 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 . + */ + + +#ifndef UL_INDEV_H +#define UL_INDEV_H + +#include "lvgl/lvgl.h" + +#include + +/** + * Auto-connect currently available keyboard, pointer and touchscreen input devices. + */ +void ul_indev_auto_connect(); + +/** + * 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(); + +/** + * Set up an LVGL text area to receive input from currently connected keyboard devices. + * + * @param textarea textarea widget + */ +void ul_indev_set_up_textarea_for_keyboard_input(lv_obj_t *textarea); + +/** + * Set up the mouse cursor image for currently connected pointer devices. + */ +void ul_indev_set_up_mouse_cursor(); + +#endif /* UL_INDEV_H */ diff --git a/libinput_multi.c b/libinput_multi.c deleted file mode 100644 index d259a16..0000000 --- a/libinput_multi.c +++ /dev/null @@ -1,249 +0,0 @@ -/** - * @file libinput_multi.c - * - */ - -/********************* - * INCLUDES - *********************/ -#include "libinput_multi.h" -#if USE_LIBINPUT || USE_BSD_LIBINPUT - -#include -#include -#include -#include -#include -#include -#include -#include - -#if USE_BSD_LIBINPUT -#include -#else -#include -#endif - -#include "libinput_xkb.h" - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ -static int open_restricted(const char *path, int flags, void *user_data); -static void close_restricted(int fd, void *user_data); - -typedef struct { - int button; - int libinput_key_val; - struct libinput_device *device; - void *keyboard_state; - - int libinput_fd; - struct libinput *libinput_context; - struct pollfd fds[1]; -} libinput_multi_state; - -/********************** - * STATIC VARIABLES - **********************/ -static const int timeout = 0; // do not block -static const nfds_t nfds = 1; -static lv_point_t most_recent_touch_point = { .x = 0, .y = 0}; - -static const struct libinput_interface interface = { - .open_restricted = open_restricted, - .close_restricted = close_restricted, -}; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -/** - * reconfigure the device file for libinput - * @param indev_drv driver object (must be initialised) - * @param dev_name set the libinput device filename - * @return true: the device file set complete - * false: the device file doesn't exist current system - */ -bool libinput_multi_set_file(lv_indev_drv_t * indev_drv, char* dev_name) -{ - libinput_multi_state *state = (libinput_multi_state *)indev_drv->user_data; - if (!state) { - perror("unable to read state from driver:"); - return false; - } - - // This check *should* not be necessary, yet applications crashes even on NULL handles. - // citing libinput.h:libinput_path_remove_device: - // > If no matching device exists, this function does nothing. - if (state->device) { - state->device = libinput_device_unref(state->device); - libinput_path_remove_device(state->device); - } - - state->device = libinput_path_add_device(state->libinput_context, dev_name); - if(!state->device) { - perror("unable to add device to libinput context:"); - return false; - } - state->device = libinput_device_ref(state->device); - if(!state->device) { - perror("unable to reference device within libinput context:"); - return false; - } - - state->button = LV_INDEV_STATE_REL; - state->libinput_key_val = 0; - - return true; -} - -/** - * initialise a driver with fresh state data - * @param indev_drv driver object - */ -void libinput_multi_init_driver(lv_indev_drv_t * indev_drv) { - libinput_multi_state *state = (libinput_multi_state *)malloc(sizeof(libinput_multi_state)); - state->device = NULL; - - state->libinput_context = libinput_path_create_context(&interface, NULL); - state->libinput_fd = libinput_get_fd(state->libinput_context); - - /* prepare poll */ - state->fds[0].fd = state->libinput_fd; - state->fds[0].events = POLLIN; - state->fds[0].revents = 0; - - state->keyboard_state = libinput_xkb_create_state(); - - indev_drv->user_data = (void *)state; -} - -/** - * destroy any existing state data on a driver - * @param indev_drv driver object - */ -void libinput_multi_deinit_driver(lv_indev_drv_t * indev_drv) { - if (indev_drv->user_data) { - libinput_multi_state *state = (libinput_multi_state *)indev_drv->user_data; - - struct libinput_device *device = libinput_device_unref(state->device); - libinput_path_remove_device(device); - - libinput_unref(state->libinput_context); - - // TODO: dealloc keyboard state - - free(indev_drv->user_data); - indev_drv->user_data = NULL; - } -} - -/** - * Get the current position and state of the libinput - * @param indev_drv driver object itself - * @param data store the libinput data here - * @return false: because the points are not buffered, so no more data to be read - */ -void libinput_multi_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data) -{ - libinput_multi_state *state = (libinput_multi_state *)indev_drv->user_data; - if (!state) { - perror("unable to read state from driver:"); - return; - } - - struct libinput_event *event; - struct libinput_event_touch *touch_event = NULL; - struct libinput_event_pointer *pointer_event = NULL; - struct libinput_event_keyboard *keyboard_event = NULL; - int rc = 0; - - rc = poll(state->fds, nfds, timeout); - switch (rc){ - case -1: - perror(NULL); - case 0: - goto report_most_recent_state; - default: - break; - } - libinput_dispatch(state->libinput_context); - while((event = libinput_get_event(state->libinput_context)) != NULL) { - enum libinput_event_type type = libinput_event_get_type(event); - switch (type) { - case LIBINPUT_EVENT_TOUCH_MOTION: - case LIBINPUT_EVENT_TOUCH_DOWN: - touch_event = libinput_event_get_touch_event(event); - most_recent_touch_point.x = libinput_event_touch_get_x_transformed(touch_event, LV_HOR_RES); - most_recent_touch_point.y = libinput_event_touch_get_y_transformed(touch_event, LV_VER_RES); - state->button = LV_INDEV_STATE_PR; - break; - case LIBINPUT_EVENT_TOUCH_UP: - state->button = LV_INDEV_STATE_REL; - break; - case LIBINPUT_EVENT_POINTER_MOTION: - pointer_event = libinput_event_get_pointer_event(event); - most_recent_touch_point.x += libinput_event_pointer_get_dx(pointer_event); - most_recent_touch_point.y += libinput_event_pointer_get_dy(pointer_event); - most_recent_touch_point.x = most_recent_touch_point.x < 0 ? 0 : most_recent_touch_point.x; - most_recent_touch_point.x = most_recent_touch_point.x > LV_HOR_RES - 1 ? LV_HOR_RES - 1 : most_recent_touch_point.x; - most_recent_touch_point.y = most_recent_touch_point.y < 0 ? 0 : most_recent_touch_point.y; - most_recent_touch_point.y = most_recent_touch_point.y > LV_VER_RES - 1 ? LV_VER_RES - 1 : most_recent_touch_point.y; - break; - case LIBINPUT_EVENT_POINTER_BUTTON: - pointer_event = libinput_event_get_pointer_event(event); - enum libinput_button_state button_state = libinput_event_pointer_get_button_state(pointer_event); - state->button = button_state == LIBINPUT_BUTTON_STATE_RELEASED ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR; - break; - case LIBINPUT_EVENT_KEYBOARD_KEY: - keyboard_event = libinput_event_get_keyboard_event(event); - enum libinput_key_state key_state = libinput_event_keyboard_get_key_state(keyboard_event); - uint32_t code = libinput_event_keyboard_get_key(keyboard_event); - state->libinput_key_val = libinput_xkb_process_key(code, key_state == LIBINPUT_KEY_STATE_PRESSED, state->keyboard_state); - if (state->libinput_key_val != 0) { - state->button = (key_state == LIBINPUT_KEY_STATE_RELEASED) ? LV_INDEV_STATE_REL : LV_INDEV_STATE_PR; // - } - break; - default: - break; - } - libinput_event_destroy(event); - } -report_most_recent_state: - data->point.x = most_recent_touch_point.x; - data->point.y = most_recent_touch_point.y; - data->state = state->button; - data->key = state->libinput_key_val; -} - - -/********************** - * STATIC FUNCTIONS - **********************/ - -static int open_restricted(const char *path, int flags, void *user_data) -{ - int fd = open(path, flags); - return fd < 0 ? -errno : fd; -} - -static void close_restricted(int fd, void *user_data) -{ - close(fd); -} - -#endif /* USE_LIBINPUT || USE_BSD_LIBINPUT */ diff --git a/libinput_multi.h b/libinput_multi.h deleted file mode 100644 index 56aa9b7..0000000 --- a/libinput_multi.h +++ /dev/null @@ -1,81 +0,0 @@ -/** - * @file libinput_multi.h - * - */ - -#ifndef LVGL_LIBINPUT_MULTI_H -#define LVGL_LIBINPUT_MULTI_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -// #ifndef LV_DRV_NO_CONF -// #ifdef LV_CONF_INCLUDE_SIMPLE -#include "lv_drv_conf.h" -// #else -// #include "../../lv_drv_conf.h" -// #endif -// #endif - -#if USE_LIBINPUT || USE_BSD_LIBINPUT - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include "lvgl.h" -#else -#include "lvgl/lvgl.h" -#endif - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -/** - * initialise a driver with fresh state data - * @param indev_drv driver object - */ -void libinput_multi_init_driver(lv_indev_drv_t * indev_drv); -/** - * destroy any existing state data on a driver - * @param indev_drv driver object - */ -void libinput_multi_deinit_driver(lv_indev_drv_t * indev_drv); -/** - * reconfigure the device file for libinput - * @param indev_drv driver object (must be initialised) - * @param dev_name set the libinput device filename - * @return true: the device file set complete - * false: the device file doesn't exist current system - */ -bool libinput_multi_set_file(lv_indev_drv_t * indev_drv, char* dev_name); -/** - * Get the current position and state of the libinput - * @param indev_drv driver object itself - * @param data store the libinput data here - * @return false: because the points are not buffered, so no more data to be read - */ -void libinput_multi_read(lv_indev_drv_t * indev_drv, lv_indev_data_t * data); - - -/********************** - * MACROS - **********************/ - -#endif /* USE_LIBINPUT || USE_BSD_LIBINPUT */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LVGL_LIBINPUT_MULTI_H */ diff --git a/libinput_xkb.c b/libinput_xkb.c deleted file mode 100644 index a085ecf..0000000 --- a/libinput_xkb.c +++ /dev/null @@ -1,146 +0,0 @@ -/** - * @file libinput_xkb.c - * - */ - -/********************* - * INCLUDES - *********************/ -#include "libinput_xkb.h" -#if USE_LIBINPUT || USE_BSD_LIBINPUT - -#include -#include -#include - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * STATIC PROTOTYPES - **********************/ - -/********************** - * STATIC VARIABLES - **********************/ -static struct xkb_context *ctx = NULL; -static struct xkb_keymap *keymap = NULL; - -/********************** - * MACROS - **********************/ - -/********************** - * GLOBAL FUNCTIONS - **********************/ - -bool libinput_xkb_init(void) { - if (ctx) { - perror("context is already initialised"); - return true; - } - - ctx = xkb_context_new(XKB_CONTEXT_NO_FLAGS); - if (!ctx) { - perror("could not create new XKB context"); - return false; - } - - struct xkb_rule_names names = { - .rules = NULL, - .model = "pc105", - .layout = "de", - .variant = "nodeadkeys", - .options = NULL - }; - - keymap = xkb_keymap_new_from_names(ctx, &names, XKB_KEYMAP_COMPILE_NO_FLAGS); - if (!keymap) { - perror("could not create XKB keymap"); - return false; - } - - keymap = xkb_keymap_ref(keymap); - if (!keymap) { - perror("could not reference XKB keymap"); - return false; - } - - return true; -} - -void *libinput_xkb_create_state(void) { - struct xkb_state *state = xkb_state_new(keymap); - if (!state) { - perror("could not create XKB state"); - return false; - } - - state = xkb_state_ref(state); - if (!state) { - perror("could not reference XKB state"); - return false; - } - - return state; -} - -uint32_t libinput_xkb_process_key(uint32_t scancode, bool down, void *state) { - /* Offset the evdev scancode by 8, see https://xkbcommon.org/doc/current/xkbcommon_8h.html#ac29aee92124c08d1953910ab28ee1997 */ - xkb_keycode_t keycode = scancode + 8; - - uint32_t result = 0; - - switch (xkb_state_key_get_one_sym(state, keycode)) { - case XKB_KEY_BackSpace: - result = LV_KEY_BACKSPACE; - break; - case XKB_KEY_Return: - result = LV_KEY_ENTER; - break; - case XKB_KEY_Prior: - result = LV_KEY_PREV; - break; - case XKB_KEY_Next: - result = LV_KEY_NEXT; - break; - case XKB_KEY_Up: - result = LV_KEY_UP; - break; - case XKB_KEY_Left: - result = LV_KEY_LEFT; - break; - case XKB_KEY_Right: - result = LV_KEY_RIGHT; - break; - case XKB_KEY_Down: - result = LV_KEY_DOWN; - break; - default: - break; - } - - if (result == 0) { - char buffer[4] = { 0, 0, 0, 0 }; - int size = xkb_state_key_get_utf8((struct xkb_state *)state, keycode, NULL, 0) + 1; - if (size > 1) { - xkb_state_key_get_utf8((struct xkb_state *)state, keycode, buffer, size); - memcpy(&result, buffer, 4); - } - } - - xkb_state_update_key((struct xkb_state *)state, keycode, down ? XKB_KEY_DOWN : XKB_KEY_UP); - - return result; -} - -/********************** - * STATIC FUNCTIONS - **********************/ - -#endif /* USE_LIBINPUT || USE_BSD_LIBINPUT */ diff --git a/libinput_xkb.h b/libinput_xkb.h deleted file mode 100644 index a8f4f21..0000000 --- a/libinput_xkb.h +++ /dev/null @@ -1,58 +0,0 @@ -/** - * @file libinput_xkb.h - * - */ - -#ifndef LVGL_LIBINPUT_XKB_H -#define LVGL_LIBINPUT_XKB_H - -#ifdef __cplusplus -extern "C" { -#endif - -/********************* - * INCLUDES - *********************/ -// #ifndef LV_DRV_NO_CONF -// #ifdef LV_CONF_INCLUDE_SIMPLE -#include "lv_drv_conf.h" -// #else -// #include "../../lv_drv_conf.h" -// #endif -// #endif - -#if USE_LIBINPUT || USE_BSD_LIBINPUT - -#ifdef LV_LVGL_H_INCLUDE_SIMPLE -#include "lvgl.h" -#else -#include "lvgl/lvgl.h" -#endif - -/********************* - * DEFINES - *********************/ - -/********************** - * TYPEDEFS - **********************/ - -/********************** - * GLOBAL PROTOTYPES - **********************/ - -bool libinput_xkb_init(void); -void *libinput_xkb_create_state(void); -uint32_t libinput_xkb_process_key(uint32_t code, bool down, void *state); - -/********************** - * MACROS - **********************/ - -#endif /* USE_LIBINPUT || USE_BSD_LIBINPUT */ - -#ifdef __cplusplus -} /* extern "C" */ -#endif - -#endif /* LVGL_LIBINPUT_XKB_H */ diff --git a/lv_drivers b/lv_drivers index 8960d0f..7a0f788 160000 --- a/lv_drivers +++ b/lv_drivers @@ -1 +1 @@ -Subproject commit 8960d0fcd0ae4b947169b4282ee7ff94ce5d1cef +Subproject commit 7a0f788733d53399c87d9572b4f5326e0fe16b16 diff --git a/main.c b/main.c index 830ddcf..b4def86 100644 --- a/main.c +++ b/main.c @@ -19,20 +19,16 @@ #include "command_line.h" -#include "cursor.h" -#include "libinput_multi.h" -#include "libinput_xkb.h" +#include "indev.h" #include "log.h" #include "unl0kr.h" #include "lv_drivers/display/fbdev.h" -#include "lv_drivers/indev/libinput_drv.h" #include "lvgl/lvgl.h" #include "squeek2lvgl/sq2lv.h" -#include #include #include #include @@ -378,70 +374,15 @@ int main(int argc, char *argv[]) { disp_drv.ver_res = ver_res; lv_disp_drv_register(&disp_drv); - /* Connect keyboards */ - libinput_xkb_init(); - #define MAX_KEYBOARDS 3 - char *keyboard_devices[MAX_KEYBOARDS] = { NULL, NULL, NULL }; - lv_indev_drv_t keyboard_indev_drvs[MAX_KEYBOARDS]; - lv_indev_t *keyboard_indevs[MAX_KEYBOARDS] = { NULL, NULL, NULL }; - size_t num_keyboards = libinput_find_devs(LIBINPUT_CAPABILITY_KEYBOARD, keyboard_devices, MAX_KEYBOARDS, false); - for (int i = 0; i < num_keyboards; ++i) { - ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting keyboard device %s\n", keyboard_devices[i]); - lv_indev_drv_init(&keyboard_indev_drvs[i]); - keyboard_indev_drvs[i].type = LV_INDEV_TYPE_KEYPAD; - keyboard_indev_drvs[i].read_cb = libinput_multi_read; - libinput_multi_init_driver(&keyboard_indev_drvs[i]); - libinput_multi_set_file(&keyboard_indev_drvs[i], keyboard_devices[i]); - keyboard_indevs[i] = lv_indev_drv_register(&keyboard_indev_drvs[i]); - } + /* Connect input devices */ + ul_indev_auto_connect(); + ul_indev_set_up_mouse_cursor(); /* Hide the on-screen keyboard by default if a physical keyboard is connected */ - if (num_keyboards > 0) { + if (ul_indev_is_keyboard_connected()) { is_keyboard_hidden = true; } - /* Connect mice and trackpads */ - #define MAX_POINTER_DEVICES 4 - char *pointer_devices[MAX_POINTER_DEVICES] = { NULL, NULL, NULL, NULL }; - lv_indev_drv_t pointer_indev_drvs[MAX_POINTER_DEVICES]; - lv_indev_t *pointer_indevs[MAX_POINTER_DEVICES] = { NULL, NULL, NULL, NULL }; - size_t num_pointer_devices = libinput_find_devs(LIBINPUT_CAPABILITY_POINTER, pointer_devices, MAX_POINTER_DEVICES, false); - for (int i = 0; i < num_pointer_devices; ++i) { - ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting pointer device %s\n", pointer_devices[i]); - lv_indev_drv_init(&pointer_indev_drvs[i]); - pointer_indev_drvs[i].type = LV_INDEV_TYPE_POINTER; - pointer_indev_drvs[i].read_cb = libinput_multi_read; - pointer_indev_drvs[i].long_press_repeat_time = USHRT_MAX; - libinput_multi_init_driver(&pointer_indev_drvs[i]); - libinput_multi_set_file(&pointer_indev_drvs[i], pointer_devices[i]); - pointer_indevs[i] = lv_indev_drv_register(&pointer_indev_drvs[i]); - } - - /* Set mouse cursor */ - if (num_pointer_devices > 0) { - lv_obj_t *cursor_obj = lv_img_create(lv_scr_act()); - lv_img_set_src(cursor_obj, &ul_cursor_img_dsc); - for (int i = 0; i < num_pointer_devices; ++i) { - lv_indev_set_cursor(pointer_indevs[i], cursor_obj); - } - } - - /* Connect touchscreens */ - #define MAX_TOUCHSCREENS 1 - char *touchscreens[MAX_TOUCHSCREENS] = { NULL }; - lv_indev_drv_t touchscreen_indev_drvs[MAX_TOUCHSCREENS]; - size_t num_touchscreens = libinput_find_devs(LIBINPUT_CAPABILITY_TOUCH, touchscreens, MAX_TOUCHSCREENS, false); - for (int i = 0; i < num_touchscreens; ++i) { - ul_log(UL_LOG_LEVEL_VERBOSE, "Connecting touchscreen device %s\n", touchscreens[i]); - lv_indev_drv_init(&touchscreen_indev_drvs[i]); - touchscreen_indev_drvs[i].type = LV_INDEV_TYPE_POINTER; - touchscreen_indev_drvs[i].read_cb = libinput_multi_read; - touchscreen_indev_drvs[i].long_press_repeat_time = USHRT_MAX; - libinput_multi_init_driver(&touchscreen_indev_drvs[i]); - libinput_multi_set_file(&touchscreen_indev_drvs[i], touchscreens[i]); - lv_indev_drv_register(&touchscreen_indev_drvs[i]); - } - /* Initialise theme and styles */ set_theme(is_dark_theme); lv_style_init(&style_text_normal); @@ -510,11 +451,7 @@ int main(int argc, char *argv[]) { lv_obj_add_style(textarea, &style_text_normal, 0); /* Route physical keyboard input into textarea */ - lv_group_t *group = lv_group_create(); - lv_group_add_obj(group, textarea); - for (int i = 0; i < num_keyboards; ++i) { - lv_indev_set_group(keyboard_indevs[i], group); - } + ul_indev_set_up_textarea_for_keyboard_input(textarea); /* Show / hide password button */ lv_obj_t *toggle_pw_btn = lv_btn_create(lv_scr_act()); diff --git a/meson.build b/meson.build index 42328a9..f389253 100644 --- a/meson.build +++ b/meson.build @@ -29,9 +29,8 @@ add_project_arguments('-DUL_VERSION="@0@"'.format(meson.project_version()), lang unl0kr_sources = [ 'command_line.c', 'cursor.c', + 'indev.c', 'log.c', - 'libinput_multi.c', - 'libinput_xkb.c', 'main.c', 'montserrat_extended_32.c', 'sq2lv_layouts.c',