245 lines
7.0 KiB
C
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 */
|