1 /*
2  * Copyright 2010 Vincent Sanders <vince@simtec.co.uk>
3  *
4  * Framebuffer windowing toolkit on screen keyboard.
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 <stdbool.h>
22 #include <limits.h>
23 
24 #include <libnsfb.h>
25 #include <libnsfb_plot.h>
26 #include <libnsfb_event.h>
27 #include <libnsfb_cursor.h>
28 
29 #include "utils/log.h"
30 #include "netsurf/browser_window.h"
31 
32 #include "framebuffer/gui.h"
33 #include "framebuffer/fbtk.h"
34 #include "framebuffer/image_data.h"
35 
36 #include "widget.h"
37 
38 struct kbd_button_s {
39 	int x;
40 	int y;
41 	int w;
42 	int h;
43 	const char *t;
44 	enum nsfb_key_code_e keycode;
45 };
46 
47 #define KEYCOUNT 58
48 
49 static struct kbd_button_s kbdbase[KEYCOUNT] = {
50 	{   0,   0,  20,  15, "`", NSFB_KEY_BACKQUOTE},
51 	{  20,   0,  20,  15, "1", NSFB_KEY_1},
52 	{  40,   0,  20,  15, "2", NSFB_KEY_2},
53 	{  60,   0,  20,  15, "3", NSFB_KEY_3},
54 	{  80,   0,  20,  15, "4", NSFB_KEY_4},
55 	{ 100,   0,  20,  15, "5", NSFB_KEY_5},
56 	{ 120,   0,  20,  15, "6", NSFB_KEY_6},
57 	{ 140,   0,  20,  15, "7", NSFB_KEY_7},
58 	{ 160,   0,  20,  15, "8", NSFB_KEY_8},
59 	{ 180,   0,  20,  15, "9", NSFB_KEY_9},
60 	{ 200,   0,  20,  15, "0", NSFB_KEY_0},
61 	{ 220,   0,  20,  15, "-", NSFB_KEY_MINUS},
62 	{ 240,   0,  20,  15, "=", NSFB_KEY_EQUALS},
63 	{ 260,   0,  40,  15, "\xe2\x8c\xab", NSFB_KEY_BACKSPACE},
64 	{   0,  15,  30,  15, "\xe2\x86\xb9", NSFB_KEY_TAB},
65 	{  30,  15,  20,  15, "q", NSFB_KEY_q},
66 	{  50,  15,  20,  15, "w", NSFB_KEY_w},
67 	{  70,  15,  20,  15, "e", NSFB_KEY_e},
68 	{  90,  15,  20,  15, "r", NSFB_KEY_r},
69 	{ 110,  15,  20,  15, "t", NSFB_KEY_t},
70 	{ 130,  15,  20,  15, "y", NSFB_KEY_y},
71 	{ 150,  15,  20,  15, "u", NSFB_KEY_u},
72 	{ 170,  15,  20,  15, "i", NSFB_KEY_i},
73 	{ 190,  15,  20,  15, "o", NSFB_KEY_o},
74 	{ 210,  15,  20,  15, "p", NSFB_KEY_p},
75 	{ 230,  15,  20,  15, "[", NSFB_KEY_LEFTBRACKET},
76 	{ 250,  15,  20,  15, "]", NSFB_KEY_RIGHTBRACKET},
77 	{ 275,  15,  25,  30, "\xe2\x8f\x8e", NSFB_KEY_RETURN},
78 	{  35,  30,  20,  15, "a", NSFB_KEY_a},
79 	{  55,  30,  20,  15, "s", NSFB_KEY_s},
80 	{  75,  30,  20,  15, "d", NSFB_KEY_d},
81 	{  95,  30,  20,  15, "f", NSFB_KEY_f},
82 	{ 115,  30,  20,  15, "g", NSFB_KEY_g},
83 	{ 135,  30,  20,  15, "h", NSFB_KEY_h},
84 	{ 155,  30,  20,  15, "j", NSFB_KEY_j},
85 	{ 175,  30,  20,  15, "k", NSFB_KEY_k},
86 	{ 195,  30,  20,  15, "l", NSFB_KEY_l},
87 	{ 215,  30,  20,  15, ";", NSFB_KEY_SEMICOLON},
88 	{ 235,  30,  20,  15, "'", NSFB_KEY_l},
89 	{ 255,  30,  20,  15, "#", NSFB_KEY_HASH},
90 	{   0,  45,  25,  15, "\xe2\x87\xa7", NSFB_KEY_LSHIFT},
91 	{  25,  45,  20,  15, "\\", NSFB_KEY_SLASH},
92 	{  45,  45,  20,  15, "z", NSFB_KEY_z},
93 	{  65,  45,  20,  15, "x", NSFB_KEY_x},
94 	{  85,  45,  20,  15, "c", NSFB_KEY_c},
95 	{ 105,  45,  20,  15, "v", NSFB_KEY_v},
96 	{ 125,  45,  20,  15, "b", NSFB_KEY_b},
97 	{ 145,  45,  20,  15, "n", NSFB_KEY_n},
98 	{ 165,  45,  20,  15, "m", NSFB_KEY_m},
99 	{ 185,  45,  20,  15, ",", NSFB_KEY_COMMA},
100 	{ 205,  45,  20,  15, ".", NSFB_KEY_PERIOD},
101 	{ 225,  45,  20,  15, "/", NSFB_KEY_BACKSLASH},
102 	{ 245,  45,  55,  15, "\xe2\x87\xa7", NSFB_KEY_RSHIFT},
103 	{  40,  67, 185,  15, "", NSFB_KEY_SPACE},
104 	{ 250,  60,  20,  15, "\xe2\x96\xb2", NSFB_KEY_UP},
105 	{ 230,  67,  20,  15, "\xe2\x97\x80", NSFB_KEY_LEFT},
106 	{ 270,  67,  20,  15, "\xe2\x96\xb6", NSFB_KEY_RIGHT},
107 	{ 250,  75,  20,  15, "\xe2\x96\xbc", NSFB_KEY_DOWN},
108 };
109 
110 static fbtk_widget_t *osk;
111 
112 static int
osk_close(fbtk_widget_t * widget,fbtk_callback_info * cbi)113 osk_close(fbtk_widget_t *widget, fbtk_callback_info *cbi)
114 {
115 	if (cbi->event->type != NSFB_EVENT_KEY_UP)
116 		return 0;
117 
118 	fbtk_set_mapping(osk, false);
119 
120 	return 0;
121 }
122 
123 static int
osk_click(fbtk_widget_t * widget,fbtk_callback_info * cbi)124 osk_click(fbtk_widget_t *widget, fbtk_callback_info *cbi)
125 {
126 	nsfb_event_t event;
127 	struct kbd_button_s *kbd_button = cbi->context;
128 
129 	event.type = cbi->event->type;
130 	event.value.keycode = kbd_button->keycode;
131 	fbtk_input(widget, &event);
132 
133 	return 0;
134 }
135 
136 /* exported function documented in fbtk.h */
137 void
fbtk_enable_oskb(fbtk_widget_t * fbtk)138 fbtk_enable_oskb(fbtk_widget_t *fbtk)
139 {
140 	fbtk_widget_t *widget;
141 	int kloop;
142 	int maxx = 0;
143 	int maxy = 0;
144 	int ww;
145 	int wh;
146 	fbtk_widget_t *root = fbtk_get_root_widget(fbtk);
147 	int furniture_width = 18;
148 
149 	for (kloop=0; kloop < KEYCOUNT; kloop++) {
150 		if ((kbdbase[kloop].x + kbdbase[kloop].w) > maxx)
151 			maxx=kbdbase[kloop].x + kbdbase[kloop].w;
152 		if ((kbdbase[kloop].y + kbdbase[kloop].h) > maxy)
153 			maxy=kbdbase[kloop].y + kbdbase[kloop].h;
154 	}
155 
156 	ww = fbtk_get_width(root);
157 
158 	/* scale window height apropriately */
159 	wh = (maxy * ww) / maxx;
160 
161 	osk = fbtk_create_window(root, 0, fbtk_get_height(root) - wh, 0, wh, 0xff202020);
162 
163 	for (kloop=0; kloop < KEYCOUNT; kloop++) {
164 		widget = fbtk_create_text_button(osk,
165 						 (kbdbase[kloop].x * ww) / maxx,
166 						 (kbdbase[kloop].y * ww) / maxx,
167 						 (kbdbase[kloop].w * ww) / maxx,
168 						 (kbdbase[kloop].h *ww) / maxx,
169 						 FB_FRAME_COLOUR,
170 						 FB_COLOUR_BLACK,
171 						 osk_click,
172 						 &kbdbase[kloop]);
173 		fbtk_set_text(widget, kbdbase[kloop].t);
174 	}
175 
176 	widget = fbtk_create_button(osk,
177 			fbtk_get_width(osk) - furniture_width,
178 			fbtk_get_height(osk) - furniture_width,
179 			furniture_width,
180 			furniture_width,
181 			FB_FRAME_COLOUR,
182 			&osk_image,
183 			osk_close,
184 			NULL);
185 }
186 
187 /* exported function documented in fbtk.h */
188 void
map_osk(void)189 map_osk(void)
190 {
191 	fbtk_set_zorder(osk, INT_MIN);
192 	fbtk_set_mapping(osk, true);
193 }
194 
195 /*
196  * Local Variables:
197  * c-basic-offset:8
198  * End:
199  */
200