suggestion picker: a persistent layer to complement virtual keyboards like wvkbd
| -rw-r--r-- | keyboard.h | 77 | ||||
| -rw-r--r-- | main.c | 74 |
2 files changed, 129 insertions, 22 deletions
@@ -6,14 +6,17 @@ struct layout; struct kbd; enum key_type { - Pad = 0, - Code, - Mod, - Layout, - EndRow, - Last, - Compose, - Copy, + Pad = 0, //Padding, not a pressable key + Code, //A normal key emitting a keycode + Mod, //A modifier key + Copy, //Copy key, copies the unicode value specified in code (creates and activates temporary keymap) + // used for keys that are not part of the keymap + Layout, //Layout switch to a specific layout + BackLayer, //Layout switch to the layout that was previously active + NextLayer, //Layout switch to the next layout in the layers sequence + Compose, //Compose modifier key, switches to a specific associated layout upon next keypress + EndRow, //Incidates the end of a key row + Last, //Indicated the end of a layout }; /* Modifiers passed to the virtual_keyboard protocol. They are based on @@ -61,18 +64,24 @@ struct key { struct layout { struct key *keys; const char *keymap_name; + const char *name; uint32_t keyheight; // absolute height (pixels) }; struct kbd { struct layout *layout; - struct layout *prevlayout; struct clr_scheme scheme; struct clr_scheme scheme1; + bool print; uint32_t w, h; uint8_t mods; struct key *last_press; + struct layout *prevlayout; + size_t layer_index; + + enum layout_ids *layers; + struct layout **layouts; struct drwsurf *surf; struct zwp_virtual_keyboard_v1 *vkbd; @@ -82,6 +91,7 @@ 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(struct kbd *kb); 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); @@ -92,6 +102,20 @@ 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); +static void kbd_switch_layout(struct kbd *kb, struct layout *l); + +void +kbd_switch_layout(struct kbd *kb, struct layout *l) { + const struct layout * prevlayout = kb->prevlayout; + kb->prevlayout = kb->layout; + kb->layout = l; + if ((!prevlayout) || + (strcmp(prevlayout->keymap_name, kb->layout->keymap_name) != 0)) { + fprintf(stderr, "Switching to keymap %s\n", kb->layout->keymap_name); + create_and_upload_keymap(kb->layout->keymap_name, 0, 0); + } + kbd_draw_layout(kb); +} uint8_t kbd_get_rows(struct layout *l) { @@ -106,6 +130,14 @@ kbd_get_rows(struct layout *l) { return rows + 1; } + +void kbd_init(struct kbd *kb) { + kb->layout = kb->layouts[kb->layer_index]; + + /* upload keymap */ + create_and_upload_keymap(kb->layout->keymap_name, 0, 0); +} + void kbd_init_layout(struct layout *l, uint32_t width, uint32_t height) { uint32_t x = 0, y = 0; @@ -237,7 +269,12 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time) { kbd_draw_key(kb, k, kb->mods & k->code); zwp_virtual_keyboard_v1_modifiers(kb->vkbd, kb->mods, 0, 0, 0); break; + case Layout: + //switch to the layout determined by the key + kbd_switch_layout(kb, k->layout); + break; case Compose: + //switch to the associated layout determined by the *next* keypress if (compose == 0) { compose = 1; } else { @@ -245,16 +282,21 @@ kbd_press_key(struct kbd *kb, struct key *k, uint32_t time) { } kbd_draw_key(kb, k, (bool)compose); break; - case Layout: - kb->layout = k->layout; - if ((!kb->prevlayout) || - (strcmp(kb->prevlayout->keymap_name, kb->layout->keymap_name) != 0)) { - fprintf(stderr, "Switching to keymap %s\n", kb->layout->keymap_name); - create_and_upload_keymap(kb->layout->keymap_name, 0, 0); + case NextLayer: + //switch to the next layout in the layer sequence + kb->layer_index++; + if (kb->layers[kb->layer_index] == NumLayouts) { + kb->layer_index = 0; } - kb->prevlayout = kb->layout; - kbd_draw_layout(kb); + kbd_switch_layout(kb, kb->layouts[kb->layer_index]); + break; + case BackLayer: + //switch to the previously active layout + if (kb->prevlayout) + kbd_switch_layout(kb, kb->prevlayout); + break; case Copy: + //copy code as unicode chr by setting a temporary keymap kb->last_press = k; kbd_draw_key(kb, k, true); fprintf(stderr, "pressing copy key\n"); @@ -317,7 +359,6 @@ kbd_resize(struct kbd *kb, uint32_t w, uint32_t h, struct layout *layouts, 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); @@ -135,6 +135,19 @@ static const struct zwlr_layer_surface_v1_listener layer_surface_listener = { #endif #include LAYOUT +char * +estrdup(const char *s) +{ + char *p; + + if (!(p = strdup(s))) { + fprintf(stderr, "strdup:"); + exit(6); + } + + return p; +} + void wl_touch_down(void *data, struct wl_touch *wl_touch, uint32_t serial, uint32_t time, struct wl_surface *surface, int32_t id, @@ -296,8 +309,62 @@ create_and_upload_keymap(const char *name, uint32_t comp_unichr, free((void *)keymap_str); } +void +usage(char *argv0) +{ + fprintf(stderr, "usage: %s [-hov] [-H height] [-fn font] [-l layers] [-s initial_layer]\n", argv0); + fprintf(stderr, "Options:\n"); + fprintf(stderr, " -D - Enable debug\n"); + fprintf(stderr, " -o - Print press keys to standard output\n"); + fprintf(stderr, " -l - Comma separated list of layers\n"); + fprintf(stderr, " -H [int] - Height in pixels\n"); + fprintf(stderr, " -fn [font] - Set font (Xft, e.g: DejaVu Sans:bold:size=20)\n"); +} + int main(int argc, char **argv) { + /* parse command line arguments */ + int i; + char *layer_names_list = NULL; + char *tmp; + uint32_t height = KBD_PIXEL_HEIGHT; + + if ((tmp = getenv("WVKBD_LAYERS"))) + layer_names_list = estrdup(tmp); + if ((tmp = getenv("WVKBD_HEIGHT"))) + height = atoi(tmp); + + + for (i = 1; argv[i]; i++) { + if (!strcmp(argv[i], "-v")) { + printf("wvkbd-%s", VERSION); + exit(0); + } else if (!strcmp(argv[i], "-h")) { + usage(argv[0]); + exit(0); + } else if (!strcmp(argv[i], "-l")) { + if (i >= argc - 1) { + usage(argv[0]); + exit(1); + } + if (layer_names_list) + free(layer_names_list); + layer_names_list = estrdup(argv[++i]); + } else if (!strcmp(argv[i], "-H")) { + if (i >= argc - 1) { + usage(argv[0]); + exit(1); + } + height = atoi(argv[++i]); + } else if (!strcmp(argv[i], "-o")) { + keyboard.print = true; + } else { + fprintf(stderr, "Invalid argument: %s\n", argv[i]); + usage(argv[0]); + exit(1); + } + } + /* connect to compositor */ display = wl_display_connect(NULL); if (display == NULL) { @@ -326,8 +393,7 @@ main(int argc, char **argv) { keyboard.vkbd = zwp_virtual_keyboard_manager_v1_create_virtual_keyboard(vkbd_mgr, seat); - /* upload keymap */ - create_and_upload_keymap(layouts[DefaultLayout].keymap_name, 0, 0); + kbd_init(&keyboard); /* assign kbd state */ keyboard.surf = &draw_surf; @@ -340,9 +406,9 @@ main(int argc, char **argv) { layer_surface = zwlr_layer_shell_v1_get_layer_surface( layer_shell, draw_surf.surf, wl_output, layer, namespace); - zwlr_layer_surface_v1_set_size(layer_surface, 0, KBD_PIXEL_HEIGHT); + zwlr_layer_surface_v1_set_size(layer_surface, 0, height); zwlr_layer_surface_v1_set_anchor(layer_surface, anchor); - zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, KBD_PIXEL_HEIGHT); + zwlr_layer_surface_v1_set_exclusive_zone(layer_surface, height); zwlr_layer_surface_v1_set_keyboard_interactivity(layer_surface, false); zwlr_layer_surface_v1_add_listener(layer_surface, &layer_surface_listener, NULL); |