Files
buffybox/squeek2lvgl/sq2lv.c
Vladimir Stoiakin 5c782575f2 misc: fix warnings
2025-04-17 14:08:19 +03:00

245 lines
7.0 KiB
C

/**
* Copyright 2021 Johannes Marbach
* SPDX-License-Identifier: GPL-3.0-or-later
*/
#include "sq2lv.h"
#include <string.h>
/**
* Static variables
*/
static sq2lv_layout_id_t current_layout_id = SQ2LV_LAYOUT_NONE;
/**
* Static prototypes
*/
/**
* Convert a layer index to an LVGL keyboard mode.
*
* @param layer_index layer index to convert
* @return corresponding LVGL keyboard mode
*/
static lv_keyboard_mode_t layer_index_to_keyboard_mode(int layer_index);
/**
* Convert an LVGL keyboard mode to a layer index.
*
* @param keyboard_mode LVGL keyboard mode to convert
* @return corresponding layer index
*/
static int keyboard_mode_to_layer_index(lv_keyboard_mode_t keyboard_mode);
/**
* Get the layer index corresponding to a keyboard's current mode.
*
* @param keyboard keyboard widget
* @return layer index
*/
static int get_layer_index(lv_obj_t *keyboard);
/**
* Get the index of the destination layer for a layer switcher key in the current layout.
*
* @param keyboard keyboard widget
* @param btn_id button index corresponding to the key
* @return the destination layer's index or -1 if the key is not a layer switcher
*/
static int get_destination_layer_index_for_layer_switcher(lv_obj_t *keyboard, uint16_t btn_id);
/**
* Static functions
*/
static lv_keyboard_mode_t layer_index_to_keyboard_mode(int layer_index) {
switch (layer_index) {
case 0:
return LV_KEYBOARD_MODE_TEXT_LOWER;
case 1:
return LV_KEYBOARD_MODE_TEXT_UPPER;
case 2:
return LV_KEYBOARD_MODE_SPECIAL;
case 3:
return LV_KEYBOARD_MODE_NUMBER;
case 4:
return LV_KEYBOARD_MODE_USER_1;
case 5:
return LV_KEYBOARD_MODE_USER_2;
case 6:
return LV_KEYBOARD_MODE_USER_3;
case 7:
return LV_KEYBOARD_MODE_USER_4;
default:
return -1;
}
}
static int keyboard_mode_to_layer_index(lv_keyboard_mode_t keyboard_mode) {
switch (keyboard_mode) {
case LV_KEYBOARD_MODE_TEXT_LOWER:
return 0;
case LV_KEYBOARD_MODE_TEXT_UPPER:
return 1;
case LV_KEYBOARD_MODE_SPECIAL:
return 2;
case LV_KEYBOARD_MODE_NUMBER:
return 3;
case LV_KEYBOARD_MODE_USER_1:
return 4;
case LV_KEYBOARD_MODE_USER_2:
return 5;
case LV_KEYBOARD_MODE_USER_3:
return 6;
case LV_KEYBOARD_MODE_USER_4:
return 7;
default:
return -1;
}
}
static int get_layer_index(lv_obj_t *keyboard) {
return keyboard_mode_to_layer_index(lv_keyboard_get_mode(keyboard));
}
static int get_destination_layer_index_for_layer_switcher(lv_obj_t *keyboard, uint16_t btn_id) {
if (current_layout_id < 0 || current_layout_id >= sq2lv_num_layouts) {
return -1;
}
int layer_index = get_layer_index(keyboard);
if (layer_index < 0 || layer_index >= sq2lv_layouts[current_layout_id].num_layers) {
return -1;
}
for (int i = 0; i < sq2lv_layouts[current_layout_id].layers[layer_index].num_switchers; ++i) {
if (sq2lv_layouts[current_layout_id].layers[layer_index].switcher_idxs[i] == btn_id) {
return sq2lv_layouts[current_layout_id].layers[layer_index].switcher_dests[i];
}
}
return -1;
}
/**
* Public functions
*/
sq2lv_layout_id_t sq2lv_find_layout_with_short_name(const char *name) {
for (int i = 0; i < sq2lv_num_layouts; ++i) {
if (strcmp(sq2lv_layouts[i].short_name, name) == 0) {
return i;
}
}
return SQ2LV_LAYOUT_NONE;
}
void sq2lv_switch_layout(lv_obj_t *keyboard, sq2lv_layout_id_t layout_id) {
if (layout_id < 0 || layout_id >= sq2lv_num_layouts) {
return;
}
/* Assign layers */
for (int i = 0; i < sq2lv_layouts[layout_id].num_layers; ++i) {
lv_keyboard_set_map(keyboard, layer_index_to_keyboard_mode(i),
(const char **)sq2lv_layouts[layout_id].layers[i].keycaps,
sq2lv_layouts[layout_id].layers[i].attributes);
}
/* Switch to default layer if current layer doesn't exist in new layout */
int layer_index = get_layer_index(keyboard);
if (layer_index < 0 || layer_index >= sq2lv_layouts[layout_id].num_layers) {
lv_keyboard_set_mode(keyboard, layer_index_to_keyboard_mode(0));
}
current_layout_id = layout_id;
}
bool sq2lv_is_layer_switcher(lv_obj_t *keyboard, uint16_t btn_id) {
return get_destination_layer_index_for_layer_switcher(keyboard, btn_id) >= 0;
}
bool sq2lv_switch_layer(lv_obj_t *keyboard, uint16_t btn_id) {
int destination_layer_index = get_destination_layer_index_for_layer_switcher(keyboard, btn_id);
if (destination_layer_index < 0 || destination_layer_index >= sq2lv_layouts[current_layout_id].num_layers) {
return false;
}
lv_keyboard_set_mode(keyboard, layer_index_to_keyboard_mode(destination_layer_index));
return true;
}
bool sq2lv_is_modifier(lv_obj_t *keyboard, uint16_t btn_id) {
if (current_layout_id < 0 || current_layout_id >= sq2lv_num_layouts) {
return false;
}
int layer_index = get_layer_index(keyboard);
if (layer_index < 0 || layer_index >= sq2lv_layouts[current_layout_id].num_layers) {
return false;
}
for (int i = 0; i < sq2lv_layouts[current_layout_id].layers[layer_index].num_modifiers; ++i) {
if (sq2lv_layouts[current_layout_id].layers[layer_index].modifier_idxs[i] == btn_id) {
return true;
}
}
return false;
}
int *sq2lv_get_modifier_indexes(lv_obj_t *keyboard, int *num_modifiers) {
if (current_layout_id < 0 || current_layout_id >= sq2lv_num_layouts) {
*num_modifiers = 0;
return NULL;
}
int layer_index = get_layer_index(keyboard);
if (layer_index < 0 || layer_index >= sq2lv_layouts[current_layout_id].num_layers) {
*num_modifiers = 0;
return NULL;
}
*num_modifiers = sq2lv_layouts[current_layout_id].layers[layer_index].num_modifiers;
if (*num_modifiers == 0) {
return NULL;
}
return (int *)(&(sq2lv_layouts[current_layout_id].layers[layer_index].modifier_idxs[0]));
}
#if SQ2LV_SCANCODES_ENABLED
const int *sq2lv_get_scancodes(lv_obj_t *keyboard, uint16_t btn_id, int *num_scancodes) {
if (current_layout_id < 0 || current_layout_id >= sq2lv_num_layouts) {
*num_scancodes = 0;
return NULL;
}
int layer_index = get_layer_index(keyboard);
if (layer_index < 0 || layer_index >= sq2lv_layouts[current_layout_id].num_layers) {
*num_scancodes = 0;
return NULL;
}
if (btn_id >= sq2lv_layouts[current_layout_id].layers[layer_index].num_keys) {
*num_scancodes = 0;
return NULL;
}
*num_scancodes = sq2lv_layouts[current_layout_id].layers[layer_index].scancode_nums[btn_id];
if (*num_scancodes == 0) {
return NULL;
}
const int index = sq2lv_layouts[current_layout_id].layers[layer_index].scancode_idxs[btn_id];
return &(sq2lv_layouts[current_layout_id].layers[layer_index].scancodes[index]);
}
#endif /* SQ2LV_SCANCODES_ENABLED */