Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
  3.  *
  4.  * Framebuffer windowing toolkit event processing.
  5.  *
  6.  * This file is part of NetSurf, http://www.netsurf-browser.org/
  7.  *
  8.  * NetSurf is free software; you can redistribute it and/or modify
  9.  * it under the terms of the GNU General Public License as published by
  10.  * the Free Software Foundation; version 2 of the License.
  11.  *
  12.  * NetSurf is distributed in the hope that it will be useful,
  13.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  * GNU General Public License for more details.
  16.  *
  17.  * You should have received a copy of the GNU General Public License
  18.  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  19.  */
  20.  
  21. #include <sys/types.h>
  22. #include <stdint.h>
  23. #include <string.h>
  24. #include <stdbool.h>
  25.  
  26. #include <libnsfb.h>
  27. #include <libnsfb_plot.h>
  28. #include <libnsfb_plot_util.h>
  29. #include <libnsfb_event.h>
  30. #include <libnsfb_cursor.h>
  31.  
  32. #include "utils/utils.h"
  33. #include "utils/log.h"
  34. #include "css/css.h"
  35. #include "desktop/browser.h"
  36. #include "desktop/plotters.h"
  37. #include "desktop/textinput.h"
  38.  
  39. #include "framebuffer/gui.h"
  40. #include "framebuffer/fbtk.h"
  41. #include "framebuffer/image_data.h"
  42.  
  43. #include "widget.h"
  44.  
  45. /* exported function documented in fbtk.h */
  46. void
  47. fbtk_input(fbtk_widget_t *root, nsfb_event_t *event)
  48. {
  49.         fbtk_widget_t *input;
  50.  
  51.         root = fbtk_get_root_widget(root);
  52.  
  53.         /* obtain widget with input focus */
  54.         input = root->u.root.input;
  55.         if (input == NULL) {
  56.                 LOG(("No widget has input focus."));
  57.                 return; /* no widget with input */
  58.         }
  59.  
  60.         fbtk_post_callback(input, FBTK_CBT_INPUT, event);
  61. }
  62.  
  63. /* exported function documented in fbtk.h */
  64. void
  65. fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event)
  66. {
  67.         fbtk_widget_t *root;
  68.         fbtk_widget_t *clicked;
  69.         nsfb_bbox_t cloc;
  70.         int x, y;
  71.  
  72.         /* ensure we have the root widget */
  73.         root = fbtk_get_root_widget(widget);
  74.  
  75.         nsfb_cursor_loc_get(root->u.root.fb, &cloc);
  76.  
  77.         clicked = fbtk_get_widget_at(root, cloc.x0, cloc.y0);
  78.  
  79.         if (clicked == NULL)
  80.                 return;
  81.  
  82.         if (fbtk_get_handler(clicked, FBTK_CBT_INPUT) != NULL) {
  83.                 fbtk_set_focus(clicked);
  84.         }
  85.  
  86.         x = fbtk_get_absx(clicked);
  87.         y = fbtk_get_absy(clicked);
  88.  
  89.         LOG(("clicked %p at %d,%d", clicked, x, y));
  90.  
  91.         /* post the click */
  92.         fbtk_post_callback(clicked, FBTK_CBT_CLICK, event, cloc.x0 - x, cloc.y0 - y);
  93. }
  94.  
  95. /* exported function documented in fbtk.h */
  96. bool
  97. fbtk_tgrab_pointer(fbtk_widget_t *widget)
  98. {
  99.         fbtk_widget_t *root;
  100.  
  101.         /* ensure we have the root widget */
  102.         root = fbtk_get_root_widget(widget);
  103.  
  104.         if (root->u.root.grabbed == widget) {
  105.                 /* release pointer grab */
  106.                 root->u.root.grabbed = NULL;
  107.                 return true;
  108.         } else if (root->u.root.grabbed == NULL) {
  109.                 /* set pointer grab */
  110.                 root->u.root.grabbed = widget;
  111.                 return true;
  112.         }
  113.         /* pointer was already grabbed */
  114.         return false;
  115. }
  116.  
  117. /* exported function documented in fbtk.h */
  118. void
  119. fbtk_warp_pointer(fbtk_widget_t *widget, int x, int y, bool relative)
  120. {
  121.         fbtk_widget_t *root;
  122.         fbtk_widget_t *moved;
  123.         nsfb_bbox_t cloc;
  124.  
  125.         /* ensure we have the root widget */
  126.         root = fbtk_get_root_widget(widget);
  127.  
  128.         if (relative) {
  129.                 nsfb_cursor_loc_get(root->u.root.fb, &cloc);
  130.                 cloc.x0 += x;
  131.                 cloc.y0 += y;
  132.         } else {
  133.                 cloc.x0 = x;
  134.                 cloc.y0 = y;
  135.         }
  136.  
  137.         /* ensure cursor location lies within the root widget */
  138.         if (cloc.x0 < root->x)
  139.                 cloc.x0 = root->x;
  140.         if (cloc.x0 >= (root->x + root->width))
  141.                 cloc.x0 = (root->x + root->width) - 1;
  142.         if (cloc.y0 < root->y)
  143.                 cloc.y0 = root->y;
  144.         if (cloc.y0 >= (root->y + root->height))
  145.                 cloc.y0 = (root->y + root->height) - 1;
  146.  
  147.         if (root->u.root.grabbed == NULL) {
  148.                 /* update the pointer cursor */
  149.                 nsfb_cursor_loc_set(root->u.root.fb, &cloc);
  150.  
  151.                 moved = fbtk_get_widget_at(root, cloc.x0, cloc.y0);
  152.  
  153.                 x = fbtk_get_absx(moved);
  154.                 y = fbtk_get_absy(moved);
  155.  
  156.                 /* post enter and leaving messages */
  157.                 if (moved != root->u.root.prev) {
  158.                         fbtk_post_callback(root->u.root.prev, FBTK_CBT_POINTERLEAVE);
  159.                         root->u.root.prev = moved;
  160.                         fbtk_post_callback(root->u.root.prev, FBTK_CBT_POINTERENTER);
  161.                 }
  162.         } else {
  163.                 /* pointer movement has been grabbed by a widget */
  164.                 moved = root->u.root.grabbed;
  165.  
  166.                 /* ensure pointer remains within widget boundary */
  167.                 x = fbtk_get_absx(moved);
  168.                 y = fbtk_get_absy(moved);
  169.  
  170.                 if (cloc.x0 < x)
  171.                         cloc.x0 = x;
  172.                 if (cloc.y0 < y)
  173.                         cloc.y0 = y;
  174.                 if (cloc.x0 > (x + moved->width))
  175.                         cloc.x0 = (x + moved->width);
  176.                 if (cloc.y0 > (y + moved->height))
  177.                         cloc.y0 = (y + moved->height);
  178.  
  179.                 /* update the pointer cursor */
  180.                 nsfb_cursor_loc_set(root->u.root.fb, &cloc);
  181.         }
  182.  
  183.         /* post the movement */
  184.         fbtk_post_callback(moved, FBTK_CBT_POINTERMOVE, cloc.x0 - x, cloc.y0 - y);
  185.  
  186. }
  187.  
  188. /* exported function documented in fbtk.h */
  189. bool
  190. fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout)
  191. {
  192.         nsfb_bbox_t cloc;
  193.         bool unused = false; /* is the event available */
  194.         bool move_pointer = false; /* whether pointer move events occured */
  195.  
  196.         /* ensure we have the root widget */
  197.         root = fbtk_get_root_widget(root);
  198.  
  199.         do {
  200.                 if (nsfb_event(root->u.root.fb, event, timeout) == false) {
  201.                         if (move_pointer)
  202.                                 fbtk_warp_pointer(root, cloc.x0, cloc.y0,
  203.                                                 false);
  204.                         return false;
  205.                 }
  206.  
  207.                 if (move_pointer && event->type != NSFB_EVENT_MOVE_RELATIVE &&
  208.                                 event->type != NSFB_EVENT_MOVE_ABSOLUTE) {
  209.                         /* Flush the movements */
  210.                         fbtk_warp_pointer(root, cloc.x0, cloc.y0, false);
  211.  
  212.                 } else if (!move_pointer &&
  213.                                 event->type == NSFB_EVENT_MOVE_RELATIVE) {
  214.                         /* Get current pointer coords */
  215.                         nsfb_cursor_loc_get(root->u.root.fb, &cloc);
  216.                 }
  217.  
  218.                 switch (event->type) {
  219.                 case NSFB_EVENT_KEY_DOWN:
  220.                 case NSFB_EVENT_KEY_UP:
  221.                         if ((event->value.keycode >= NSFB_KEY_MOUSE_1) &&
  222.                             (event->value.keycode <= NSFB_KEY_MOUSE_5)) {
  223.                                 fbtk_click(root, event);
  224.                         } else {
  225.                                 fbtk_input(root, event);
  226.                         }
  227.                         break;
  228.  
  229.                 case NSFB_EVENT_CONTROL:
  230.                         unused = true;
  231.                         break;
  232.  
  233.                 case NSFB_EVENT_MOVE_RELATIVE:
  234.                         /* Consecutive move events are consolidated into a
  235.                          * single pointer warp */
  236.                         move_pointer = true;
  237.                         cloc.x0 += event->value.vector.x;
  238.                         cloc.y0 += event->value.vector.y;
  239.                         timeout = 0;
  240.                         break;
  241.  
  242.                 case NSFB_EVENT_MOVE_ABSOLUTE:
  243.                         /* Consecutive move events are consolidated into a
  244.                          * single pointer warp */
  245.                         move_pointer = true;
  246.                         cloc.x0 = event->value.vector.x;
  247.                         cloc.y0 = event->value.vector.y;
  248.                         timeout = 0;
  249.                         break;
  250.  
  251.                 default:
  252.                         break;
  253.                 }
  254.         } while (event->type == NSFB_EVENT_MOVE_RELATIVE ||
  255.                         event->type == NSFB_EVENT_MOVE_ABSOLUTE);
  256.         return unused;
  257. }
  258.  
  259. static int keymap[] = {
  260.         /* 0    1    2    3    4    5    6    7    8    9               */
  261.         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   8,   9, /*   0 -   9 */
  262.         -1,  -1,  -1,  13,  -1,  -1,  -1,  -1,  -1,  -1, /*  10 -  19 */
  263.         -1,  -1,  -1,  -1,  -1,  -1,  -1,  27,  -1,  -1, /*  20 -  29 */
  264.         -1,  -1, ' ', '!', '"', '#', '$',  -1, '&','\'', /*  30 -  39 */
  265.         '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', /*  40 -  49 */
  266.         '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', /*  50 -  59 */
  267.         '<', '=', '>', '?', '@',  -1,  -1,  -1,  -1,  -1, /*  60 -  69 */
  268.         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, /*  70 -  79 */
  269.         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, /*  80 -  89 */
  270.         -1, '[','\\', ']', '~', '_', '`', 'a', 'b', 'c', /*  90 -  99 */
  271.         'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', /* 100 - 109 */
  272.         'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 110 - 119 */
  273.         'x', 'y', 'z',  -1,  -1,  -1,  -1,  -1,  -1,  -1, /* 120 - 129 */
  274. };
  275.  
  276. static int sh_keymap[] = {
  277.         /* 0    1    2    3    4    5    6    7    8    9               */
  278.         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,   8,   9, /*   0 -   9 */
  279.         -1,  -1,  -1,  13,  -1,  -1,  -1,  -1,  -1,  -1, /*  10 -  19 */
  280.         -1,  -1,  -1,  -1,  -1,  -1,  -1,  27,  -1,  -1, /*  20 -  29 */
  281.         -1,  -1, ' ', '!', '"', '~', '$',  -1, '&', '@', /*  30 -  39 */
  282.         '(', ')', '*', '+', '<', '_', '>', '?', ')', '!', /*  40 -  49 */
  283.         '"', 243, '$', '%', '^', '&', '*', '(', ';', ':', /*  50 -  59 */
  284.         '<', '+', '>', '?', '@',  -1,  -1,  -1,  -1,  -1, /*  60 -  69 */
  285.         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, /*  70 -  79 */
  286.         -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1,  -1, /*  80 -  89 */
  287.         -1, '{', '|', '}', '~', '_', 254, 'A', 'B', 'C', /*  90 -  99 */
  288.         'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', /* 100 - 109 */
  289.         'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 110 - 119 */
  290.         'X', 'Y', 'Z',  -1,  -1,  -1,  -1,  -1,  -1,  -1, /* 120 - 129 */
  291. };
  292.  
  293.  
  294. /* exported function documented in fbtk.h */
  295. int
  296. fbtk_keycode_to_ucs4(int code, fbtk_modifier_type mods)
  297. {
  298.         int ucs4 = -1;
  299.  
  300.         if (mods & FBTK_MOD_LSHIFT || mods & FBTK_MOD_RSHIFT) {
  301.                 if ((code >= 0) && (code < (int) NOF_ELEMENTS(sh_keymap)))
  302.                         ucs4 = sh_keymap[code];
  303.  
  304.         } else if (mods == FBTK_MOD_CLEAR) {
  305.                 if ((code >= 0) && (code < (int) NOF_ELEMENTS(keymap)))
  306.                         ucs4 = keymap[code];
  307.  
  308.         } else if (mods & FBTK_MOD_LCTRL || mods & FBTK_MOD_RCTRL) {
  309.                 switch (code) {
  310.                 case NSFB_KEY_a:
  311.                         ucs4 = KEY_SELECT_ALL;
  312.                         break;
  313.  
  314.                 case NSFB_KEY_c:
  315.                         ucs4 = KEY_COPY_SELECTION;
  316.                         break;
  317.  
  318.                 case NSFB_KEY_u:
  319.                         ucs4 = KEY_CUT_LINE;
  320.                         break;
  321.  
  322.                 case NSFB_KEY_v:
  323.                         ucs4 = KEY_PASTE;
  324.                         break;
  325.  
  326.                 case NSFB_KEY_x:
  327.                         ucs4 = KEY_CUT_SELECTION;
  328.                         break;
  329.  
  330.                 case NSFB_KEY_z:
  331.                         ucs4 = KEY_CLEAR_SELECTION;
  332.                         break;
  333.                 default:
  334.                         break;
  335.                 }
  336.         }
  337.         return ucs4;
  338. }
  339.  
  340. /*
  341.  * Local Variables:
  342.  * c-basic-offset:8
  343.  * End:
  344.  */
  345.