diff --git a/Makefile b/Makefile index f97e8d9..3a7e113 100644 --- a/Makefile +++ b/Makefile @@ -23,7 +23,7 @@ CFLAGS ?= -O3 -g0 -I$(LVGL_DIR)/ -Wall -Wshadow -Wundef -Wmissing-prototypes -Wn LDFLAGS ?= -lm -linput BIN = buffyboard -MAINSRC = ./cursor.c ./layout.c ./libinput_multi.c ./main.c ./montserrat_extended_32.c ./sq2lv_layouts.c ./terminal.c ./uinput_device.c +MAINSRC = ./cursor.c ./libinput_multi.c ./main.c ./montserrat_extended_32.c ./sq2lv_layouts.c ./squeek2lvgl/sq2lv.c ./terminal.c ./uinput_device.c include $(LVGL_DIR)/lvgl/lvgl.mk include $(LVGL_DIR)/lv_drivers/lv_drivers.mk diff --git a/layout.c b/layout.c deleted file mode 100644 index c6059eb..0000000 --- a/layout.c +++ /dev/null @@ -1,229 +0,0 @@ -/** - * Copyright 2021 Johannes Marbach - * - * This file is part of buffyboard, 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 "layout.h" - - -/** - * Static variables - */ - -static sq2lv_layout_id_t current_layout_id = -1; - - -/** - * 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; - 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; - 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 - */ - -void bb_layout_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), - 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 bb_layout_is_layer_switcher(lv_obj_t *keyboard, uint16_t btn_id) { - return get_destination_layer_index_for_layer_switcher(keyboard, btn_id) >= 0; -} - -bool bb_layout_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; -} - -const int * const bb_layout_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]); -} - -bool bb_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; -} - -const int * const bb_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 &(sq2lv_layouts[current_layout_id].layers[layer_index].modifier_idxs[0]); -} diff --git a/layout.h b/layout.h deleted file mode 100644 index fcf6da1..0000000 --- a/layout.h +++ /dev/null @@ -1,80 +0,0 @@ -/** - * Copyright 2021 Johannes Marbach - * - * This file is part of buffyboard, 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 BB_LAYOUT_H -#define BB_LAYOUT_H - -#include "sq2lv_layouts.h" - -/** - * Apply a layout to a keyboard. - * - * @param keyboard keyboard widget - * @param layout_id layout ID - */ -void bb_layout_switch_layout(lv_obj_t *keyboard, sq2lv_layout_id_t layout_id); - -/** - * Check if a key acts as a layer switcher in the current layer. - * - * @param keyboard keyboard widget - * @param btn_id button index corresponding to the key - * @return true if a layer switch would happen if the key is pressed, false otherwise - */ -bool bb_layout_is_layer_switcher(lv_obj_t *keyboard, uint16_t btn_id); - -/** - * Attempt to perform a layer switch after pressing a key in the current layer. - * - * @param keyboard keyboard widget - * @param btn_id button index corresponding to the pressed key - * @return true if a layer switch was performed, false otherwise - */ -bool bb_layout_switch_layer(lv_obj_t *keyboard, uint16_t btn_id); - -/** - * Get scancodes associated with a key in the current layer. - * - * @param keyboard keyboard widget - * @param btn_id button index corresponding to the key - * @param num_scancodes pointer to an integer into which the number of scancodes will be written - * @return pointer into an array of scancodes at the appropriate index - */ -const int * const bb_layout_get_scancodes(lv_obj_t *keyboard, uint16_t btn_id, int *num_scancodes); - -/** - * Check if a key is a modifier in the current layer. - * - * @param keyboard keyboard widget - * @param btn_id button index corresponding to the key - * @return true if the key is a modifier, false otherwise - */ -bool bb_is_modifier(lv_obj_t *keyboard, uint16_t btn_id); - -/** - * Get the button indexes for all modifier keys in the current layer. - * - * @param keyboard keyboard widget - * @param num_modifiers pointer to an integer into which the number of modifiers will be written - * @return pointer to the array of button indexes corresponding to modifier keys - */ -const int * const bb_get_modifier_indexes(lv_obj_t *keyboard, int *num_modifiers); - -#endif /* BB_LAYOUT_H */ diff --git a/lv_drv_conf.h b/lv_drv_conf.h index c4a7e34..d2f50a6 100644 --- a/lv_drv_conf.h +++ b/lv_drv_conf.h @@ -416,7 +416,7 @@ *------------------------------------------------*/ #if USE_LIBINPUT || USE_BSD_LIBINPUT || USE_EVDEV || USE_BSD_EVDEV # ifndef USE_XKB -# define USE_XKB 1 +# define USE_XKB 0 # endif # if USE_XKB diff --git a/main.c b/main.c index 559df8d..c87ba86 100644 --- a/main.c +++ b/main.c @@ -19,16 +19,18 @@ #include "cursor.h" -#include "layout.h" #include "libinput_multi.h" #include "sq2lv_layouts.h" #include "terminal.h" #include "uinput_device.h" -#include "lvgl/lvgl.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 @@ -89,19 +91,16 @@ static void keyboard_value_changed_cb(lv_event_t *event); /** * Emit key down and up events for a key. * - * @param keyboard keyboard widget * @param btn_id button index corresponding to the key * @param key_down true if a key down event should be emitted * @param key_up true if a key up event should be emitted */ -static void emit_key_events(lv_obj_t *keyboard, uint16_t btn_id, bool key_down, bool key_up); +static void emit_key_events(uint16_t btn_id, bool key_down, bool key_up); /** * Release any previously pressed modifier keys. - * - * @param keyboard keyboard widget */ -static void pop_checked_modifier_keys(lv_obj_t *keyboard); +static void pop_checked_modifier_keys(void); /** @@ -126,16 +125,16 @@ static void set_theme(bool is_dark) { } static void keyboard_value_changed_cb(lv_event_t *event) { - lv_obj_t *obj = lv_event_get_target(event); + lv_obj_t *kb = lv_event_get_target(event); - uint16_t btn_id = lv_btnmatrix_get_selected_btn(obj); + uint16_t btn_id = lv_btnmatrix_get_selected_btn(kb); if (btn_id == LV_BTNMATRIX_BTN_NONE) { return; } - if (bb_layout_is_layer_switcher(obj, btn_id)) { - pop_checked_modifier_keys(keyboard); - bb_layout_switch_layer(obj, btn_id); + if (sq2lv_is_layer_switcher(kb, btn_id)) { + pop_checked_modifier_keys(); + sq2lv_switch_layer(kb, btn_id); return; } @@ -143,22 +142,22 @@ static void keyboard_value_changed_cb(lv_event_t *event) { * contains LV_BTNMATRIX_CTRL_CHECKED. As a result, pressing e.g. CTRL will _un_check the key. To account * for this, we invert the meaning of "checked" here and elsewhere in the code. */ - bool is_modifier = bb_is_modifier(keyboard, btn_id); + bool is_modifier = sq2lv_is_modifier(keyboard, btn_id); bool is_checked = !lv_btnmatrix_has_btn_ctrl(keyboard, btn_id, LV_BTNMATRIX_CTRL_CHECKED); /* Emit key events. Suppress key up events for modifiers unless they were unchecked. For checked modifiers * the key up events are sent with the next non-modifier key press. */ - emit_key_events(keyboard, btn_id, true, !is_modifier || !is_checked); + emit_key_events(btn_id, true, !is_modifier || !is_checked); /* Pop any previously checked modifiers when a non-modifier key was pressed */ if (!is_modifier) { - pop_checked_modifier_keys(keyboard); + pop_checked_modifier_keys(); } } -static void emit_key_events(lv_obj_t *keyboard, uint16_t btn_id, bool key_down, bool key_up) { +static void emit_key_events(uint16_t btn_id, bool key_down, bool key_up) { int num_scancodes = 0; - int *scancodes = bb_layout_get_scancodes(keyboard, btn_id, &num_scancodes); + int *scancodes = sq2lv_get_scancodes(keyboard, btn_id, &num_scancodes); if (key_down) { /* Emit key down events in forward order */ @@ -175,13 +174,13 @@ static void emit_key_events(lv_obj_t *keyboard, uint16_t btn_id, bool key_down, } } -static void pop_checked_modifier_keys(lv_obj_t *keyboard) { +static void pop_checked_modifier_keys(void) { int num_modifiers = 0; - int *modifier_idxs = bb_get_modifier_indexes(keyboard, &num_modifiers); + int *modifier_idxs = sq2lv_get_modifier_indexes(keyboard, &num_modifiers); for (int i = 0; i < num_modifiers; ++i) { if (!lv_btnmatrix_has_btn_ctrl(keyboard, modifier_idxs[i], LV_BTNMATRIX_CTRL_CHECKED)) { - emit_key_events(keyboard, modifier_idxs[i], false, true); + emit_key_events(modifier_idxs[i], false, true); lv_btnmatrix_set_btn_ctrl(keyboard, modifier_idxs[i], LV_BTNMATRIX_CTRL_CHECKED); } } @@ -316,7 +315,7 @@ int main(void) { touchscreen_indevs[i] = lv_indev_drv_register(&touchscreen_indev_drvs[i]); } - /* Initialise theme and styles */ + /* Initialise theme and styles */ set_theme(true); lv_style_init(&style_text_normal); lv_style_set_text_font(&style_text_normal, &montserrat_extended_32); @@ -334,7 +333,7 @@ int main(void) { lv_obj_add_event_cb(keyboard, keyboard_draw_part_begin_cb, LV_EVENT_DRAW_PART_BEGIN, NULL); /* Apply default keyboard layout */ - bb_layout_switch_layout(keyboard, SQ2LV_LAYOUT_TERMINAL_US); + sq2lv_switch_layout(keyboard, SQ2LV_LAYOUT_TERMINAL_US); /* Start timer for periodically resizing terminals */ lv_timer_create(terminal_resize_timer_cb, 1000, NULL); diff --git a/sq2lv_layouts.c b/sq2lv_layouts.c index 73c8e42..25d2d3d 100644 --- a/sq2lv_layouts.c +++ b/sq2lv_layouts.c @@ -1,5 +1,5 @@ /** - * Auto-generated with unsqu33kr + * Auto-generated with squeek2lvgl **/ #include "sq2lv_layouts.h" @@ -9,7 +9,8 @@ * Layout: US English (Terminal) - generated from terminal/us **/ -static const char * const name_terminal_us = "terminal/us"; +static const char * const name_terminal_us = "US English (Terminal)"; +static const char * const short_name_terminal_us = "terminal/us"; /* Layer: Lowercase letters - generated from base */ @@ -255,14 +256,19 @@ const int sq2lv_num_layouts = 1; const sq2lv_layout_t sq2lv_layouts[] = { /* US English (Terminal) */ { + .name = name_terminal_us, + .short_name = short_name_terminal_us, .num_layers = num_layers_terminal_us, .layers = layers_terminal_us } }; -const char * const sq2lv_layout_names = +const char * const sq2lv_layout_names = "US English (Terminal)"; +const char * const sq2lv_layout_short_names = + "terminal/us"; + const int sq2lv_num_unique_scancodes = 57; const int sq2lv_unique_scancodes[] = { diff --git a/sq2lv_layouts.h b/sq2lv_layouts.h index e8cff27..d2add50 100644 --- a/sq2lv_layouts.h +++ b/sq2lv_layouts.h @@ -1,5 +1,5 @@ /** - * Auto-generated with unsqu33kr + * Auto-generated with squeek2lvgl **/ #ifndef SQ2LV_LAYOUTS_H @@ -7,6 +7,8 @@ #include "lvgl/lvgl.h" +#define SQ2LV_SCANCODES_ENABLED 1 + /* Layout IDs, values can be used as indexes into the sq2lv_layouts array */ typedef enum { SQ2LV_LAYOUT_TERMINAL_US = 0 @@ -42,6 +44,10 @@ typedef struct { /* Layout type */ typedef struct { + /* Layout name */ + const char * const name; + /* Layout short name */ + const char * const short_name; /* Total number of layers */ const int num_layers; /* Layers array */ @@ -54,6 +60,7 @@ extern const sq2lv_layout_t sq2lv_layouts[]; /* Layout names (suitable for use in lv_dropdown_t) */ extern const char * const sq2lv_layout_names; +extern const char * const sq2lv_layout_short_names; /* Unique scancodes from all layout (suitable for setting up uinput devices) */ extern const int sq2lv_num_unique_scancodes;