#include #include #include "keyboard.h" #include "drw.h" #include "os-compatibility.h" #define KBD_KEY_BORDER 1 /* lazy die macro */ #define die(...) \ fprintf(stderr, __VA_ARGS__); \ exit(1) void kbd_init(struct kbd *kb) { fprintf(stderr, "Initializing keyboard\n"); kb->suggs[0].label = strdup("Hello"); kb->suggs[1].label = strdup("Sugar"); kb->suggs[2].label = strdup("Pie"); kb->suggs[3].label = NULL; } void kbd_init_suggs(struct key *suggs, uint32_t width, uint32_t height) { uint32_t x = 0, y = 0; uint8_t rows = 1; uint32_t keyheight = height / rows; struct key *k = suggs; double rowlength = kbd_get_row_length(k); while (k->label != NULL) { k->x = x; k->y = y; k->w = width / rowlength; x += k->w; k->h = keyheight; k++; } } double kbd_get_row_length(struct key *k) { double l = 0.0; while (k->label != NULL) { l += 1.0; k++; } return l; } struct key * kbd_get_key(struct kbd *kb, uint32_t x, uint32_t y) { struct key *k = kb->suggs; if (kb->debug) fprintf(stderr, "get key: +%d+%d\n", x, y); while (k->label != NULL) { if ((x >= k->x) && (y >= k->y) && (x < k->x + k->w) && (y < k->y + k->h)) { return k; } k++; } return NULL; } void kbd_unpress_key(struct kbd *kb) { if (kb->last_press) { kbd_draw_key(kb, kb->last_press, Unpress); kb->last_press = NULL; } } void kbd_release_key(struct kbd *kb) { kbd_unpress_key(kb); printf("\n"); // Important so autocompleted words get typed in time fflush(stdout); kbd_draw_layout(kb); } void kbd_motion_key(struct kbd *kb, uint32_t x, uint32_t y) { } void kbd_press_key(struct kbd *kb, struct key *k) { if (k->label) { kb->last_press = k; kbd_draw_key(kb, k, Press); printf("%s", k->label); fflush(stdout); } } void kbd_draw_key(struct kbd *kb, struct key *k, enum key_draw_type type) { struct drwsurf *d = kb->surf; const char *label = k->label; if (kb->debug) fprintf(stderr, "Draw key +%d+%d %dx%d -> %s\n", k->x, k->y, k->w, k->h, label); struct clr_scheme *scheme = &(kb->scheme); switch (type) { case Unpress: draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->fg); break; case Press: draw_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->high); break; case Swipe: draw_over_inset(d, k->x, k->y, k->w, k->h, KBD_KEY_BORDER, scheme->swipe); break; } drw_draw_text(d, scheme->text, k->x, k->y, k->w, k->h, label); } void kbd_draw_layout(struct kbd *kb) { struct drwsurf *d = kb->surf; struct key *next_key = kb->suggs; if (kb->debug) fprintf(stderr, "Draw layout"); drw_fill_rectangle(d, kb->scheme.bg, 0, 0, kb->w, kb->h); while (next_key->label != NULL) { kbd_draw_key(kb, next_key, Unpress); next_key++; } } void kbd_resize(struct kbd *kb) { struct drwsurf *d = kb->surf; fprintf(stderr, "Resize %dx%d %d\n", kb->w, kb->h, kb->s); drwsurf_resize(d, kb->w, kb->h, kb->s); kbd_init_suggs(kb->suggs, kb->w, kb->h); kbd_draw_layout(kb); } void draw_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t border, Color color) { drw_fill_rectangle(ds, color, x + border, y + border, width - (border*2), height - (border*2)); } void draw_over_inset(struct drwsurf *ds, uint32_t x, uint32_t y, uint32_t width, uint32_t height, uint32_t border, Color color) { drw_over_rectangle(ds, color, x + border, y + border, width - (border*2), height - (border*2)); }