/** * handler for toolkit window redraw event */ static int fb_cw_draw_event(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct fb_corewindow *fb_cw; nsfb_bbox_t rbox; struct rect clip; fb_cw = (struct fb_corewindow *)cbi->context; rbox.x0 = fbtk_get_absx(widget); rbox.y0 = fbtk_get_absy(widget); rbox.x1 = rbox.x0 + fbtk_get_width(widget); rbox.y1 = rbox.y0 + fbtk_get_height(widget); nsfb_claim(fbtk_get_nsfb(widget), &rbox); clip.x0 = fb_cw->scrollx; clip.y0 = fb_cw->scrolly; clip.x1 = fbtk_get_width(widget) + fb_cw->scrollx; clip.y1 = fbtk_get_height(widget) + fb_cw->scrolly; fb_cw->draw(fb_cw, &clip); nsfb_update(fbtk_get_nsfb(widget), &rbox); return 0; }
static void fb_cw_get_window_dimensions(struct core_window *cw, int *width, int *height) { struct fb_corewindow *fb_cw = (struct fb_corewindow *)cw; *width = fbtk_get_width(fb_cw->drawable); *height = fbtk_get_height(fb_cw->drawable); }
static void gui_window_update_extent(struct gui_window *gw) { int w, h; browser_window_get_extents(gw->bw, true, &w, &h); fbtk_set_scroll_parameters(gw->hscroll, 0, w, fbtk_get_width(gw->browser), 100); fbtk_set_scroll_parameters(gw->vscroll, 0, h, fbtk_get_height(gw->browser), 100); }
void gui_window_update_extent(struct gui_window *gw) { float scale = gw->bw->scale; fbtk_set_scroll_parameters(gw->hscroll, 0, content_get_width(gw->bw->current_content) * scale, fbtk_get_width(gw->browser), 100); fbtk_set_scroll_parameters(gw->vscroll, 0, content_get_height(gw->bw->current_content) * scale, fbtk_get_height(gw->browser), 100); }
void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bool scaled) { *width = fbtk_get_width(g->browser); *height = fbtk_get_height(g->browser); if (scaled) { *width /= g->bw->scale; *height /= g->bw->scale; } }
static void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, bool scaled) { float scale = browser_window_get_scale(g->bw); *width = fbtk_get_width(g->browser); *height = fbtk_get_height(g->browser); if (scaled) { *width /= scale; *height /= scale; } }
/* queue a window scroll */ static void widget_scroll_y(struct gui_window *gw, int y, bool abs) { struct browser_widget_s *bwidget = fbtk_get_userpw(gw->browser); int content_width, content_height; int height; LOG(("window scroll")); if (abs) { bwidget->pany = y - bwidget->scrolly; } else { bwidget->pany += y; } browser_window_get_extents(gw->bw, true, &content_width, &content_height); height = fbtk_get_height(gw->browser); /* dont pan off the top */ if ((bwidget->scrolly + bwidget->pany) < 0) bwidget->pany = -bwidget->scrolly; /* do not pan off the bottom of the content */ if ((bwidget->scrolly + bwidget->pany) > (content_height - height)) bwidget->pany = (content_height - height) - bwidget->scrolly; if (bwidget->pany == 0) { return; } bwidget->pan_required = true; fbtk_request_redraw(gw->browser); fbtk_set_scroll_position(gw->vscroll, bwidget->scrolly + bwidget->pany); }
static int localhistory_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_localhistory *glh = cbi->context; nsfb_bbox_t rbox; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &fb_plotters }; rbox.x0 = fbtk_get_absx(widget); rbox.y0 = fbtk_get_absy(widget); rbox.x1 = rbox.x0 + fbtk_get_width(widget); rbox.y1 = rbox.y0 + fbtk_get_height(widget); nsfb_claim(fbtk_get_nsfb(widget), &rbox); nsfb_plot_rectangle_fill(fbtk_get_nsfb(widget), &rbox, 0xffffffff); history_redraw_rectangle(glh->bw->history, glh->scrollx, glh->scrolly, fbtk_get_width(widget) + glh->scrollx, fbtk_get_height(widget) + glh->scrolly, 0, 0, &ctx); nsfb_update(fbtk_get_nsfb(widget), &rbox); return 0; } static int localhistory_click(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_localhistory *glh = cbi->context; if (cbi->event->type != NSFB_EVENT_KEY_UP) return 0; history_click(glh->bw, glh->bw->history, cbi->x, cbi->y, false); fbtk_set_mapping(glh->window, false); return 1; } struct gui_localhistory * fb_create_localhistory(struct browser_window *bw, fbtk_widget_t *parent, int furniture_width) { struct gui_localhistory *glh; glh = calloc(1, sizeof(struct gui_localhistory)); if (glh == NULL) return NULL; glh->bw = bw; /* container window */ glh->window = fbtk_create_window(parent, 0, 0, 0, 0, 0); glh->history = fbtk_create_user(glh->window, 0, 0, -furniture_width, -furniture_width, glh); fbtk_set_handler(glh->history, FBTK_CBT_REDRAW, localhistory_redraw, glh); fbtk_set_handler(glh->history, FBTK_CBT_CLICK, localhistory_click, glh); /* fbtk_set_handler(gw->localhistory, FBTK_CBT_INPUT, fb_browser_window_input, gw); fbtk_set_handler(gw->localhistory, FBTK_CBT_POINTERMOVE, fb_browser_window_move, bw); */ /* create horizontal scrollbar */ glh->hscroll = fbtk_create_hscroll(glh->window, 0, fbtk_get_height(glh->window) - furniture_width, fbtk_get_width(glh->window) - furniture_width, furniture_width, FB_SCROLL_COLOUR, FB_FRAME_COLOUR, NULL, NULL); glh->vscroll = fbtk_create_vscroll(glh->window, fbtk_get_width(glh->window) - furniture_width, 0, furniture_width, fbtk_get_height(glh->window) - furniture_width, FB_SCROLL_COLOUR, FB_FRAME_COLOUR, NULL, NULL); fbtk_create_fill(glh->window, fbtk_get_width(glh->window) - furniture_width, fbtk_get_height(glh->window) - furniture_width, furniture_width, furniture_width, FB_FRAME_COLOUR); return glh; } void fb_localhistory_map(struct gui_localhistory * glh) { fbtk_set_zorder(glh->window, INT_MIN); fbtk_set_mapping(glh->window, true); }
/* exported function documented fb/corewindow.h */ nserror fb_corewindow_init(fbtk_widget_t *parent, struct fb_corewindow *fb_cw) { int furniture_width; furniture_width = nsoption_int(fb_furniture_size); /* setup the core window callback table */ fb_cw->cb_table = &fb_cw_cb_table; fb_cw->drag_status = CORE_WINDOW_DRAG_NONE; /* container window */ fb_cw->wnd = fbtk_create_window(parent, 0, 0, 0, 0, 0); fb_cw->drawable = fbtk_create_user(fb_cw->wnd, 0, 0, -furniture_width, -furniture_width, fb_cw); fbtk_set_handler(fb_cw->drawable, FBTK_CBT_REDRAW, fb_cw_draw_event, fb_cw); fbtk_set_handler(fb_cw->drawable, FBTK_CBT_CLICK, fb_cw_mouse_press_event, fb_cw); /* fbtk_set_handler(fb_cw->drawable, FBTK_CBT_INPUT, fb_cw_input_event, fb_cw); fbtk_set_handler(fb_cw->drawable, FBTK_CBT_POINTERMOVE, fb_cw_move_event, fb_cw); */ /* create horizontal scrollbar */ fb_cw->hscroll = fbtk_create_hscroll(fb_cw->wnd, 0, fbtk_get_height(fb_cw->wnd) - furniture_width, fbtk_get_width(fb_cw->wnd) - furniture_width, furniture_width, FB_SCROLL_COLOUR, FB_FRAME_COLOUR, NULL, NULL); fb_cw->vscroll = fbtk_create_vscroll(fb_cw->wnd, fbtk_get_width(fb_cw->wnd) - furniture_width, 0, furniture_width, fbtk_get_height(fb_cw->wnd) - furniture_width, FB_SCROLL_COLOUR, FB_FRAME_COLOUR, NULL, NULL); fbtk_create_fill(fb_cw->wnd, fbtk_get_width(fb_cw->wnd) - furniture_width, fbtk_get_height(fb_cw->wnd) - furniture_width, furniture_width, furniture_width, FB_FRAME_COLOUR); return NSERROR_OK; }
static int fb_browser_window_input(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_window *gw = cbi->context; static fbtk_modifier_type modifier = FBTK_MOD_CLEAR; int ucs4 = -1; LOG(("got value %d", cbi->event->value.keycode)); switch (cbi->event->type) { case NSFB_EVENT_KEY_DOWN: switch (cbi->event->value.keycode) { case NSFB_KEY_DELETE: browser_window_key_press(gw->bw, KEY_DELETE_RIGHT); break; case NSFB_KEY_PAGEUP: if (browser_window_key_press(gw->bw, KEY_PAGE_UP) == false) widget_scroll_y(gw, -fbtk_get_height( gw->browser), false); break; case NSFB_KEY_PAGEDOWN: if (browser_window_key_press(gw->bw, KEY_PAGE_DOWN) == false) widget_scroll_y(gw, fbtk_get_height( gw->browser), false); break; case NSFB_KEY_RIGHT: if (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL) { /* CTRL held */ if (browser_window_key_press(gw->bw, KEY_LINE_END) == false) widget_scroll_x(gw, INT_MAX, true); } else if (modifier & FBTK_MOD_RSHIFT || modifier & FBTK_MOD_LSHIFT) { /* SHIFT held */ if (browser_window_key_press(gw->bw, KEY_WORD_RIGHT) == false) widget_scroll_x(gw, fbtk_get_width( gw->browser), false); } else { /* no modifier */ if (browser_window_key_press(gw->bw, KEY_RIGHT) == false) widget_scroll_x(gw, 100, false); } break; case NSFB_KEY_LEFT: if (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL) { /* CTRL held */ if (browser_window_key_press(gw->bw, KEY_LINE_START) == false) widget_scroll_x(gw, 0, true); } else if (modifier & FBTK_MOD_RSHIFT || modifier & FBTK_MOD_LSHIFT) { /* SHIFT held */ if (browser_window_key_press(gw->bw, KEY_WORD_LEFT) == false) widget_scroll_x(gw, -fbtk_get_width( gw->browser), false); } else { /* no modifier */ if (browser_window_key_press(gw->bw, KEY_LEFT) == false) widget_scroll_x(gw, -100, false); } break; case NSFB_KEY_UP: if (browser_window_key_press(gw->bw, KEY_UP) == false) widget_scroll_y(gw, -100, false); break; case NSFB_KEY_DOWN: if (browser_window_key_press(gw->bw, KEY_DOWN) == false) widget_scroll_y(gw, 100, false); break; case NSFB_KEY_RSHIFT: modifier |= FBTK_MOD_RSHIFT; break; case NSFB_KEY_LSHIFT: modifier |= FBTK_MOD_LSHIFT; break; case NSFB_KEY_RCTRL: modifier |= FBTK_MOD_RCTRL; break; case NSFB_KEY_LCTRL: modifier |= FBTK_MOD_LCTRL; break; case NSFB_KEY_y: case NSFB_KEY_z: if (cbi->event->value.keycode == NSFB_KEY_z && (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL) && (modifier & FBTK_MOD_RSHIFT || modifier & FBTK_MOD_LSHIFT)) { /* Z pressed with CTRL and SHIFT held */ browser_window_key_press(gw->bw, KEY_REDO); break; } else if (cbi->event->value.keycode == NSFB_KEY_z && (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL)) { /* Z pressed with CTRL held */ browser_window_key_press(gw->bw, KEY_UNDO); break; } else if (cbi->event->value.keycode == NSFB_KEY_y && (modifier & FBTK_MOD_RCTRL || modifier & FBTK_MOD_LCTRL)) { /* Y pressed with CTRL held */ browser_window_key_press(gw->bw, KEY_REDO); break; } /* Z or Y pressed but not undo or redo; * Fall through to default handling */ default: ucs4 = fbtk_keycode_to_ucs4(cbi->event->value.keycode, modifier); if (ucs4 != -1) browser_window_key_press(gw->bw, ucs4); break; } break; case NSFB_EVENT_KEY_UP: switch (cbi->event->value.keycode) { case NSFB_KEY_RSHIFT: modifier &= ~FBTK_MOD_RSHIFT; break; case NSFB_KEY_LSHIFT: modifier &= ~FBTK_MOD_LSHIFT; break; case NSFB_KEY_RCTRL: modifier &= ~FBTK_MOD_RCTRL; break; case NSFB_KEY_LCTRL: modifier &= ~FBTK_MOD_LCTRL; break; default: break; } break; default: break; } return 0; }
static void fb_redraw(fbtk_widget_t *widget, struct browser_widget_s *bwidget, struct browser_window *bw) { int x; int y; int caret_x, caret_y, caret_h; struct rect clip; struct redraw_context ctx = { .interactive = true, .background_images = true, .plot = &fb_plotters }; nsfb_t *nsfb = fbtk_get_nsfb(widget); float scale = browser_window_get_scale(bw); LOG(("%d,%d to %d,%d", bwidget->redraw_box.x0, bwidget->redraw_box.y0, bwidget->redraw_box.x1, bwidget->redraw_box.y1)); x = fbtk_get_absx(widget); y = fbtk_get_absy(widget); /* adjust clipping co-ordinates according to window location */ bwidget->redraw_box.y0 += y; bwidget->redraw_box.y1 += y; bwidget->redraw_box.x0 += x; bwidget->redraw_box.x1 += x; nsfb_claim(nsfb, &bwidget->redraw_box); /* redraw bounding box is relative to window */ clip.x0 = bwidget->redraw_box.x0; clip.y0 = bwidget->redraw_box.y0; clip.x1 = bwidget->redraw_box.x1; clip.y1 = bwidget->redraw_box.y1; browser_window_redraw(bw, (x - bwidget->scrollx) / scale, (y - bwidget->scrolly) / scale, &clip, &ctx); if (fbtk_get_caret(widget, &caret_x, &caret_y, &caret_h)) { /* This widget has caret, so render it */ nsfb_bbox_t line; nsfb_plot_pen_t pen; line.x0 = x - bwidget->scrollx + caret_x; line.y0 = y - bwidget->scrolly + caret_y; line.x1 = x - bwidget->scrollx + caret_x; line.y1 = y - bwidget->scrolly + caret_y + caret_h; pen.stroke_type = NFSB_PLOT_OPTYPE_SOLID; pen.stroke_width = 1; pen.stroke_colour = 0xFF0000FF; nsfb_plot_line(nsfb, &line, &pen); } nsfb_update(fbtk_get_nsfb(widget), &bwidget->redraw_box); bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX; bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = INT_MIN; bwidget->redraw_required = false; } static int fb_browser_window_redraw(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct gui_window *gw = cbi->context; struct browser_widget_s *bwidget; bwidget = fbtk_get_userpw(widget); if (bwidget == NULL) { LOG(("browser widget from widget %p was null", widget)); return -1; } if (bwidget->pan_required) { fb_pan(widget, bwidget, gw->bw); } if (bwidget->redraw_required) { fb_redraw(widget, bwidget, gw->bw); } else { bwidget->redraw_box.x0 = 0; bwidget->redraw_box.y0 = 0; bwidget->redraw_box.x1 = fbtk_get_width(widget); bwidget->redraw_box.y1 = fbtk_get_height(widget); fb_redraw(widget, bwidget, gw->bw); } return 0; } static int fb_browser_window_destroy(fbtk_widget_t *widget, fbtk_callback_info *cbi) { struct browser_widget_s *browser_widget; if (widget == NULL) { return 0; } /* Free private data */ browser_widget = fbtk_get_userpw(widget); free(browser_widget); return 0; } static const char *fename; static int febpp; static int fewidth; static int feheight; static const char *feurl; static bool process_cmdline(int argc, char** argv) { int opt; LOG(("argc %d, argv %p", argc, argv)); fename = "mtl"; febpp = 32; fewidth = nsoption_int(window_width); if (fewidth <= 0) { fewidth = 800; } feheight = nsoption_int(window_height); if (feheight <= 0) { feheight = 480; } if ((nsoption_charp(homepage_url) != NULL) && (nsoption_charp(homepage_url)[0] != '\0')) { feurl = nsoption_charp(homepage_url); } else { feurl = NETSURF_HOMEPAGE; } while((opt = getopt(argc, argv, "f:b:w:h:")) != -1) { switch (opt) { case 'f': fename = optarg; break; case 'b': febpp = atoi(optarg); break; case 'w': fewidth = atoi(optarg); break; case 'h': feheight = atoi(optarg); break; default: fprintf(stderr, "Usage: %s [-f frontend] [-b bpp] url\n", argv[0]); return false; } } if (optind < argc) { feurl = argv[optind]; } return true; }
static void fb_pan(fbtk_widget_t *widget, struct browser_widget_s *bwidget, struct browser_window *bw) { int x; int y; int width; int height; nsfb_bbox_t srcbox; nsfb_bbox_t dstbox; nsfb_t *nsfb = fbtk_get_nsfb(widget); height = fbtk_get_height(widget); width = fbtk_get_width(widget); LOG(("panning %d, %d", bwidget->panx, bwidget->pany)); x = fbtk_get_absx(widget); y = fbtk_get_absy(widget); /* if the pan exceeds the viewport size just redraw the whole area */ if (bwidget->pany >= height || bwidget->pany <= -height || bwidget->panx >= width || bwidget->panx <= -width) { bwidget->scrolly += bwidget->pany; bwidget->scrollx += bwidget->panx; fb_queue_redraw(widget, 0, 0, width, height); /* ensure we don't try to scroll again */ bwidget->panx = 0; bwidget->pany = 0; bwidget->pan_required = false; return; } if (bwidget->pany < 0) { /* pan up by less then viewport height */ srcbox.x0 = x; srcbox.y0 = y; srcbox.x1 = srcbox.x0 + width; srcbox.y1 = srcbox.y0 + height + bwidget->pany; dstbox.x0 = x; dstbox.y0 = y - bwidget->pany; dstbox.x1 = dstbox.x0 + width; dstbox.y1 = dstbox.y0 + height + bwidget->pany; /* move part that remains visible up */ nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox); /* redraw newly exposed area */ bwidget->scrolly += bwidget->pany; fb_queue_redraw(widget, 0, 0, width, - bwidget->pany); } else if (bwidget->pany > 0) { /* pan down by less then viewport height */ srcbox.x0 = x; srcbox.y0 = y + bwidget->pany; srcbox.x1 = srcbox.x0 + width; srcbox.y1 = srcbox.y0 + height - bwidget->pany; dstbox.x0 = x; dstbox.y0 = y; dstbox.x1 = dstbox.x0 + width; dstbox.y1 = dstbox.y0 + height - bwidget->pany; /* move part that remains visible down */ nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox); /* redraw newly exposed area */ bwidget->scrolly += bwidget->pany; fb_queue_redraw(widget, 0, height - bwidget->pany, width, height); } if (bwidget->panx < 0) { /* pan left by less then viewport width */ srcbox.x0 = x; srcbox.y0 = y; srcbox.x1 = srcbox.x0 + width + bwidget->panx; srcbox.y1 = srcbox.y0 + height; dstbox.x0 = x - bwidget->panx; dstbox.y0 = y; dstbox.x1 = dstbox.x0 + width + bwidget->panx; dstbox.y1 = dstbox.y0 + height; /* move part that remains visible left */ nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox); /* redraw newly exposed area */ bwidget->scrollx += bwidget->panx; fb_queue_redraw(widget, 0, 0, -bwidget->panx, height); } else if (bwidget->panx > 0) { /* pan right by less then viewport width */ srcbox.x0 = x + bwidget->panx; srcbox.y0 = y; srcbox.x1 = srcbox.x0 + width - bwidget->panx; srcbox.y1 = srcbox.y0 + height; dstbox.x0 = x; dstbox.y0 = y; dstbox.x1 = dstbox.x0 + width - bwidget->panx; dstbox.y1 = dstbox.y0 + height; /* move part that remains visible right */ nsfb_plot_copy(nsfb, &srcbox, nsfb, &dstbox); /* redraw newly exposed area */ bwidget->scrollx += bwidget->panx; fb_queue_redraw(widget, width - bwidget->panx, 0, width, height); } bwidget->pan_required = false; bwidget->panx = 0; bwidget->pany = 0; }
static void gui_window_redraw_window(struct gui_window *g) { fb_queue_redraw(g->browser, 0, 0, fbtk_get_width(g->browser), fbtk_get_height(g->browser) ); }
static void create_normal_browser_window(struct gui_window *gw, int furniture_width) { fbtk_widget_t *widget; fbtk_widget_t *toolbar; int statusbar_width = 0; int toolbar_height = nsoption_int(fb_toolbar_size); LOG(("Normal window")); gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0, 0); statusbar_width = nsoption_int(toolbar_status_size) * fbtk_get_width(gw->window) / 10000; /* toolbar */ toolbar = create_toolbar(gw, toolbar_height, 2, FB_FRAME_COLOUR, nsoption_charp(fb_toolbar_layout)); /* set the actually created toolbar height */ if (toolbar != NULL) { toolbar_height = fbtk_get_height(toolbar); } else { toolbar_height = 0; } /* status bar */ gw->status = fbtk_create_text(gw->window, 0, fbtk_get_height(gw->window) - furniture_width, statusbar_width, furniture_width, FB_FRAME_COLOUR, FB_COLOUR_BLACK, false); fbtk_set_handler(gw->status, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL); LOG(("status bar %p at %d,%d", gw->status, fbtk_get_absx(gw->status), fbtk_get_absy(gw->status))); /* create horizontal scrollbar */ gw->hscroll = fbtk_create_hscroll(gw->window, statusbar_width, fbtk_get_height(gw->window) - furniture_width, fbtk_get_width(gw->window) - statusbar_width - furniture_width, furniture_width, FB_SCROLL_COLOUR, FB_FRAME_COLOUR, fb_scroll_callback, gw); /* fill bottom right area */ if (nsoption_bool(fb_osk) == true) { widget = fbtk_create_text_button(gw->window, fbtk_get_width(gw->window) - furniture_width, fbtk_get_height(gw->window) - furniture_width, furniture_width, furniture_width, FB_FRAME_COLOUR, FB_COLOUR_BLACK, fb_osk_click, NULL); widget = fbtk_create_button(gw->window, fbtk_get_width(gw->window) - furniture_width, fbtk_get_height(gw->window) - furniture_width, furniture_width, furniture_width, FB_FRAME_COLOUR, &osk_image, fb_osk_click, NULL); } else { widget = fbtk_create_fill(gw->window, fbtk_get_width(gw->window) - furniture_width, fbtk_get_height(gw->window) - furniture_width, furniture_width, furniture_width, FB_FRAME_COLOUR); fbtk_set_handler(widget, FBTK_CBT_POINTERENTER, set_ptr_default_move, NULL); } /* create vertical scrollbar */ gw->vscroll = fbtk_create_vscroll(gw->window, fbtk_get_width(gw->window) - furniture_width, toolbar_height, furniture_width, fbtk_get_height(gw->window) - toolbar_height - furniture_width, FB_SCROLL_COLOUR, FB_FRAME_COLOUR, fb_scroll_callback, gw); /* browser widget */ create_browser_widget(gw, toolbar_height, nsoption_int(fb_furniture_size)); /* Give browser_window's user widget input focus */ fbtk_set_focus(gw->browser); }