From e8a794e1ee7422613be28dbe6263b5877d9bf840 Mon Sep 17 00:00:00 2001 From: Michael Forney Date: Sun, 25 Dec 2016 14:46:31 -0800 Subject: [PATCH] framebuffer: Use XKB key events --- frontends/framebuffer/fbtk/event.c | 86 +------------ frontends/framebuffer/fbtk/text.c | 83 ++++--------- frontends/framebuffer/gui.c | 240 +++++++++++++++---------------------- 3 files changed, 128 insertions(+), 281 deletions(-) diff --git a/frontends/framebuffer/fbtk/event.c b/frontends/framebuffer/fbtk/event.c index a48e63809..29eed3286 100644 --- a/frontends/framebuffer/fbtk/event.c +++ b/frontends/framebuffer/fbtk/event.c @@ -224,6 +224,11 @@ fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout) } break; + case NSFB_EVENT_XKB_KEY_DOWN: + case NSFB_EVENT_XKB_KEY_UP: + fbtk_input(root, event); + break; + case NSFB_EVENT_CONTROL: unused = true; break; @@ -261,87 +266,6 @@ fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout) return unused; } -static int keymap[] = { - /* 0 1 2 3 4 5 6 7 8 9 */ - -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */ - -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */ - -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */ - -1, -1, ' ', '!', '"', '#', '$', -1, '&','\'', /* 30 - 39 */ - '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', /* 40 - 49 */ - '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', /* 50 - 59 */ - '<', '=', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */ - -1, '[','\\', ']', '~', '_', '`', 'a', 'b', 'c', /* 90 - 99 */ - 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', /* 100 - 109 */ - 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 110 - 119 */ - 'x', 'y', 'z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */ -}; - -static int sh_keymap[] = { - /* 0 1 2 3 4 5 6 7 8 9 */ - -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */ - -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */ - -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */ - -1, -1, ' ', '!', '"', '~', '$', -1, '&', '@', /* 30 - 39 */ - '(', ')', '*', '+', '<', '_', '>', '?', ')', '!', /* 40 - 49 */ - '"', 243, '$', '%', '^', '&', '*', '(', ';', ':', /* 50 - 59 */ - '<', '+', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */ - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */ - -1, '{', '|', '}', '~', '_', 254, 'A', 'B', 'C', /* 90 - 99 */ - 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', /* 100 - 109 */ - 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 110 - 119 */ - 'X', 'Y', 'Z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */ -}; - - -/* exported function documented in fbtk.h */ -int -fbtk_keycode_to_ucs4(int code, fbtk_modifier_type mods) -{ - int ucs4 = -1; - - if (mods & FBTK_MOD_LSHIFT || mods & FBTK_MOD_RSHIFT) { - if ((code >= 0) && (code < (int) NOF_ELEMENTS(sh_keymap))) - ucs4 = sh_keymap[code]; - - } else if (mods == FBTK_MOD_CLEAR) { - if ((code >= 0) && (code < (int) NOF_ELEMENTS(keymap))) - ucs4 = keymap[code]; - - } else if (mods & FBTK_MOD_LCTRL || mods & FBTK_MOD_RCTRL) { - switch (code) { - case NSFB_KEY_a: - ucs4 = NS_KEY_SELECT_ALL; - break; - - case NSFB_KEY_c: - ucs4 = NS_KEY_COPY_SELECTION; - break; - - case NSFB_KEY_u: - ucs4 = NS_KEY_DELETE_LINE; - break; - - case NSFB_KEY_v: - ucs4 = NS_KEY_PASTE; - break; - - case NSFB_KEY_x: - ucs4 = NS_KEY_CUT_SELECTION; - break; - - case NSFB_KEY_z: - ucs4 = NS_KEY_CLEAR_SELECTION; - break; - default: - break; - } - } - return ucs4; -} - /* * Local Variables: * c-basic-offset:8 diff --git a/frontends/framebuffer/fbtk/text.c b/frontends/framebuffer/fbtk/text.c index 00dcba491..95333a52f 100644 --- a/frontends/framebuffer/fbtk/text.c +++ b/frontends/framebuffer/fbtk/text.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "utils/log.h" #include "netsurf/browser_window.h" @@ -287,13 +288,14 @@ fb_text_input_remove_caret_cb(fbtk_widget_t *widget) static int text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) { - int value; - static fbtk_modifier_type modifier = FBTK_MOD_CLEAR; + xkb_keysym_t sym; + enum nsfb_mod_e mods; char *temp; plot_font_style_t font_style; int fh; int border; bool caret_moved = false; + uint32_t key; fb_text_font_style(widget, &fh, &border, &font_style); @@ -305,34 +307,14 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) return 0; } - value = cbi->event->value.keycode; - - if (cbi->event->type != NSFB_EVENT_KEY_DOWN) { - switch (value) { - case NSFB_KEY_RSHIFT: - modifier &= ~FBTK_MOD_RSHIFT; - break; - - case NSFB_KEY_LSHIFT: - modifier &= ~FBTK_MOD_LSHIFT; - break; - - case NSFB_KEY_RCTRL: - modifier &= ~FBTK_MOD_RCTRL; - break; - - case NSFB_KEY_LCTRL: - modifier &= ~FBTK_MOD_LCTRL; - break; - - default: - break; - } + if (cbi->event->type != NSFB_EVENT_XKB_KEY_DOWN) return 0; - } - switch (value) { - case NSFB_KEY_BACKSPACE: + sym = cbi->event->value.xkb.sym; + mods = cbi->event->value.xkb.mod; + + switch (sym) { + case XKB_KEY_BackSpace: if (widget->u.text.idx <= 0) break; memmove(widget->u.text.text + widget->u.text.idx - 1, @@ -348,13 +330,13 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) caret_moved = true; break; - case NSFB_KEY_RETURN: + case XKB_KEY_Return: widget->u.text.enter(widget->u.text.pw, widget->u.text.text); break; - case NSFB_KEY_RIGHT: + case XKB_KEY_Right: if (widget->u.text.idx < widget->u.text.len) { - if (modifier == FBTK_MOD_CLEAR) + if (mods == 0) widget->u.text.idx++; else widget->u.text.idx = widget->u.text.len; @@ -363,9 +345,9 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) } break; - case NSFB_KEY_LEFT: + case XKB_KEY_Left: if (widget->u.text.idx > 0) { - if (modifier == FBTK_MOD_CLEAR) + if (mods == 0) widget->u.text.idx--; else widget->u.text.idx = 0; @@ -374,34 +356,18 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) } break; - case NSFB_KEY_PAGEUP: - case NSFB_KEY_PAGEDOWN: - case NSFB_KEY_UP: - case NSFB_KEY_DOWN: + case XKB_KEY_Page_Up: + case XKB_KEY_Page_Down: + case XKB_KEY_Up: + case XKB_KEY_Down: /* Not handling any of these correctly yet, but avoid putting * charcters in the text widget when they're pressed. */ break; - case NSFB_KEY_RSHIFT: - modifier |= FBTK_MOD_RSHIFT; - break; - - case NSFB_KEY_LSHIFT: - modifier |= FBTK_MOD_LSHIFT; - break; - - case NSFB_KEY_RCTRL: - modifier |= FBTK_MOD_RCTRL; - break; - - case NSFB_KEY_LCTRL: - modifier |= FBTK_MOD_LCTRL; - break; - default: - if (modifier & FBTK_MOD_LCTRL || modifier & FBTK_MOD_RCTRL) { + if (mods & NSFB_MOD_CTRL) { /* CTRL pressed, don't enter any text */ - if (value == NSFB_KEY_u) { + if (sym == XKB_KEY_u) { /* CTRL+U: clear writable */ widget->u.text.idx = 0; widget->u.text.len = 0; @@ -412,6 +378,10 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) break; } + key = xkb_keysym_to_utf32(sym); + if (key == 0) + break; + /* allow for new character and null */ temp = realloc(widget->u.text.text, widget->u.text.len + 2); if (temp == NULL) { @@ -422,8 +392,7 @@ text_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) memmove(widget->u.text.text + widget->u.text.idx + 1, widget->u.text.text + widget->u.text.idx, widget->u.text.len - widget->u.text.idx); - widget->u.text.text[widget->u.text.idx] = - fbtk_keycode_to_ucs4(value, modifier); + widget->u.text.text[widget->u.text.idx] = key; widget->u.text.idx++; widget->u.text.len++; widget->u.text.text[widget->u.text.len] = '\0'; diff --git a/frontends/framebuffer/gui.c b/frontends/framebuffer/gui.c index e176ac9e4..6bf5152c0 100644 --- a/frontends/framebuffer/gui.c +++ b/frontends/framebuffer/gui.c @@ -28,6 +28,7 @@ #include #include #include +#include #include "utils/utils.h" #include "utils/nsoption.h" @@ -831,170 +832,123 @@ static int fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_window *gw = cbi->context; - static fbtk_modifier_type modifier = FBTK_MOD_CLEAR; - int ucs4 = -1; + xkb_keysym_t sym = cbi->event->value.xkb.sym; + enum nsfb_mod_e mods = cbi->event->value.xkb.mod; + uint32_t key; - LOG("got value %d", cbi->event->value.keycode); - - switch (cbi->event->type) { - case NSFB_EVENT_KEY_DOWN: - switch (cbi->event->value.keycode) { - - case NSFB_KEY_DELETE: - browser_window_key_press(gw->bw, NS_KEY_DELETE_RIGHT); - break; + if (cbi->event->type != NSFB_EVENT_XKB_KEY_DOWN) + return 0; - case NSFB_KEY_PAGEUP: - if (browser_window_key_press(gw->bw, - NS_KEY_PAGE_UP) == false) - widget_scroll_y(gw, -fbtk_get_height( - gw->browser), false); - break; + LOG("got value %d", cbi->event->value.xkb.sym); - case NSFB_KEY_PAGEDOWN: - if (browser_window_key_press(gw->bw, - NS_KEY_PAGE_DOWN) == false) - widget_scroll_y(gw, fbtk_get_height( - gw->browser), false); - break; + switch (sym) { + case XKB_KEY_Delete: + browser_window_key_press(gw->bw, NS_KEY_DELETE_RIGHT); + break; - case NSFB_KEY_RIGHT: - if (modifier & FBTK_MOD_RCTRL || - modifier & FBTK_MOD_LCTRL) { - /* CTRL held */ - if (browser_window_key_press(gw->bw, - NS_KEY_LINE_END) == false) - widget_scroll_x(gw, INT_MAX, true); - - } else if (modifier & FBTK_MOD_RSHIFT || - modifier & FBTK_MOD_LSHIFT) { - /* SHIFT held */ - if (browser_window_key_press(gw->bw, - NS_KEY_WORD_RIGHT) == false) - widget_scroll_x(gw, fbtk_get_width( - gw->browser), false); + case XKB_KEY_Page_Up: + if (browser_window_key_press(gw->bw, + NS_KEY_PAGE_UP) == false) + widget_scroll_y(gw, -fbtk_get_height( + gw->browser), false); + break; - } else { - /* no modifier */ - if (browser_window_key_press(gw->bw, - NS_KEY_RIGHT) == false) - widget_scroll_x(gw, 100, false); - } - break; + case XKB_KEY_Page_Down: + if (browser_window_key_press(gw->bw, + NS_KEY_PAGE_DOWN) == false) + widget_scroll_y(gw, fbtk_get_height( + gw->browser), false); + break; - case NSFB_KEY_LEFT: - if (modifier & FBTK_MOD_RCTRL || - modifier & FBTK_MOD_LCTRL) { - /* CTRL held */ - if (browser_window_key_press(gw->bw, - NS_KEY_LINE_START) == false) - widget_scroll_x(gw, 0, true); - - } else if (modifier & FBTK_MOD_RSHIFT || - modifier & FBTK_MOD_LSHIFT) { - /* SHIFT held */ - if (browser_window_key_press(gw->bw, - NS_KEY_WORD_LEFT) == false) - widget_scroll_x(gw, -fbtk_get_width( - gw->browser), false); + case XKB_KEY_Right: + if (mods & NSFB_MOD_CTRL) { + /* CTRL held */ + if (browser_window_key_press(gw->bw, + NS_KEY_LINE_END) == false) + widget_scroll_x(gw, INT_MAX, true); - } else { - /* no modifier */ - if (browser_window_key_press(gw->bw, - NS_KEY_LEFT) == false) - widget_scroll_x(gw, -100, false); - } - break; + } else if (mods & NSFB_MOD_SHIFT) { + /* SHIFT held */ + if (browser_window_key_press(gw->bw, + NS_KEY_WORD_RIGHT) == false) + widget_scroll_x(gw, fbtk_get_width( + gw->browser), false); - case NSFB_KEY_UP: + } else { + /* no modifier */ if (browser_window_key_press(gw->bw, - NS_KEY_UP) == false) - widget_scroll_y(gw, -100, false); - break; + NS_KEY_RIGHT) == false) + widget_scroll_x(gw, 100, false); + } + break; - case NSFB_KEY_DOWN: + case XKB_KEY_Left: + if (mods & NSFB_MOD_CTRL) { + /* CTRL held */ if (browser_window_key_press(gw->bw, - NS_KEY_DOWN) == false) - widget_scroll_y(gw, 100, false); - break; + NS_KEY_LINE_START) == false) + widget_scroll_x(gw, 0, true); - case NSFB_KEY_RSHIFT: - modifier |= FBTK_MOD_RSHIFT; - break; + } else if (mods & NSFB_MOD_SHIFT) { + /* SHIFT held */ + if (browser_window_key_press(gw->bw, + NS_KEY_WORD_LEFT) == false) + widget_scroll_x(gw, -fbtk_get_width( + gw->browser), false); - case NSFB_KEY_LSHIFT: - modifier |= FBTK_MOD_LSHIFT; - break; + } else { + /* no modifier */ + if (browser_window_key_press(gw->bw, + NS_KEY_LEFT) == false) + widget_scroll_x(gw, -100, false); + } + break; - case NSFB_KEY_RCTRL: - modifier |= FBTK_MOD_RCTRL; - break; + case XKB_KEY_Up: + if (browser_window_key_press(gw->bw, + NS_KEY_UP) == false) + widget_scroll_y(gw, -100, false); + break; - case NSFB_KEY_LCTRL: - modifier |= FBTK_MOD_LCTRL; - break; + case XKB_KEY_Down: + if (browser_window_key_press(gw->bw, + NS_KEY_DOWN) == false) + widget_scroll_y(gw, 100, false); + break; - case NSFB_KEY_y: - case NSFB_KEY_z: - if (cbi->event->value.keycode == NSFB_KEY_z && - (modifier & FBTK_MOD_RCTRL || - modifier & FBTK_MOD_LCTRL) && - (modifier & FBTK_MOD_RSHIFT || - modifier & FBTK_MOD_LSHIFT)) { - /* Z pressed with CTRL and SHIFT held */ - browser_window_key_press(gw->bw, NS_KEY_REDO); + default: + if (mods & NSFB_MOD_CTRL) { + switch (sym) { + case XKB_KEY_a: + key = NS_KEY_SELECT_ALL; break; - - } else if (cbi->event->value.keycode == NSFB_KEY_z && - (modifier & FBTK_MOD_RCTRL || - modifier & FBTK_MOD_LCTRL)) { - /* Z pressed with CTRL held */ - browser_window_key_press(gw->bw, NS_KEY_UNDO); + case XKB_KEY_c: + key = NS_KEY_COPY_SELECTION; break; - - } else if (cbi->event->value.keycode == NSFB_KEY_y && - (modifier & FBTK_MOD_RCTRL || - modifier & FBTK_MOD_LCTRL)) { - /* Y pressed with CTRL held */ - browser_window_key_press(gw->bw, NS_KEY_REDO); + case XKB_KEY_u: + key = NS_KEY_DELETE_LINE; + break; + case XKB_KEY_v: + key = NS_KEY_PASTE; + break; + case XKB_KEY_x: + key = NS_KEY_CUT_SELECTION; + break; + case XKB_KEY_y: + key = NS_KEY_REDO; + break; + case XKB_KEY_z: + key = mods & NSFB_MOD_SHIFT ? NS_KEY_REDO : NS_KEY_UNDO; + break; + default: + key = 0; break; } - /* Z or Y pressed but not undo or redo; - * Fall through to default handling */ - - default: - ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode, - modifier); - if (ucs4 != -1) - browser_window_key_press(gw->bw, ucs4); - break; - } - break; - - case NSFB_EVENT_KEY_UP: - switch (cbi->event->value.keycode) { - case NSFB_KEY_RSHIFT: - modifier &= ~FBTK_MOD_RSHIFT; - break; - - case NSFB_KEY_LSHIFT: - modifier &= ~FBTK_MOD_LSHIFT; - break; - - case NSFB_KEY_RCTRL: - modifier &= ~FBTK_MOD_RCTRL; - break; - - case NSFB_KEY_LCTRL: - modifier &= ~FBTK_MOD_LCTRL; - break; - - default: - break; } - break; - - default: + if (key == 0) + key = xkb_keysym_to_utf32(cbi->event->value.xkb.sym); + if (key != 0) + browser_window_key_press(gw->bw, key); break; } -- 2.11.0