1 /*
2  * Copyright 2008,2010 Vincent Sanders <vince@simtec.co.uk>
3  *
4  * This file is part of NetSurf, http://www.netsurf-browser.org/
5  *
6  * NetSurf is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * NetSurf is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #ifndef NETSURF_FB_FBTK_H
20 #define NETSURF_FB_FBTK_H
21 
22 #include "netsurf/types.h"
23 
24 #define FB_SCROLL_COLOUR 0xFFAAAAAA
25 #define FB_FRAME_COLOUR 0xFFDDDDDD
26 #define FB_COLOUR_BLACK 0xFF000000
27 #define FB_COLOUR_WHITE 0xFFFFFFFF
28 
29 #define FBTK_WIDGET_PADDING 30 /**< percentage of widget size used for padding */
30 #define FBTK_DPI 90 /**< screen DPI */
31 
32 typedef struct fbtk_widget_s fbtk_widget_t;
33 
34 /** Widget Callback type */
35 typedef enum fbtk_callback_type {
36 	FBTK_CBT_START = 0,
37 	FBTK_CBT_SCROLLX,
38 	FBTK_CBT_SCROLLY,
39 	FBTK_CBT_CLICK,
40 	FBTK_CBT_INPUT,
41 	FBTK_CBT_POINTERMOVE,
42 	FBTK_CBT_POINTERLEAVE,
43 	FBTK_CBT_POINTERENTER,
44 	FBTK_CBT_REDRAW,
45 	FBTK_CBT_DESTROY,
46 	FBTK_CBT_USER,
47 	FBTK_CBT_STRIP_FOCUS,
48 	FBTK_CBT_END,
49 } fbtk_callback_type;
50 
51 /** widget callback information */
52 typedef struct fbtk_callback_info {
53 	enum fbtk_callback_type type;
54 	void *context;
55 	nsfb_event_t *event;
56 	int x;
57 	int y;
58 	char *text;
59 	fbtk_widget_t *widget;
60 } fbtk_callback_info;
61 
62 /** framebuffer toolkit bitmaps  */
63 struct fbtk_bitmap {
64         int width;
65         int height;
66         uint8_t *pixdata;
67         bool opaque;
68 
69         /* The following two are only used for cursors */
70         int hot_x;
71         int hot_y;
72 };
73 
74 /** Key modifier status */
75 typedef enum fbtk_modifier_type {
76 	FBTK_MOD_CLEAR  = 0,
77 	FBTK_MOD_LSHIFT = (1 << 0),
78 	FBTK_MOD_RSHIFT = (1 << 1),
79 	FBTK_MOD_LCTRL  = (1 << 2),
80 	FBTK_MOD_RCTRL  = (1 << 3)
81 } fbtk_modifier_type;
82 
83 typedef int (*fbtk_callback)(fbtk_widget_t *widget, fbtk_callback_info *cbi);
84 
85 /* enter pressed on writable icon */
86 typedef int (*fbtk_enter_t)(void *pw, char *text);
87 
88 
89 /************************ Core ****************************/
90 
91 
92 /**
93  * Initialise widget toolkit.
94  *
95  * Initialises widget toolkit against a framebuffer.
96  *
97  * @param fb The underlying framebuffer.
98  * @return The root widget handle.
99  */
100 fbtk_widget_t *fbtk_init(nsfb_t *fb);
101 
102 /**
103  * Retrieve the framebuffer library handle from toolkit widget.
104  *
105  * @param widget A fbtk widget.
106  * @return The underlying framebuffer.
107  */
108 nsfb_t *fbtk_get_nsfb(fbtk_widget_t *widget);
109 
110 /** Perform any pending widget redraws.
111  *
112  * @param widget A fbtk widget.
113  */
114 int fbtk_redraw(fbtk_widget_t *widget);
115 
116 /** Determine if there are any redraws pending for a widget.
117  *
118  * Mainly used by clients on the root widget to determine if they need
119  * to call ::fbtk_redraw
120  *
121  * @param widget to check.
122  */
123 bool fbtk_get_redraw_pending(fbtk_widget_t *widget);
124 
125 /** clip a bounding box to a widgets area.
126  */
127 bool fbtk_clip_to_widget(fbtk_widget_t *widget, bbox_t * restrict box);
128 
129 /** clip one bounding box to another.
130  */
131 bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box);
132 
133 /***************** Callback processing ********************/
134 
135 /** Helper function to allow simple calling of callbacks with parameters.
136  *
137  * @param widget The fbtk widget to post the callback to.
138  * @param cbt The type of callback to post
139  * @param ... Parameters appropriate for the callback type.
140  */
141 int fbtk_post_callback(fbtk_widget_t *widget, fbtk_callback_type cbt, ...);
142 
143 /** Set a callback handler.
144  *
145  * Set a callback handler and the pointer to pass for a widget.
146  *
147  * @param widget The widget to set the handler for.
148  * @param cbt The type of callback to set.
149  * @param cb The callback.
150  * @param pw The private pointer to pass when calling the callback.
151  * @return The previous callback handler for the type or NULL.
152  */
153 fbtk_callback fbtk_set_handler(fbtk_widget_t *widget, fbtk_callback_type cbt, fbtk_callback cb, void *pw);
154 
155 /** Get a callback handler.
156  */
157 fbtk_callback fbtk_get_handler(fbtk_widget_t *widget, fbtk_callback_type cbt);
158 
159 
160 /******************* Event processing **********************/
161 
162 /** Retrive events from the framebuffer input.
163  *
164  * Obtain events from the framebuffer input system with a
165  * timeout. Some events may be used by the toolkit instead of being
166  * returned to the caller.
167  *
168  * @param root An fbtk widget.
169  * @param event an event structure to update.
170  * @param timeout The number of miliseconds to wait for an event. 0
171  *                means do not wait and -1 means wait foreevr.
172  * @return wether \a event has been updated.
173  */
174 bool fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout);
175 
176 /** Insert mouse button press into toolkit.
177  */
178 void fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event);
179 
180 /** Insert input into toolkit.
181  */
182 void fbtk_input(fbtk_widget_t *widget, nsfb_event_t *event);
183 
184 /** Move pointer.
185  *
186  * Move the pointer cursor to a given location.
187  *
188  * @param widget any tookit widget.
189  * @param x movement in horizontal plane.
190  * @param y movement in vertical plane.
191  * @param relative Wheter the /a x and /a y should be considered relative to
192  *                current pointer position.
193  */
194 void fbtk_warp_pointer(fbtk_widget_t *widget, int x, int y, bool relative);
195 
196 /** Toggle pointer grab.
197  *
198  * Toggles the movement grab for a widget.
199  *
200  * @param widget The widget trying to grab the movement.
201  * @return true if the grab was ok, false if the grab failed (already grabbed).
202  */
203 bool fbtk_tgrab_pointer(fbtk_widget_t *widget);
204 
205 /** Convert a framebuffer keycode to ucs4.
206  *
207  * Character mapping between keycode with modifier state and ucs-4.
208  */
209 int fbtk_keycode_to_ucs4(int code, fbtk_modifier_type mods);
210 
211 
212 /******************* Widget Information **********************/
213 
214 /** Obtain the widget at a point on screen.
215  *
216  * @param widget any tookit widget.
217  * @param x location in horizontal plane.
218  * @param y location in vertical plane.
219  * @return widget or NULL.
220  */
221 fbtk_widget_t *fbtk_get_widget_at(fbtk_widget_t *widget, int x, int y);
222 
223 /** Get a widget's absolute horizontal screen co-ordinate.
224  *
225  * @param widget The widget to inspect.
226  * @return The absolute screen co-ordinate.
227  */
228 int fbtk_get_absx(fbtk_widget_t *widget);
229 
230 /** Get a widget's absolute vertical screen co-ordinate.
231  *
232  * @param widget The widget to inspect.
233  * @return The absolute screen co-ordinate.
234  */
235 int fbtk_get_absy(fbtk_widget_t *widget);
236 
237 /**
238  * Get a widget's width.
239  *
240  * @param widget The widget to inspect.
241  * @return The widget width.
242  */
243 int fbtk_get_width(fbtk_widget_t *widget);
244 
245 /**
246  * Get a widget's height.
247  *
248  * @param widget The widget to inspect.
249  * @return The widget height.
250  */
251 int fbtk_get_height(fbtk_widget_t *widget);
252 
253 /**
254  * Get a widget's bounding box in absolute screen co-ordinates.
255  *
256  * @param widget The widget to inspect.
257  * @param bbox The bounding box structure to update.
258  * @return If the \a bbox parameter has been updated.
259  */
260 bool fbtk_get_bbox(fbtk_widget_t *widget, struct nsfb_bbox_s *bbox);
261 
262 /**
263  * Get a widget caret pos, if it owns caret.
264  *
265  * @param widget  The widget to inspect.
266  * @param x       If widget has caret, returns x-coord of caret within widget
267  * @param y       If widget has caret, returns y-coord of caret within widget
268  * @param height  If widget has caret, returns caret height
269  * @return true iff widget has caret
270  */
271 bool fbtk_get_caret(fbtk_widget_t *widget, int *x, int *y, int *height);
272 
273 
274 /******************* Widget Manipulation **********************/
275 
276 /**
277  * Change the widget's position and size. (Doesn't redraw)
278  *
279  */
280 bool fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height);
281 
282 /**
283  * Set caret owner and position
284  *
285  * @param widget  widget to give caret to, or ensure caret is released from
286  * @param set     true: caret to be set for widget, false: caret to be released
287  * @param x       x-coordinate of caret top
288  * @param y       y-coordinate of caret top
289  * @param height  height of caret
290  * @param remove_caret callback when caret is removed.
291  */
292 void fbtk_set_caret(fbtk_widget_t *widget, bool set, int x, int y, int height,
293 		void (*remove_caret)(fbtk_widget_t *widget));
294 
295 /**
296  * Map a widget and request it is redrawn.
297  */
298 int fbtk_set_mapping(fbtk_widget_t *widget, bool mapped);
299 
300 /**
301  * Set the z order of a widget.
302  */
303 int fbtk_set_zorder(fbtk_widget_t *widget, int z);
304 
305 /**
306  * Indicate a widget should be redrawn.
307  */
308 void fbtk_request_redraw(fbtk_widget_t *widget);
309 
310 /**
311  * Destroy a widget and all its descendants.
312  *
313  * Removes a widget from the hierachy and frees it and all its children.
314  *
315  * @param widget The widget to destroy.
316  * @return 0 on success or -1 on error.
317  */
318 int fbtk_destroy_widget(fbtk_widget_t *widget);
319 
320 
321 
322 /********************************* Widgets *********************************/
323 
324 
325 /**
326  * Create a window widget.
327  *
328  * @param parent The parent window or the root widget for a top level window.
329  * @param x The x location relative to the parent window.
330  * @param y the y location relative to the parent window.
331  * @param width The width of the window. 0 indicates parents width should be
332  *              used. Negative value indicates parents width less the value
333  *              should be used. The width is limited to lie within the parent
334  *              window.
335  * @param height The height of the window limited in a similar way to the
336  *               /a width.
337  * @param bg The background colour.
338  * @return new window widget handle or NULL on error.
339  */
340 fbtk_widget_t *fbtk_create_window(fbtk_widget_t *parent, int x, int y, int width, int height, colour bg);
341 
342 
343 
344 /**
345  * Create a filled rectangle
346  *
347  * Create a widget which is a filled rectangle, usually used for backgrounds.
348  *
349  * @param window The window to add the filled area widget to.
350  * @param x X coordinate of widget.
351  * @param y Y coordinate of widget.
352  * @param width Width of the widget
353  * @param height Height of the widget
354  * @param c widget colour
355  * @return new widget handle or NULL on error.
356  */
357 fbtk_widget_t *
358 fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c);
359 
360 
361 /**
362  * Create a horizontal scroll widget
363  *
364  * Create a horizontal scroll widget.
365  *
366  * @param window The window to add the filled area widget to.
367  * @param x X coordinate of widget.
368  * @param y Y coordinate of widget.
369  * @param width Width of the widget
370  * @param height Height of the widget
371  * @param bg background colour
372  * @param fg foreground colour
373  * @param callback Called on scroll
374  * @param context context passed to callback.
375  * @return new widget handle or NULL on error.
376  */
377 fbtk_widget_t *
378 fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg, fbtk_callback callback, void *context);
379 
380 /**
381  * Create a vertical scroll widget
382  *
383  * Create a vertical scroll widget.
384  *
385  * @param window The window to add the filled area widget to.
386  * @param x X coordinate of widget.
387  * @param y Y coordinate of widget.
388  * @param width Width of the widget
389  * @param height Height of the widget
390  * @param bg background colour
391  * @param fg foreground colour
392  * @param callback Called on scroll
393  * @param context context passed to callback.
394  * @return new widget handle or NULL on error.
395  */
396 fbtk_widget_t *
397 fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg, fbtk_callback callback, void *context);
398 
399 /**
400  * Set scoll widget parameters
401  *
402  * @param widget The widget to set the parameters for.
403  * @param min The minimum range value.
404  * @param max The maximum range value.
405  * @param thumb The size of the slider.
406  * @param page The amout to scroll for a page.
407  * @return true if the scroll parameter was set else false.
408  */
409 bool fbtk_set_scroll_parameters(fbtk_widget_t *widget, int min, int max, int thumb, int page);
410 
411 /**
412  * set scroll widget position.
413  *
414  * @param widget The widget to set the position on.
415  * @param pos The position to set
416  * @return true if the scroll parameter was set else false.
417  */
418 bool fbtk_set_scroll_position(fbtk_widget_t *widget, int pos);
419 
420 
421 /**
422  * Move and/or resize a horizontal scroll widget
423  *
424  * @param scrollh  the horizontal scroll widget
425  * @param x        new x pos
426  * @param y        new y pos
427  * @param width    new width
428  * @param height   new height
429  */
430 void fbtk_reposition_hscroll(fbtk_widget_t *scrollh,
431 		int x, int y, int width, int height);
432 
433 /**
434  * Move and/or resize a vertical scroll widget
435  *
436  * @param scrollv  the vertical scroll widget
437  * @param x        new x pos
438  * @param y        new y pos
439  * @param width    new width
440  * @param height   new height
441  */
442 void fbtk_reposition_vscroll(fbtk_widget_t *scrollv,
443 		int x, int y, int width, int height);
444 
445 
446 /**
447  * Create a user widget.
448  *
449  * Create a widget which is to be handled entirely by the calling application.
450  *
451  * @param window The window to add the user widget to.
452  * @param x X coordinate of widget.
453  * @param y Y coordinate of widget.
454  * @param width Width of the widget
455  * @param height Height of the widget
456  * @param pw The private pointer which can be read using ::fbtk_get_userpw
457  * @return new widget handle or NULL on error.
458  */
459 fbtk_widget_t *fbtk_create_user(fbtk_widget_t *window, int x, int y, int width, int height, void *pw);
460 
461 
462 /**
463  * Get the user context from a widget
464  *
465  * @param widget The widget to get the context from.
466  * @return The context or NULL.
467  */
468 void *fbtk_get_userpw(fbtk_widget_t *widget);
469 
470 
471 /**
472  * Create a bitmap widget.
473  *
474  * Create a widget which shows a bitmap.
475  *
476  * @param window The window to add the bitmap widget to.
477  * @param x X coordinate of widget.
478  * @param y Y coordinate of widget.
479  * @param width Width of the widget
480  * @param height Height of the widget
481  * @param c background colour
482  * @param image The bitmap to put in the widget
483  * @return new widget handle or NULL on error.
484  */
485 fbtk_widget_t *fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, int width, int height, colour c, struct fbtk_bitmap *image);
486 
487 
488 /**
489  * Change the bitmap in a widget.
490  *
491  * @param widget The widget to get the context from.
492  * @param image The bitmap to put in the widget
493  */
494 void fbtk_set_bitmap(fbtk_widget_t *widget, struct fbtk_bitmap *image);
495 
496 
497 /**
498  * Create a button widget with an image.
499  *
500  * Helper function which creates a bitmap widget and associate a handler for
501  * when it is clicked.
502  *
503  * @param window The window to add the button widget to.
504  * @param x X coordinate of widget.
505  * @param y Y coordinate of widget.
506  * @param width Width of the widget
507  * @param height Height of the widget
508  * @param c background colour
509  * @param image The bitmap to put in the widget
510  * @param click The callback upon a click
511  * @param pw The context tp pass to the callback
512  * @return new widget handle or NULL on error.
513  */
514 fbtk_widget_t *fbtk_create_button(fbtk_widget_t *window, int x, int y, int width, int height, colour c, struct fbtk_bitmap *image, fbtk_callback click, void *pw);
515 
516 
517 /**
518  * Create a text widget.
519  *
520  * @param window The window to add the text widget to.
521  * @param x X coordinate of widget.
522  * @param y Y coordinate of widget.
523  * @param width Width of the widget
524  * @param height Height of the widget
525  * @param bg background colour
526  * @param fg foreground colour
527  * @param outline widget will have a border.
528  * @return new widget handle or NULL on error.
529  */
530 fbtk_widget_t *fbtk_create_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline);
531 
532 
533 /**
534  * Create a button with text.
535  *
536  * @param window The window to add the text widget to.
537  * @param x X coordinate of widget.
538  * @param y Y coordinate of widget.
539  * @param width Width of the widget
540  * @param height Height of the widget
541  * @param bg background colour
542  * @param fg foreground colour
543  * @param click The callback upon a click
544  * @param pw The context tp pass to the callback
545  * @return new widget handle or NULL on error.
546  */
547 fbtk_widget_t *fbtk_create_text_button(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, fbtk_callback click, void *pw);
548 
549 
550 /**
551  * Create a writable text widget.
552  *
553  * Helper function which creates a text widget and configures an input handler
554  * to create a writable text field. This call is equivalent to calling
555  * ::fbtk_create_text followed by ::fbtk_writable_text
556  *
557  * @param window The window to add the text widget to.
558  * @param x X coordinate of widget.
559  * @param y Y coordinate of widget.
560  * @param width Width of the widget
561  * @param height Height of the widget
562  * @param bg background colour
563  * @param fg foreground colour
564  * @param outline widget will have a border.
565  * @param enter Callback when enter is pressed in widget.
566  * @param pw Context pointer passed to entry callback.
567  * @return new widget handle or NULL on error.
568  */
569 fbtk_widget_t *fbtk_create_writable_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline, fbtk_enter_t enter, void *pw);
570 
571 
572 /**
573  * Alter a text widget to be writable.
574  *
575  * @param widget Text widget.
576  * @param enter The routine to call when enter is pressed.
577  * @param pw The context to pass to the enter callback routine.
578  */
579 void fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw);
580 
581 
582 /**
583  * Change the text of a text widget.
584  *
585  * @param widget Text widget.
586  * @param text The new UTF-8 text to put in the widget.
587  */
588 void fbtk_set_text(fbtk_widget_t *widget, const char *text);
589 
590 
591 /**
592  * Give widget input focus.
593  *
594  * @param widget Widget to be given input focus.
595  */
596 void fbtk_set_focus(fbtk_widget_t *widget);
597 
598 
599 /**
600  * enable the on screen keyboard for input
601  *
602  * @param widget Widget to be given input focus.
603  */
604 void fbtk_enable_oskb(fbtk_widget_t *widget);
605 
606 
607 /**
608  * show the osk.
609  */
610 void map_osk(void);
611 
612 #endif
613