You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
This repo is archived. You can view files and clone it, but cannot push or open issues/pull-requests.
ndg/lib/lv_drivers/indev/xkb.c

223 lines
5.9 KiB
C

/**
* @file xkb.c
*
*/
/*********************
* INCLUDES
*********************/
#include "xkb.h"
#if USE_XKB
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <xkbcommon/xkbcommon.h>
/*********************
* DEFINES
*********************/
/**********************
* TYPEDEFS
**********************/
/**********************
* STATIC PROTOTYPES
**********************/
/**********************
* STATIC VARIABLES
**********************/
static struct xkb_context *context = NULL;
static xkb_drv_state_t default_state = { .keymap = NULL, .state = NULL };
/**********************
* MACROS
**********************/
/**********************
* GLOBAL FUNCTIONS
**********************/
/**
* Initialise the XKB system using the default driver state. Use this function if you only want
* to connect a single device.
* @return true if the initialisation was successful
*/
bool xkb_init(void) {
return xkb_init_state(&default_state);
}
/**
* Initialise the XKB system using a specific driver state. Use this function if you want to
* connect multiple devices.
* @param state XKB driver state to use
* @return true if the initialisation was successful
*/
bool xkb_init_state(xkb_drv_state_t *state) {
if (!context) {
context = xkb_context_new(XKB_CONTEXT_NO_FLAGS);
if (!context) {
perror("could not create new XKB context");
return false;
}
}
#ifdef XKB_KEY_MAP
struct xkb_rule_names names = XKB_KEY_MAP;
return xkb_set_keymap_state(state, names);
#else
return false; /* Keymap needs to be set manually using xkb_set_keymap_state to complete initialisation */
#endif
}
Squashed 'lib/lv_drivers/' changes from 718302577..0091dc612 0091dc612 fix(wayland): fix compile error wrt LV_WAYLAND_CLIENT_SIDE_DECORATIONS (#307) 451e659cf Add pkgconfig file (#301) 5a5b4a1a3 added x11 display driver port (#300) 4391dbf32 perf(drm): use wait_cb for direct double-buffered rendering (#299) 7e18481ce fix(drm): backport drm driver fixes from lvgl 9 (#298) f5b58b947 feat(evdev): backport multi device support from lvgl 9 (#296) ad66ff155 add return value to drm_init c239cc465 Removed clamp from Calibrate section as it has map in it e44e7f043 fix(build): Update xpt2046_read to match signature required by lv_indev_drv_t's read callback. (#290) 7b9dee11c Fix crash during startup in certain conditions (#286) 9d153fb65 Add USE_WAYLAND to smm.c (#285) 8669c6fc8 libInput: Add POINTER_MOTION_ABSOLUTE support (#284) c71e5f84b drm: Default to XRGB8888 framebuffer (#282) 57494ff8e Add a way to set SDL window title from lv_drv_conf.h (#277) b03c9dac9 fix(xkb): Fix memory leak by avoiding double reference (#276) ec0ad8296 feature(libinput): Expose function for querying capability (#275) 0d5de84e2 feature(libinput): Add function to reset driver states (#274) 94dc4ce06 Use win32 singly linked list instead of LVGL linked list for fixing memory access conflict issues for win32drv. (#273) 1792ab20a feature(wayland): add a shared memory manager, allowing backing buffers to be allocated on demand. (#270) f7935569f use SDL_RES instead of LV_RES for touch events (#268) ba9c3cc4f Update README.md (#261) f261225d9 follow lvgl changes ab5e30ccb Add the multiple display support for win32drv. (#259) 820341ea1 Improve the keyboard support for win32drv. (#258) b13361a1f fix: The mouse moves outside the screen area (#251) 829e0ffc3 chore(wayland) : accelerate damage updates, reduce unnecessary cycles (#249) 5523f9974 fix(wayland-protocols): minimum version (#246) fe9de86e9 Wayland api fixes (#243) 59e698ce1 fix(wayland) : fix possible memory leak (#238) 2ed01feab fix(drm): Fix compiler warnings (#237) cf4e6d75a make windows.h lower case (#236) dc0d71a3a chore(sdl): fix warning (#232) c68b59e42 fix(fbdev): Fix rendering for 24 bits per pixel (#231) 4f98fddd2 hide the SDL2 include from public LVGL functions (#227) ff01834db fix(fbdev): Gracefully handle FBIOBLANK errors (#229) 73219786a bump version number to v9.0.0-dev git-subtree-dir: lib/lv_drivers git-subtree-split: 0091dc612facc94dce1061a9b78d641c77f1791a
7 months ago
/**
* De-initialise a previously initialised driver state and free any dynamically allocated memory. Use this function if you want to
* reuse an existing driver state.
* @param state XKB driver state to use
*/
void xkb_deinit_state(xkb_drv_state_t *state) {
if (state->state) {
xkb_state_unref(state->state);
state->state = NULL;
}
if (state->keymap) {
xkb_keymap_unref(state->keymap);
state->keymap = NULL;
}
}
/**
* Set a new keymap to be used for processing future key events using the default driver state. Use
* this function if you only want to connect a single device.
* @param names XKB rule names structure (use NULL components for default values)
* @return true if creating the keymap and associated state succeeded
*/
bool xkb_set_keymap(struct xkb_rule_names names) {
return xkb_set_keymap_state(&default_state, names);
}
/**
* Set a new keymap to be used for processing future key events using a specific driver state. Use
* this function if you want to connect multiple devices.
* @param state XKB driver state to use
* @param names XKB rule names structure (use NULL components for default values)
* @return true if creating the keymap and associated state succeeded
*/
bool xkb_set_keymap_state(xkb_drv_state_t *state, struct xkb_rule_names names) {
if (state->keymap) {
xkb_keymap_unref(state->keymap);
state->keymap = NULL;
}
Squashed 'lib/lv_drivers/' changes from 718302577..0091dc612 0091dc612 fix(wayland): fix compile error wrt LV_WAYLAND_CLIENT_SIDE_DECORATIONS (#307) 451e659cf Add pkgconfig file (#301) 5a5b4a1a3 added x11 display driver port (#300) 4391dbf32 perf(drm): use wait_cb for direct double-buffered rendering (#299) 7e18481ce fix(drm): backport drm driver fixes from lvgl 9 (#298) f5b58b947 feat(evdev): backport multi device support from lvgl 9 (#296) ad66ff155 add return value to drm_init c239cc465 Removed clamp from Calibrate section as it has map in it e44e7f043 fix(build): Update xpt2046_read to match signature required by lv_indev_drv_t's read callback. (#290) 7b9dee11c Fix crash during startup in certain conditions (#286) 9d153fb65 Add USE_WAYLAND to smm.c (#285) 8669c6fc8 libInput: Add POINTER_MOTION_ABSOLUTE support (#284) c71e5f84b drm: Default to XRGB8888 framebuffer (#282) 57494ff8e Add a way to set SDL window title from lv_drv_conf.h (#277) b03c9dac9 fix(xkb): Fix memory leak by avoiding double reference (#276) ec0ad8296 feature(libinput): Expose function for querying capability (#275) 0d5de84e2 feature(libinput): Add function to reset driver states (#274) 94dc4ce06 Use win32 singly linked list instead of LVGL linked list for fixing memory access conflict issues for win32drv. (#273) 1792ab20a feature(wayland): add a shared memory manager, allowing backing buffers to be allocated on demand. (#270) f7935569f use SDL_RES instead of LV_RES for touch events (#268) ba9c3cc4f Update README.md (#261) f261225d9 follow lvgl changes ab5e30ccb Add the multiple display support for win32drv. (#259) 820341ea1 Improve the keyboard support for win32drv. (#258) b13361a1f fix: The mouse moves outside the screen area (#251) 829e0ffc3 chore(wayland) : accelerate damage updates, reduce unnecessary cycles (#249) 5523f9974 fix(wayland-protocols): minimum version (#246) fe9de86e9 Wayland api fixes (#243) 59e698ce1 fix(wayland) : fix possible memory leak (#238) 2ed01feab fix(drm): Fix compiler warnings (#237) cf4e6d75a make windows.h lower case (#236) dc0d71a3a chore(sdl): fix warning (#232) c68b59e42 fix(fbdev): Fix rendering for 24 bits per pixel (#231) 4f98fddd2 hide the SDL2 include from public LVGL functions (#227) ff01834db fix(fbdev): Gracefully handle FBIOBLANK errors (#229) 73219786a bump version number to v9.0.0-dev git-subtree-dir: lib/lv_drivers git-subtree-split: 0091dc612facc94dce1061a9b78d641c77f1791a
7 months ago
state->keymap = xkb_keymap_new_from_names(context, &names, XKB_KEYMAP_COMPILE_NO_FLAGS);
if (!state->keymap) {
perror("could not create XKB keymap");
return false;
}
if (state->state) {
xkb_state_unref(state->state);
state->state = NULL;
}
state->state = xkb_state_new(state->keymap);
if (!state->state) {
perror("could not create XKB state");
return false;
}
return true;
}
/**
* Process an evdev scancode using the default driver state. Use this function if you only want to
* connect a single device.
* @param scancode evdev scancode to process
* @param down true if the key was pressed, false if it was releases
* @return the (first) UTF-8 character produced by the event or 0 if no output was produced
*/
uint32_t xkb_process_key(uint32_t scancode, bool down) {
return xkb_process_key_state(&default_state, scancode, down);
}
/**
* Process an evdev scancode using a specific driver state. Use this function if you want to connect
* multiple devices.
* @param state XKB driver state to use
* @param scancode evdev scancode to process
* @param down true if the key was pressed, false if it was releases
* @return the (first) UTF-8 character produced by the event or 0 if no output was produced
*/
uint32_t xkb_process_key_state(xkb_drv_state_t *state, uint32_t scancode, bool down) {
/* 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->state, keycode)) {
case XKB_KEY_BackSpace:
result = LV_KEY_BACKSPACE;
break;
case XKB_KEY_Return:
case XKB_KEY_KP_Enter:
result = LV_KEY_ENTER;
break;
case XKB_KEY_Prior:
case XKB_KEY_KP_Prior:
result = LV_KEY_PREV;
break;
case XKB_KEY_Next:
case XKB_KEY_KP_Next:
result = LV_KEY_NEXT;
break;
case XKB_KEY_Up:
case XKB_KEY_KP_Up:
result = LV_KEY_UP;
break;
case XKB_KEY_Left:
case XKB_KEY_KP_Left:
result = LV_KEY_LEFT;
break;
case XKB_KEY_Right:
case XKB_KEY_KP_Right:
result = LV_KEY_RIGHT;
break;
case XKB_KEY_Down:
case XKB_KEY_KP_Down:
result = LV_KEY_DOWN;
break;
case XKB_KEY_Tab:
case XKB_KEY_KP_Tab:
result = LV_KEY_NEXT;
break;
case XKB_KEY_ISO_Left_Tab: /* Sent on SHIFT + TAB */
result = LV_KEY_PREV;
break;
default:
break;
}
if (result == 0) {
char buffer[4] = { 0, 0, 0, 0 };
int size = xkb_state_key_get_utf8(state->state, keycode, NULL, 0) + 1;
if (size > 1) {
xkb_state_key_get_utf8(state->state, keycode, buffer, size);
memcpy(&result, buffer, 4);
}
}
xkb_state_update_key(state->state, keycode, down ? XKB_KEY_DOWN : XKB_KEY_UP);
return result;
}
/**********************
* STATIC FUNCTIONS
**********************/
#endif /* USE_XKB */