wvkbd

git clone https://git.tarina.org/wvkbd
Log | Files | Refs | README | LICENSE

commit eab4da9765aadb5f552a309bb2d0c37385ddf239
parent f402064cd60718ac235c98770ad7b58e6498c745
Author: Maarten van Gompel <proycon@anaproy.nl>
Date:   Sun, 22 Aug 2021 12:38:10 +0200

Allow more flexible layouts rather than fixed grid and first layout overhaul

Diffstat:
Mconfig.h | 230+++++++++++++++++++++++++++++++++++++++++++++++++------------------------------
Mkeyboard.h | 119++++++++++++++++++++++++++++++++++++++++++++++---------------------------------
Mmain.c | 9+--------
3 files changed, 214 insertions(+), 144 deletions(-)

diff --git a/config.h b/config.h @@ -1,25 +1,22 @@ /* constants */ /* how tall the keyboard should be */ -#define KBD_PIXEL_HEIGHT 155 +#define KBD_PIXEL_HEIGHT 240 /* if your layout leaves an empty margin, increase this to fix it */ -#define KBD_PIXEL_OVERSCAN_WIDTH 0 +#define KBD_PIXEL_OVERSCAN_WIDTH 5 -/* rows for each layout */ -#define KBD_ROWS 4 - -/* columns for each layout (maximum keys per row) */ -#define KBD_COLS 10 +/* Maximum number of keys */ +#define KBD_POINTS 66 /* spacing between keys */ -#define KBD_KEY_BORDER 1 +#define KBD_KEY_BORDER 2 #include "keyboard.h" /* font (see `man fonts-conf` for instructions) */ static const char *fc_font_pattern = - "monospace:size=14:antialias=true:hinting=true"; + "FiraMono Nerd Font:size=16:antialias=true:hinting=true"; /* layout declarations */ enum layout_names { @@ -57,7 +54,7 @@ static struct kbd keyboard = { * "label", * "SHIFT_LABEL", * 1, - * [Code, Mod, Layout, Last], + * [Code, Mod, Layout, EndRow, Last], * [KEY_CODE, Modifier], * [&layout] * },` @@ -78,88 +75,147 @@ static struct kbd keyboard = { * - layout: layout to switch to when key is pressed */ static struct key keys_basic[] = { - {"q", "Q", 1, Code, KEY_Q}, - {"w", "W", 1, Code, KEY_W}, - {"e", "E", 1, Code, KEY_E}, - {"r", "R", 1, Code, KEY_R}, - {"t", "T", 1, Code, KEY_T}, - {"y", "Y", 1, Code, KEY_Y}, - {"u", "U", 1, Code, KEY_U}, - {"i", "I", 1, Code, KEY_I}, - {"o", "O", 1, Code, KEY_O}, - {"p", "P", 1, Code, KEY_P}, - - {"a", "A", 1, Code, KEY_A}, - {"s", "S", 1, Code, KEY_S}, - {"d", "D", 1, Code, KEY_D}, - {"f", "F", 1, Code, KEY_F}, - {"g", "G", 1, Code, KEY_G}, - {"h", "H", 1, Code, KEY_H}, - {"j", "J", 1, Code, KEY_J}, - {"k", "K", 1, Code, KEY_K}, - {"l", "L", 1, Code, KEY_L}, - {";", ":", 1, Code, KEY_SEMICOLON}, - - {"z", "Z", 1, Code, KEY_Z}, - {"x", "X", 1, Code, KEY_X}, - {"c", "C", 1, Code, KEY_C}, - {"v", "V", 1, Code, KEY_V}, - {"b", "B", 1, Code, KEY_B}, - {"n", "N", 1, Code, KEY_N}, - {"m", "M", 1, Code, KEY_M}, - {"Tab", "Tab", 1, Code, KEY_TAB}, - {"Bk", "Bk", 1, Code, KEY_BACKSPACE}, - {"Ret", "Ret", 1, Code, KEY_ENTER}, - - {"Sft", "Sft", 1, Mod, Shift}, - {"Sp", "Sp", 1, Mod, Super}, - {"Alt", "Alt", 1, Mod, AltGr}, - {"", "", 3, Code, KEY_SPACE}, - {"Esc", "Esc", 1, Code, KEY_ESC}, - {"Ctl", "Ctl", 1, Mod, Ctrl}, - {"Sm", "Sm", 2, Layout, 0, &layouts[Special]}, + {"Esc", "Esc", 1.0, Code, KEY_ESC}, + {"Tab", "Tab", 1.0, Code, KEY_TAB}, + {"↑", "↑", 1.0, Code, KEY_UP}, + {"↓", "↓", 1.0, Code, KEY_DOWN}, + {"←", "←", 1.0, Code, KEY_LEFT}, + {"→", "→", 1.0, Code, KEY_RIGHT}, + {"'", "\"", 1.0, Code, KEY_APOSTROPHE}, + {"/", "?", 1.0, Code, KEY_SLASH}, + {";", ":", 1.0, Code, KEY_SEMICOLON}, + {"`", "~", 1.0, Code, KEY_GRAVE}, + {"", "", 0.0, EndRow}, + + {"1", "!", 1.0, Code, KEY_1}, + {"2", "@", 1.0, Code, KEY_2}, + {"3", "#", 1.0, Code, KEY_3}, + {"4", "$", 1.0, Code, KEY_4}, + {"5", "%", 1.0, Code, KEY_5}, + {"6", "^", 1.0, Code, KEY_6}, + {"7", "&", 1.0, Code, KEY_7}, + {"8", "*", 1.0, Code, KEY_8}, + {"9", "(", 1.0, Code, KEY_9}, + {"0", ")", 1.0, Code, KEY_0}, + {"-", "_", 1.0, Code, KEY_MINUS}, + {"=", "+", 1.0, Code, KEY_EQUAL}, + {"", "", 0.0, EndRow}, + + {"", "", 0.5, Pad}, + {"q", "Q", 1.0, Code, KEY_Q}, + {"w", "W", 1.0, Code, KEY_W}, + {"e", "E", 1.0, Code, KEY_E}, + {"r", "R", 1.0, Code, KEY_R}, + {"t", "T", 1.0, Code, KEY_T}, + {"y", "Y", 1.0, Code, KEY_Y}, + {"u", "U", 1.0, Code, KEY_U}, + {"i", "I", 1.0, Code, KEY_I}, + {"o", "O", 1.0, Code, KEY_O}, + {"p", "P", 1.0, Code, KEY_P}, + {"", "", 0.0, EndRow}, + + {"Ct", "Ct", 1.0, Mod, Ctrl}, + {"a", "A", 1.0, Code, KEY_A}, + {"s", "S", 1.0, Code, KEY_S}, + {"d", "D", 1.0, Code, KEY_D}, + {"f", "F", 1.0, Code, KEY_F}, + {"g", "G", 1.0, Code, KEY_G}, + {"h", "H", 1.0, Code, KEY_H}, + {"j", "J", 1.0, Code, KEY_J}, + {"k", "K", 1.0, Code, KEY_K}, + {"l", "L", 1.0, Code, KEY_L}, + {"", "", 0.5, Pad}, + {"", "", 0.0, EndRow}, + + {"⇧", "⇧", 1.5, Mod, Shift}, + {"z", "Z", 1.0, Code, KEY_Z}, + {"x", "X", 1.0, Code, KEY_X}, + {"c", "C", 1.0, Code, KEY_C}, + {"v", "V", 1.0, Code, KEY_V}, + {"b", "B", 1.0, Code, KEY_B}, + {"n", "N", 1.0, Code, KEY_N}, + {"m", "M", 1.0, Code, KEY_M}, + {"⌫", "⌫", 1.5, Code, KEY_BACKSPACE}, + {"", "", 0.0, EndRow}, + + {"Sym", "Sym", 1.0, Layout, 0, &layouts[Special]}, + {"Alt", "Alt", 1.0, Mod, AltGr}, + {",", "<", 1.0, Code, KEY_COMMA}, + {"", "", 4.0, Code, KEY_SPACE}, + {".", ">", 1.0, Code, KEY_DOT}, + {"Entr", "Entr", 2.0, Code, KEY_ENTER}, + /* end of layout */ - {"", "", 0, Last}, + {"", "", 0.0, Last}, }; static struct key keys_special[] = { - {"1", "!", 1, Code, KEY_1}, - {"2", "@", 1, Code, KEY_2}, - {"3", "#", 1, Code, KEY_3}, - {"4", "$", 1, Code, KEY_4}, - {"5", "%", 1, Code, KEY_5}, - {"6", "^", 1, Code, KEY_6}, - {"7", "&", 1, Code, KEY_7}, - {"8", "*", 1, Code, KEY_8}, - {"9", "(", 1, Code, KEY_9}, - {"0", ")", 1, Code, KEY_0}, - - {"'", "\"", 1, Code, KEY_APOSTROPHE}, - {"`", "~", 1, Code, KEY_GRAVE}, - {"-", "_", 1, Code, KEY_MINUS}, - {"=", "+", 1, Code, KEY_EQUAL}, - {"[", "{", 1, Code, KEY_LEFTBRACE}, - {"]", "}", 1, Code, KEY_RIGHTBRACE}, - {",", "<", 1, Code, KEY_COMMA}, - {".", ">", 1, Code, KEY_DOT}, - {"/", "?", 1, Code, KEY_SLASH}, - {"\\", "|", 1, Code, KEY_BACKSLASH}, - - {"↑", "↑", 1, Code, KEY_UP}, - {"↓", "↓", 1, Code, KEY_DOWN}, - {"←", "←", 1, Code, KEY_LEFT}, - {"→", "→", 1, Code, KEY_RIGHT}, - {"Sp", "Sp", 1, Mod, Super}, - {"Alt", "Alt", 1, Mod, AltGr}, - {"Ctl", "Ctl", 1, Mod, Ctrl}, - {"Sft", "Sft", 1, Mod, Shift}, - - {"Ret", "Ret", 1, Code, KEY_ENTER}, - {"Bk", "Bk", 1, Code, KEY_BACKSPACE}, - {"", "", 3, Code, KEY_SPACE}, - {"Bsc", "Bsc", 2, Layout, 0, &layouts[Basic]}, + {"Esc", "Esc", 1.0, Code, KEY_ESC}, + {"Tab", "Tab", 1.0, Code, KEY_TAB}, + {"↑", "↑", 1.0, Code, KEY_UP}, + {"↓", "↓", 1.0, Code, KEY_DOWN}, + {"←", "←", 1.0, Code, KEY_LEFT}, + {"→", "→", 1.0, Code, KEY_RIGHT}, + {"⇈", "⇈", 1.0, Code, KEY_PAGEUP}, + {"⇊", "⇊", 1.0, Code, KEY_PAGEDOWN}, + {"⇤", "⇤", 1.0, Code, KEY_HOME}, + {"⇥", "⇥", 1.0, Code, KEY_END}, + {"", "", 0.0, EndRow}, + + {"1", "!", 1.0, Code, KEY_1}, + {"2", "@", 1.0, Code, KEY_2}, + {"3", "#", 1.0, Code, KEY_3}, + {"4", "$", 1.0, Code, KEY_4}, + {"5", "%", 1.0, Code, KEY_5}, + {"6", "^", 1.0, Code, KEY_6}, + {"7", "&", 1.0, Code, KEY_7}, + {"8", "*", 1.0, Code, KEY_8}, + {"9", "(", 1.0, Code, KEY_9}, + {"0", ")", 1.0, Code, KEY_0}, + {"", "", 0.0, EndRow}, + + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 0.0, EndRow}, + + {"Ct", "Ct", 2.0, Mod, Ctrl}, + {"`", "~", 1.0, Code, KEY_GRAVE}, + {"'", "\"", 1.0, Code, KEY_APOSTROPHE}, + {"-", "_", 1.0, Code, KEY_MINUS}, + {"=", "+", 1.0, Code, KEY_EQUAL}, + {"[", "{", 1.0, Code, KEY_LEFTBRACE}, + {"]", "}", 1.0, Code, KEY_RIGHTBRACE}, + {"\\", "|", 1.0, Code, KEY_BACKSLASH}, + {"Del", "Del", 1.0, Code, KEY_DELETE}, + {"", "", 0.0, EndRow}, + + {"⇧", "⇧", 2.0, Mod, Shift}, + {";", ":", 1.0, Code, KEY_SEMICOLON}, + {"/", "?", 1.0, Code, KEY_SLASH}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"", "", 1.0, Code, KEY_SPACE}, + {"⌫", "⌫", 1.0, Code, KEY_BACKSPACE}, + {"", "", 0.0, EndRow}, + + {"Abc", "Abc", 1.0, Layout, 0, &layouts[Basic]}, + {"Alt", "Alt", 1.0, Mod, AltGr}, + {",", "<", 1.0, Code, KEY_COMMA}, + {"", "", 4.0, Code, KEY_SPACE}, + {".", ">", 1.0, Code, KEY_DOT}, + {"Entr", "Entr", 2.0, Code, KEY_ENTER}, /* end of layout */ - {"", "", 0, Last}, + {"", "", 0.0, Last}, }; diff --git a/keyboard.h b/keyboard.h @@ -1,7 +1,3 @@ -/* clang-format off */ -#define KBD_POINTS KBD_ROWS * KBD_COLS -/* clang-format on */ - enum key_type; enum key_modifier_type; struct clr_scheme; @@ -14,6 +10,7 @@ enum key_type { Code, Mod, Layout, + EndRow, Last, }; @@ -39,18 +36,19 @@ struct clr_scheme { struct key { const char *label; const char *shift_label; - const uint8_t width; + const double width; const enum key_type type; const uint32_t code; struct layout *layout; - uint8_t col, row; + //actual coordinates on the surface + uint32_t x, y, w, h; }; struct layout { struct key *keys; - struct key *gridpoints[KBD_POINTS]; + uint32_t keyheight; }; struct kbd { @@ -58,7 +56,6 @@ struct kbd { struct clr_scheme scheme; uint32_t w, h; - uint32_t kw, kh; uint8_t mods; struct key *last_press; @@ -70,58 +67,77 @@ static inline void draw_inset(struct drwsurf *d, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t border, uint32_t color); -static void kbd_init_layout(struct layout *l); +static void kbd_init_layout(struct layout *l, uint32_t width, uint32_t height); static struct key *kbd_get_key(struct kbd *kb, uint32_t x, uint32_t y); static void kbd_unpress_key(struct kbd *kb, uint32_t time); static void kbd_press_key(struct kbd *kb, struct key *k, uint32_t time); static void kbd_draw_key(struct kbd *kb, struct key *k, bool pressed); -static void kbd_draw_key(struct kbd *kb, struct key *k, bool pressed); static void kbd_draw_layout(struct kbd *kb); -static void kbd_resize(struct kbd *kb, uint32_t w, uint32_t h); - -void -kbd_init_layout(struct layout *l) { - uint8_t i = 0, width = 0, ncol = 0, col = 0, row = 0; +static void kbd_resize(struct kbd *kb, uint32_t w, uint32_t h, struct layout * layouts, uint8_t layoutcount); +static uint8_t kbd_get_rows(struct layout *l); +static double kbd_get_row_length(struct key *k); +uint8_t kbd_get_rows(struct layout *l) { + uint8_t rows = 0; struct key *k = l->keys; - struct key **point = l->gridpoints, - **end_point = l->gridpoints + (KBD_POINTS); - - memset(point, 0, sizeof(uint8_t) * KBD_POINTS); - - while ((k->type != Last) && (point < end_point)) { - width = k->width; - ncol = col + width; - - if (ncol > KBD_COLS) { - width = KBD_COLS - col; - col = 0; - row += 1; - - for (i = 0; (i < width) && (point < end_point); i++, point++) { - } - continue; + while (k->type != Last) { + if (k->type == EndRow) { + rows++; } + k++; + } + return rows + 1; +} - k->col = col; - k->row = row; - col = ncol; +void +kbd_init_layout(struct layout *l, uint32_t width, uint32_t height) { + uint32_t x = 0, y = 0; + fprintf(stderr, "Init layout\n"); + uint8_t rows = kbd_get_rows(l); - for (i = 0; (i < width) && (point < end_point); i++, point++) { - *point = k; + l->keyheight = height / rows; + + struct key *k = l->keys; + double rowlength = kbd_get_row_length(k); + while (k->type != Last) { + if (k->type == EndRow) { + y += l->keyheight; + x = 0; + rowlength = kbd_get_row_length(k+1); + } else if (k->width > 0) { + k->x = x; + k->y = y; + fprintf(stderr, "(%d/%f)*%f -> %s\n",width,rowlength,k->width, k->label); + k->w = ((double) width / rowlength) * k->width; + x += k->w; } + k->h = l->keyheight; + k++; + } +} +double +kbd_get_row_length(struct key *k) { + double l = 0.0; + while ((k->type != Last) && (k->type != EndRow)) { + l += k->width; k++; } + return l; } struct key * kbd_get_key(struct kbd *kb, uint32_t x, uint32_t y) { struct layout *l = kb->layout; - uint32_t col = KBD_COLS * ((float)x / (float)kb->w); - uint32_t row = KBD_ROWS * ((float)y / (float)kb->h); - - return l->gridpoints[(row * KBD_COLS) + col]; + struct key *k = l->keys; + fprintf(stderr,"get key: +%d+%d\n",x,y); + while (k->type != Last) { + if ((k->type != EndRow) && (k->type != Pad) && (k->type != Pad) && (x >= k->x) && (y >= k->y) && (x < k->x + k->w) && (y < k->y + k->h)) { + return k; + } + k++; + } + return NULL; } void @@ -167,12 +183,13 @@ void kbd_draw_key(struct kbd *kb, struct key *k, bool pressed) { struct drwsurf *d = kb->surf; const char *label = (kb->mods & Shift) ? k->shift_label : k->label; + fprintf(stderr, "Draw key +%d+%d %dx%d -> %s\n", k->x, k->y, k->w, k->h, k->label); Color *fill = pressed ? &kb->scheme.high : &kb->scheme.fg; - uint32_t x = k->col * kb->kw, y = k->row * kb->kh, width = k->width * kb->kw; - - draw_inset(d, x, y, width, kb->kh, KBD_KEY_BORDER, fill->color); + draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, fill->color); + uint32_t xoffset = k->w / (strlen(label) + 2); + fprintf(stderr, " xoffset=%d\n", xoffset); wld_draw_text(d->render, d->ctx->font, kb->scheme.text.color, - x + (width * 0.35), y + (kb->kh / 2), label, -1, NULL); + k->x + xoffset, k->y + (k->h / 2), label, -1, NULL); } void @@ -180,11 +197,12 @@ kbd_draw_layout(struct kbd *kb) { struct drwsurf *d = kb->surf; struct key *next_key = kb->layout->keys; bool pressed = false; + fprintf(stderr, "Draw layout"); wld_fill_rectangle(d->render, kb->scheme.bg.color, 0, 0, kb->w, kb->h); while (next_key->type != Last) { - if (next_key->type == Pad) { + if ((next_key->type == Pad) || (next_key->type == EndRow)) { next_key++; continue; } @@ -195,16 +213,19 @@ kbd_draw_layout(struct kbd *kb) { } void -kbd_resize(struct kbd *kb, uint32_t w, uint32_t h) { +kbd_resize(struct kbd *kb, uint32_t w, uint32_t h, struct layout * layouts, uint8_t layoutcount) { struct drwsurf *d = kb->surf; kb->w = w; kb->h = h; - kb->kw = (float)w / (float)KBD_COLS; - kb->kh = (float)h / (float)KBD_ROWS; + fprintf(stderr, "Resize %dx%d, %d layouts\n",w,h,layoutcount); drwsurf_resize(d, w, h); + for (int i = 0; i < layoutcount; i++) { + fprintf(stderr,"i=%d\n",i ); + kbd_init_layout(&layouts[i], w, h); + } kbd_draw_layout(kb); d->dirty = true; } diff --git a/main.c b/main.c @@ -258,7 +258,7 @@ handle_global_remove(void *data, struct wl_registry *registry, uint32_t name) {} void layer_surface_configure(void *data, struct zwlr_layer_surface_v1 *surface, uint32_t serial, uint32_t w, uint32_t h) { - kbd_resize(&keyboard, w + KBD_PIXEL_OVERSCAN_WIDTH, h); + kbd_resize(&keyboard, w + KBD_PIXEL_OVERSCAN_WIDTH, h, layouts, NumLayouts); zwlr_layer_surface_v1_ack_configure(surface, serial); } @@ -315,13 +315,6 @@ main(int argc, char **argv) { zwp_virtual_keyboard_v1_keymap( keyboard.vkbd, WL_KEYBOARD_KEYMAP_FORMAT_XKB_V1, keymap_fd, keymap_size); - /* init layouts */ - for (i = 0; i < NumLayouts; i++) { - if (layouts[i].keys) { - kbd_init_layout(&layouts[i]); - } - } - /* assign kbd state */ keyboard.surf = &draw_surf;