From d21447d096a320a08b3efb2b8768fad0dcdcfd64 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 5 May 2016 22:28:51 +0100 Subject: move frontends into sub directory --- frontends/framebuffer/fbtk/event.c | 349 +++++++++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 frontends/framebuffer/fbtk/event.c (limited to 'frontends/framebuffer/fbtk/event.c') diff --git a/frontends/framebuffer/fbtk/event.c b/frontends/framebuffer/fbtk/event.c new file mode 100644 index 000000000..c0894921e --- /dev/null +++ b/frontends/framebuffer/fbtk/event.c @@ -0,0 +1,349 @@ +/* + * Copyright 2010 Vincent Sanders + * + * Framebuffer windowing toolkit event processing. + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf 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; version 2 of the License. + * + * NetSurf 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 +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "utils/utils.h" +#include "utils/log.h" +#include "desktop/browser.h" +#include "desktop/textinput.h" + +#include "framebuffer/gui.h" +#include "framebuffer/fbtk.h" +#include "framebuffer/image_data.h" + +#include "widget.h" + +/* exported function documented in fbtk.h */ +void +fbtk_input(fbtk_widget_t *root, nsfb_event_t *event) +{ + fbtk_widget_t *input; + + root = fbtk_get_root_widget(root); + + /* obtain widget with input focus */ + input = root->u.root.input; + if (input == NULL) { + LOG("No widget has input focus."); + return; /* no widget with input */ + } + + fbtk_post_callback(input, FBTK_CBT_INPUT, event); +} + +/* exported function documented in fbtk.h */ +void +fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event) +{ + fbtk_widget_t *root; + fbtk_widget_t *clicked; + nsfb_bbox_t cloc; + int x, y; + + /* ensure we have the root widget */ + root = fbtk_get_root_widget(widget); + + nsfb_cursor_loc_get(root->u.root.fb, &cloc); + + clicked = fbtk_get_widget_at(root, cloc.x0, cloc.y0); + + if (clicked == NULL) + return; + + if (fbtk_get_handler(clicked, FBTK_CBT_INPUT) != NULL) { + fbtk_set_focus(clicked); + } + + x = fbtk_get_absx(clicked); + y = fbtk_get_absy(clicked); + + LOG("clicked %p at %d,%d", clicked, x, y); + + /* post the click */ + fbtk_post_callback(clicked, FBTK_CBT_CLICK, event, cloc.x0 - x, cloc.y0 - y); +} + +/* exported function documented in fbtk.h */ +bool +fbtk_tgrab_pointer(fbtk_widget_t *widget) +{ + fbtk_widget_t *root; + + /* ensure we have the root widget */ + root = fbtk_get_root_widget(widget); + + if (root->u.root.grabbed == widget) { + /* release pointer grab */ + root->u.root.grabbed = NULL; + return true; + } else if (root->u.root.grabbed == NULL) { + /* set pointer grab */ + root->u.root.grabbed = widget; + return true; + } + /* pointer was already grabbed */ + return false; +} + +/* exported function documented in fbtk.h */ +void +fbtk_warp_pointer(fbtk_widget_t *widget, int x, int y, bool relative) +{ + fbtk_widget_t *root; + fbtk_widget_t *moved; + nsfb_bbox_t cloc; + + /* ensure we have the root widget */ + root = fbtk_get_root_widget(widget); + + if (relative) { + nsfb_cursor_loc_get(root->u.root.fb, &cloc); + cloc.x0 += x; + cloc.y0 += y; + } else { + cloc.x0 = x; + cloc.y0 = y; + } + + /* ensure cursor location lies within the root widget */ + if (cloc.x0 < root->x) + cloc.x0 = root->x; + if (cloc.x0 >= (root->x + root->width)) + cloc.x0 = (root->x + root->width) - 1; + if (cloc.y0 < root->y) + cloc.y0 = root->y; + if (cloc.y0 >= (root->y + root->height)) + cloc.y0 = (root->y + root->height) - 1; + + if (root->u.root.grabbed == NULL) { + /* update the pointer cursor */ + nsfb_cursor_loc_set(root->u.root.fb, &cloc); + + moved = fbtk_get_widget_at(root, cloc.x0, cloc.y0); + + x = fbtk_get_absx(moved); + y = fbtk_get_absy(moved); + + /* post enter and leaving messages */ + if (moved != root->u.root.prev) { + fbtk_post_callback(root->u.root.prev, FBTK_CBT_POINTERLEAVE); + root->u.root.prev = moved; + fbtk_post_callback(root->u.root.prev, FBTK_CBT_POINTERENTER); + } + } else { + /* pointer movement has been grabbed by a widget */ + moved = root->u.root.grabbed; + + /* ensure pointer remains within widget boundary */ + x = fbtk_get_absx(moved); + y = fbtk_get_absy(moved); + + if (cloc.x0 < x) + cloc.x0 = x; + if (cloc.y0 < y) + cloc.y0 = y; + if (cloc.x0 > (x + moved->width)) + cloc.x0 = (x + moved->width); + if (cloc.y0 > (y + moved->height)) + cloc.y0 = (y + moved->height); + + /* update the pointer cursor */ + nsfb_cursor_loc_set(root->u.root.fb, &cloc); + } + + /* post the movement */ + fbtk_post_callback(moved, FBTK_CBT_POINTERMOVE, cloc.x0 - x, cloc.y0 - y); + +} + +/* exported function documented in fbtk.h */ +bool +fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout) +{ + nsfb_bbox_t cloc; + bool unused = false; /* is the event available */ + bool move_pointer = false; /* whether pointer move events occured */ + + /* ensure we have the root widget */ + root = fbtk_get_root_widget(root); + + do { + if (nsfb_event(root->u.root.fb, event, timeout) == false) { + if (move_pointer) + fbtk_warp_pointer(root, cloc.x0, cloc.y0, + false); + return false; + } + + if (move_pointer && event->type != NSFB_EVENT_MOVE_RELATIVE && + event->type != NSFB_EVENT_MOVE_ABSOLUTE) { + /* Flush the movements */ + fbtk_warp_pointer(root, cloc.x0, cloc.y0, false); + + } else if (!move_pointer && + event->type == NSFB_EVENT_MOVE_RELATIVE) { + /* Get current pointer coords */ + nsfb_cursor_loc_get(root->u.root.fb, &cloc); + } + + switch (event->type) { + case NSFB_EVENT_KEY_DOWN: + case NSFB_EVENT_KEY_UP: + if ((event->value.keycode >= NSFB_KEY_MOUSE_1) && + (event->value.keycode <= NSFB_KEY_MOUSE_5)) { + fbtk_click(root, event); + } else { + fbtk_input(root, event); + } + break; + + case NSFB_EVENT_CONTROL: + unused = true; + break; + + case NSFB_EVENT_MOVE_RELATIVE: + /* Consecutive move events are consolidated into a + * single pointer warp */ + move_pointer = true; + cloc.x0 += event->value.vector.x; + cloc.y0 += event->value.vector.y; + timeout = 0; + break; + + case NSFB_EVENT_MOVE_ABSOLUTE: + /* Consecutive move events are consolidated into a + * single pointer warp */ + move_pointer = true; + cloc.x0 = event->value.vector.x; + cloc.y0 = event->value.vector.y; + timeout = 0; + break; + + case NSFB_EVENT_RESIZE: + /* Try to resize framebuffer */ + gui_resize(root, + event->value.resize.w, + event->value.resize.h); + break; + + default: + break; + } + } while (event->type == NSFB_EVENT_MOVE_RELATIVE || + event->type == NSFB_EVENT_MOVE_ABSOLUTE); + 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 + * End: + */ -- cgit v1.2.3