From 2b309755d61d979ce37de9329c9394312b32fdc9 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Tue, 10 Mar 2009 21:45:54 +0000 Subject: move framebuffer port to framebuffer toolkit svn path=/trunk/netsurf/; revision=6760 --- framebuffer/fb_cursor.c | 7 +- framebuffer/fb_cursor.h | 2 + framebuffer/fb_frontend.h | 2 +- framebuffer/fb_frontend_ablefb.c | 14 +- framebuffer/fb_frontend_linuxfb.c | 91 ++-- framebuffer/fb_frontend_sdl.c | 112 ++-- framebuffer/fb_frontend_vnc.c | 202 ++------ framebuffer/fb_gui.c | 760 +++++++++++++++++++-------- framebuffer/fb_gui.h | 27 +- framebuffer/fb_image_data.h | 12 + framebuffer/fb_plotters.c | 17 +- framebuffer/fb_rootwindow.c | 515 ------------------- framebuffer/fb_rootwindow.h | 36 -- framebuffer/fb_tk.c | 1028 +++++++++++++++++++++++++++++++++++++ framebuffer/fb_tk.h | 199 +++++++ framebuffer/res/icons/scrolll.png | Bin 0 -> 522 bytes framebuffer/res/icons/scrollr.png | Bin 0 -> 509 bytes framebuffer/res/throbber | 1 + 18 files changed, 1946 insertions(+), 1079 deletions(-) delete mode 100644 framebuffer/fb_rootwindow.c delete mode 100644 framebuffer/fb_rootwindow.h create mode 100644 framebuffer/fb_tk.c create mode 100644 framebuffer/fb_tk.h create mode 100644 framebuffer/res/icons/scrolll.png create mode 100644 framebuffer/res/icons/scrollr.png create mode 120000 framebuffer/res/throbber (limited to 'framebuffer') diff --git a/framebuffer/fb_cursor.c b/framebuffer/fb_cursor.c index 2b7772d9d..a5e77e543 100644 --- a/framebuffer/fb_cursor.c +++ b/framebuffer/fb_cursor.c @@ -16,9 +16,6 @@ * along with this program. If not, see . */ -#include -#include - #include #include #include @@ -31,11 +28,11 @@ #include "image/bitmap.h" #include "framebuffer/fb_gui.h" +#include "framebuffer/fb_tk.h" #include "framebuffer/fb_plotters.h" #include "framebuffer/fb_bitmap.h" #include "framebuffer/fb_cursor.h" #include "framebuffer/fb_frontend.h" -#include "framebuffer/fb_rootwindow.h" #include "framebuffer/fb_image_data.h" struct fb_cursor_s { @@ -91,7 +88,7 @@ static void fb_cursor_save(framebuffer_t *fb) } } -static void fb_cursor_clear(framebuffer_t *fb) +void fb_cursor_clear(framebuffer_t *fb) { uint8_t *savebuf; int savelen; diff --git a/framebuffer/fb_cursor.h b/framebuffer/fb_cursor.h index cb39c7097..b875cea4e 100644 --- a/framebuffer/fb_cursor.h +++ b/framebuffer/fb_cursor.h @@ -27,6 +27,8 @@ void fb_cursor_move(struct framebuffer_s *fb, int x, int y); void fb_cursor_plot(struct framebuffer_s *fb); +void fb_cursor_clear(struct framebuffer_s *fb); + void fb_cursor_set(fb_cursor_t *cursor, struct bitmap *bmp); fb_cursor_t *fb_cursor_init(struct framebuffer_s *fb, struct bitmap *bmp); diff --git a/framebuffer/fb_frontend.h b/framebuffer/fb_frontend.h index 773c40382..57f3c4a3f 100644 --- a/framebuffer/fb_frontend.h +++ b/framebuffer/fb_frontend.h @@ -21,7 +21,7 @@ extern framebuffer_t *fb_os_init(int argc, char** argv); extern void fb_os_quit(framebuffer_t *fb); -extern void fb_os_input(struct gui_window *g, bool active); +extern void fb_os_input(fbtk_widget_t *root, bool active); extern void fb_os_option_override(void); extern void fb_os_redraw(struct bbox_s *box); diff --git a/framebuffer/fb_frontend_ablefb.c b/framebuffer/fb_frontend_ablefb.c index 0a489adf6..a04bfe876 100644 --- a/framebuffer/fb_frontend_ablefb.c +++ b/framebuffer/fb_frontend_ablefb.c @@ -29,8 +29,10 @@ #include "desktop/gui.h" #include "desktop/options.h" #include "utils/messages.h" +#include "desktop/textinput.h" #include "framebuffer/fb_gui.h" +#include "framebuffer/fb_tk.h" #include "framebuffer/fb_plotters.h" #include "framebuffer/fb_frontend.h" #include "framebuffer/fb_options.h" @@ -99,7 +101,7 @@ void fb_os_quit(framebuffer_t *fb) { } -void fb_os_input(struct gui_window *g) +void fb_os_input(fbtk_widget_t *root, bool active) { ssize_t amt; char key; @@ -108,17 +110,13 @@ void fb_os_input(struct gui_window *g) if (amt > 0) { if (key == 'j') { - g->scrolly +=100; - gui_window_redraw_window(g); + fbtk_input(root, KEY_UP); } if (key == 'k') { - g->scrolly -=100; - if (g->scrolly < 0) - g->scrolly = 0; - gui_window_redraw_window(g); + fbtk_input(root, KEY_DOWN); } if (key == 'q') { - browser_window_destroy(g->bw); + netsurf_quit = true; } if (key == 'd') { list_schedule(); diff --git a/framebuffer/fb_frontend_linuxfb.c b/framebuffer/fb_frontend_linuxfb.c index 2fc6b0368..a003cf0ba 100644 --- a/framebuffer/fb_frontend_linuxfb.c +++ b/framebuffer/fb_frontend_linuxfb.c @@ -41,15 +41,24 @@ #include #include "css/css.h" -#include "desktop/browser.h" +#include "utils/messages.h" #include "desktop/gui.h" +/* #include "desktop/textinput.h" cannot include this becaus eit conflicts with the linux defines */ +#define NSKEY_PAGE_DOWN 135 +#define NSKEY_PAGE_UP 134 +#define NSKEY_DOWN 31 +#define NSKEY_UP 30 +#define NSKEY_LEFT 28 +#define NSKEY_RIGHT 29 +#define NSKEY_ESCAPE 27 + #include "framebuffer/fb_gui.h" +#include "framebuffer/fb_tk.h" #include "framebuffer/fb_plotters.h" #include "framebuffer/fb_schedule.h" #include "framebuffer/fb_cursor.h" #include "framebuffer/fb_frontend.h" #include "framebuffer/fb_options.h" -#include "framebuffer/fb_rootwindow.h" #include "utils/log.h" #include "utils/messages.h" @@ -416,7 +425,7 @@ framebuffer_init(const char *device, int width, int height, int refresh, int bpp if (vt != 0) fb_setvt(vt); - if (-1 == ioctl(tty,VT_GETSTATE, &vts)) { + if (ioctl(tty,VT_GETSTATE, &vts) == -1) { fprintf(stderr,"ioctl VT_GETSTATE: %s (not a linux console?)\n", strerror(errno)); exit(1); @@ -538,23 +547,23 @@ fb_catch_exit_signals(void) memset(&act,0,sizeof(act)); act.sa_handler = fb_catch_exit_signal; sigemptyset(&act.sa_mask); - sigaction(SIGINT, &act,&old); - sigaction(SIGQUIT,&act,&old); - sigaction(SIGTERM,&act,&old); + sigaction(SIGINT, &act, &old); + sigaction(SIGQUIT, &act, &old); + sigaction(SIGTERM, &act, &old); - sigaction(SIGABRT,&act,&old); - sigaction(SIGTSTP,&act,&old); + sigaction(SIGABRT, &act, &old); + sigaction(SIGTSTP, &act, &old); - sigaction(SIGBUS, &act,&old); - sigaction(SIGILL, &act,&old); - sigaction(SIGSEGV,&act,&old); + sigaction(SIGBUS, &act, &old); + sigaction(SIGILL, &act, &old); + sigaction(SIGSEGV, &act, &old); - if (0 == (termsig = sigsetjmp(fb_fatal_cleanup,0))) + if ((termsig = sigsetjmp(fb_fatal_cleanup,0)) == 0) return; /* cleanup */ fb_cleanup(); - fprintf(stderr,"Oops: %s\n",sys_siglist[termsig]); + fprintf(stderr, "Oops: %s\n", sys_siglist[termsig]); exit(42); } @@ -652,7 +661,7 @@ static int keycode_to_ucs4(int code, bool shift) return ucs4; } -void fb_os_input(struct gui_window *g, bool active) +void fb_os_input(fbtk_widget_t *root, bool active) { ssize_t amt; struct input_event event; @@ -674,49 +683,43 @@ void fb_os_input(struct gui_window *g, bool active) break; case BTN_LEFT: - fb_rootwindow_click(g, - BROWSER_MOUSE_CLICK_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - break; + fbtk_click(root, BROWSER_MOUSE_CLICK_1); + break; } return; } switch (event.code) { case KEY_PAGEDOWN: - fb_window_scroll(g, 0, g->height); + ucs4 = NSKEY_PAGE_DOWN; break; case KEY_PAGEUP: - fb_window_scroll(g, 0, -g->height); + ucs4 = NSKEY_PAGE_UP; break; case KEY_DOWN: - fb_window_scroll(g, 0, 100); + ucs4 = NSKEY_DOWN; break; case KEY_UP: - fb_window_scroll(g, 0, -100); + ucs4 = NSKEY_UP; break; case KEY_LEFT: - fb_window_scroll(g, -100, 0); + ucs4 = NSKEY_LEFT; break; case KEY_RIGHT: - fb_window_scroll(g, 100, 0); + ucs4 = NSKEY_RIGHT; break; case KEY_ESC: - browser_window_destroy(g->bw); + ucs4 = NSKEY_ESCAPE; break; case BTN_LEFT: - fb_rootwindow_click(g, - BROWSER_MOUSE_PRESS_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); + fbtk_click(root, BROWSER_MOUSE_PRESS_1); break; case KEY_LEFTSHIFT: @@ -730,22 +733,36 @@ void fb_os_input(struct gui_window *g, bool active) } } else if (event.type == EV_REL) { switch (event.code) { - case 0: - fb_rootwindow_move(framebuffer, g, event.value, 0, true); + case REL_X: + fbtk_move_pointer(root, event.value, 0, true); break; - case 1: - fb_rootwindow_move(framebuffer, g, 0, event.value, true); + case REL_Y: + fbtk_move_pointer(root, 0, event.value, true); break; - case 8: - fb_window_scroll(g, 0, event.value * -100); + case REL_WHEEL: + if (event.value > 0) + fbtk_input(root, NSKEY_UP); + else + fbtk_input(root, NSKEY_DOWN); break; } + } else if (event.type == EV_ABS) { + switch (event.code) { + case ABS_X: + fbtk_move_pointer(root, event.value, -1, false); + break; + + case ABS_Y: + fbtk_move_pointer(root, -1, event.value, false); + break; + + } } if (ucs4 != -1) { - fb_rootwindow_input(g, ucs4); + fbtk_input(root, ucs4); ucs4 = -1; } diff --git a/framebuffer/fb_frontend_sdl.c b/framebuffer/fb_frontend_sdl.c index 02d2e6af8..127088f92 100644 --- a/framebuffer/fb_frontend_sdl.c +++ b/framebuffer/fb_frontend_sdl.c @@ -26,23 +26,21 @@ #include #include "css/css.h" -#include "desktop/options.h" #include "desktop/gui.h" #include "desktop/options.h" #include "utils/messages.h" #include "desktop/history_core.h" +#include "desktop/textinput.h" #include "framebuffer/fb_gui.h" +#include "framebuffer/fb_tk.h" #include "framebuffer/fb_plotters.h" #include "framebuffer/fb_frontend.h" #include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_rootwindow.h" #include "framebuffer/fb_options.h" #include "utils/log.h" -#define FILE_PFX "/home/vince/netsurf/netsurf/framebuffer/res/" - static SDL_Surface *sdl_screen; framebuffer_t *fb_os_init(int argc, char** argv) @@ -79,9 +77,9 @@ framebuffer_t *fb_os_init(int argc, char** argv) newfb->bpp = fb_depth; sdl_screen = SDL_SetVideoMode(newfb->width, - newfb->height, - newfb->bpp, - SDL_SWSURFACE); + newfb->height, + newfb->bpp, + SDL_SWSURFACE); if ( sdl_screen == NULL ) { fprintf(stderr, @@ -102,10 +100,11 @@ void fb_os_quit(framebuffer_t *fb) { } -void fb_os_input(struct gui_window *g, bool active) +void fb_os_input(fbtk_widget_t *root, bool active) { int got_event; SDL_Event event; + int nskey; if (active) got_event = SDL_PollEvent(&event); @@ -119,73 +118,61 @@ void fb_os_input(struct gui_window *g, bool active) switch (event.type) { case SDL_KEYDOWN: - switch (event.key.keysym.sym) { - - case SDLK_PAGEDOWN: - fb_window_scroll(g, 0, g->height); - break; + switch (event.key.keysym.sym) { + case SDLK_PAGEDOWN: + nskey = KEY_PAGE_DOWN; + break; - case SDLK_PAGEUP: - fb_window_scroll(g, 0, -g->height); - break; + case SDLK_PAGEUP: + nskey = KEY_PAGE_UP; + break; - case SDLK_DOWN: - fb_window_scroll(g, 0, 100); - break; - - case SDLK_UP: - fb_window_scroll(g, 0, -100); - break; - - case SDLK_ESCAPE: - browser_window_destroy(g->bw); - break; + case SDLK_LEFT: + nskey = KEY_LEFT; + break; - case SDLK_LEFT: - fb_window_scroll(g, -100, 0); - break; + case SDLK_RIGHT: + nskey = KEY_RIGHT; + break; - case SDLK_RIGHT: - fb_window_scroll(g, 100, 0); - break; + case SDLK_DOWN: + nskey = KEY_DOWN; + break; - default: - fb_rootwindow_input(g, event.key.keysym.sym); - break; - } - break; + case SDLK_UP: + nskey = KEY_UP; + break; + + default: + nskey = event.key.keysym.sym; + break; + } + fbtk_input(root, nskey); + + break; case SDL_MOUSEMOTION: - fb_rootwindow_move(framebuffer, g, event.motion.x, event.motion.y, false); + fbtk_move_pointer(root, event.motion.x, event.motion.y, false); break; case SDL_MOUSEBUTTONDOWN: switch (event.button.button) { case SDL_BUTTON_LEFT: - fb_rootwindow_click(g, BROWSER_MOUSE_PRESS_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); + fbtk_click(root, BROWSER_MOUSE_PRESS_1); break; case SDL_BUTTON_RIGHT: - fb_rootwindow_click(g, BROWSER_MOUSE_PRESS_2, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); + fbtk_click(root, BROWSER_MOUSE_PRESS_2); break; case SDL_BUTTON_WHEELUP: - fb_window_scroll(g, 0, -100); - break; + fbtk_input(root, KEY_UP); + break; case SDL_BUTTON_WHEELDOWN: - fb_window_scroll(g, 0, 100); - break; - - case SDL_BUTTON_MIDDLE: - default: - LOG(("Mouse button %d pressed at (%d,%d)\n", - event.button.button, event.button.x, event.button.y)); + fbtk_input(root, KEY_DOWN); + break; } break; @@ -194,27 +181,20 @@ void fb_os_input(struct gui_window *g, bool active) switch (event.button.button) { case SDL_BUTTON_LEFT: - fb_rootwindow_click(g, BROWSER_MOUSE_CLICK_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); + fbtk_click(root, BROWSER_MOUSE_CLICK_1); break; case SDL_BUTTON_RIGHT: - fb_rootwindow_click(g, BROWSER_MOUSE_CLICK_2, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); + fbtk_click(root, BROWSER_MOUSE_CLICK_2); break; - default: - LOG(("Mouse button %d pressed at (%d,%d)\n", - event.button.button, event.button.x, event.button.y)); - } break; case SDL_QUIT: - browser_window_destroy(g->bw); - } + netsurf_quit = true; + break; + } } diff --git a/framebuffer/fb_frontend_vnc.c b/framebuffer/fb_frontend_vnc.c index f7ee89151..837cddaaf 100644 --- a/framebuffer/fb_frontend_vnc.c +++ b/framebuffer/fb_frontend_vnc.c @@ -32,130 +32,100 @@ #include "desktop/options.h" #include "utils/messages.h" #include "desktop/history_core.h" +#include "desktop/textinput.h" #include "framebuffer/fb_gui.h" +#include "framebuffer/fb_tk.h" #include "framebuffer/fb_plotters.h" #include "framebuffer/fb_frontend.h" #include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_rootwindow.h" #include "framebuffer/fb_options.h" #include "utils/log.h" static rfbScreenInfoPtr vnc_screen; -static struct gui_window *cur_window; +static fbtk_widget_t *vncroot; static void fb_vnc_doptr(int buttonMask,int x,int y,rfbClientPtr cl) { - struct gui_window *g = cur_window; if (buttonMask == 0) { - fb_rootwindow_move(framebuffer, g, x, y, false); + fbtk_move_pointer(vncroot, x, y, false); } else { /* left button */ - /* if (buttonMask && 0x1) { - fb_rootwindow_click(g, BROWSER_MOUSE_PRESS_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - }*/ if (buttonMask && 0x1) { - fb_rootwindow_click(g, BROWSER_MOUSE_CLICK_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); + fbtk_click(vncroot, BROWSER_MOUSE_CLICK_1); } /* right button */ - /*if (buttonMask && 0x4) { - fb_rootwindow_click(g, BROWSER_MOUSE_PRESS_2, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - }*/ if (buttonMask && 0x4) { - fb_rootwindow_click(g, BROWSER_MOUSE_CLICK_2, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); + fbtk_click(vncroot, BROWSER_MOUSE_CLICK_2); } if (buttonMask && 0x8) { /* wheelup */ - fb_window_scroll(g, 0, -100); + fbtk_input(vncroot, KEY_UP); } if (buttonMask && 0x10) { /* wheeldown */ - fb_window_scroll(g, 0, 100); + fbtk_input(vncroot, KEY_DOWN); } - - - - /* - case SDL_MOUSEBUTTONUP: - switch (event.button.button) { - - case SDL_BUTTON_LEFT: - fb_rootwindow_click(g, BROWSER_MOUSE_CLICK_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - break; - - case SDL_BUTTON_RIGHT: - fb_rootwindow_click(g, BROWSER_MOUSE_CLICK_2, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - break; - - default: - printf("Mouse button %d pressed at (%d,%d)\n", - event.button.button, event.button.x, event.button.y); - - } - break; - */ } } -static void fb_vnc_dokey(rfbBool down,rfbKeySym key,rfbClientPtr cl) + +static void fb_vnc_dokey(rfbBool down, rfbKeySym key, rfbClientPtr cl) { - struct gui_window *g = cur_window; + int nskey; LOG(("Processing keycode %d",key)); - if(down) { + if (down) { switch (key) { case XK_Page_Down: - fb_window_scroll(g, 0, g->height); + nskey = KEY_PAGE_DOWN; break; case XK_Page_Up: - fb_window_scroll(g, 0, -g->height); + nskey = KEY_PAGE_UP; break; case XK_Down: - fb_window_scroll(g, 0, 100); + nskey = KEY_DOWN; break; case XK_Up: - fb_window_scroll(g, 0, -100); + nskey = KEY_UP; break; case XK_Escape: - browser_window_destroy(g->bw); + nskey = 27; break; case XK_Left: - if (history_back_available(g->bw->history)) - history_back(g->bw, g->bw->history); + nskey = KEY_LEFT; break; case XK_Right: - if (history_forward_available(g->bw->history)) - history_forward(g->bw, g->bw->history); + nskey = KEY_RIGHT; + break; + + case XK_BackSpace: + nskey = 8; + break; + + case XK_Return: + nskey = 13; break; default: - fb_rootwindow_input(g, key); + nskey = key; break; } + + fbtk_input(vncroot, nskey); + } } @@ -232,120 +202,14 @@ void fb_os_quit(framebuffer_t *fb) { } -void fb_os_input(struct gui_window *g, bool active) +void fb_os_input(fbtk_widget_t *root, bool active) { - //SDL_Event event; - cur_window = g; + vncroot = root; if (active) rfbProcessEvents(vnc_screen, 10000); else rfbProcessEvents(vnc_screen, 100000); - /* - switch (event.type) { - case SDL_KEYDOWN: - - switch (event.key.keysym.sym) { - - case SDLK_PAGEDOWN: - fb_window_scroll(g, 0, g->height); - break; - - case SDLK_PAGEUP: - fb_window_scroll(g, 0, -g->height); - break; - - case SDLK_DOWN: - fb_window_scroll(g, 0, 100); - break; - - case SDLK_UP: - fb_window_scroll(g, 0, -100); - break; - - case SDLK_ESCAPE: - browser_window_destroy(g->bw); - break; - - case SDLK_LEFT: - if (history_back_available(g->bw->history)) - history_back(g->bw, g->bw->history); - break; - - case SDLK_RIGHT: - if (history_forward_available(g->bw->history)) - history_forward(g->bw, g->bw->history); - break; - - default: - printf("The %s key was pressed!\n", - SDL_GetKeyName(event.key.keysym.sym)); - fb_rootwindow_input(g, event.key.keysym.sym); - break; - } - break; - - case SDL_MOUSEMOTION: - fb_rootwindow_move(framebuffer, g, event.motion.x, event.motion.y, false); - break; - - case SDL_MOUSEBUTTONDOWN: - switch (event.button.button) { - - case SDL_BUTTON_LEFT: - fb_rootwindow_click(g, BROWSER_MOUSE_PRESS_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - break; - - case SDL_BUTTON_RIGHT: - fb_rootwindow_click(g, BROWSER_MOUSE_PRESS_2, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - break; - - case SDL_BUTTON_WHEELUP: - fb_window_scroll(g, 0, -100); - break; - - case SDL_BUTTON_WHEELDOWN: - fb_window_scroll(g, 0, 100); - break; - - case SDL_BUTTON_MIDDLE: - default: - printf("Mouse button %d pressed at (%d,%d)\n", - event.button.button, event.button.x, event.button.y); - - } - break; - - case SDL_MOUSEBUTTONUP: - switch (event.button.button) { - - case SDL_BUTTON_LEFT: - fb_rootwindow_click(g, BROWSER_MOUSE_CLICK_1, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - break; - - case SDL_BUTTON_RIGHT: - fb_rootwindow_click(g, BROWSER_MOUSE_CLICK_2, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); - break; - - default: - printf("Mouse button %d pressed at (%d,%d)\n", - event.button.button, event.button.x, event.button.y); - - } - break; - - case SDL_QUIT: - browser_window_destroy(g->bw); - } - */ } void diff --git a/framebuffer/fb_gui.c b/framebuffer/fb_gui.c index 276aba62d..80fcc8c3d 100644 --- a/framebuffer/fb_gui.c +++ b/framebuffer/fb_gui.c @@ -34,15 +34,16 @@ #include "utils/log.h" #include "utils/messages.h" #include "utils/utils.h" +#include "desktop/textinput.h" -#include "framebuffer/fb_bitmap.h" #include "framebuffer/fb_gui.h" +#include "framebuffer/fb_tk.h" +#include "framebuffer/fb_bitmap.h" #include "framebuffer/fb_frontend.h" #include "framebuffer/fb_plotters.h" #include "framebuffer/fb_schedule.h" #include "framebuffer/fb_cursor.h" #include "framebuffer/fb_findfile.h" -#include "framebuffer/fb_rootwindow.h" #include "framebuffer/fb_image_data.h" #include "framebuffer/fb_font.h" @@ -53,6 +54,9 @@ char *default_stylesheet_url; char *adblock_stylesheet_url; char *options_file_location; + +fbtk_widget_t *fbtk; + struct gui_window *input_window = NULL; struct gui_window *search_current_window; struct gui_window *window_list = NULL; @@ -61,141 +65,209 @@ bool redraws_pending = false; framebuffer_t *framebuffer; -static void fb_queue_redraw(struct gui_window *g, int x0, int y0, int x1, int y1); +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +/* private data for browser user widget */ +struct browser_widget_s { + struct browser_window *bw; /**< The browser window connected to this gui window */ + int scrollx, scrolly; /**< scroll offsets. */ + + /* Pending window redraw state. */ + bool redraw_required; /**< flag indicating the foreground loop + * needs to redraw the browser widget. + */ + bbox_t redraw_box; /**< Area requiring redraw. */ + bool pan_required; /**< flag indicating the foreground loop + * needs to pan the window. + */ + int panx, pany; /**< Panning required. */ +}; -static void fb_pan(struct gui_window *g) + +/* queue a redraw operation, co-ordinates are relative to the window */ +static void +fb_queue_redraw(struct fbtk_widget_s *widget, int x0, int y0, int x1, int y1) +{ + struct browser_widget_s *bwidget = fbtk_get_userpw(widget); + + bwidget->redraw_box.x0 = MIN(bwidget->redraw_box.x0, x0); + bwidget->redraw_box.y0 = MIN(bwidget->redraw_box.y0, y0); + bwidget->redraw_box.x1 = MAX(bwidget->redraw_box.x1, x1); + bwidget->redraw_box.y1 = MAX(bwidget->redraw_box.y1, y1); + + bwidget->redraw_required = true; + + fbtk_request_redraw(widget); +} + +static void fb_pan(fbtk_widget_t *widget, + struct browser_widget_s *bwidget, + struct browser_window *bw) { struct content *c; + int x; + int y; + int width; + int height; - if (!g) - return; + c = bw->current_content; - c = g->bw->current_content; + if ((!c) || (c->locked)) + return; - if (!c) return; - if (c->locked) return; + height = fbtk_get_height(widget); + width = fbtk_get_width(widget); + x = fbtk_get_x(widget); + y = fbtk_get_y(widget); - LOG(("panning %d, %d from %d, %d in content %d,%d", - g->panx, g->pany,g->scrollx,g->scrolly,c->width, c->height)); /* dont pan off the top */ - if ((g->scrolly + g->pany) < 0) - g->pany = - g->scrolly; + if ((bwidget->scrolly + bwidget->pany) < 0) + bwidget->pany = - bwidget->scrolly; /* do not pan off the bottom of the content */ - if ((g->scrolly + g->pany) > (c->height - g->height)) - g->pany = (c->height - g->height) - g->scrolly; + if ((bwidget->scrolly + bwidget->pany) > (c->height - height)) + bwidget->pany = (c->height - height) - bwidget->scrolly; /* dont pan off the left */ - if ((g->scrollx + g->panx) < 0) - g->panx = - g->scrollx; + if ((bwidget->scrollx + bwidget->panx) < 0) + bwidget->panx = - bwidget->scrollx; /* do not pan off the right of the content */ - if ((g->scrollx + g->panx) > (c->width - g->width)) - g->panx = (c->width - g->width) - g->scrollx; + if ((bwidget->scrollx + bwidget->panx) > (c->width - width)) + bwidget->panx = (c->width - width) - bwidget->scrollx; - LOG(("panning %d, %d",g->panx, g->pany)); + LOG(("panning %d, %d",bwidget->panx, bwidget->pany)); /* pump up the volume. dance, dance! lets do it */ - if (g->pany < 0) { + if (bwidget->pany < 0) { /* we cannot pan more than a window height at a time */ - if (g->pany < -g->height) - g->pany = -g->height; + if (bwidget->pany < -height) + bwidget->pany = -height; - LOG(("panning up %d", g->pany)); + LOG(("panning up %d", bwidget->pany)); - fb_plotters_move_block(g->x, g->y, - g->width, g->height + g->pany, - g->x, g->y - g->pany); - g->scrolly += g->pany; - fb_queue_redraw(g, 0, 0, - g->width, - g->pany); + fb_plotters_move_block(x, y, + width, height + bwidget->pany, + x, y - bwidget->pany); + bwidget->scrolly += bwidget->pany; + fb_queue_redraw(widget, 0, 0, width, - bwidget->pany); } - if (g->pany > 0) { + + if (bwidget->pany > 0) { /* we cannot pan more than a window height at a time */ - if (g->pany > g->height) - g->pany = g->height; + if (bwidget->pany > height) + bwidget->pany = height; - LOG(("panning down %d", g->pany)); + LOG(("panning down %d", bwidget->pany)); - fb_plotters_move_block(g->x, g->y + g->pany, - g->width, g->height - g->pany, - g->x, g->y); - g->scrolly += g->pany; - fb_queue_redraw(g, 0, g->height - g->pany, - g->width, g->height); + fb_plotters_move_block(x, y + bwidget->pany, + width, height - bwidget->pany, + x, y); + bwidget->scrolly += bwidget->pany; + fb_queue_redraw(widget, 0, height - bwidget->pany, width, height); } - if (g->panx < 0) { + if (bwidget->panx < 0) { /* we cannot pan more than a window width at a time */ - if (g->panx < -g->width) - g->panx = -g->width; + if (bwidget->panx < -width) + bwidget->panx = -width; - LOG(("panning left %d", g->panx)); + LOG(("panning left %d", bwidget->panx)); - fb_plotters_move_block(g->x, g->y, - g->width + g->panx, g->height , - g->x - g->panx, g->y ); - g->scrollx += g->panx; - fb_queue_redraw(g, 0, 0, - - g->panx, g->height); + fb_plotters_move_block(x, y, + width + bwidget->panx, height , + x - bwidget->panx, y ); + bwidget->scrollx += bwidget->panx; + fb_queue_redraw(widget, 0, 0, -bwidget->panx, height); } - if (g->panx > 0) { + if (bwidget->panx > 0) { /* we cannot pan more than a window width at a time */ - if (g->panx > g->width) - g->panx = g->width; + if (bwidget->panx > width) + bwidget->panx = width; - LOG(("panning right %d", g->panx)); + LOG(("panning right %d", bwidget->panx)); - fb_plotters_move_block(g->x + g->panx, g->y, - g->width - g->panx, g->height, - g->x, g->y); - g->scrollx += g->panx; - fb_queue_redraw(g, g->width - g->panx, 0, - g->width, g->height); + fb_plotters_move_block(x + bwidget->panx, y, + width - bwidget->panx, height, + x, y); + bwidget->scrollx += bwidget->panx; + fb_queue_redraw(widget, width - bwidget->panx, 0, width, height); } - g->pan_required = false; - g->panx = 0; - g->pany = 0; + + bwidget->pan_required = false; + bwidget->panx = 0; + bwidget->pany = 0; } -static void fb_redraw(struct gui_window *g) +static void fb_redraw(fbtk_widget_t *widget, + struct browser_widget_s *bwidget, + struct browser_window *bw) { struct content *c; + int x; + int y; + int width; + int height; - if (!g) - return; + c = bw->current_content; - c = g->bw->current_content; + if ((!c) || (c->locked)) + return; - if (!c) return; - if (c->locked) return; + height = fbtk_get_height(widget); + width = fbtk_get_width(widget); + x = fbtk_get_x(widget); + y = fbtk_get_y(widget); /* adjust clipping co-ordinates according to window location */ - g->redraw_box.y0 += g->y; - g->redraw_box.y1 += g->y; - g->redraw_box.x0 += g->x; - g->redraw_box.x1 += g->x; + bwidget->redraw_box.y0 += y; + bwidget->redraw_box.y1 += y; + bwidget->redraw_box.x0 += x; + bwidget->redraw_box.x1 += x; /* redraw bounding box is relative to window */ content_redraw(c, - g->x - g->scrollx, - g->y - g->scrolly , - g->width, - g->height, - g->redraw_box.x0, g->redraw_box.y0, - g->redraw_box.x1, g->redraw_box.y1, - g->bw->scale, 0xFFFFFF); + x - bwidget->scrollx, y - bwidget->scrolly, + width, height, + bwidget->redraw_box.x0, bwidget->redraw_box.y0, + bwidget->redraw_box.x1, bwidget->redraw_box.y1, + bw->scale, 0xFFFFFF); - fb_os_redraw(&g->redraw_box); + fb_os_redraw(&bwidget->redraw_box); + + bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX; + bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = -(INT_MAX); + bwidget->redraw_required = false; +} + +static int +fb_browser_window_redraw(fbtk_widget_t *widget, void *pw) +{ + struct gui_window *gw = pw; + struct browser_widget_s *bwidget; - g->redraw_required = false; - g->redraw_box.y0 = g->redraw_box.x0 = INT_MAX; - g->redraw_box.y1 = g->redraw_box.x1 = -(INT_MAX); - g->panx = 0; - g->pany = 0; - redraws_pending = false; + bwidget = fbtk_get_userpw(widget); + + if (bwidget->pan_required) { + int pos; + fb_pan(widget, bwidget, gw->bw); + pos = (bwidget->scrollx * 100) / gw->bw->current_content->width;; + fbtk_set_scroll_pos(gw->hscroll, pos); + + } + + if (bwidget->redraw_required) { + fb_redraw(widget, bwidget, gw->bw); + } + return 0; } #ifdef WITH_HUBBUB @@ -268,6 +340,7 @@ void gui_init(int argc, char** argv) if (fb_font_init() == false) die("Unable to initialise the font system"); + fbtk = fbtk_init(framebuffer); } void gui_init2(int argc, char** argv) @@ -282,8 +355,6 @@ void gui_init2(int argc, char** argv) if (argc > 1) addr = argv[1]; - fb_rootwindow_create(framebuffer); - LOG(("calling browser_window_create")); bw = browser_window_create(addr, 0, 0, true, false); } @@ -301,31 +372,12 @@ void gui_poll(bool active) if (active) fetch_poll(); - //LOG(("enter schedule run")); active = schedule_run() | active | redraws_pending; - fb_os_input(input_window, active); - - if (redraws_pending == true) { - struct gui_window *g; - - fb_cursor_move(framebuffer, - fb_cursor_x(framebuffer), - fb_cursor_y(framebuffer)); + fb_os_input(fbtk, active); - redraws_pending = false; + fbtk_redraw(fbtk); - for (g = window_list; g != NULL; g = g->next) { - if (g->pan_required == true) { - fb_pan(g); - } - if (g->redraw_required == true) { - fb_redraw(g); - } - } - } - - fb_cursor_plot(framebuffer); } void gui_quit(void) @@ -340,162 +392,361 @@ void gui_quit(void) /* called back when click in browser window */ static int -fb_browser_window_click(struct gui_window *g, browser_mouse_state st, int x, int y) +fb_browser_window_click(fbtk_widget_t *widget, + browser_mouse_state st, + int x, int y, + void *pw) { + struct browser_window *bw = pw; + struct browser_widget_s *bwidget = fbtk_get_userpw(widget); + LOG(("browser window clicked at %d,%d",x,y)); - browser_window_mouse_click(g->bw, + browser_window_mouse_click(bw, st, - x + g->scrollx, - y + g->scrolly); + x + bwidget->scrollx, + y + bwidget->scrolly); + return 0; +} + +/* called back when movement in browser window */ +static int +fb_browser_window_move(fbtk_widget_t *widget, + int x, int y, + void *pw) +{ + struct browser_window *bw = pw; + struct browser_widget_s *bwidget = fbtk_get_userpw(widget); + + browser_window_mouse_track(bw, + 0, + x + bwidget->scrollx, + y + bwidget->scrolly); + return 0; } static int -fb_browser_window_input(fb_widget_t *widget, struct gui_window *g, int value) +fb_browser_window_input(fbtk_widget_t *widget, int value, void *pw) { + struct gui_window *gw = pw; + int res = 0; LOG(("got value %d",value)); - if (value >= 0) - return browser_window_key_press(g->bw, value); + switch (value) { + + case KEY_PAGE_UP: + fb_window_scroll(gw, 0, -fbtk_get_height(gw->browser)); + break; + + case KEY_PAGE_DOWN: + fb_window_scroll(gw, 0, fbtk_get_height(gw->browser)); + break; + + case KEY_RIGHT: + fb_window_scroll(gw, 100, 0); + break; + + case KEY_LEFT: + fb_window_scroll(gw, -100, 0); + break; + + case KEY_UP: + fb_window_scroll(gw, 0, -100); + break; + + case KEY_DOWN: + fb_window_scroll(gw, 0, 100); + break; + + default: + res = browser_window_key_press(gw->bw, value); + break; + } + return 0; } -struct gui_window *gui_create_browser_window(struct browser_window *bw, - struct browser_window *clone, - bool new_tab) +/* left icon click routine */ +static int +fb_leftarrow_click(fbtk_widget_t *widget, + browser_mouse_state st, + int x, int y, void *pw) { - struct gui_window *g, *p; - LOG(("bw %p, clone %p", bw, clone)); - - g = calloc(1, sizeof(struct gui_window)); - if (g == NULL) - return NULL; + struct browser_window *bw = pw; - g->x = 0; - g->y = 30; - g->width = framebuffer->width; - g->height = framebuffer->height - 50; - g->bw = bw; - - if (window_list == NULL) { - window_list = input_window = g; - fb_add_window_widget(g, 0, fb_browser_window_click, fb_browser_window_input); - } else { - for (p = window_list; p->next != NULL; p = p->next); - p->next = g; - g->prev = p; + if (st == BROWSER_MOUSE_CLICK_1) { + if (history_back_available(bw->history)) + history_back(bw, bw->history); } + return 0; - return g; } -void gui_window_destroy(struct gui_window *g) +/* right arrow icon click routine */ +static int +fb_rightarrow_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) { - LOG(("g %p", g)); + struct browser_window *bw = pw; - if (g->prev == NULL) { - window_list = input_window = g->next; - } else { - g->prev->next = g->next; + if (st == BROWSER_MOUSE_CLICK_1) { + if (history_forward_available(bw->history)) + history_forward(bw, bw->history); } - if (g->next != NULL) - g->next->prev = g->prev; + return 0; - free(g); +} - if (window_list == NULL) - netsurf_quit = true; +/* reload icon click routine */ +static int +fb_reload_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) +{ + struct browser_window *bw = pw; + browser_window_reload(bw, true); + return 0; +} +/* stop icon click routine */ +static int +fb_stop_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) +{ + struct browser_window *bw = pw; + browser_window_stop(bw); + return 0; } -void gui_window_set_title(struct gui_window *g, const char *title) +/* left scroll icon click routine */ +static int +fb_scrolll_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) { - LOG(("%s(%p, %s)", __func__, g, title)); + fbtk_input(widget, KEY_LEFT); + return 0; } -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif +static int +fb_scrollr_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) +{ + fbtk_input(widget, KEY_RIGHT); + return 0; +} -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif +static int +fb_url_enter(void *pw, char *text) +{ + struct browser_window *bw = pw; + browser_window_go(bw, text, 0, true); + return 0; +} -/* queue a redraw operation, co-ordinates are relative to the window */ -static void -fb_queue_redraw(struct gui_window *g, int x0, int y0, int x1, int y1) +static int +fb_url_move(fbtk_widget_t *widget, + int x, int y, + void *pw) { - if (!g) return; + fb_cursor_set(framebuffer->cursor, &caret_image); + return 0; +} + +static int +set_ptr_default_move(fbtk_widget_t *widget, + int x, int y, + void *pw) +{ + fb_cursor_set(framebuffer->cursor, &pointer_image); + return 0; +} + +static int +set_ptr_hand_move(fbtk_widget_t *widget, + int x, int y, + void *pw) +{ + fb_cursor_set(framebuffer->cursor, &hand_image); + return 0; +} + +struct gui_window * +gui_create_browser_window(struct browser_window *bw, + struct browser_window *clone, + bool new_tab) +{ + struct gui_window *gw; + struct browser_widget_s *browser_widget; + fbtk_widget_t *widget; + int top = 0; + int bot = 0; + + gw = calloc(1, sizeof(struct gui_window)); + + if (gw == NULL) + return NULL; + + /* seems we need to associate the gui window with the underlying + * browser window + */ + gw->bw = bw; + + + switch(bw->browser_window_type) { + case BROWSER_WINDOW_NORMAL: + gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0); + + top = 30; + bot = -50; + + LOG(("Normal window")); + + /* fill toolbar background */ + widget = fbtk_create_fill(gw->window, 0, 0, 0, 30, FB_FRAME_COLOUR); + fbtk_set_handler_move(widget, set_ptr_default_move, bw); + + /* back button */ + widget = fbtk_create_button(gw->window, 5, 2, FB_FRAME_COLOUR, &left_arrow, fb_leftarrow_click, bw); + fbtk_set_handler_move(widget, set_ptr_hand_move, bw); + + /* forward button */ + widget = fbtk_create_button(gw->window, 35, 2, FB_FRAME_COLOUR, &right_arrow, fb_rightarrow_click, bw); + fbtk_set_handler_move(widget, set_ptr_hand_move, bw); + + /* reload button */ + widget = fbtk_create_button(gw->window, 65, 2, FB_FRAME_COLOUR, &stop_image, fb_stop_click, bw); + fbtk_set_handler_move(widget, set_ptr_hand_move, bw); - LOG(("%p, %d, %d, %d, %d", g, x0 , y0, x1, y1)); + /* reload button */ + widget = fbtk_create_button(gw->window, 95, 2, FB_FRAME_COLOUR, &reload, fb_reload_click, bw); + fbtk_set_handler_move(widget, set_ptr_hand_move, bw); - g->redraw_box.x0 = MIN(g->redraw_box.x0, x0); - g->redraw_box.y0 = MIN(g->redraw_box.y0, y0); - g->redraw_box.x1 = MAX(g->redraw_box.x1, x1); - g->redraw_box.y1 = MAX(g->redraw_box.y1, y1); + /* url widget */ + gw->url = fbtk_create_writable_text(gw->window, + 125 , 3, + fbtk_get_width(gw->window) - 160, 24, + FB_COLOUR_WHITE, + FB_COLOUR_BLACK, + true, + fb_url_enter, + bw); + fbtk_set_handler_move(gw->url, fb_url_move, bw); - redraws_pending = true; - g->redraw_required = true; + gw->throbber = fbtk_create_bitmap(gw->window, + 130 + fbtk_get_width(gw->url), + 3, + FB_FRAME_COLOUR, + &throbber0); + + + + /* add status area widget, width of framebuffer less some for + * scrollbar + */ + gw->status = fbtk_create_text(gw->window, + 0 , fbtk_get_height(gw->window) - 20, + fbtk_get_width(gw->window) - 200, 20, + FB_FRAME_COLOUR, FB_COLOUR_BLACK, + false); + + fbtk_set_handler_move(gw->status, set_ptr_default_move, bw); + + + fbtk_create_button(gw->window, fbtk_get_width(gw->window) - 200, fbtk_get_height(gw->window) - 20, FB_FRAME_COLOUR, &scrolll, fb_scrolll_click, bw); + fbtk_create_button(gw->window, fbtk_get_width(gw->window) - 20, fbtk_get_height(gw->window) - 20, FB_FRAME_COLOUR, &scrollr, fb_scrollr_click, bw); + + gw->hscroll = fbtk_create_hscroll(gw->window, + fbtk_get_width(gw->window) - 180, + fbtk_get_height(gw->window) - 20, + 160, + 20, + FB_COLOUR_BLACK, + FB_FRAME_COLOUR); + + break; + + case BROWSER_WINDOW_FRAME: + gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0); + LOG(("create frame")); + break; + + default: + gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0); + LOG(("unhandled type")); + + } + + browser_widget = calloc(1, sizeof(struct browser_widget_s)); + + gw->browser = fbtk_create_user(gw->window, 0, top, 0, bot, browser_widget); + + fbtk_set_handler_click(gw->browser, fb_browser_window_click, bw); + fbtk_set_handler_input(gw->browser, fb_browser_window_input, gw); + fbtk_set_handler_redraw(gw->browser, fb_browser_window_redraw, gw); + fbtk_set_handler_move(gw->browser, fb_browser_window_move, bw); + + return gw; } -static void fb_queue_pan(struct gui_window *g, int x, int y) +void gui_window_destroy(struct gui_window *gw) { - if (!g) return; + fbtk_destroy_widget(gw->window); - LOG(("%p, x %d, y %d", g, x , y)); + free(gw); - g->panx +=x; - g->pany +=y; - redraws_pending = true; - g->pan_required = true; } +void gui_window_set_title(struct gui_window *g, const char *title) +{ + LOG(("%p, %s", g, title)); +} + + + void fb_window_scroll(struct gui_window *g, int x, int y) { - fb_queue_pan(g, x, y); + struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); + + bwidget->panx += x; + bwidget->pany += y; + bwidget->pan_required = true; + + fbtk_request_redraw(g->browser); } void gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1) { - if (!g) return; - - fb_queue_redraw(g, x0, y0, x1, y1); + fb_queue_redraw(g->browser, x0, y0, x1, y1); } void gui_window_redraw_window(struct gui_window *g) { - if (!g) return; - - fb_queue_redraw(g, 0, 0, g->width, g->height); + fb_queue_redraw(g->browser, 0, 0, fbtk_get_width(g->browser),fbtk_get_height(g->browser) ); } void gui_window_update_box(struct gui_window *g, const union content_msg_data *data) { - struct content *c; - - if (!g) return; - - c = g->bw->current_content; - - if (c == NULL) return; - - gui_window_redraw(g, data->redraw.x, data->redraw.y, data->redraw.x + data->redraw.width, data->redraw.y + data->redraw.height); + fb_queue_redraw(g->browser, + data->redraw.x, + data->redraw.y, + data->redraw.x + data->redraw.width, + data->redraw.y + data->redraw.height); } bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) { - LOG(("g %p, sx %d, sy%d", g, *sx, *sy)); - *sx=0; - *sy=g->scrolly; + struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); + + *sx = bwidget->scrollx; + *sy = bwidget->scrolly; return true; } void gui_window_set_scroll(struct gui_window *g, int sx, int sy) { - LOG(("%s:(%p, %d, %d)", __func__, g, sx, sy)); - g->scrolly = sy; + struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); + LOG(("scroll %d",sx)); + bwidget->panx = sx; + bwidget->pany = sy; + bwidget->pan_required = true; + + fbtk_request_redraw(g->browser); } void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, @@ -507,36 +758,49 @@ void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, void gui_window_position_frame(struct gui_window *g, int x0, int y0, int x1, int y1) { - LOG(("%p, %d, %d, %d, %d", g, x0, y0, x1, y1)); + struct gui_window *parent; + int px, py; + int w, h; + LOG(("%s: %d, %d, %d, %d", g->bw->name, x0, y0, x1, y1)); + parent = g->bw->parent->window; + + if (parent->window == NULL) + return; /* doesnt have an fbtk widget */ + + px = fbtk_get_x(parent->browser) + x0; + py = fbtk_get_y(parent->browser) + y0; + w = x1 - x0; + h = y1 - y0; + if (w > (fbtk_get_width(parent->browser) - px)) + w = fbtk_get_width(parent->browser) - px; + + if (h > (fbtk_get_height(parent->browser) - py)) + h = fbtk_get_height(parent->browser) - py; + + fbtk_set_pos_and_size(g->window, px, py , w , h); + + fbtk_request_redraw(parent->browser); + } void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bool scaled) { - LOG(("%p, %d, %d, %d", g, *width, *height, scaled)); - *width = g->width; - *height = g->height; - + *width = fbtk_get_width(g->browser); + *height = fbtk_get_height(g->browser); } void gui_window_update_extent(struct gui_window *g) { - LOG(("g %p", g)); + int pct; + + pct = (fbtk_get_width(g->browser) * 100) / g->bw->current_content->width; + fbtk_set_scroll(g->hscroll, pct); } void gui_window_set_status(struct gui_window *g, const char *text) { - static char *cur_text = NULL; - - if (cur_text != NULL) { - if (strcmp(cur_text, text) == 0) - return; - - free(cur_text); - } - cur_text = strdup(text); - - fb_rootwindow_status(text); + fbtk_set_text(g->status, text); } void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) @@ -561,15 +825,79 @@ void gui_window_hide_pointer(struct gui_window *g) void gui_window_set_url(struct gui_window *g, const char *url) { - fb_rootwindow_url(url); + fbtk_set_text(g->url, url); +} + +static void +throbber_advance(void *pw) +{ + struct gui_window *g = pw; + struct bitmap *image; + + switch (g->throbber_index) { + case 0: + image = &throbber1; + g->throbber_index = 1; + break; + + case 1: + image = &throbber2; + g->throbber_index = 2; + break; + + case 2: + image = &throbber3; + g->throbber_index = 3; + break; + + case 3: + image = &throbber4; + g->throbber_index = 4; + break; + + case 4: + image = &throbber5; + g->throbber_index = 5; + break; + + case 5: + image = &throbber6; + g->throbber_index = 6; + break; + + case 6: + image = &throbber7; + g->throbber_index = 7; + break; + + case 7: + image = &throbber8; + g->throbber_index = 8; + break; + + case 8: + image = &throbber0; + g->throbber_index = 0; + break; + + } + + if (g->throbber_index >= 0) { + fbtk_set_bitmap(g->throbber, image); + schedule(10, throbber_advance, g); + } } void gui_window_start_throbber(struct gui_window *g) { + g->throbber_index = 0; + schedule(10, throbber_advance, g); } void gui_window_stop_throbber(struct gui_window *g) { + g->throbber_index = -1; + fbtk_set_bitmap(g->throbber, &throbber0); } void gui_window_place_caret(struct gui_window *g, int x, int y, int height) diff --git a/framebuffer/fb_gui.h b/framebuffer/fb_gui.h index 138846084..e064ede56 100644 --- a/framebuffer/fb_gui.h +++ b/framebuffer/fb_gui.h @@ -40,26 +40,17 @@ typedef struct framebuffer_s { } framebuffer_t; struct gui_window { - struct gui_window *next, *prev; /**< List of windows */ - struct browser_window *bw; /**< The browser window connected to this gui window */ - - int x; - int y; - int width; /**< Window width */ - int height; /**< window height */ - int scrollx, scrolly; /**< scroll offsets. */ - - /* Pending window redraw state. */ - bool redraw_required; /**< flag indicating the foreground loop - * needs to redraw the window. - */ - bbox_t redraw_box; /**< Area requiring redraw. */ - bool pan_required; /**< flag indicating the foreground loop - * needs to pan the window. - */ - int panx, pany; /**< Panning required. */ + struct browser_window *bw; + struct fbtk_widget_s *window; + struct fbtk_widget_s *url; + struct fbtk_widget_s *status; + struct fbtk_widget_s *throbber; + struct fbtk_widget_s *hscroll; + struct fbtk_widget_s *browser; + int throbber_index; }; + extern framebuffer_t *framebuffer; extern struct gui_window *window_list; diff --git a/framebuffer/fb_image_data.h b/framebuffer/fb_image_data.h index 1f45650ff..9f6c3a0ee 100644 --- a/framebuffer/fb_image_data.h +++ b/framebuffer/fb_image_data.h @@ -25,9 +25,21 @@ extern struct bitmap left_arrow; extern struct bitmap right_arrow; extern struct bitmap reload; extern struct bitmap stop_image; +extern struct bitmap scrolll; +extern struct bitmap scrollr; extern struct bitmap pointer_image; extern struct bitmap hand_image; extern struct bitmap caret_image; +extern struct bitmap throbber0; +extern struct bitmap throbber1; +extern struct bitmap throbber2; +extern struct bitmap throbber3; +extern struct bitmap throbber4; +extern struct bitmap throbber5; +extern struct bitmap throbber6; +extern struct bitmap throbber7; +extern struct bitmap throbber8; + #endif /* FB_IMAGE_DATA */ diff --git a/framebuffer/fb_plotters.c b/framebuffer/fb_plotters.c index 2428dcc6a..dc3172a21 100644 --- a/framebuffer/fb_plotters.c +++ b/framebuffer/fb_plotters.c @@ -24,14 +24,18 @@ #include "utils/log.h" #include "utils/utf8.h" +#include "desktop/browser.h" #include "desktop/plotters.h" #include "framebuffer/fb_gui.h" +#include "framebuffer/fb_tk.h" #include "framebuffer/fb_plotters.h" #include "framebuffer/fb_bitmap.h" #include "framebuffer/fb_font.h" #include "framebuffer/fb_frontend.h" +extern fbtk_widget_t *fbtk; + /* max height the poly plotter can cope with */ #define WINDOW_HEIGHT (2048) @@ -184,17 +188,14 @@ bool fb_plotters_clip_line_ctx(int *x0, int *y0, int *x1, int *y1) bool fb_clip(int x0, int y0, int x1, int y1) { bbox_t clip; - struct gui_window *g; - - g = window_list; if (x1 < x0) SWAP(x0, x1); if (y1 < y0) SWAP(y0, y1); - clip.x0 = g->x; - clip.y0 = g->y; - clip.x1 = g->x + g->width; - clip.y1 = g->y + g->height; + clip.x0 = fbtk_get_x(fbtk); + clip.y0 = fbtk_get_y(fbtk); + clip.x1 = fbtk_get_width(fbtk); + clip.y1 = fbtk_get_height(fbtk); if (fb_plotters_clip_rect(&clip, &x0, &y0, &x1, &y1)) { /* new clipping region is inside the root window */ @@ -202,7 +203,7 @@ bool fb_clip(int x0, int y0, int x1, int y1) fb_plot_ctx.y0 = y0; fb_plot_ctx.x1 = x1; fb_plot_ctx.y1 = y1; - } + } /*LOG(("%d, %d - %d, %d clipped to %d, %d - %d, %d", x0,y0,x1,y1, diff --git a/framebuffer/fb_rootwindow.c b/framebuffer/fb_rootwindow.c deleted file mode 100644 index 3293acbb0..000000000 --- a/framebuffer/fb_rootwindow.c +++ /dev/null @@ -1,515 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * 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 - -#ifdef WITH_HUBBUB -#include -#endif - -#include "desktop/gui.h" -#include "desktop/plotters.h" -#include "desktop/netsurf.h" -#include "desktop/options.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/utils.h" -#include "desktop/history_core.h" - -#include "image/bitmap.h" - -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_frontend.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_schedule.h" -#include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_rootwindow.h" -#include "framebuffer/fb_image_data.h" - -#define FB_FRAME_COLOUR 0xFFDDDDDD -#define FB_COLOUR_BLACK 0xFF000000 -#define FB_COLOUR_WHITE 0xFFFFFFFF - -enum fb_widget_type_e { - FB_WIDGET_TYPE_NONE = 0, - FB_WIDGET_TYPE_BUTTON, - FB_WIDGET_TYPE_WINDOW, - FB_WIDGET_TYPE_TEXT, -}; - -struct fb_widget { - struct fb_widget *next; - - /* properties */ - enum fb_widget_type_e type; - int x; - int y; - int width; - int height; - colour bg; - colour fg; - bool outline; - - /* handlers */ - fb_widget_mouseclick_t click; - fb_widget_input_t input; - - /* data */ - struct bitmap *bitmap; - struct gui_window *g; - char* text; -}; - -static struct css_style root_style; - -static struct fb_widget *widget_list; - -/* widget for status */ -static struct fb_widget *status_widget; - -/* widget for url */ -static struct fb_widget *url_widget; - -/* widget with input focus */ -static struct fb_widget *inputfocus_widget; -static int input_idx; - -struct gui_window *rootwindow; - -static void -fb_redraw_widget(struct fb_widget *widget) -{ - bbox_t saved_plot_ctx; - - /* set the clipping rectangle to the widget area */ - saved_plot_ctx = fb_plot_ctx; - - fb_plot_ctx.x0 = widget->x; - fb_plot_ctx.y0 = widget->y; - fb_plot_ctx.x1 = widget->x + widget->width; - fb_plot_ctx.y1 = widget->y + widget->height; - - /* clear background */ - if ((widget->bg & 0xFF000000) != 0) { - /* transparent polygon filling isnt working so fake it */ - plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, - fb_plot_ctx.x1, fb_plot_ctx.y1, - widget->bg); - } - - /* do our drawing according to type*/ - - switch (widget->type) { - - case FB_WIDGET_TYPE_BUTTON: - /* plot the image */ - plot.bitmap(widget->x, - widget->y, - widget->width, - widget->height, - widget->bitmap, - 0, NULL); - break; - - case FB_WIDGET_TYPE_WINDOW: - break; - - case FB_WIDGET_TYPE_TEXT: - if (widget->outline) { - plot.rectangle(fb_plot_ctx.x0, fb_plot_ctx.y0, - fb_plot_ctx.x1 - fb_plot_ctx.x0 - 1, - fb_plot_ctx.y1 - fb_plot_ctx.y0 - 1, - 1, 0x00000000, false, false); - } - if (widget->text != NULL) { - plot.text(fb_plot_ctx.x0 + 3, - fb_plot_ctx.y0 + 17, - &root_style, - widget->text, - strlen(widget->text), - widget->bg, - widget->fg); - } - break; - - default: - break; - } - - fb_os_redraw(&fb_plot_ctx); - - /* restore clipping rectangle */ - fb_plot_ctx = saved_plot_ctx; - - -} - -/* inserts widget into head of list and issues a redraw request */ -static void -fb_insert_widget(struct fb_widget *widget) -{ - widget->next = widget_list; - widget_list = widget; - - fb_redraw_widget(widget); -} - -/* generic input click focus handler */ -static void -fb_change_input_focus(struct fb_widget *widget) -{ - LOG(("Changing input focus to %p", widget)); - - if (inputfocus_widget == widget) - return; - - /* new widget gainig focus */ - inputfocus_widget = widget; - - /* tell it so */ - widget->input(widget, NULL, - 1); -} - -static int -fb_widget_url_input(struct fb_widget *widget, struct gui_window *g, int value) -{ - - if (url_widget == NULL) - return 0; - - if (value == -1) { - /* gain focus */ - if (widget->text == NULL) - widget->text = calloc(1,1); - input_idx = strlen(widget->text); - } else { - if (value == '\b') { - if (input_idx <= 0) - return 0; - input_idx--; - widget->text[input_idx] = 0; - } else if (value == '\r') { - browser_window_go(g->bw, widget->text, 0, true); - } else { - widget->text = realloc(widget->text, input_idx + 2); /* allow for new character and null */ - widget->text[input_idx] = value; - widget->text[input_idx + 1] = '\0'; - input_idx++; - } - fb_redraw_widget(url_widget); - } - return 0; -} - -static struct fb_widget * -fb_add_button_widget(int x, - int y, - struct bitmap *widget_image, - fb_widget_mouseclick_t click_rtn) -{ - struct fb_widget *new_widget; - new_widget = calloc(1, sizeof(struct fb_widget)); - if (new_widget == NULL) - return NULL; - - new_widget->type = FB_WIDGET_TYPE_BUTTON; - new_widget->x = x; - new_widget->y = y; - new_widget->width = widget_image->width; - new_widget->height = widget_image->height; - new_widget->outline = false; - - new_widget->click = click_rtn; - - new_widget->bitmap = widget_image; - - fb_insert_widget(new_widget); - - return new_widget; -} - -static struct fb_widget * -fb_add_text_widget(int x, int y, int width, int height, colour bg, bool outline, fb_widget_input_t input_rtn) -{ - struct fb_widget *new_widget; - new_widget = calloc(1, sizeof(struct fb_widget)); - if (new_widget == NULL) - return NULL; - - new_widget->type = FB_WIDGET_TYPE_TEXT; - new_widget->x = x; - new_widget->y = y; - new_widget->width = width; - new_widget->height = height; - new_widget->bg = bg; - new_widget->fg = FB_COLOUR_BLACK; - new_widget->outline = outline; - - new_widget->input = input_rtn; - - fb_insert_widget(new_widget); - - return new_widget; -} - -struct fb_widget * -fb_add_window_widget(struct gui_window *g, - colour bg, - fb_widget_mouseclick_t click_rtn, - fb_widget_input_t input_rtn) -{ - struct fb_widget *new_widget; - new_widget = calloc(1, sizeof(struct fb_widget)); - if (new_widget == NULL) - return NULL; - - new_widget->type = FB_WIDGET_TYPE_WINDOW; - new_widget->x = g->x; - new_widget->y = g->y; - new_widget->width = g->width; - new_widget->height = g->height; - new_widget->bg = bg; - new_widget->outline = false; - - new_widget->click = click_rtn; - new_widget->input = input_rtn; - - new_widget->g = g; - - fb_insert_widget(new_widget); - - return new_widget; -} - - -/* left icon click routine */ -static int -fb_widget_leftarrow_click(struct gui_window *g, browser_mouse_state st, int x, int y) -{ - if (st == BROWSER_MOUSE_CLICK_1) { - if (history_back_available(g->bw->history)) - history_back(g->bw, g->bw->history); - } - return 0; - -} - -/* right arrow icon click routine */ -static int -fb_widget_rightarrow_click(struct gui_window *g, browser_mouse_state st, int x, int y) -{ - if (st == BROWSER_MOUSE_CLICK_1) { - if (history_forward_available(g->bw->history)) - history_forward(g->bw, g->bw->history); - } - return 0; - -} - -/* reload icon click routine */ -static int -fb_widget_reload_click(struct gui_window *g, browser_mouse_state st, int x, int y) -{ - browser_window_reload(g->bw, true); - return 0; -} - -/* stop icon click routine */ -static int -fb_widget_stop_click(struct gui_window *g, browser_mouse_state st, int x, int y) -{ - browser_window_stop(g->bw); - return 0; -} - - -/* update status widget */ -void fb_rootwindow_status(const char* text) -{ - if (status_widget == NULL) - return; - - if (status_widget->text != NULL) - free(status_widget->text); - - status_widget->text = strdup(text); - - fb_redraw_widget(status_widget); -} - -/* update url widget */ -void fb_rootwindow_url(const char* text) -{ - if (url_widget == NULL) - return; - - if (url_widget->text != NULL) - free(url_widget->text); - - url_widget->text = strdup(text); - input_idx = strlen(text); - - fb_redraw_widget(url_widget); -} - - -void fb_rootwindow_create(framebuffer_t *fb) -{ - struct fb_widget *newwidget; - - /* empty widget list */ - widget_list = NULL; - - /* no widget yet has input */ - inputfocus_widget = NULL; - - /* setup root css style (for text etc.) */ - root_style.font_size.value.length.unit = CSS_UNIT_PX; - root_style.font_size.value.length.value = 14; - - /* underlying root window, cannot take input and lowest in stack */ - rootwindow = calloc(1, sizeof(struct gui_window)); - rootwindow->x = 0; - rootwindow->y = 0; - rootwindow->width = fb->width; - rootwindow->height = fb->height; - fb_add_window_widget(rootwindow, FB_FRAME_COLOUR, NULL, NULL); - - /* back button */ - newwidget = fb_add_button_widget(5, 2, - &left_arrow, - fb_widget_leftarrow_click); - - /* forward button */ - newwidget = fb_add_button_widget(newwidget->x + newwidget->width + 5, - 2, - &right_arrow, - fb_widget_rightarrow_click); - - /* reload button */ - newwidget = fb_add_button_widget(newwidget->x + newwidget->width + 5, - 2, - &stop_image, - fb_widget_stop_click); - - /* reload button */ - newwidget = fb_add_button_widget(newwidget->x + newwidget->width + 5, - 2, - &reload, - fb_widget_reload_click); - - /* url widget */ - url_widget = fb_add_text_widget(newwidget->x + newwidget->width + 5, 3, - fb->width - - (newwidget->x + newwidget->width + 5) - - (25 + 10), - 24, - FB_COLOUR_WHITE, true, - fb_widget_url_input); - - - /* add status area widget, width of framebuffer less some for - * scrollbar - */ - status_widget = fb_add_text_widget(0, fb->height - 20, - fb->width - 200, 20, - FB_FRAME_COLOUR, false, - NULL); - -} - -void -fb_rootwindow_input(struct gui_window *g, int value) -{ - if ((inputfocus_widget != NULL) && - (inputfocus_widget->input != NULL)) { - inputfocus_widget->input(inputfocus_widget, g, value); - } -} - -void -fb_rootwindow_click(struct gui_window *g, browser_mouse_state st, int x, int y) -{ - struct fb_widget *widget; - - widget = widget_list; - while (widget != NULL) { - if ((x > widget->x) && - (y > widget->y) && - (x < widget->x + widget->width) && - (y < widget->y + widget->height)) { - if (widget->click != NULL) { - widget->click(g, st, - x - widget->x, y - widget->y); - } - - if (widget->input != NULL) { - fb_change_input_focus(widget); - } - - break; - } - widget = widget->next; - } -} - - -void -fb_rootwindow_move(framebuffer_t *fb, - struct gui_window *g, - int x, - int y, - bool relative) -{ - struct fb_widget *widget; - - if (relative) { - x += fb_cursor_x(fb); - y += fb_cursor_y(fb); - } - - fb_cursor_move(fb, x, y); - - widget = widget_list; - while (widget != NULL) { - if ((x > widget->x) && - (y > widget->y) && - (x < widget->x + widget->width) && - (y < widget->y + widget->height)) { - - if (widget->g == g) { - browser_window_mouse_track(g->bw, 0, x - widget->x + g->scrollx, y - widget->y + g->scrolly); - break; - } - } - widget = widget->next; - } - -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_rootwindow.h b/framebuffer/fb_rootwindow.h deleted file mode 100644 index 62d9e61f2..000000000 --- a/framebuffer/fb_rootwindow.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * 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 . - */ - -typedef struct fb_widget fb_widget_t; - -typedef int (*fb_widget_input_t)(fb_widget_t *widget, struct gui_window *g,int value); -typedef int (*fb_widget_mouseclick_t)(struct gui_window *g, browser_mouse_state st, int x, int y); - -void fb_rootwindow_click(struct gui_window *g, - browser_mouse_state st , int x, int y); -void fb_rootwindow_input(struct gui_window *g, int value); -void fb_rootwindow_move(framebuffer_t *fb, struct gui_window *g, int x, int y, bool relative); - -void fb_rootwindow_status(const char* text); -void fb_rootwindow_url(const char* text); - - -void fb_rootwindow_create(framebuffer_t *fb); - -struct fb_widget *fb_add_window_widget(struct gui_window *g, colour bg, fb_widget_mouseclick_t click_rtn, fb_widget_input_t input_rtn); - diff --git a/framebuffer/fb_tk.c b/framebuffer/fb_tk.c new file mode 100644 index 000000000..3ce4d90ef --- /dev/null +++ b/framebuffer/fb_tk.c @@ -0,0 +1,1028 @@ +/* + * Copyright 2008 Vincent Sanders + * + * Framebuffer windowing toolkit + * + * 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 "utils/log.h" +#include "css/css.h" +#include "desktop/browser.h" +#include "desktop/plotters.h" + +#include "framebuffer/fb_gui.h" +#include "framebuffer/fb_tk.h" +#include "framebuffer/fb_plotters.h" +#include "framebuffer/fb_bitmap.h" +#include "framebuffer/fb_cursor.h" +#include "framebuffer/fb_image_data.h" +#include "framebuffer/fb_frontend.h" + +static struct css_style root_style; + +enum fbtk_widgettype_e { + FB_WIDGET_TYPE_ROOT = 0, + FB_WIDGET_TYPE_WINDOW, + FB_WIDGET_TYPE_BITMAP, + FB_WIDGET_TYPE_FILL, + FB_WIDGET_TYPE_TEXT, + FB_WIDGET_TYPE_HSCROLL, + FB_WIDGET_TYPE_USER, +}; + +typedef struct fbtk_widget_list_s fbtk_widget_list_t; + +/* wrapper struct for all widget types */ +struct fbtk_widget_s { + /* Generic properties */ + int x; + int y; + int width; + int height; + colour bg; + colour fg; + + /* handlers */ + fbtk_mouseclick_t click; + void *clickpw; /* private data for callback */ + + fbtk_input_t input; + void *inputpw; /* private data for callback */ + + fbtk_move_t move; + void *movepw; /* private data for callback */ + + fbtk_redraw_t redraw; + void *redrawpw; /* private data for callback */ + + bool redraw_required; + + fbtk_widget_t *parent; /* parent widget */ + + /* Widget specific */ + enum fbtk_widgettype_e type; + + union { + /* toolkit base handle */ + struct { + framebuffer_t *fb; + fbtk_widget_t *rootw; + fbtk_widget_t *input; + } root; + + /* window */ + struct { + /* widgets associated with this window */ + fbtk_widget_list_t *widgets; /* begining of list */ + fbtk_widget_list_t *widgets_end; /* end of list */ + } window; + + /* bitmap */ + struct { + struct bitmap *bitmap; + } bitmap; + + /* text */ + struct { + char* text; + bool outline; + fbtk_enter_t enter; + void *pw; + int idx; + } text; + + /* application driven widget */ + struct { + void *pw; /* private data for user widget */ + } user; + + struct { + int pos; + int pct; + } scroll; + + } u; +}; + +/* widget list */ +struct fbtk_widget_list_s { + struct fbtk_widget_list_s *next; + struct fbtk_widget_list_s *prev; + fbtk_widget_t *widget; +} ; + +/* creates a new widget of a given type */ +static fbtk_widget_t * +new_widget(enum fbtk_widgettype_e type) +{ + fbtk_widget_t *neww; + neww = calloc(1, sizeof(fbtk_widget_t)); + neww->type = type; + return neww; +} + + +/* find the root widget from any widget in the toolkits hierarchy */ +static fbtk_widget_t * +get_root_widget(fbtk_widget_t *widget) +{ + while (widget->parent != NULL) + widget = widget->parent; + + /* check root widget was found */ + if (widget->type != FB_WIDGET_TYPE_ROOT) { + LOG(("Widget with null parent that is not the root widget!")); + return NULL; + } + + return widget; +} + + +/* set widget to be redrawn */ +void +fbtk_request_redraw(fbtk_widget_t *widget) +{ + widget->redraw_required = 1; + + if (widget->type == FB_WIDGET_TYPE_WINDOW) { + fbtk_widget_list_t *lent = widget->u.window.widgets; + + while (lent != NULL) { + lent->widget->redraw_required = 1; + lent = lent->next; + } + } + + while (widget->parent != NULL) { + widget = widget->parent; + widget->redraw_required = 1; + } +} + +static fbtk_widget_t * +add_widget_to_window(fbtk_widget_t *window, fbtk_widget_t *widget) +{ + fbtk_widget_list_t *newent; + fbtk_widget_list_t **nextent; + fbtk_widget_list_t *prevent; /* previous entry pointer */ + + if (window->type == FB_WIDGET_TYPE_WINDOW) { + /* caller attached widget to a window */ + + nextent = &window->u.window.widgets; + prevent = NULL; + while (*nextent != NULL) { + prevent = (*nextent); + nextent = &(prevent->next); + } + + newent = calloc(1, sizeof(struct fbtk_widget_list_s)); + + newent->widget = widget; + newent->next = NULL; + newent->prev = prevent; + + *nextent = newent; + + window->u.window.widgets_end = newent; + } + widget->parent = window; + + fbtk_request_redraw(widget); + + return widget; +} + +static void +remove_widget_from_window(fbtk_widget_t *window, fbtk_widget_t *widget) +{ + fbtk_widget_list_t *lent = window->u.window.widgets; + + while ((lent != NULL) && (lent->widget != widget)) { + lent = lent->next; + } + + if (lent != NULL) { + if (lent->prev == NULL) { + window->u.window.widgets = lent->next; + } else { + lent->prev->next = lent->next; + } + if (lent->next == NULL) { + window->u.window.widgets_end = lent->prev; + } else { + lent->next->prev = lent->prev; + } + free(lent); + } +} + +static void +fbtk_redraw_widget(fbtk_widget_t *widget) +{ + bbox_t saved_plot_ctx; + + //LOG(("widget %p type %d", widget, widget->type)); + + /* set the clipping rectangle to the widget area */ + saved_plot_ctx = fb_plot_ctx; + + fb_plot_ctx.x0 = widget->x; + fb_plot_ctx.y0 = widget->y; + fb_plot_ctx.x1 = widget->x + widget->width; + fb_plot_ctx.y1 = widget->y + widget->height; + + /* do our drawing according to type */ + widget->redraw(widget, widget->redrawpw); + + widget->redraw_required = false; + //LOG(("OS redrawing %d,%d %d,%d", fb_plot_ctx.x0, fb_plot_ctx.y0, fb_plot_ctx.x1, fb_plot_ctx.y1)); + fb_os_redraw(&fb_plot_ctx); + + /* restore clipping rectangle */ + fb_plot_ctx = saved_plot_ctx; + //LOG(("Redraw Complete")); +} + +/*************** redraw widgets **************/ + +static int +fb_redraw_fill(fbtk_widget_t *widget, void *pw) +{ + /* clear background */ + if ((widget->bg & 0xFF000000) != 0) { + /* transparent polygon filling isnt working so fake it */ + plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, + fb_plot_ctx.x1, fb_plot_ctx.y1, + widget->bg); + } + return 0; +} + +static int +fb_redraw_hscroll(fbtk_widget_t *widget, void *pw) +{ + int hscroll; + int hpos; + + plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, + fb_plot_ctx.x1, fb_plot_ctx.y1, + widget->bg); + + plot.rectangle(fb_plot_ctx.x0, + fb_plot_ctx.y0 + 2, + fb_plot_ctx.x1 - fb_plot_ctx.x0 - 1, + fb_plot_ctx.y1 - fb_plot_ctx.y0 - 5, + 1, 0x00000000, false, false); + + hscroll = ((widget->width - 4) * widget->u.scroll.pct) / 100 ; + hpos = ((widget->width - 4) * widget->u.scroll.pos) / 100 ; + + LOG(("hscroll %d",hscroll)); + + plot.fill(fb_plot_ctx.x0 + 3 + hpos, + fb_plot_ctx.y0 + 5, + fb_plot_ctx.x0 + hscroll + hpos, + fb_plot_ctx.y0 + widget->height - 5, + widget->fg); + + return 0; +} + +static int +fb_redraw_bitmap(fbtk_widget_t *widget, void *pw) +{ + /* clear background */ + if ((widget->bg & 0xFF000000) != 0) { + /* transparent polygon filling isnt working so fake it */ + plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, + fb_plot_ctx.x1, fb_plot_ctx.y1, + widget->bg); + } + + /* plot the image */ + plot.bitmap(widget->x, widget->y, widget->width, widget->height, + widget->u.bitmap.bitmap, 0, NULL); + return 0; +} + +static int +fbtk_window_default_redraw(fbtk_widget_t *window, void *pw) +{ + fbtk_widget_list_t *lent; + fbtk_widget_t *widget; + int res = 0; + + /* get the list of widgets */ + lent = window->u.window.widgets; + + while (lent != NULL) { + widget = lent->widget; + + if ((widget->redraw != NULL) && + (widget->redraw_required)) { + fbtk_redraw_widget(widget); + + } + lent = lent->next; + } + return res; +} + +static int +fbtk_window_default_move(fbtk_widget_t *window, int x, int y, void *pw) +{ + fbtk_widget_list_t *lent; + fbtk_widget_t *widget; + int res = 0; + + /* get the list of widgets */ + lent = window->u.window.widgets_end; + + while (lent != NULL) { + widget = lent->widget; + + if ((x > widget->x) && + (y > widget->y) && + (x < widget->x + widget->width) && + (y < widget->y + widget->height)) { + if (widget->move != NULL) { + res = widget->move(widget, + x - widget->x, + y - widget->y, + widget->movepw); + } + break; + } + lent = lent->prev; + } + return res; +} + +static int +fbtk_window_default_click(fbtk_widget_t *window, browser_mouse_state st, int x, int y, void *pw) +{ + fbtk_widget_list_t *lent; + fbtk_widget_t *widget; + int res = 0; + + /* get the list of widgets */ + lent = window->u.window.widgets; + + while (lent != NULL) { + widget = lent->widget; + + if ((x > widget->x) && + (y > widget->y) && + (x < widget->x + widget->width) && + (y < widget->y + widget->height)) { + if (widget->input != NULL) { + fbtk_widget_t *root = get_root_widget(widget); + root->u.root.input = widget; + } + + if (widget->click != NULL) { + res = widget->click(widget, + st, + x - widget->x, + y - widget->y, + widget->clickpw); + break; + } + + + + } + lent = lent->next; + } + return res; +} + +static int +fb_redraw_text(fbtk_widget_t *widget, void *pw) +{ + /* clear background */ + if ((widget->bg & 0xFF000000) != 0) { + /* transparent polygon filling isnt working so fake it */ + plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, + fb_plot_ctx.x1, fb_plot_ctx.y1, + widget->bg); + } + + if (widget->u.text.outline) { + plot.rectangle(fb_plot_ctx.x0, fb_plot_ctx.y0, + fb_plot_ctx.x1 - fb_plot_ctx.x0 - 1, + fb_plot_ctx.y1 - fb_plot_ctx.y0 - 1, + 1, 0x00000000, false, false); + } + if (widget->u.text.text != NULL) { + plot.text(fb_plot_ctx.x0 + 3, + fb_plot_ctx.y0 + 17, + &root_style, + widget->u.text.text, + strlen(widget->u.text.text), + widget->bg, + widget->fg); + } + return 0; +} + + + + +static int +text_input(fbtk_widget_t *widget, int value, void *pw) +{ + + switch (value) { + case -1: + /* gain focus */ + if (widget->u.text.text == NULL) + widget->u.text.text = calloc(1,1); + widget->u.text.idx = strlen(widget->u.text.text); + break; + + case '\b': + if (widget->u.text.idx <= 0) + break; + widget->u.text.idx--; + widget->u.text.text[widget->u.text.idx] = 0; + break; + + case '\r': + widget->u.text.enter(widget->u.text.pw, widget->u.text.text); + break; + + default: + /* allow for new character and null */ + widget->u.text.text = realloc(widget->u.text.text, widget->u.text.idx + 2); + widget->u.text.text[widget->u.text.idx] = value; + widget->u.text.text[widget->u.text.idx + 1] = '\0'; + widget->u.text.idx++; + break; + } + + fbtk_request_redraw(widget); + + return 0; +} + +/* sets the enter action on a writable icon */ +void +fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw) +{ + widget->u.text.enter = enter; + widget->u.text.pw = pw; + + widget->input = text_input; + widget->inputpw = widget; +} + + +/********** acessors ***********/ +int +fbtk_get_height(fbtk_widget_t *widget) +{ + return widget->height; +} + +int +fbtk_get_width(fbtk_widget_t *widget) +{ + return widget->width; +} + +int +fbtk_get_x(fbtk_widget_t *widget) +{ + int x = widget->x; + + while (widget->parent != NULL) { + widget = widget->parent; + x += widget->x; + } + + return x; +} + +int +fbtk_get_y(fbtk_widget_t *widget) +{ + int y = widget->y; + + while (widget->parent != NULL) { + widget = widget->parent; + y += widget->y; + } + + return y; +} + +void +fbtk_set_handler_click(fbtk_widget_t *widget, fbtk_mouseclick_t click, void *pw) +{ + widget->click = click; + widget->clickpw = pw; +} + +void +fbtk_set_handler_input(fbtk_widget_t *widget, fbtk_input_t input, void *pw) +{ + widget->input = input; + widget->inputpw = pw; +} + +void +fbtk_set_handler_redraw(fbtk_widget_t *widget, fbtk_redraw_t redraw, void *pw) +{ + widget->redraw = redraw; + widget->redrawpw = pw; +} + +void +fbtk_set_handler_move(fbtk_widget_t *widget, fbtk_move_t move, void *pw) +{ + widget->move = move; + widget->movepw = pw; +} + +void * +fbtk_get_userpw(fbtk_widget_t *widget) +{ + if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_USER)) + return NULL; + + return widget->u.user.pw; +} + +void +fbtk_set_text(fbtk_widget_t *widget, const char *text) +{ + if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_TEXT)) + return; + if (widget->u.text.text != NULL) { + if (strcmp(widget->u.text.text, text) == 0) + return; /* text is being set to the same thing */ + free(widget->u.text.text); + } + widget->u.text.text = strdup(text); + widget->u.text.idx = strlen(text); + + fbtk_request_redraw(widget); +} + +void +fbtk_set_scroll(fbtk_widget_t *widget, int pct) +{ + if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_HSCROLL)) + return; + + widget->u.scroll.pct = pct; + + fbtk_request_redraw(widget); +} + +void +fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos) +{ + if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_HSCROLL)) + return; + + widget->u.scroll.pos = pos; + + fbtk_request_redraw(widget); +} + +void +fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image) +{ + if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_BITMAP)) + return; + + widget->u.bitmap.bitmap = image; + + fbtk_request_redraw(widget); +} + +void +fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height) +{ + if ((widget->x != x) || + (widget->y != y) || + (widget->width != width) || + (widget->height != height)) { + widget->x = x; + widget->y = y; + widget->width = width; + widget->height = height; + fbtk_request_redraw(widget); + LOG(("%d,%d %d,%d",x,y,width,height)); + } +} + +int +fbtk_count_children(fbtk_widget_t *widget) +{ + int count = 0; + fbtk_widget_list_t *lent; + + if (widget->type != FB_WIDGET_TYPE_WINDOW) { + if (widget->type != FB_WIDGET_TYPE_ROOT) + return -1; + widget = widget->u.root.rootw; + } + + lent = widget->u.window.widgets; + + while (lent != NULL) { + count++; + lent = lent->next; + } + + return count; +} + + +void +fbtk_input(fbtk_widget_t *widget, uint32_t ucs4) +{ + fbtk_widget_t *input; + + widget = get_root_widget(widget); + + /* obtain widget with input focus */ + input = widget->u.root.input; + if (input == NULL) + return; + + if (input->input == NULL) + return; + + input->input(input, ucs4, input->inputpw); +} + +void +fbtk_click(fbtk_widget_t *widget, browser_mouse_state st) +{ + fbtk_widget_t *root; + fbtk_widget_t *window; + int x; + int y; + + /* ensure we have the root widget */ + root = get_root_widget(widget); + + x = fb_cursor_x(root->u.root.fb); + y = fb_cursor_y(root->u.root.fb); + + /* get the root window */ + window = root->u.root.rootw; + + if (window->click != NULL) + window->click(window, st, x, y, window->clickpw); +} + + + +void +fbtk_move_pointer(fbtk_widget_t *widget, int x, int y, bool relative) +{ + fbtk_widget_t *root; + fbtk_widget_t *window; + + /* ensure we have the root widget */ + root = get_root_widget(widget); + + if (relative) { + x += fb_cursor_x(root->u.root.fb); + y += fb_cursor_y(root->u.root.fb); + } + + root->redraw_required = true; + + fb_cursor_move(root->u.root.fb, x, y); + + /* get the root window */ + window = root->u.root.rootw; + + if (window->move != NULL) + window->move(window, x, y,window->movepw); + +} + +int +fbtk_redraw(fbtk_widget_t *widget) +{ + fbtk_widget_t *root; + fbtk_widget_t *window; + + /* ensure we have the root widget */ + root = get_root_widget(widget); + + if (!root->redraw_required) + return 0; + + /* get the root window */ + window = root->u.root.rootw; + + fb_cursor_clear(root->u.root.fb); + + if (window->redraw != NULL) + fbtk_redraw_widget(window); + + root->redraw_required = false; + + fb_cursor_plot(root->u.root.fb); + + return 1; + +} + +/****** widget destruction ********/ +int fbtk_destroy_widget(fbtk_widget_t *widget) +{ + if (widget->type == FB_WIDGET_TYPE_WINDOW) { + /* TODO: walk child widgets and destroy them */ + } + + remove_widget_from_window(widget->parent, widget); + free(widget); + + return 0; +} + + +/************** Widget creation *************/ +fbtk_widget_t * +fbtk_create_text(fbtk_widget_t *window, + int x, int y, + int width, int height, + colour bg, colour fg, + bool outline) +{ + fbtk_widget_t *newt = new_widget(FB_WIDGET_TYPE_TEXT); + + newt->x = x; + newt->y = y; + newt->width = width; + newt->height = height; + newt->u.text.outline = outline; + + newt->fg = fg; + newt->bg = bg; + + newt->redraw = fb_redraw_text; + + return add_widget_to_window(window, newt); +} + +fbtk_widget_t * +fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c, struct bitmap *image) +{ + fbtk_widget_t *newb = new_widget(FB_WIDGET_TYPE_BITMAP); + + newb->x = x; + newb->y = y; + newb->width = image->width; + newb->height = image->height; + newb->bg = c; + + newb->u.bitmap.bitmap = image; + + newb->redraw = fb_redraw_bitmap; + + return add_widget_to_window(window, newb); +} + +static void +fbtk_width_height(fbtk_widget_t *parent, int x, int y, int *width, int *height) +{ + /* make widget fit inside parent */ + if (*width == 0) { + *width = parent->width - x; + } else if (*width < 0) { + *width = parent->width + *width; + } + if ((*width + x) > parent->width) { + *width = parent->width - x; + } + + if (*height == 0) { + *height = parent->height - y; + } else if (*height < 0) { + *height = parent->height + *height; + } + if ((*height + y) > parent->height) { + *height = parent->height - y; + } +} + +fbtk_widget_t * +fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c) +{ + fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_FILL); + + neww->x = x; + neww->y = y; + neww->width = width; + neww->height = height; + + fbtk_width_height(window, x, y, &neww->width, &neww->height); + + neww->bg = c; + + neww->redraw = fb_redraw_fill; + + return add_widget_to_window(window, neww); +} + +fbtk_widget_t * +fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg) +{ + fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_HSCROLL); + + neww->x = x; + neww->y = y; + neww->width = width; + neww->height = height; + neww->fg = fg; + neww->bg = bg; + + neww->redraw = fb_redraw_hscroll; + + return add_widget_to_window(window, neww); +} + +fbtk_widget_t * +fbtk_create_button(fbtk_widget_t *window, + int x, int y, + colour c, + struct bitmap *image, + fbtk_mouseclick_t click, + void *pw) +{ + fbtk_widget_t *newb = fbtk_create_bitmap(window, x, y, c, image); + + newb->click = click; + newb->clickpw = pw; + + return newb; +} + +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) +{ + fbtk_widget_t *newt = fbtk_create_text(window, x, y, width, height, bg,fg,outline); + newt->u.text.enter = enter; + newt->u.text.pw = pw; + + newt->input = text_input; + newt->inputpw = newt; + return newt; +} + +/* create user widget + * + * @param x coord relative to parent + */ +fbtk_widget_t * +fbtk_create_user(fbtk_widget_t *window, + int x, int y, + int width, int height, + void *pw) +{ + fbtk_widget_t *newu = new_widget(FB_WIDGET_TYPE_USER); + + + /* make new window fit inside parent */ + if (width == 0) { + width = window->width - x; + } else if (width < 0) { + width = window->width + width; + } + if ((width + x) > window->width) { + width = window->width - x; + } + + if (height == 0) { + height = window->height - y; + } else if (height < 0) { + height = window->height + height; + } + if ((height + y) > window->height) { + height = window->height - y; + } + + newu->x = x; + newu->y = y; + newu->width = width; + newu->height = height; + + newu->u.user.pw = pw; + + return add_widget_to_window(window, newu); +} + + +/* create new window + * + * @param x coord relative to parent + */ +fbtk_widget_t * +fbtk_create_window(fbtk_widget_t *parent, + int x, int y, int width, int height) +{ + fbtk_widget_t *newwin; + + LOG(("Creating window %p %d,%d %d,%d",parent,x,y,width,height)); + if (parent == NULL) + return NULL; + + if ((parent->type == FB_WIDGET_TYPE_ROOT) && + (parent->u.root.rootw != NULL)) { + LOG(("Using root window")); + parent = parent->u.root.rootw; + } + + newwin = new_widget(FB_WIDGET_TYPE_WINDOW); + + /* make new window fit inside parent */ + if (width == 0) { + width = parent->width - x; + } else if (width < 0) { + width = parent->width + width; + } + if ((width + x) > parent->width) { + width = parent->width - x; + } + + if (height == 0) { + height = parent->height - y; + } else if (height < 0) { + height = parent->height + height; + } + if ((height + y) > parent->height) { + height = parent->height - y; + } + + newwin->x = x; + newwin->y = y; + newwin->width = width; + newwin->height = height; + + newwin->redraw = fbtk_window_default_redraw; + newwin->move = fbtk_window_default_move; + newwin->click = fbtk_window_default_click; + + LOG(("Created window %p %d,%d %d,%d",newwin,x,y,width,height)); + + return add_widget_to_window(parent, newwin); +} + + +/* Initialise toolkit for use */ +fbtk_widget_t * +fbtk_init(framebuffer_t *fb) +{ + fbtk_widget_t *root = new_widget(FB_WIDGET_TYPE_ROOT); + + root->u.root.fb = fb; + root->x = 0; + root->y = 0; + root->width = framebuffer->width; + root->height = framebuffer->height; + root->u.root.rootw = fbtk_create_window(root, 0, 0, 0, 0); + + root_style.font_size.value.length.unit = CSS_UNIT_PX; + root_style.font_size.value.length.value = 14; + + return root; +} + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ diff --git a/framebuffer/fb_tk.h b/framebuffer/fb_tk.h new file mode 100644 index 000000000..0dede3500 --- /dev/null +++ b/framebuffer/fb_tk.h @@ -0,0 +1,199 @@ + +#define FB_FRAME_COLOUR 0xFFDDDDDD +#define FB_COLOUR_BLACK 0xFF000000 +#define FB_COLOUR_WHITE 0xFFFFFFFF + +typedef struct fbtk_widget_s fbtk_widget_t; + +/* user widget callback */ +typedef int (*fbtk_user_t)(fbtk_widget_t *widget, void *pw); + +/* input callback */ +typedef int (*fbtk_input_t)(fbtk_widget_t *widget, int value, void *pw); + +/* mouse click callback */ +typedef int (*fbtk_mouseclick_t)(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw); + +/* mouse move callback */ +typedef int (*fbtk_move_t)(fbtk_widget_t *widget, int x, int y, void *pw); + +/* redraw function */ +typedef int (*fbtk_redraw_t)(fbtk_widget_t *widget, void *pw); + +/* enter pressed on writable icon */ +typedef int (*fbtk_enter_t)(void *pw, char *text); + + +/* Widget creation */ + +/** Initialise widget toolkit. + * + * Initialises widget toolkit and creates root window against a framebuffer. + * + * @param fb The underlying framebuffer. + * @return The root widget handle. + */ +fbtk_widget_t *fbtk_init(framebuffer_t *fb); + +/** Create a window widget. + * + * @param parent The parent window or the root widget for a top level window. + * @param x The x location relative to the parent window. + * @param y the y location relative to the parent window. + * @param width The width of the window. 0 indicates parents width should be + * used. Negative value indicates parents width less the value + * should be used. The width is limited to lie within the parent + * window. + * @param height The height of the window limited in a similar way to the + * /a width. + * @param c The background colour. + * @return new window widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_window(fbtk_widget_t *parent, int x, int y, int width, int height); + +/** Create a text widget. + * + * @param window The window to add the text widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline); + +/** Create a bitmap widget. + * + * Create a widget which shows a bitmap. + * + * @param window The window to add the bitmap widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c,struct bitmap *image); + +/** Create a filled rectangle + * + * Create a widget which is a filled rectangle, usually used for backgrounds. + * + * @param window The window to add the filled area widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t * +fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c); + +/** Create a horizontal scroll widget + * + * Create a horizontal scroll widget. + * + * @param window The window to add the filled area widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t * +fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg); + +/** Create a user widget. + * + * Create a widget which is to be handled entirely by the calling application. + * + * @param window The window to add the user widget to. + * @param pw The private pointer which can be read using ::fbtk_get_pw + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_user(fbtk_widget_t *window, int x, int y, int width, int height, void *pw); + + +/** Create a button widget. + * + * Helper function which creates a bitmap widget and associate a handler for + * when it is clicked. + * + * @param window The window to add the button widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_button(fbtk_widget_t *window, int x, int y, colour c, struct bitmap *image, fbtk_mouseclick_t click, void *pw); + +/** Create a writable text widget. + * + * Helper function which creates a text widget and configures an input handler + * to create a writable text field. This call is equivalent to calling + * ::fbtk_create_text followed by ::fbtk_writable_text + * + * @param window The window to add the text widget to. + * @return new widget handle or NULL on error. + */ +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); + + +/* Widget Destruction */ + +/** Destroy and free a widget and all its children. + * + * @param widget The widget to destroy. + * @return 0 on success or -1 on error. + */ +int fbtk_destroy_widget(fbtk_widget_t *widget); + +/* Widget information */ + +int fbtk_get_y(fbtk_widget_t *widget); +int fbtk_get_x(fbtk_widget_t *widget); +int fbtk_get_width(fbtk_widget_t *widget); +int fbtk_get_height(fbtk_widget_t *widget); +void *fbtk_get_userpw(fbtk_widget_t *widget); + +/* Set widget properties */ + +void fbtk_set_text(fbtk_widget_t *widget, const char *text); +void fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image); +void fbtk_set_scroll(fbtk_widget_t *widget, int pct); +void fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos); +void fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height); +void fbtk_set_handler_redraw(fbtk_widget_t *widget, fbtk_redraw_t input, void *pw); +void fbtk_set_handler_input(fbtk_widget_t *widget, fbtk_input_t input, void *pw); +void fbtk_set_handler_click(fbtk_widget_t *widget, fbtk_mouseclick_t click, void *pw); +void fbtk_set_handler_move(fbtk_widget_t *widget, fbtk_move_t move, void *pw); + +/** Alter a text widget to be writable. + */ +void fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw); + + +/* General routines */ + +/** Pointer movement. + * + * Pointer has been moved. + * + * @param widget any tookit widget. + * @parm x movement in horizontal plane. + * @parm y movement in vertical plane. + * @parm relative Wether the /a x and /a y should be considered relative to + * current pointer position. + */ +void fbtk_move_pointer(fbtk_widget_t *widget, int x, int y, bool relative); + +/** Mouse has been clicked + */ +void fbtk_click(fbtk_widget_t *widget, browser_mouse_state st); + +/** Input has been recived + */ +void fbtk_input(fbtk_widget_t *widget, uint32_t ucs4); + +/** Indicate a widget has to be redrawn + */ +void fbtk_request_redraw(fbtk_widget_t *widget); + +/** Cause a redraw to happen. + */ +int fbtk_redraw(fbtk_widget_t *widget); + +int fbtk_count_children(fbtk_widget_t *widget); + + + + + + + + + + + + diff --git a/framebuffer/res/icons/scrolll.png b/framebuffer/res/icons/scrolll.png new file mode 100644 index 000000000..1bd4bd868 Binary files /dev/null and b/framebuffer/res/icons/scrolll.png differ diff --git a/framebuffer/res/icons/scrollr.png b/framebuffer/res/icons/scrollr.png new file mode 100644 index 000000000..b4f717fb4 Binary files /dev/null and b/framebuffer/res/icons/scrollr.png differ diff --git a/framebuffer/res/throbber b/framebuffer/res/throbber new file mode 120000 index 000000000..ccb7ff5d8 --- /dev/null +++ b/framebuffer/res/throbber @@ -0,0 +1 @@ +../../gtk/res/throbber \ No newline at end of file -- cgit v1.2.3