summaryrefslogtreecommitdiff
path: root/frontends/monkey
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2016-05-05 22:28:51 +0100
committerVincent Sanders <vince@kyllikki.org>2016-05-15 13:44:34 +0100
commitd21447d096a320a08b3efb2b8768fad0dcdcfd64 (patch)
tree1a83814b7c9e94b2f13c473261f23dd3a17dee64 /frontends/monkey
parent2cbb337756d9af5bda4d594964d446439f602551 (diff)
downloadnetsurf-d21447d096a320a08b3efb2b8768fad0dcdcfd64.tar.gz
netsurf-d21447d096a320a08b3efb2b8768fad0dcdcfd64.tar.bz2
move frontends into sub directory
Diffstat (limited to 'frontends/monkey')
-rw-r--r--frontends/monkey/401login.c55
-rw-r--r--frontends/monkey/401login.h9
-rw-r--r--frontends/monkey/Makefile55
-rw-r--r--frontends/monkey/Makefile.defaults13
-rw-r--r--frontends/monkey/bitmap.c150
-rw-r--r--frontends/monkey/bitmap.h24
-rw-r--r--frontends/monkey/browser.c527
-rw-r--r--frontends/monkey/browser.h48
-rw-r--r--frontends/monkey/cert.c58
-rw-r--r--frontends/monkey/cert.h28
-rw-r--r--frontends/monkey/dispatch.c105
-rw-r--r--frontends/monkey/dispatch.h28
-rw-r--r--frontends/monkey/download.c94
-rw-r--r--frontends/monkey/fetch.c53
-rw-r--r--frontends/monkey/fetch.h24
-rw-r--r--frontends/monkey/filetype.c215
-rw-r--r--frontends/monkey/filetype.h22
-rw-r--r--frontends/monkey/layout.c117
-rw-r--r--frontends/monkey/layout.h24
-rw-r--r--frontends/monkey/main.c398
-rw-r--r--frontends/monkey/options.h43
-rw-r--r--frontends/monkey/plot.c111
-rw-r--r--frontends/monkey/plot.h26
l---------frontends/monkey/res1
-rw-r--r--frontends/monkey/schedule.c223
-rw-r--r--frontends/monkey/schedule.h48
26 files changed, 2499 insertions, 0 deletions
diff --git a/frontends/monkey/401login.c b/frontends/monkey/401login.c
new file mode 100644
index 000000000..8b4d33d7d
--- /dev/null
+++ b/frontends/monkey/401login.c
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#include "utils/ring.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "monkey/401login.h"
+
+typedef struct monkey401 {
+ struct monkey401 *r_next, *r_prev;
+ uint32_t num;
+ lwc_string *host; /* Ignore */
+ nserror (*cb)(bool,void*);
+ void *pw;
+} monkey401_t;
+
+static monkey401_t *m4_ring = NULL;
+static uint32_t m4_ctr = 0;
+
+void gui_401login_open(nsurl *url, const char *realm,
+ nserror (*cb)(bool proceed, void *pw), void *cbpw)
+{
+ monkey401_t *m4t = calloc(sizeof(*m4t), 1);
+ if (m4t == NULL) {
+ cb(false, cbpw);
+ return;
+ }
+ m4t->cb = cb;
+ m4t->pw = cbpw;
+ m4t->num = m4_ctr++;
+
+ RING_INSERT(m4_ring, m4t);
+
+ fprintf(stdout, "401LOGIN OPEN M4 %u URL %s REALM %s\n",
+ m4t->num, nsurl_access(url), realm);
+}
+
+
diff --git a/frontends/monkey/401login.h b/frontends/monkey/401login.h
new file mode 100644
index 000000000..e78355ea2
--- /dev/null
+++ b/frontends/monkey/401login.h
@@ -0,0 +1,9 @@
+
+#include <stdbool.h>
+
+#include "utils/nsurl.h"
+#include "utils/errors.h"
+
+
+void gui_401login_open(nsurl *url, const char *realm,
+ nserror (*cb)(bool proceed, void *pw), void *cbpw);
diff --git a/frontends/monkey/Makefile b/frontends/monkey/Makefile
new file mode 100644
index 000000000..86f1d912e
--- /dev/null
+++ b/frontends/monkey/Makefile
@@ -0,0 +1,55 @@
+#
+# Makefile for NetSurf monkey target
+#
+# This file is part of NetSurf
+
+# ----------------------------------------------------------------------------
+# Monkey flag setup (using pkg-config)
+# ----------------------------------------------------------------------------
+
+CWARNFLAGS += -Werror
+
+CFLAGS += -std=c99 -Dmonkey -Dnsmonkey -g \
+ -D_BSD_SOURCE \
+ -D_DEFAULT_SOURCE \
+ -D_XOPEN_SOURCE=700 \
+ -D_POSIX_C_SOURCE=200809L \
+ -D_NETBSD_SOURCE \
+ -DMONKEY_RESPATH=\"$(NETSURF_MONKEY_RESOURCES)\"
+
+LDFLAGS += -lm
+
+# ---------------------------------------------------------------------------
+# Windows flag setup
+# ---------------------------------------------------------------------------
+
+ifeq ($(HOST),Windows_NT)
+ CFLAGS += -U__STRICT_ANSI__
+endif
+
+# ----------------------------------------------------------------------------
+# Source file setup
+# ----------------------------------------------------------------------------
+
+# S_MONKEY are sources purely for the MONKEY build
+S_FRONTEND := main.c filetype.c schedule.c bitmap.c plot.c browser.c \
+ download.c 401login.c cert.c layout.c dispatch.c fetch.c
+
+
+# This is the final source build list
+# Note this is deliberately *not* expanded here as common and image
+# are not yet available
+SOURCES = $(S_COMMON) $(S_IMAGE) $(S_BROWSER) $(S_PDF) $(S_FRONTEND)
+EXETARGET := nsmonkey
+
+# ----------------------------------------------------------------------------
+# Install target
+# ----------------------------------------------------------------------------
+
+install-monkey:
+
+# ----------------------------------------------------------------------------
+# Package target
+# ----------------------------------------------------------------------------
+
+package-monkey:
diff --git a/frontends/monkey/Makefile.defaults b/frontends/monkey/Makefile.defaults
new file mode 100644
index 000000000..d6a90a3dc
--- /dev/null
+++ b/frontends/monkey/Makefile.defaults
@@ -0,0 +1,13 @@
+# ----------------------------------------------------------------------------
+# Monkey-specific options
+# ----------------------------------------------------------------------------
+
+# How did I get mixed up with this fucking monkey anyhow?
+NETSURF_MONKEY_RESOURCES := $(PREFIX)/share/netsurf/
+NETSURF_MONKEY_BIN := $(PREFIX)/bin/
+NETSURF_USE_RSVG := NO
+NETSURF_USE_NSSVG := NO
+NETSURF_USE_ROSPRITE := NO
+NETSURF_USE_HARU_PDF := NO
+
+CFLAGS += -O2
diff --git a/frontends/monkey/bitmap.c b/frontends/monkey/bitmap.c
new file mode 100644
index 000000000..5605073ba
--- /dev/null
+++ b/frontends/monkey/bitmap.c
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#include <stdbool.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "utils/errors.h"
+#include "image/bitmap.h"
+
+#include "monkey/bitmap.h"
+
+struct bitmap {
+ void *ptr;
+ size_t rowstride;
+ int width;
+ int height;
+ unsigned int state;
+};
+
+static void *bitmap_create(int width, int height, unsigned int state)
+{
+ struct bitmap *ret = calloc(sizeof(*ret), 1);
+ if (ret == NULL)
+ return NULL;
+
+ ret->width = width;
+ ret->height = height;
+ ret->state = state;
+
+ ret->ptr = calloc(width, height * 4);
+
+ if (ret->ptr == NULL) {
+ free(ret);
+ return NULL;
+ }
+
+ return ret;
+}
+
+static void bitmap_destroy(void *bitmap)
+{
+ struct bitmap *bmap = bitmap;
+ free(bmap->ptr);
+ free(bmap);
+}
+
+static void bitmap_set_opaque(void *bitmap, bool opaque)
+{
+ struct bitmap *bmap = bitmap;
+
+ if (opaque)
+ bmap->state |= (BITMAP_OPAQUE);
+ else
+ bmap->state &= ~(BITMAP_OPAQUE);
+}
+
+static bool bitmap_test_opaque(void *bitmap)
+{
+ return false;
+}
+
+static bool bitmap_get_opaque(void *bitmap)
+{
+ struct bitmap *bmap = bitmap;
+
+ return (bmap->state & BITMAP_OPAQUE) == BITMAP_OPAQUE;
+}
+
+static unsigned char *bitmap_get_buffer(void *bitmap)
+{
+ struct bitmap *bmap = bitmap;
+
+ return (unsigned char *)(bmap->ptr);
+}
+
+static size_t bitmap_get_rowstride(void *bitmap)
+{
+ struct bitmap *bmap = bitmap;
+ return bmap->width * 4;
+}
+
+static size_t bitmap_get_bpp(void *bitmap)
+{
+ /* OMG?! */
+ return 4;
+}
+
+static bool bitmap_save(void *bitmap, const char *path, unsigned flags)
+{
+ return true;
+}
+
+static void bitmap_modified(void *bitmap)
+{
+ struct bitmap *bmap = bitmap;
+ bmap->state |= BITMAP_MODIFIED;
+}
+
+static int bitmap_get_width(void *bitmap)
+{
+ struct bitmap *bmap = bitmap;
+ return bmap->width;
+}
+
+static int bitmap_get_height(void *bitmap)
+{
+ struct bitmap *bmap = bitmap;
+ return bmap->height;
+}
+
+static nserror bitmap_render(struct bitmap *bitmap,
+ struct hlcache_handle *content)
+{
+ fprintf(stdout, "GENERIC BITMAP RENDER\n");
+ return NSERROR_OK;
+}
+
+static struct gui_bitmap_table bitmap_table = {
+ .create = bitmap_create,
+ .destroy = bitmap_destroy,
+ .set_opaque = bitmap_set_opaque,
+ .get_opaque = bitmap_get_opaque,
+ .test_opaque = bitmap_test_opaque,
+ .get_buffer = bitmap_get_buffer,
+ .get_rowstride = bitmap_get_rowstride,
+ .get_width = bitmap_get_width,
+ .get_height = bitmap_get_height,
+ .get_bpp = bitmap_get_bpp,
+ .save = bitmap_save,
+ .modified = bitmap_modified,
+ .render = bitmap_render,
+};
+
+struct gui_bitmap_table *monkey_bitmap_table = &bitmap_table;
diff --git a/frontends/monkey/bitmap.h b/frontends/monkey/bitmap.h
new file mode 100644
index 000000000..e293ce93f
--- /dev/null
+++ b/frontends/monkey/bitmap.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2015 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/>.
+ */
+
+#ifndef NS_MONKEY_BITMAP_H
+#define NS_MONKEY_BITMAP_H
+
+extern struct gui_bitmap_table *monkey_bitmap_table;
+
+#endif /* NS_MONKEY_BITMAP_H */
diff --git a/frontends/monkey/browser.c b/frontends/monkey/browser.c
new file mode 100644
index 000000000..dfd2dcf6c
--- /dev/null
+++ b/frontends/monkey/browser.c
@@ -0,0 +1,527 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+/* Browser-related callbacks */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include "utils/utils.h"
+#include "utils/ring.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "desktop/mouse.h"
+#include "desktop/gui_window.h"
+#include "desktop/browser.h"
+#include "desktop/plotters.h"
+#include "content/hlcache.h"
+
+#include "monkey/browser.h"
+#include "monkey/plot.h"
+
+static uint32_t win_ctr = 0;
+
+static struct gui_window *gw_ring = NULL;
+
+/* exported function documented in monkey/browser.h */
+nserror monkey_warn_user(const char *warning, const char *detail)
+{
+ fprintf(stderr, "WARN %s %s\n", warning, detail);
+ return NSERROR_OK;
+}
+
+struct gui_window *
+monkey_find_window_by_num(uint32_t win_num)
+{
+ struct gui_window *ret = NULL;
+
+ RING_ITERATE_START(struct gui_window, gw_ring, c_ring) {
+ if (c_ring->win_num == win_num) {
+ ret = c_ring;
+ RING_ITERATE_STOP(gw_ring, c_ring);
+ }
+ } RING_ITERATE_END(gw_ring, c_ring);
+
+ return ret;
+}
+
+
+/**
+ * callback from core to reformat a window.
+ */
+static void monkey_window_reformat(struct gui_window *gw)
+{
+ browser_window_reformat(gw->bw, false, gw->width, gw->height);
+}
+
+void
+monkey_kill_browser_windows(void)
+{
+ while (gw_ring != NULL) {
+ browser_window_destroy(gw_ring->bw);
+ }
+}
+
+static struct gui_window *
+gui_window_create(struct browser_window *bw,
+ struct gui_window *existing,
+ gui_window_create_flags flags)
+{
+ struct gui_window *ret = calloc(sizeof(*ret), 1);
+ if (ret == NULL)
+ return NULL;
+
+ ret->win_num = win_ctr++;
+ ret->bw = bw;
+
+ ret->width = 800;
+ ret->height = 600;
+
+ fprintf(stdout, "WINDOW NEW WIN %u FOR %p EXISTING %p NEWTAB %s CLONE %s\n",
+ ret->win_num, bw, existing, flags & GW_CREATE_TAB ? "TRUE" : "FALSE",
+ flags & GW_CREATE_CLONE ? "TRUE" : "FALSE");
+ fprintf(stdout, "WINDOW SIZE WIN %u WIDTH %d HEIGHT %d\n",
+ ret->win_num, ret->width, ret->height);
+
+ RING_INSERT(gw_ring, ret);
+
+ return ret;
+}
+
+static void
+gui_window_destroy(struct gui_window *g)
+{
+ fprintf(stdout, "WINDOW DESTROY WIN %u\n", g->win_num);
+ RING_REMOVE(gw_ring, g);
+ free(g);
+}
+
+static void
+gui_window_set_title(struct gui_window *g, const char *title)
+{
+ fprintf(stdout, "WINDOW TITLE WIN %u STR %s\n", g->win_num, title);
+}
+
+static void
+gui_window_redraw_window(struct gui_window *g)
+{
+ fprintf(stdout, "WINDOW REDRAW WIN %u\n", g->win_num);
+}
+
+static void
+gui_window_get_dimensions(struct gui_window *g, int *width, int *height,
+ bool scaled)
+{
+ fprintf(stdout, "WINDOW GET_DIMENSIONS WIN %u WIDTH %d HEIGHT %d\n",
+ g->win_num, g->width, g->height);
+ *width = g->width;
+ *height = g->height;
+}
+
+static void
+gui_window_new_content(struct gui_window *g)
+{
+ fprintf(stdout, "WINDOW NEW_CONTENT WIN %u\n", g->win_num);
+}
+
+static void
+gui_window_set_icon(struct gui_window *g, hlcache_handle *icon)
+{
+ fprintf(stdout, "WINDOW NEW_ICON WIN %u\n", g->win_num);
+}
+
+static void
+gui_window_start_throbber(struct gui_window *g)
+{
+ fprintf(stdout, "WINDOW START_THROBBER WIN %u\n", g->win_num);
+}
+
+static void
+gui_window_stop_throbber(struct gui_window *g)
+{
+ fprintf(stdout, "WINDOW STOP_THROBBER WIN %u\n", g->win_num);
+}
+
+static void
+gui_window_set_scroll(struct gui_window *g, int sx, int sy)
+{
+ g->scrollx = sx;
+ g->scrolly = sy;
+ fprintf(stdout, "WINDOW SET_SCROLL WIN %u X %d Y %d\n", g->win_num, sx, sy);
+}
+
+static void
+gui_window_update_box(struct gui_window *g, const struct rect *rect)
+{
+ fprintf(stdout, "WINDOW UPDATE_BOX WIN %u X %d Y %d WIDTH %d HEIGHT %d\n",
+ g->win_num, rect->x0, rect->y0,
+ (rect->x1 - rect->x0), (rect->y1 - rect->y0));
+
+}
+
+static void
+gui_window_update_extent(struct gui_window *g)
+{
+ int width, height;
+
+ if (browser_window_get_extents(g->bw, false, &width, &height) != NSERROR_OK)
+ return;
+
+ fprintf(stdout, "WINDOW UPDATE_EXTENT WIN %u WIDTH %d HEIGHT %d\n",
+ g->win_num, width, height);
+}
+
+static void
+gui_window_set_status(struct gui_window *g, const char *text)
+{
+ fprintf(stdout, "WINDOW SET_STATUS WIN %u STR %s\n", g->win_num, text);
+}
+
+static void
+gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape)
+{
+ const char *ptr_name = "UNKNOWN";
+
+ switch (shape) {
+ case GUI_POINTER_POINT:
+ ptr_name = "POINT";
+ break;
+ case GUI_POINTER_CARET:
+ ptr_name = "CARET";
+ break;
+ case GUI_POINTER_UP:
+ ptr_name = "UP";
+ break;
+ case GUI_POINTER_DOWN:
+ ptr_name = "DOWN";
+ break;
+ case GUI_POINTER_LEFT:
+ ptr_name = "LEFT";
+ break;
+ case GUI_POINTER_RIGHT:
+ ptr_name = "RIGHT";
+ break;
+ case GUI_POINTER_LD:
+ ptr_name = "LD";
+ break;
+ case GUI_POINTER_RD:
+ ptr_name = "RD";
+ break;
+ case GUI_POINTER_LU:
+ ptr_name = "LU";
+ break;
+ case GUI_POINTER_RU:
+ ptr_name = "RU";
+ break;
+ case GUI_POINTER_CROSS:
+ ptr_name = "CROSS";
+ break;
+ case GUI_POINTER_MOVE:
+ ptr_name = "MOVE";
+ break;
+ case GUI_POINTER_WAIT:
+ ptr_name = "WAIT";
+ break;
+ case GUI_POINTER_HELP:
+ ptr_name = "HELP";
+ break;
+ case GUI_POINTER_MENU:
+ ptr_name = "MENU";
+ break;
+ case GUI_POINTER_PROGRESS:
+ ptr_name = "PROGRESS";
+ break;
+ case GUI_POINTER_NO_DROP:
+ ptr_name = "NO_DROP";
+ break;
+ case GUI_POINTER_NOT_ALLOWED:
+ ptr_name = "NOT_ALLOWED";
+ break;
+ case GUI_POINTER_DEFAULT:
+ ptr_name = "DEFAULT";
+ break;
+ default:
+ break;
+ }
+ fprintf(stdout, "WINDOW SET_POINTER WIN %u POINTER %s\n", g->win_num, ptr_name);
+}
+
+static nserror
+gui_window_set_url(struct gui_window *g, nsurl *url)
+{
+ fprintf(stdout, "WINDOW SET_URL WIN %u URL %s\n", g->win_num, nsurl_access(url));
+ return NSERROR_OK;
+}
+
+static bool
+gui_window_get_scroll(struct gui_window *g, int *sx, int *sy)
+{
+ fprintf(stdout, "WINDOW GET_SCROLL WIN %u X %d Y %d\n",
+ g->win_num, g->scrollx, g->scrolly);
+ *sx = g->scrollx;
+ *sy = g->scrolly;
+ return true;
+}
+
+static bool
+gui_window_scroll_start(struct gui_window *g)
+{
+ fprintf(stdout, "WINDOW SCROLL_START WIN %u\n", g->win_num);
+ g->scrollx = g->scrolly = 0;
+ return true;
+}
+
+static void
+gui_window_scroll_visible(struct gui_window *g, int x0, int y0,
+ int x1, int y1)
+{
+ fprintf(stdout, "WINDOW SCROLL_VISIBLE WIN %u X0 %d Y0 %d X1 %d Y1 %d\n",
+ g->win_num, x0, y0, x1, y1);
+}
+
+static void
+gui_window_place_caret(struct gui_window *g, int x, int y, int height,
+ const struct rect *clip)
+{
+ fprintf(stdout, "WINDOW PLACE_CARET WIN %u X %d Y %d HEIGHT %d\n",
+ g->win_num, x, y, height);
+}
+
+static void
+gui_window_remove_caret(struct gui_window *g)
+{
+ fprintf(stdout, "WINDOW REMOVE_CARET WIN %u\n", g->win_num);
+}
+
+static bool
+gui_window_drag_start(struct gui_window *g, gui_drag_type type,
+ const struct rect *rect)
+{
+ fprintf(stdout, "WINDOW SCROLL_START WIN %u TYPE %i\n", g->win_num, type);
+ return false;
+}
+
+static nserror
+gui_window_save_link(struct gui_window *g, nsurl *url, const char *title)
+{
+ fprintf(stdout, "WINDOW SAVE_LINK WIN %u URL %s TITLE %s\n",
+ g->win_num, nsurl_access(url), title);
+ return NSERROR_OK;
+}
+
+
+
+/**** Handlers ****/
+
+static void
+monkey_window_handle_new(int argc, char **argv)
+{
+ nsurl *url = NULL;
+ nserror error = NSERROR_OK;
+
+ if (argc > 3)
+ return;
+
+ if (argc == 3) {
+ error = nsurl_create(argv[2], &url);
+ }
+ if (error == NSERROR_OK) {
+ error = browser_window_create(BW_CREATE_HISTORY,
+ url,
+ NULL,
+ NULL,
+ NULL);
+ if (url != NULL) {
+ nsurl_unref(url);
+ }
+ }
+ if (error != NSERROR_OK) {
+ monkey_warn_user(messages_get_errorcode(error), 0);
+ }
+}
+
+static void
+monkey_window_handle_destroy(int argc, char **argv)
+{
+ struct gui_window *gw;
+ uint32_t nr = atoi((argc > 2) ? argv[2] : "-1");
+
+ gw = monkey_find_window_by_num(nr);
+
+ if (gw == NULL) {
+ fprintf(stdout, "ERROR WINDOW NUM BAD\n");
+ } else {
+ browser_window_destroy(gw->bw);
+ }
+}
+
+static void
+monkey_window_handle_go(int argc, char **argv)
+{
+ struct gui_window *gw;
+ nsurl *url;
+ nsurl *ref_url = NULL;
+ nserror error;
+
+ if (argc < 4 || argc > 5) {
+ fprintf(stdout, "ERROR WINDOW GO ARGS BAD\n");
+ return;
+ }
+
+ gw = monkey_find_window_by_num(atoi(argv[2]));
+
+ if (gw == NULL) {
+ fprintf(stdout, "ERROR WINDOW NUM BAD\n");
+ return;
+ }
+
+ error = nsurl_create(argv[3], &url);
+ if (error == NSERROR_OK) {
+ if (argc == 5) {
+ error = nsurl_create(argv[4], &ref_url);
+ }
+
+ if (error == NSERROR_OK) {
+ error = browser_window_navigate(gw->bw,
+ url,
+ ref_url,
+ BW_NAVIGATE_HISTORY,
+ NULL,
+ NULL,
+ NULL);
+ if (ref_url != NULL) {
+ nsurl_unref(ref_url);
+ }
+ }
+ nsurl_unref(url);
+ }
+
+ if (error != NSERROR_OK) {
+ monkey_warn_user(messages_get_errorcode(error), 0);
+ }
+}
+
+static void
+monkey_window_handle_redraw(int argc, char **argv)
+{
+ struct gui_window *gw;
+ struct rect clip;
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = monkey_plotters
+ };
+
+ if (argc != 3 && argc != 7) {
+ fprintf(stdout, "ERROR WINDOW REDRAW ARGS BAD\n");
+ return;
+ }
+
+ gw = monkey_find_window_by_num(atoi(argv[2]));
+
+ if (gw == NULL) {
+ fprintf(stdout, "ERROR WINDOW NUM BAD\n");
+ return;
+ }
+
+ clip.x0 = 0;
+ clip.y0 = 0;
+ clip.x1 = gw->width;
+ clip.y1 = gw->height;
+
+ if (argc == 7) {
+ clip.x0 = atoi(argv[3]);
+ clip.y0 = atoi(argv[4]);
+ clip.x1 = atoi(argv[5]);
+ clip.y1 = atoi(argv[6]);
+ }
+
+ LOG("Issue redraw");
+ fprintf(stdout, "WINDOW REDRAW WIN %d START\n", atoi(argv[2]));
+ browser_window_redraw(gw->bw, gw->scrollx, gw->scrolly, &clip, &ctx);
+ fprintf(stdout, "WINDOW REDRAW WIN %d STOP\n", atoi(argv[2]));
+}
+
+static void
+monkey_window_handle_reload(int argc, char **argv)
+{
+ struct gui_window *gw;
+ if (argc != 3 && argc != 4) {
+ fprintf(stdout, "ERROR WINDOW RELOAD ARGS BAD\n");
+ }
+
+ gw = monkey_find_window_by_num(atoi(argv[2]));
+
+ if (gw == NULL) {
+ fprintf(stdout, "ERROR WINDOW NUM BAD\n");
+ } else {
+ browser_window_reload(gw->bw, argc == 4);
+ }
+}
+
+
+void
+monkey_window_handle_command(int argc, char **argv)
+{
+ if (argc == 1)
+ return;
+
+ if (strcmp(argv[1], "NEW") == 0) {
+ monkey_window_handle_new(argc, argv);
+ } else if (strcmp(argv[1], "DESTROY") == 0) {
+ monkey_window_handle_destroy(argc, argv);
+ } else if (strcmp(argv[1], "GO") == 0) {
+ monkey_window_handle_go(argc, argv);
+ } else if (strcmp(argv[1], "REDRAW") == 0) {
+ monkey_window_handle_redraw(argc, argv);
+ } else if (strcmp(argv[1], "RELOAD") == 0) {
+ monkey_window_handle_reload(argc, argv);
+ } else {
+ fprintf(stdout, "ERROR WINDOW COMMAND UNKNOWN %s\n", argv[1]);
+ }
+
+}
+
+static struct gui_window_table window_table = {
+ .create = gui_window_create,
+ .destroy = gui_window_destroy,
+ .redraw = gui_window_redraw_window,
+ .update = gui_window_update_box,
+ .get_scroll = gui_window_get_scroll,
+ .set_scroll = gui_window_set_scroll,
+ .get_dimensions = gui_window_get_dimensions,
+ .update_extent = gui_window_update_extent,
+ .reformat = monkey_window_reformat,
+
+ .set_title = gui_window_set_title,
+ .set_url = gui_window_set_url,
+ .set_icon = gui_window_set_icon,
+ .set_status = gui_window_set_status,
+ .set_pointer = gui_window_set_pointer,
+ .place_caret = gui_window_place_caret,
+ .remove_caret = gui_window_remove_caret,
+ .drag_start = gui_window_drag_start,
+ .save_link = gui_window_save_link,
+ .scroll_visible = gui_window_scroll_visible,
+ .scroll_start = gui_window_scroll_start,
+ .new_content = gui_window_new_content,
+ .start_throbber = gui_window_start_throbber,
+ .stop_throbber = gui_window_stop_throbber,
+};
+
+struct gui_window_table *monkey_window_table = &window_table;
diff --git a/frontends/monkey/browser.h b/frontends/monkey/browser.h
new file mode 100644
index 000000000..32572742a
--- /dev/null
+++ b/frontends/monkey/browser.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#ifndef NETSURF_MONKEY_BROWSER_H
+#define NETSURF_MONKEY_BROWSER_H
+
+extern struct gui_window_table *monkey_window_table;
+extern struct gui_download_table *monkey_download_table;
+
+struct gui_window {
+ struct gui_window *r_next;
+ struct gui_window *r_prev;
+
+ uint32_t win_num;
+ struct browser_window *bw;
+
+ int width, height;
+ int scrollx, scrolly;
+
+ char *host; /* Ignore this, it's in case RING*() gets debugging for fetchers */
+
+};
+
+struct gui_window *monkey_find_window_by_num(uint32_t win_num);
+struct gui_window *monkey_find_window_by_content(hlcache_handle *content);
+void monkey_window_process_reformats(void);
+
+void monkey_window_handle_command(int argc, char **argv);
+void monkey_kill_browser_windows(void);
+
+nserror monkey_warn_user(const char *warning, const char *detail);
+
+#endif /* NETSURF_MONKEY_BROWSER_H */
diff --git a/frontends/monkey/cert.c b/frontends/monkey/cert.c
new file mode 100644
index 000000000..ec1b1ce43
--- /dev/null
+++ b/frontends/monkey/cert.c
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "utils/ring.h"
+#include "utils/nsurl.h"
+
+#include "monkey/cert.h"
+
+typedef struct monkey_cert {
+ struct monkey_cert *r_next, *r_prev;
+ uint32_t num;
+ char *host; /* Ignore */
+ nserror (*cb)(bool,void*);
+ void *pw;
+} monkey_cert_t;
+
+static monkey_cert_t *cert_ring = NULL;
+static uint32_t cert_ctr = 0;
+
+void
+gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
+ unsigned long num, nserror (*cb)(bool proceed, void *pw),
+ void *cbpw)
+{
+ monkey_cert_t *m4t = calloc(sizeof(*m4t), 1);
+ if (m4t == NULL) {
+ cb(false, cbpw);
+ return;
+ }
+ m4t->cb = cb;
+ m4t->pw = cbpw;
+ m4t->num = cert_ctr++;
+
+ RING_INSERT(cert_ring, m4t);
+
+ fprintf(stdout, "SSLCERT VERIFY CERT %u URL %s\n",
+ m4t->num, nsurl_access(url));
+}
+
+
diff --git a/frontends/monkey/cert.h b/frontends/monkey/cert.h
new file mode 100644
index 000000000..283817f3d
--- /dev/null
+++ b/frontends/monkey/cert.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2012 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/>.
+ */
+
+#ifndef _NETSURF_MONKEY_CERT_H_
+#define _NETSURF_MONKEY_CERT_H_
+
+struct ssl_cert_info;
+
+void gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs,
+ unsigned long num, nserror (*cb)(bool proceed, void *pw),
+ void *cbpw);
+
+#endif
diff --git a/frontends/monkey/dispatch.c b/frontends/monkey/dispatch.c
new file mode 100644
index 000000000..563534d64
--- /dev/null
+++ b/frontends/monkey/dispatch.c
@@ -0,0 +1,105 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "utils/log.h"
+#include "utils/utils.h"
+#include "utils/ring.h"
+
+#include "monkey/dispatch.h"
+
+typedef struct cmdhandler {
+ struct cmdhandler *r_next, *r_prev;
+ const char *cmd;
+ handle_command_fn fn;
+} monkey_cmdhandler_t;
+
+static monkey_cmdhandler_t *handler_ring = NULL;
+
+nserror
+monkey_register_handler(const char *cmd, handle_command_fn fn)
+{
+ monkey_cmdhandler_t *ret = calloc(sizeof(*ret), 1);
+ if (ret == NULL) {
+ LOG("Unable to allocate handler");
+ return NSERROR_NOMEM;
+ }
+ ret->cmd = strdup(cmd);
+ ret->fn = fn;
+ RING_INSERT(handler_ring, ret);
+ return NSERROR_OK;
+}
+
+void
+monkey_process_command(void)
+{
+ char buffer[PATH_MAX];
+ int argc = 0;
+ char **argv = NULL;
+ char *p, *r = NULL;
+ handle_command_fn fn = NULL;
+ char **nargv;
+
+ if (fgets(buffer, PATH_MAX, stdin) == NULL) {
+ /* end of input or read error so issue QUIT */
+ sprintf(buffer, "QUIT\n");
+ }
+
+ /* remove newline */
+ buffer[strlen(buffer) - 1] = '\0';
+
+ argv = malloc(sizeof *argv);
+ if (argv == NULL) {
+ return;
+ }
+ argc = 1;
+ *argv = buffer;
+
+ for (p = r = buffer; *p != '\0'; p++) {
+ if (*p == ' ') {
+ nargv = realloc(argv, sizeof(*argv) * (argc + 1));
+ if (nargv == NULL) {
+ /* reallocation of argument vector failed, try using what is
+ * already processed.
+ */
+ break;
+ } else {
+ argv = nargv;
+ }
+ argv[argc++] = r = p + 1;
+ *p = '\0';
+ }
+ }
+
+ RING_ITERATE_START(monkey_cmdhandler_t, handler_ring, handler) {
+ if (strcmp(argv[0], handler->cmd) == 0) {
+ fn = handler->fn;
+ RING_ITERATE_STOP(handler_ring, handler);
+ }
+ } RING_ITERATE_END(handler_ring, handler);
+
+ if (fn != NULL) {
+ fn(argc, argv);
+ }
+
+ free(argv);
+}
diff --git a/frontends/monkey/dispatch.h b/frontends/monkey/dispatch.h
new file mode 100644
index 000000000..dc6e50a0b
--- /dev/null
+++ b/frontends/monkey/dispatch.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#ifndef NETSURF_MONKEY_DISPATCH_H
+#define NETSURF_MONKEY_DISPATCH_H 1
+
+typedef void (*handle_command_fn)(int argc, char **argv);
+
+nserror monkey_register_handler(const char *cmd, handle_command_fn fn);
+
+void monkey_process_command(void);
+
+#endif /* NETSURF_MONKEY_DISPATCH_H */
diff --git a/frontends/monkey/download.c b/frontends/monkey/download.c
new file mode 100644
index 000000000..242136662
--- /dev/null
+++ b/frontends/monkey/download.c
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+
+#include "utils/errors.h"
+#include "utils/ring.h"
+#include "desktop/gui_download.h"
+#include "desktop/download.h"
+#include "content/hlcache.h"
+
+#include "monkey/browser.h"
+
+static uint32_t dwin_ctr = 0;
+
+struct gui_download_window {
+ struct gui_download_window *r_next;
+ struct gui_download_window *r_prev;
+ struct gui_window *g;
+ uint32_t dwin_num;
+ char *host; /* ignore */
+};
+
+static struct gui_download_window *dw_ring = NULL;
+
+static struct gui_download_window *
+gui_download_window_create(download_context *ctx,
+ struct gui_window *parent)
+{
+ struct gui_download_window *ret = calloc(sizeof(*ret), 1);
+ if (ret == NULL)
+ return NULL;
+ ret->g = parent;
+ ret->dwin_num = dwin_ctr++;
+
+ RING_INSERT(dw_ring, ret);
+
+ fprintf(stdout, "DOWNLOAD_WINDOW CREATE DWIN %u WIN %u\n",
+ ret->dwin_num, parent->win_num);
+
+ return ret;
+}
+
+static nserror
+gui_download_window_data(struct gui_download_window *dw,
+ const char *data, unsigned int size)
+{
+ fprintf(stdout, "DOWNLOAD_WINDOW DATA DWIN %u SIZE %u DATA %s\n",
+ dw->dwin_num, size, data);
+ return NSERROR_OK;
+}
+
+static void
+gui_download_window_error(struct gui_download_window *dw,
+ const char *error_msg)
+{
+ fprintf(stdout, "DOWNLOAD_WINDOW ERROR DWIN %u ERROR %s\n",
+ dw->dwin_num, error_msg);
+}
+
+static void
+gui_download_window_done(struct gui_download_window *dw)
+{
+ fprintf(stdout, "DOWNLOAD_WINDOW DONE DWIN %u\n",
+ dw->dwin_num);
+ RING_REMOVE(dw_ring, dw);
+ free(dw);
+}
+
+static struct gui_download_table download_table = {
+ .create = gui_download_window_create,
+ .data = gui_download_window_data,
+ .error = gui_download_window_error,
+ .done = gui_download_window_done,
+};
+
+struct gui_download_table *monkey_download_table = &download_table;
diff --git a/frontends/monkey/fetch.c b/frontends/monkey/fetch.c
new file mode 100644
index 000000000..86732cfce
--- /dev/null
+++ b/frontends/monkey/fetch.c
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2014 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/>.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdbool.h>
+#include <limits.h>
+
+#include "utils/errors.h"
+#include "utils/file.h"
+#include "utils/nsurl.h"
+#include "utils/filepath.h"
+#include "desktop/gui_fetch.h"
+
+#include "monkey/filetype.h"
+#include "monkey/fetch.h"
+
+extern char **respaths;
+
+
+static nsurl *gui_get_resource_url(const char *path)
+{
+ char buf[PATH_MAX];
+ nsurl *url = NULL;
+
+ netsurf_path_to_nsurl(filepath_sfind(respaths, buf, path), &url);
+
+ return url;
+}
+
+static struct gui_fetch_table fetch_table = {
+ .filetype = monkey_fetch_filetype,
+
+ .get_resource_url = gui_get_resource_url,
+};
+
+struct gui_fetch_table *monkey_fetch_table = &fetch_table;
diff --git a/frontends/monkey/fetch.h b/frontends/monkey/fetch.h
new file mode 100644
index 000000000..f146e2ef8
--- /dev/null
+++ b/frontends/monkey/fetch.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2014 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/>.
+ */
+
+#ifndef NS_MONKEY_FETCH_H
+#define NS_MONKEY_FETCH_H
+
+struct gui_fetch_table *monkey_fetch_table;
+
+#endif /* NS_MONKEY_FETCH_H */
diff --git a/frontends/monkey/filetype.c b/frontends/monkey/filetype.c
new file mode 100644
index 000000000..d5517bf06
--- /dev/null
+++ b/frontends/monkey/filetype.c
@@ -0,0 +1,215 @@
+/*
+ * Copyright 2007 Rob Kendrick <rjek@netsurf-browser.org>
+ * Copyright 2007 Vincent Sanders <vince@debian.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/>.
+ */
+
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "content/fetch.h"
+#include "utils/log.h"
+#include "utils/hashtable.h"
+
+#include "monkey/filetype.h"
+
+static struct hash_table *mime_hash = NULL;
+
+void monkey_fetch_filetype_init(const char *mimefile)
+{
+ struct stat statbuf;
+ FILE *fh = NULL;
+
+ mime_hash = hash_create(117);
+
+ /* first, check to see if /etc/mime.types in preference */
+
+ if ((stat("/etc/mime.types", &statbuf) == 0) &&
+ S_ISREG(statbuf.st_mode)) {
+ mimefile = "/etc/mime.types";
+
+ }
+
+ fh = fopen(mimefile, "r");
+
+ /* Some OSes (mentioning no Solarises) have a worthlessly tiny
+ * /etc/mime.types that don't include essential things, so we
+ * pre-seed our hash with the essentials. These will get
+ * over-ridden if they are mentioned in the mime.types file.
+ */
+
+ hash_add(mime_hash, "css", "text/css");
+ hash_add(mime_hash, "htm", "text/html");
+ hash_add(mime_hash, "html", "text/html");
+ hash_add(mime_hash, "jpg", "image/jpeg");
+ hash_add(mime_hash, "jpeg", "image/jpeg");
+ hash_add(mime_hash, "gif", "image/gif");
+ hash_add(mime_hash, "png", "image/png");
+ hash_add(mime_hash, "jng", "image/jng");
+ hash_add(mime_hash, "mng", "image/mng");
+ hash_add(mime_hash, "webp", "image/webp");
+ hash_add(mime_hash, "spr", "image/x-riscos-sprite");
+
+ if (fh == NULL) {
+ LOG("Unable to open a mime.types file, so using a minimal one for you.");
+ return;
+ }
+
+ while (!feof(fh)) {
+ char line[256], *ptr, *type, *ext;
+ if (fgets(line, 256, fh) == NULL)
+ break;
+ if (!feof(fh) && line[0] != '#') {
+ ptr = line;
+
+ /* search for the first non-whitespace character */
+ while (isspace(*ptr))
+ ptr++;
+
+ /* is this line empty other than leading whitespace? */
+ if (*ptr == '\n' || *ptr == '\0')
+ continue;
+
+ type = ptr;
+
+ /* search for the first non-whitespace char or NUL or
+ * NL */
+ while (*ptr && (!isspace(*ptr)) && *ptr != '\n')
+ ptr++;
+
+ if (*ptr == '\0' || *ptr == '\n') {
+ /* this mimetype has no extensions - read next
+ * line.
+ */
+ continue;
+ }
+
+ *ptr++ = '\0';
+
+ /* search for the first non-whitespace character which
+ * will be the first filename extenion */
+ while (isspace(*ptr))
+ ptr++;
+
+ while(true) {
+ ext = ptr;
+
+ /* search for the first whitespace char or
+ * NUL or NL which is the end of the ext.
+ */
+ while (*ptr && (!isspace(*ptr)) &&
+ *ptr != '\n')
+ ptr++;
+
+ if (*ptr == '\0' || *ptr == '\n') {
+ /* special case for last extension on
+ * the line
+ */
+ *ptr = '\0';
+ hash_add(mime_hash, ext, type);
+ break;
+ }
+
+ *ptr++ = '\0';
+ hash_add(mime_hash, ext, type);
+
+ /* search for the first non-whitespace char or
+ * NUL or NL, to find start of next ext.
+ */
+ while (*ptr && (isspace(*ptr)) && *ptr != '\n')
+ ptr++;
+ }
+ }
+ }
+
+ fclose(fh);
+}
+
+void monkey_fetch_filetype_fin(void)
+{
+ hash_destroy(mime_hash);
+}
+
+/**
+ * Determine the MIME type of a local file.
+ *
+ * @note used in file fetcher
+ *
+ * \param unix_path Unix style path to file on disk
+ * \return Pointer to static MIME type string (should not be freed) not NULL.
+ * invalidated on next call to fetch_filetype.
+ */
+const char *monkey_fetch_filetype(const char *unix_path)
+{
+ struct stat statbuf;
+ char *ext;
+ const char *ptr;
+ char *lowerchar;
+ const char *type;
+ int l;
+
+ if (stat(unix_path, &statbuf) != 0) {
+ /* error calling stat, the file has probably become
+ * inacessible, this routine cannot fail so just
+ * return the default mime type.
+ */
+ return "text/plain";
+ }
+ if (S_ISDIR(statbuf.st_mode)) {
+ return "application/x-netsurf-directory";
+ }
+
+ l = strlen(unix_path);
+ if ((3 < l) && (strcasecmp(unix_path + l - 4, ",f79") == 0)) {
+ return "text/css";
+ }
+
+ if (strchr(unix_path, '.') == NULL) {
+ /* no extension anywhere! */
+ return "text/plain";
+ }
+
+ ptr = unix_path + strlen(unix_path);
+ while (*ptr != '.' && *ptr != '/')
+ ptr--;
+
+ if (*ptr != '.') {
+ return "text/plain";
+ }
+
+ ext = strdup(ptr + 1); /* skip the . */
+
+ /* the hash table only contains lower-case versions - make sure this
+ * copy is lower case too.
+ */
+ lowerchar = ext;
+ while(*lowerchar) {
+ *lowerchar = tolower(*lowerchar);
+ lowerchar++;
+ }
+
+ type = hash_get(mime_hash, ext);
+ free(ext);
+
+ return type != NULL ? type : "text/plain";
+}
diff --git a/frontends/monkey/filetype.h b/frontends/monkey/filetype.h
new file mode 100644
index 000000000..6c16db01b
--- /dev/null
+++ b/frontends/monkey/filetype.h
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2007 Rob Kendrick <rjek@netsurf-browser.org>
+ * Copyright 2007 Vincent Sanders <vince@debian.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/>.
+ */
+
+void monkey_fetch_filetype_init(const char *mimefile);
+void monkey_fetch_filetype_fin(void);
+const char *monkey_fetch_filetype(const char *unix_path);
diff --git a/frontends/monkey/layout.c b/frontends/monkey/layout.c
new file mode 100644
index 000000000..401ca158c
--- /dev/null
+++ b/frontends/monkey/layout.c
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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
+ * monkey implementation of font layout.
+ */
+
+#include <stddef.h>
+
+#include "utils/utf8.h"
+#include "desktop/plot_style.h"
+#include "desktop/gui_layout.h"
+
+#include "monkey/layout.h"
+
+static nserror nsfont_width(const plot_font_style_t *fstyle,
+ const char *string, size_t length,
+ int *width)
+{
+ *width = (fstyle->size * utf8_bounded_length(string, length)) / FONT_SIZE_SCALE;
+ return NSERROR_OK;
+}
+
+/**
+ * Find the position in a string where an x coordinate falls.
+ *
+ * \param fstyle style for this text
+ * \param string UTF-8 string to measure
+ * \param length length of string
+ * \param x x coordinate to search for
+ * \param char_offset updated to offset in string of actual_x, [0..length]
+ * \param actual_x updated to x coordinate of character closest to x
+ * \return true on success, false on error and error reported
+ */
+
+static nserror nsfont_position_in_string(const plot_font_style_t *fstyle,
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
+{
+ *char_offset = x / (fstyle->size / FONT_SIZE_SCALE);
+ if (*char_offset > length)
+ *char_offset = length;
+ *actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE);
+ return NSERROR_OK;
+}
+
+
+/**
+ * Find where to split a string to make it fit a width.
+ *
+ * \param fstyle style for this text
+ * \param string UTF-8 string to measure
+ * \param length length of string, in bytes
+ * \param x width available
+ * \param char_offset updated to offset in string of actual_x, [1..length]
+ * \param actual_x updated to x coordinate of character closest to x
+ * \return true on success, false on error and error reported
+ *
+ * On exit, char_offset indicates first character after split point.
+ *
+ * Note: char_offset of 0 should never be returned.
+ *
+ * Returns:
+ * char_offset giving split point closest to x, where actual_x <= x
+ * else
+ * char_offset giving split point closest to x, where actual_x > x
+ *
+ * Returning char_offset == length means no split possible
+ */
+
+static nserror nsfont_split(const plot_font_style_t *fstyle,
+ const char *string, size_t length,
+ int x, size_t *char_offset, int *actual_x)
+{
+ int c_off = *char_offset = x / (fstyle->size / FONT_SIZE_SCALE);
+ if (*char_offset > length) {
+ *char_offset = length;
+ } else {
+ while (*char_offset > 0) {
+ if (string[*char_offset] == ' ')
+ break;
+ (*char_offset)--;
+ }
+ if (*char_offset == 0) {
+ *char_offset = c_off;
+ while (*char_offset < length && string[*char_offset] != ' ') {
+ (*char_offset)++;
+ }
+ }
+ }
+ *actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE);
+ return NSERROR_OK;
+}
+
+static struct gui_layout_table layout_table = {
+ .width = nsfont_width,
+ .position = nsfont_position_in_string,
+ .split = nsfont_split,
+};
+
+struct gui_layout_table *monkey_layout_table = &layout_table;
diff --git a/frontends/monkey/layout.h b/frontends/monkey/layout.h
new file mode 100644
index 000000000..1e713c27f
--- /dev/null
+++ b/frontends/monkey/layout.h
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2016 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/>.
+ */
+
+#ifndef NS_MONKEY_LAYOUT_H
+#define NS_MONKEY_LAYOUT_H
+
+extern struct gui_layout_table *monkey_layout_table;
+
+#endif /* NS_MONKEY_LAYOUT_H */
diff --git a/frontends/monkey/main.c b/frontends/monkey/main.c
new file mode 100644
index 000000000..ff70bda71
--- /dev/null
+++ b/frontends/monkey/main.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <sys/select.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include "utils/config.h"
+#include "utils/sys_time.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/filepath.h"
+#include "utils/nsoption.h"
+#include "content/urldb.h"
+#include "content/fetchers.h"
+#include "content/fetchers/resource.h"
+#include "content/hlcache.h"
+#include "desktop/gui_misc.h"
+#include "desktop/netsurf.h"
+
+#include "monkey/dispatch.h"
+#include "monkey/browser.h"
+#include "monkey/cert.h"
+#include "monkey/401login.h"
+#include "monkey/filetype.h"
+#include "monkey/fetch.h"
+#include "monkey/schedule.h"
+#include "monkey/bitmap.h"
+#include "monkey/layout.h"
+
+/** maximum number of languages in language vector */
+#define LANGV_SIZE 32
+/** maximum length of all strings in language vector */
+#define LANGS_SIZE 4096
+
+/** resource search path vector */
+char **respaths;
+
+static bool monkey_done = false;
+
+/**
+ * Cause an abnormal program termination.
+ *
+ * \note This never returns and is intended to terminate without any cleanup.
+ *
+ * \param error The message to display to the user.
+ */
+static void die(const char * const error)
+{
+ fprintf(stderr, "DIE %s\n", error);
+ exit(EXIT_FAILURE);
+}
+
+/** obtain language from environment
+ *
+ * start with GNU extension LANGUAGE environment variable and then try
+ * POSIX variables LC_ALL, LC_MESSAGES and LANG
+ *
+ */
+static const char *get_language(void)
+{
+ const char *lang;
+
+ lang = getenv("LANGUAGE");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LC_ALL");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LC_MESSAGES");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ lang = getenv("LANG");
+ if ((lang != NULL) && (lang[0] != '\0')) {
+ return lang;
+ }
+
+ return NULL;
+}
+
+
+/** provide a string vector of languages in preference order
+ *
+ * environment variables are processed to aquire a colon separated
+ * list of languages which are converted into a string vector. The
+ * vector will always have the C language as its last entry.
+ *
+ * This implementation creates an internal static representation of
+ * the vector when first called and returns that for all subsequent
+ * calls. i.e. changing the environment does not change the returned
+ * vector on repeated calls.
+ *
+ * If the environment variables have more than LANGV_SIZE languages or
+ * LANGS_SIZE bytes of data the results list will be curtailed.
+ */
+static const char * const *get_languagev(void)
+{
+ static const char *langv[LANGV_SIZE];
+ int langidx = 0; /* index of next entry in vector */
+ static char langs[LANGS_SIZE];
+ char *curp; /* next language parameter in langs string */
+ const char *lange; /* language from environment variable */
+ int lang_len;
+ char *cln; /* colon in lange */
+
+ /* return cached vector */
+ if (langv[0] != NULL) {
+ return &langv[0];
+ }
+
+ curp = &langs[0];
+
+ lange = get_language();
+
+ if (lange != NULL) {
+ lang_len = strlen(lange) + 1;
+ if (lang_len < (LANGS_SIZE - 2)) {
+ memcpy(curp, lange, lang_len);
+ while ((curp[0] != 0) &&
+ (langidx < (LANGV_SIZE - 2))) {
+ /* avoid using strchrnul as it is not portable */
+ cln = strchr(curp, ':');
+ if (cln == NULL) {
+ langv[langidx++] = curp;
+ curp += lang_len;
+ break;
+ } else {
+ if ((cln - curp) > 1) {
+ /* only place non empty entries in vector */
+ langv[langidx++] = curp;
+ }
+ *cln++ = 0; /* null terminate */
+ lang_len -= (cln - curp);
+ curp = cln;
+ }
+ }
+ }
+ }
+
+ /* ensure C language is present */
+ langv[langidx++] = curp;
+ *curp++ = 'C';
+ *curp++ = 0;
+ langv[langidx] = NULL;
+
+ return &langv[0];
+}
+
+/* Stolen from gtk/gui.c */
+static char **
+nsmonkey_init_resource(const char *resource_path)
+{
+ const char * const *langv;
+ char **pathv; /* resource path string vector */
+ char **respath; /* resource paths vector */
+
+ pathv = filepath_path_to_strvec(resource_path);
+
+ langv = get_languagev();
+
+ respath = filepath_generate(pathv, langv);
+
+ filepath_free_strvec(pathv);
+
+ return respath;
+}
+
+static void monkey_quit(void)
+{
+ urldb_save_cookies(nsoption_charp(cookie_jar));
+ urldb_save(nsoption_charp(url_file));
+ monkey_fetch_filetype_fin();
+}
+
+static nserror gui_launch_url(struct nsurl *url)
+{
+ fprintf(stdout, "GENERIC LAUNCH URL %s\n", nsurl_access(url));
+ return NSERROR_OK;
+}
+
+static void quit_handler(int argc, char **argv)
+{
+ monkey_done = true;
+}
+
+/**
+ * Set option defaults for monkey frontend
+ *
+ * @param defaults The option table to update.
+ * @return error status.
+ */
+static nserror set_defaults(struct nsoption_s *defaults)
+{
+ /* Set defaults for absent option strings */
+ nsoption_setnull_charp(cookie_file, strdup("~/.netsurf/Cookies"));
+ nsoption_setnull_charp(cookie_jar, strdup("~/.netsurf/Cookies"));
+ nsoption_setnull_charp(url_file, strdup("~/.netsurf/URLs"));
+
+ return NSERROR_OK;
+}
+
+
+/**
+ * Ensures output logging stream is correctly configured
+ */
+static bool nslog_stream_configure(FILE *fptr)
+{
+ /* set log stream to be non-buffering */
+ setbuf(fptr, NULL);
+
+ return true;
+}
+
+static struct gui_misc_table monkey_misc_table = {
+ .schedule = monkey_schedule,
+ .warning = monkey_warn_user,
+
+ .quit = monkey_quit,
+ .launch_url = gui_launch_url,
+ .cert_verify = gui_cert_verify,
+ .login = gui_401login_open,
+};
+
+static void monkey_run(void)
+{
+ fd_set read_fd_set, write_fd_set, exc_fd_set;
+ int max_fd;
+ int rdy_fd;
+ int schedtm;
+ struct timeval tv;
+ struct timeval* timeout;
+
+ while (!monkey_done) {
+
+ /* clears fdset */
+ fetcher_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd);
+
+ /* add stdin to the set */
+ if (max_fd < 0) {
+ max_fd = 0;
+ }
+ FD_SET(0, &read_fd_set);
+ FD_SET(0, &exc_fd_set);
+
+ /* discover the next scheduled event time */
+ schedtm = monkey_schedule_run();
+
+ /* setup timeout */
+ switch (schedtm) {
+ case -1:
+ LOG("Iterate blocking");
+ fprintf(stdout, "GENERIC POLL BLOCKING\n");
+ timeout = NULL;
+ break;
+
+ case 0:
+ LOG("Iterate immediate");
+ tv.tv_sec = 0;
+ tv.tv_usec = 0;
+ timeout = &tv;
+ break;
+
+ default:
+ LOG("Iterate non-blocking");
+ fprintf(stdout, "GENERIC POLL TIMED\n");
+ tv.tv_sec = schedtm / 1000; /* miliseconds to seconds */
+ tv.tv_usec = (schedtm % 1000) * 1000; /* remainder to microseconds */
+ timeout = &tv;
+ break;
+ }
+
+ rdy_fd = select(max_fd + 1,
+ &read_fd_set,
+ &write_fd_set,
+ &exc_fd_set,
+ timeout);
+ if (rdy_fd < 0) {
+ monkey_done = true;
+ } else if (rdy_fd > 0) {
+ if (FD_ISSET(0, &read_fd_set)) {
+ monkey_process_command();
+ }
+ }
+ }
+
+}
+
+int
+main(int argc, char **argv)
+{
+ char *messages;
+ char *options;
+ char buf[PATH_MAX];
+ nserror ret;
+ struct netsurf_table monkey_table = {
+ .misc = &monkey_misc_table,
+ .window = monkey_window_table,
+ .download = monkey_download_table,
+ .fetch = monkey_fetch_table,
+ .bitmap = monkey_bitmap_table,
+ .layout = monkey_layout_table,
+ };
+
+ ret = netsurf_register(&monkey_table);
+ if (ret != NSERROR_OK) {
+ die("NetSurf operation table failed registration");
+ }
+
+ /* Unbuffer stdin/out/err */
+ setbuf(stdin, NULL);
+ setbuf(stdout, NULL);
+ setbuf(stderr, NULL);
+
+ /* Prep the search paths */
+ respaths = nsmonkey_init_resource("${HOME}/.netsurf/:${NETSURFRES}:"MONKEY_RESPATH":./monkey/res");
+
+ /* initialise logging. Not fatal if it fails but not much we can do
+ * about it either.
+ */
+ nslog_init(nslog_stream_configure, &argc, argv);
+
+ /* user options setup */
+ ret = nsoption_init(set_defaults, &nsoptions, &nsoptions_default);
+ if (ret != NSERROR_OK) {
+ die("Options failed to initialise");
+ }
+ options = filepath_find(respaths, "Choices");
+ nsoption_read(options, nsoptions);
+ free(options);
+ nsoption_commandline(&argc, argv, nsoptions);
+
+ messages = filepath_find(respaths, "Messages");
+ ret = messages_add_from_file(messages);
+ if (ret != NSERROR_OK) {
+ LOG("Messages failed to load");
+ }
+
+ /* common initialisation */
+ ret = netsurf_init(NULL);
+ free(messages);
+ if (ret != NSERROR_OK) {
+ die("NetSurf failed to initialise");
+ }
+
+ filepath_sfinddef(respaths, buf, "mime.types", "/etc/");
+ monkey_fetch_filetype_init(buf);
+
+ urldb_load(nsoption_charp(url_file));
+ urldb_load_cookies(nsoption_charp(cookie_file));
+
+ ret = monkey_register_handler("QUIT", quit_handler);
+ if (ret != NSERROR_OK) {
+ die("quit handler failed to register");
+ }
+
+ ret = monkey_register_handler("WINDOW", monkey_window_handle_command);
+ if (ret != NSERROR_OK) {
+ die("window handler fialed to register");
+ }
+
+ fprintf(stdout, "GENERIC STARTED\n");
+ monkey_run();
+
+ fprintf(stdout, "GENERIC CLOSING_DOWN\n");
+ monkey_kill_browser_windows();
+
+ netsurf_exit();
+ fprintf(stdout, "GENERIC FINISHED\n");
+
+ /* finalise options */
+ nsoption_finalise(nsoptions, nsoptions_default);
+
+ return 0;
+}
diff --git a/frontends/monkey/options.h b/frontends/monkey/options.h
new file mode 100644
index 000000000..57cce7e1f
--- /dev/null
+++ b/frontends/monkey/options.h
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2012 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/>.
+ */
+
+#ifndef _NETSURF_MONKEY_OPTIONS_H_
+#define _NETSURF_MONKEY_OPTIONS_H_
+
+/* currently nothing here */
+
+#endif
+
+NSOPTION_BOOL(render_resample, true)
+NSOPTION_BOOL(downloads_clear, false)
+NSOPTION_BOOL(request_overwrite, true)
+NSOPTION_STRING(downloads_directory, NULL)
+NSOPTION_STRING(url_file, NULL)
+NSOPTION_BOOL(show_single_tab, false)
+NSOPTION_INTEGER(button_type, 0)
+NSOPTION_BOOL(disable_popups, false)
+NSOPTION_BOOL(disable_plugins, false)
+NSOPTION_INTEGER(history_age, 0)
+NSOPTION_BOOL(hover_urls, false)
+NSOPTION_BOOL(focus_new, false)
+NSOPTION_BOOL(new_blank, false)
+NSOPTION_STRING(hotlist_path, NULL)
+NSOPTION_BOOL(source_tab, false)
+NSOPTION_INTEGER(current_theme, 0)
+
+
diff --git a/frontends/monkey/plot.c b/frontends/monkey/plot.c
new file mode 100644
index 000000000..50f812480
--- /dev/null
+++ b/frontends/monkey/plot.c
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2011 Daniel Silverstone <dsilvers@digital-scurf.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/>.
+ */
+
+#include <stdio.h>
+
+#include "utils/utils.h"
+#include "desktop/plotters.h"
+
+static bool
+monkey_plot_disc(int x, int y, int radius, const plot_style_t *style)
+{
+ return true;
+}
+
+static bool
+monkey_plot_arc(int x, int y, int radius, int angle1, int angle2, const plot_style_t *style)
+{
+ return true;
+}
+
+static bool
+monkey_plot_polygon(const int *p, unsigned int n, const plot_style_t *style)
+{
+ return true;
+}
+
+
+static bool
+monkey_plot_text(int x, int y, const char *text, size_t length,
+ const plot_font_style_t *fstyle)
+{
+ fprintf(stdout, "PLOT TEXT X %d Y %d STR %*s\n", x, y, (int)length, text);
+ return true;
+}
+
+static bool
+monkey_plot_bitmap(int x, int y,
+ int width, int height,
+ struct bitmap *bitmap, colour bg,
+ bitmap_flags_t flags)
+{
+ fprintf(stdout, "PLOT BITMAP X %d Y %d WIDTH %d HEIGHT %d\n",
+ x, y, width, height);
+ return true;
+}
+
+static bool
+monkey_plot_rectangle(int x0, int y0, int x1, int y1, const plot_style_t *style)
+{
+ fprintf(stdout, "PLOT RECT X0 %d Y0 %d X1 %d Y1 %d\n",
+ x0, y0, x1, y1);
+ return true;
+}
+
+static bool
+monkey_plot_line(int x0, int y0, int x1, int y1, const plot_style_t *style)
+{
+ fprintf(stdout, "PLOT LINE X0 %d Y0 %d X1 %d Y1 %d\n",
+ x0, y0, x1, y1);
+ return true;
+}
+
+
+static bool
+monkey_plot_path(const float *p,
+ unsigned int n,
+ colour fill,
+ float width,
+ colour c,
+ const float transform[6])
+{
+ return true;
+}
+
+static bool
+monkey_plot_clip(const struct rect *clip)
+{
+ fprintf(stdout, "PLOT CLIP X0 %d Y0 %d X1 %d Y1 %d\n",
+ clip->x0, clip->y0, clip->x1, clip->y1);
+ return true;
+}
+
+static const struct plotter_table plotters = {
+ .clip = monkey_plot_clip,
+ .arc = monkey_plot_arc,
+ .disc = monkey_plot_disc,
+ .line = monkey_plot_line,
+ .rectangle = monkey_plot_rectangle,
+ .polygon = monkey_plot_polygon,
+ .path = monkey_plot_path,
+ .bitmap = monkey_plot_bitmap,
+ .text = monkey_plot_text,
+ .option_knockout = true,
+};
+
+const struct plotter_table* monkey_plotters = &plotters;
diff --git a/frontends/monkey/plot.h b/frontends/monkey/plot.h
new file mode 100644
index 000000000..3632bcf4a
--- /dev/null
+++ b/frontends/monkey/plot.h
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2016 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/>.
+ */
+
+#ifndef NS_MONKEY_PLOT_H
+#define NS_MONKEY_PLOT_H
+
+struct plotter_table;
+
+extern const struct plotter_table *monkey_plotters;
+
+#endif
diff --git a/frontends/monkey/res b/frontends/monkey/res
new file mode 120000
index 000000000..ea9dff35c
--- /dev/null
+++ b/frontends/monkey/res
@@ -0,0 +1 @@
+../gtk/res \ No newline at end of file
diff --git a/frontends/monkey/schedule.c b/frontends/monkey/schedule.c
new file mode 100644
index 000000000..8c638c0b9
--- /dev/null
+++ b/frontends/monkey/schedule.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright 2012 Vincent Sanders <vince@netsurf-browser.co.uk>
+ *
+ * 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/>.
+ */
+
+#include <time.h>
+#include <stdlib.h>
+
+#include "utils/sys_time.h"
+#include "utils/log.h"
+
+#include "monkey/schedule.h"
+
+#ifdef DEBUG_SCHEDULER
+#define SRLOG(x...) LOG(x)
+#else
+#define SRLOG(x...) ((void) 0)
+#endif
+
+/* linked list of scheduled callbacks */
+static struct nscallback *schedule_list = NULL;
+
+/**
+ * scheduled callback.
+ */
+struct nscallback
+{
+ struct nscallback *next;
+ struct timeval tv;
+ void (*callback)(void *p);
+ void *p;
+};
+
+/**
+ * Unschedule a callback.
+ *
+ * \param callback callback function
+ * \param p user parameter, passed to callback function
+ *
+ * All scheduled callbacks matching both callback and p are removed.
+ */
+static nserror schedule_remove(void (*callback)(void *p), void *p)
+{
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+
+ /* check there is something on the list to remove */
+ if (schedule_list == NULL) {
+ return NSERROR_OK;
+ }
+
+ SRLOG("removing %p, %p", callback, p);
+
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+
+ while (cur_nscb != NULL) {
+ if ((cur_nscb->callback == callback) &&
+ (cur_nscb->p == p)) {
+ /* item to remove */
+
+ SRLOG("callback entry %p removing %p(%p)",
+ cur_nscb, cur_nscb->callback, cur_nscb->p);
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+ cur_nscb = unlnk_nscb->next;
+
+ if (prev_nscb == NULL) {
+ schedule_list = cur_nscb;
+ } else {
+ prev_nscb->next = cur_nscb;
+ }
+ free (unlnk_nscb);
+ } else {
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ return NSERROR_OK;
+}
+
+/* exported function documented in framebuffer/schedule.h */
+nserror monkey_schedule(int tival, void (*callback)(void *p), void *p)
+{
+ struct nscallback *nscb;
+ struct timeval tv;
+ nserror ret;
+
+ /* ensure uniqueness of the callback and context */
+ ret = schedule_remove(callback, p);
+ if ((tival < 0) || (ret != NSERROR_OK)) {
+ return ret;
+ }
+
+ SRLOG("Adding %p(%p) in %d", callback, p, tival);
+
+ tv.tv_sec = tival / 1000; /* miliseconds to seconds */
+ tv.tv_usec = (tival % 1000) * 1000; /* remainder to microseconds */
+
+ nscb = calloc(1, sizeof(struct nscallback));
+
+ gettimeofday(&nscb->tv, NULL);
+ timeradd(&nscb->tv, &tv, &nscb->tv);
+
+ nscb->callback = callback;
+ nscb->p = p;
+
+ /* add to list front */
+ nscb->next = schedule_list;
+ schedule_list = nscb;
+
+ return NSERROR_OK;
+}
+
+/* exported function documented in framebuffer/schedule.h */
+int monkey_schedule_run(void)
+{
+ struct timeval tv;
+ struct timeval nexttime;
+ struct timeval rettime;
+ struct nscallback *cur_nscb;
+ struct nscallback *prev_nscb;
+ struct nscallback *unlnk_nscb;
+
+ if (schedule_list == NULL)
+ return -1;
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+
+ gettimeofday(&tv, NULL);
+
+ while (cur_nscb != NULL) {
+ if (timercmp(&tv, &cur_nscb->tv, >)) {
+ /* scheduled time */
+
+ /* remove callback */
+ unlnk_nscb = cur_nscb;
+
+ if (prev_nscb == NULL) {
+ schedule_list = unlnk_nscb->next;
+ } else {
+ prev_nscb->next = unlnk_nscb->next;
+ }
+
+ unlnk_nscb->callback(unlnk_nscb->p);
+
+ free(unlnk_nscb);
+
+ /* need to deal with callback modifying the list. */
+ if (schedule_list == NULL)
+ return -1; /* no more callbacks scheduled */
+
+ /* reset enumeration to the start of the list */
+ cur_nscb = schedule_list;
+ prev_nscb = NULL;
+ nexttime = cur_nscb->tv;
+ } else {
+ /* if the time to the event is sooner than the
+ * currently recorded soonest event record it
+ */
+ if (timercmp(&nexttime, &cur_nscb->tv, >)) {
+ nexttime = cur_nscb->tv;
+ }
+ /* move to next element */
+ prev_nscb = cur_nscb;
+ cur_nscb = prev_nscb->next;
+ }
+ }
+
+ /* make rettime relative to now */
+ timersub(&nexttime, &tv, &rettime);
+
+ SRLOG("returning time to next event as %ldms",
+ (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000));
+
+ /* return next event time in milliseconds (24days max wait) */
+ return (rettime.tv_sec * 1000) + (rettime.tv_usec / 1000);
+}
+
+void monkey_schedule_list(void)
+{
+ struct timeval tv;
+ struct nscallback *cur_nscb;
+
+ gettimeofday(&tv, NULL);
+
+ LOG("schedule list at %lld:%ld", (long long)tv.tv_sec, tv.tv_usec);
+
+ cur_nscb = schedule_list;
+
+ while (cur_nscb != NULL) {
+ LOG("Schedule %p at %lld:%ld",
+ cur_nscb, (long long)cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec);
+ cur_nscb = cur_nscb->next;
+ }
+}
+
+
+/*
+ * Local Variables:
+ * c-basic-offset:2
+ * End:
+ */
diff --git a/frontends/monkey/schedule.h b/frontends/monkey/schedule.h
new file mode 100644
index 000000000..14fad8247
--- /dev/null
+++ b/frontends/monkey/schedule.h
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * 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/>.
+ */
+
+#ifndef NETSURF_MONKEY_SCHEDULE_H
+#define NETSURF_MONKEY_SCHEDULE_H
+
+/**
+ * Schedule a callback.
+ *
+ * \param tival interval before the callback should be made in ms
+ * \param callback callback function
+ * \param p user parameter, passed to callback function
+ *
+ * The callback function will be called as soon as possible after t ms have
+ * passed.
+ */
+
+nserror monkey_schedule(int tival, void (*callback)(void *p), void *p);
+
+/**
+ * Process scheduled callbacks up to current time.
+ *
+ * @return The number of milliseconds untill the next scheduled event
+ * or -1 for no event.
+ */
+int monkey_schedule_run(void);
+
+/**
+ * Log a list of all scheduled callbacks.
+ */
+void monkey_schedule_list(void);
+
+#endif