summaryrefslogtreecommitdiff
path: root/frontends/fltk/window.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'frontends/fltk/window.cpp')
-rw-r--r--frontends/fltk/window.cpp344
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;