diff options
Diffstat (limited to 'frontends/fltk/window.cpp')
-rw-r--r-- | frontends/fltk/window.cpp | 344 |
1 files changed, 344 insertions, 0 deletions
diff --git a/frontends/fltk/window.cpp b/frontends/fltk/window.cpp new file mode 100644 index 000000000..19aa26556 --- /dev/null +++ b/frontends/fltk/window.cpp @@ -0,0 +1,344 @@ +/* + * Copyright 2021 Vincent Sanders <vince@netsurf-browser.org> + * + * 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 <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * Implementation of netsurf window (widget) for fltk. + */ + +#include <stddef.h> +#include <FL/Fl.H> +#include <FL/Fl_Double_Window.H> +#include <FL/fl_draw.H> + +extern "C" { + +#include "utils/errors.h" +#include "netsurf/types.h" +#include "netsurf/mouse.h" +#include "netsurf/window.h" +#include "netsurf/plotters.h" +#include "netsurf/content.h" +#include "netsurf/browser_window.h" +#include "netsurf/mouse.h" + +} + +#include "fltk/window.h" +#include "fltk/plotters.h" + +extern bool nsfltk_done; + +class NS_Widget : public Fl_Widget +{ +private: + struct browser_window *mbw; + +protected: + void draw(); + int handle(int event); + +public: + NS_Widget(int X,int Y,int W,int H, struct browser_window *bw) + : Fl_Widget(X,Y,W,H), mbw(bw) {} +}; + + +class NS_Window : public Fl_Double_Window +{ +private: + struct browser_window *mbw; + NS_Widget *mnswidget; + + void close_callback(Fl_Widget *w); + static void static_close_callback(Fl_Widget *w, void *f) { ((NS_Window *)f)->close_callback(w); } + +public: + NS_Window(int W, int H, struct browser_window *bw) + : Fl_Double_Window(W,H), mbw(bw) { + this->callback(static_close_callback, (void *)this); + mnswidget = new NS_Widget(0, 0, W, H, bw); + this->end(); + } + ~NS_Window() { nsfltk_done=true; } + + NS_Widget *get_nswidget() { return mnswidget; } +}; + +struct gui_window { + struct browser_window *bw; + NS_Window *window; +}; + +/** + * method to handle events on the netsurf browsing widget + */ +int NS_Widget::handle(int event) +{ + int state = BROWSER_MOUSE_HOVER; + int button; + + switch (event) { + case FL_PUSH: + button = Fl::event_button(); + if (button == FL_LEFT_MOUSE) { + state |= BROWSER_MOUSE_PRESS_1; + } + browser_window_mouse_click(mbw, + (browser_mouse_state)state, + Fl::event_x() - x(), + Fl::event_y() - y()); + return 1; + + case FL_RELEASE: + button = Fl::event_button(); + if (button == FL_LEFT_MOUSE) { + state |= BROWSER_MOUSE_CLICK_1; + + } + browser_window_mouse_click(mbw, + (browser_mouse_state)state, + Fl::event_x() - x(), + Fl::event_y() - y()); + + return 1; + default: + return Fl_Widget::handle(event); + } +} + + +/** + * method to redraw the netsurf browsing widget + */ +void NS_Widget::draw() +{ + struct rect clip; + fl_clip_box(x(), y(), w(), h(), clip.x0, clip.y0, clip.x1, clip.y1); + /* clip box generates width/height so convert to absolute */ + clip.x1 += clip.x0; + clip.y1 += clip.y0; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &nsfltk_plotters, + .priv = NULL, + }; + + browser_window_redraw(mbw, x(), y(), &clip, &ctx); + +} + +/** + * callback when fltk window is closed + */ +void NS_Window::close_callback(Fl_Widget *w) +{ + browser_window_destroy(mbw); +} + +/** + * Create and open a gui window for a browsing context. + * + * The implementing front end must create a context suitable + * for it to display a window referred to as the "gui window". + * + * The frontend will be expected to request the core redraw + * areas of the gui window which have become invalidated + * either from toolkit expose events or as a result of a + * invalidate() call. + * + * Most core operations used by the frontend concerning browser + * windows require passing the browser window context therefor + * the gui window must include a reference to the browser + * window passed here. + * + * If GW_CREATE_CLONE flag is set existing is non-NULL. + * + * \param bw The core browsing context associated with the gui window + * \param existing An existing gui_window, may be NULL. + * \param flags flags to control the gui window creation. + * \return gui window, or NULL on error. + */ +static struct gui_window * +nsfltk_window_create(struct browser_window *bw, + struct gui_window *existing, + gui_window_create_flags flags) +{ + struct gui_window *gw; + gw = (struct gui_window *)calloc(1, sizeof(struct gui_window)); + + gw->window = new NS_Window(800,600, bw); + + gw->window->show(); + + return gw; +} + +/** + * Destroy previously created gui window + * + * \param gw The gui window to destroy. + */ +static void nsfltk_window_destroy(struct gui_window *gw) +{ + Fl::delete_widget(gw->window); + free(gw); +} + + +/** + * Invalidate an area of a window. + * + * The specified area of the window should now be considered + * out of date. If the area is NULL the entire window must be + * invalidated. It is expected that the windowing system will + * then subsequently cause redraw/expose operations as + * necessary. + * + * \note the frontend should not attempt to actually start the + * redraw operations as a result of this callback because the + * core redraw functions may already be threaded. + * + * \param gw The gui window to invalidate. + * \param rect area to redraw or NULL for the entire window area + * \return NSERROR_OK on success or appropriate error code + */ +static nserror +nsfltk_window_invalidate(struct gui_window *gw, const struct rect *rect) +{ + NS_Widget *nswidget; + nswidget = gw->window->get_nswidget(); + + if (rect == NULL) { + nswidget->damage(FL_DAMAGE_ALL); + } else { + nswidget->damage(FL_DAMAGE_ALL, + rect->x0, + rect->y0, + rect->x1 - rect->x0, + rect->y1 - rect->y0); + } + return NSERROR_OK; +} + + +/** + * Get the scroll position of a browser window. + * + * \param gw The gui window to obtain the scroll position from. + * \param sx receives x ordinate of point at top-left of window + * \param sy receives y ordinate of point at top-left of window + * \return true iff successful + */ +static bool nsfltk_window_get_scroll(struct gui_window *gw, int *sx, int *sy) +{ + return false; +} + + +/** + * Set the scroll position of a browser window. + * + * scrolls the viewport to ensure the specified rectangle of + * the content is shown. + * If the rectangle is of zero size i.e. x0 == x1 and y0 == y1 + * the contents will be scrolled so the specified point in the + * content is at the top of the viewport. + * If the size of the rectangle is non zero the frontend may + * add padding or centre the defined area or it may simply + * align as in the zero size rectangle + * + * \param gw The gui window to scroll. + * \param rect The rectangle to ensure is shown. + * \return NSERROR_OK on success or appropriate error code. + */ +static nserror +nsfltk_window_set_scroll(struct gui_window *gw, const struct rect *rect) +{ + return NSERROR_OK; +} + + +/** + * Find the current dimensions of a browser window's content area. + * + * This is used to determine the actual available drawing size + * in pixels. This allows contents that can be dynamically + * reformatted, such as HTML, to better use the available + * space. + * + * \param gw The gui window to measure content area of. + * \param width receives width of window + * \param height receives height of window + * \return NSERROR_OK on success and width and height updated + * else error code. + */ +static nserror +nsfltk_window_get_dimensions(struct gui_window *gw, int *width, int *height) +{ + NS_Widget *nswidget; + nswidget = gw->window->get_nswidget(); + + *width = nswidget->w(); + *height = nswidget->h(); + + return NSERROR_OK; +} + + +/** + * Miscellaneous event occurred for a window + * + * This is used to inform the frontend of window events which + * require no additional parameters. + * + * \param gw The gui window the event occurred for + * \param event Which event has occurred. + * \return NSERROR_OK if the event was processed else error code. + */ +static nserror +nsfltk_window_event(struct gui_window *gw, enum gui_window_event event) +{ + return NSERROR_OK; +} + +static struct gui_window_table window_table = { + .create = nsfltk_window_create, + .destroy = nsfltk_window_destroy, + .invalidate = nsfltk_window_invalidate, + .get_scroll = nsfltk_window_get_scroll, + .set_scroll = nsfltk_window_set_scroll, + .get_dimensions = nsfltk_window_get_dimensions, + .event = nsfltk_window_event, + .set_title = NULL, + .set_url = NULL, + .set_icon = NULL, + .set_status = NULL, + .set_pointer = NULL, + .place_caret = NULL, + .drag_start = NULL, + .save_link = NULL, + .create_form_select_menu = NULL, + .file_gadget_open = NULL, + .drag_save_object = NULL, + .drag_save_selection = NULL, + .console_log = NULL, +}; + +struct gui_window_table *nsfltk_window_table = &window_table; |