diff options
Diffstat (limited to 'frontends/monkey')
-rw-r--r-- | frontends/monkey/401login.c | 212 | ||||
-rw-r--r-- | frontends/monkey/401login.h | 38 | ||||
-rw-r--r-- | frontends/monkey/Makefile | 36 | ||||
-rw-r--r-- | frontends/monkey/Makefile.defaults | 1 | ||||
-rw-r--r-- | frontends/monkey/Makefile.tools | 15 | ||||
-rw-r--r-- | frontends/monkey/bitmap.c | 48 | ||||
-rw-r--r-- | frontends/monkey/browser.c | 406 | ||||
-rw-r--r-- | frontends/monkey/cert.c | 59 | ||||
-rw-r--r-- | frontends/monkey/dispatch.c | 13 | ||||
-rw-r--r-- | frontends/monkey/dispatch.h | 2 | ||||
-rw-r--r-- | frontends/monkey/download.c | 16 | ||||
-rw-r--r-- | frontends/monkey/farmer.py | 363 | ||||
-rw-r--r-- | frontends/monkey/fetch.h | 2 | ||||
-rw-r--r-- | frontends/monkey/filetype.c | 10 | ||||
-rw-r--r-- | frontends/monkey/layout.c | 10 | ||||
-rw-r--r-- | frontends/monkey/main.c | 128 | ||||
-rw-r--r-- | frontends/monkey/options.h | 6 | ||||
-rw-r--r-- | frontends/monkey/output.c | 53 | ||||
-rw-r--r-- | frontends/monkey/output.h (renamed from frontends/monkey/cert.h) | 21 | ||||
-rw-r--r-- | frontends/monkey/plot.c | 42 | ||||
-rw-r--r-- | frontends/monkey/schedule.c | 10 |
21 files changed, 847 insertions, 644 deletions
diff --git a/frontends/monkey/401login.c b/frontends/monkey/401login.c index 090f18984..1629425f6 100644 --- a/frontends/monkey/401login.c +++ b/frontends/monkey/401login.c @@ -16,40 +16,208 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include "utils/ring.h" - #include <stdlib.h> #include <stdio.h> +#include <stdint.h> +#include <string.h> +#include "utils/ring.h" +#include "utils/nsurl.h" + +#include "monkey/output.h" #include "monkey/401login.h" -typedef struct monkey401 { +struct monkey401 { struct monkey401 *r_next, *r_prev; uint32_t num; - lwc_string *host; /* Ignore */ - nserror (*cb)(bool,void*); - void *pw; -} monkey401_t; + nserror (*cb)(struct nsurl*, const char *, const char *, const char *, void *); + void *cbpw; + char *username; + char *password; + char *realm; + struct nsurl *url; +}; + +static struct monkey401 *m401_ring = NULL; +static uint32_t m401_ctr = 0; + + +nserror +gui_401login_open(struct nsurl *url, + const char *realm, + const char *username, + const char *password, + nserror (*cb)(struct nsurl *url, + const char *realm, + const char *username, + const char *password, + void *pw), + void *cbpw) +{ + struct monkey401 *m401_ctx; + + m401_ctx = calloc(sizeof(*m401_ctx), 1); + if (m401_ctx == NULL) { + return NSERROR_NOMEM; + } + m401_ctx->realm = strdup(realm); + if (m401_ctx->realm == NULL) { + free(m401_ctx); + return NSERROR_NOMEM; + } + m401_ctx->url = nsurl_ref(url); + m401_ctx->cb = cb; + m401_ctx->cbpw = cbpw; + m401_ctx->num = m401_ctr++; + + RING_INSERT(m401_ring, m401_ctx); + + if (username == NULL) { + username = ""; + } + + if (password == NULL) { + password = ""; + } + + moutf(MOUT_LOGIN, "OPEN LWIN %u URL %s", m401_ctx->num, nsurl_access(url)); + moutf(MOUT_LOGIN, "USER LWIN %u STR %s", m401_ctx->num, username); + moutf(MOUT_LOGIN, "PASS LWIN %u STR %s", m401_ctx->num, password); + moutf(MOUT_LOGIN, "REALM LWIN %u STR %s", m401_ctx->num, realm); + + return NSERROR_OK; +} + +static struct monkey401 * +monkey_find_login_by_num(uint32_t login_num) +{ + struct monkey401 *ret = NULL; + + RING_ITERATE_START(struct monkey401, m401_ring, c_ring) { + if (c_ring->num == login_num) { + ret = c_ring; + RING_ITERATE_STOP(m401_ring, c_ring); + } + } RING_ITERATE_END(m401_ring, c_ring); + + return ret; +} + +static void free_login_context(struct monkey401 *m401_ctx) { + moutf(MOUT_LOGIN, "DESTROY LWIN %u", m401_ctx->num); + RING_REMOVE(m401_ring, m401_ctx); + if (m401_ctx->username != NULL) { + free(m401_ctx->username); + } + if (m401_ctx->password != NULL) { + free(m401_ctx->password); + } + free(m401_ctx->realm); + nsurl_unref(m401_ctx->url); + free(m401_ctx); +} + +static void +monkey_login_handle_go(int argc, char **argv) +{ + struct monkey401 *m401_ctx; + + if (argc != 3) { + moutf(MOUT_ERROR, "LOGIN GO ARGS BAD"); + return; + } + + m401_ctx = monkey_find_login_by_num(atoi(argv[2])); + if (m401_ctx == NULL) { + moutf(MOUT_ERROR, "LOGIN NUM BAD"); + return; + } -static monkey401_t *m4_ring = NULL; -static uint32_t m4_ctr = 0; + m401_ctx->cb(m401_ctx->url, m401_ctx->realm, m401_ctx->username, m401_ctx->password, m401_ctx->cbpw); + + free_login_context(m401_ctx); +} -void gui_401login_open(nsurl *url, const char *realm, - nserror (*cb)(bool proceed, void *pw), void *cbpw) +static void +monkey_login_handle_destroy(int argc, char **argv) { - monkey401_t *m4t = calloc(sizeof(*m4t), 1); - if (m4t == NULL) { - cb(false, cbpw); + struct monkey401 *m401_ctx; + + if (argc != 3) { + moutf(MOUT_ERROR, "LOGIN DESTROY ARGS BAD"); 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); + + m401_ctx = monkey_find_login_by_num(atoi(argv[2])); + if (m401_ctx == NULL) { + moutf(MOUT_ERROR, "LOGIN NUM BAD"); + return; + } + + free_login_context(m401_ctx); } +static void +monkey_login_handle_username(int argc, char **argv) +{ + struct monkey401 *m401_ctx; + + if (argc != 4) { + moutf(MOUT_ERROR, "LOGIN USERNAME ARGS BAD"); + return; + } + + m401_ctx = monkey_find_login_by_num(atoi(argv[2])); + if (m401_ctx == NULL) { + moutf(MOUT_ERROR, "LOGIN NUM BAD"); + return; + } + + if (m401_ctx->username != NULL) { + free(m401_ctx->username); + } + + m401_ctx->username = strdup(argv[3]); +} +static void +monkey_login_handle_password(int argc, char **argv) +{ + struct monkey401 *m401_ctx; + + if (argc != 4) { + moutf(MOUT_ERROR, "LOGIN PASSWORD ARGS BAD"); + return; + } + + m401_ctx = monkey_find_login_by_num(atoi(argv[2])); + if (m401_ctx == NULL) { + moutf(MOUT_ERROR, "LOGIN NUM BAD"); + return; + } + + if (m401_ctx->password != NULL) { + free(m401_ctx->password); + } + + m401_ctx->password = strdup(argv[3]); +} + +void +monkey_login_handle_command(int argc, char **argv) +{ + if (argc == 1) + return; + + if (strcmp(argv[1], "USERNAME") == 0) { + monkey_login_handle_username(argc, argv); + } else if (strcmp(argv[1], "PASSWORD") == 0) { + monkey_login_handle_password(argc, argv); + } else if (strcmp(argv[1], "DESTROY") == 0) { + monkey_login_handle_destroy(argc, argv); + } else if (strcmp(argv[1], "GO") == 0) { + monkey_login_handle_go(argc, argv); + } else { + moutf(MOUT_ERROR, "LOGIN COMMAND UNKNOWN %s\n", argv[1]); + } +} diff --git a/frontends/monkey/401login.h b/frontends/monkey/401login.h index e78355ea2..45a2a1b52 100644 --- a/frontends/monkey/401login.h +++ b/frontends/monkey/401login.h @@ -1,9 +1,39 @@ +/* + * Copyright 2018 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 <stdbool.h> +#ifndef NS_MONKEY_401LOGIN_H +#define NS_MONKEY_401LOGIN_H -#include "utils/nsurl.h" #include "utils/errors.h" +struct nsurl; -void gui_401login_open(nsurl *url, const char *realm, - nserror (*cb)(bool proceed, void *pw), void *cbpw); +nserror gui_401login_open(struct nsurl *url, + const char *realm, + const char *username, + const char *password, + nserror (*cb)(struct nsurl *url, + const char *realm, + const char *username, + const char *password, + void *pw), + void *cbpw); + +void monkey_login_handle_command(int argc, char **argv); + +#endif diff --git a/frontends/monkey/Makefile b/frontends/monkey/Makefile index 86f1d912e..d2dae3e16 100644 --- a/frontends/monkey/Makefile +++ b/frontends/monkey/Makefile @@ -9,20 +9,38 @@ 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 \ +CFLAGS += -std=c99 \ + -Dmonkey -Dnsmonkey -g \ -DMONKEY_RESPATH=\"$(NETSURF_MONKEY_RESOURCES)\" LDFLAGS += -lm # --------------------------------------------------------------------------- -# Windows flag setup +# Target setup # --------------------------------------------------------------------------- +# Path to monkey resources +MONKEY_RESOURCES_DIR := $(FRONTEND_RESOURCES_DIR) + +# The filter and target for split messages +MESSAGES_FILTER=monkey +MESSAGES_TARGET=$(MONKEY_RESOURCES_DIR) + +# --------------------------------------------------------------------------- +# HOST specific feature flags +# --------------------------------------------------------------------------- + +# enable POSIX and XSI features. +# everywhere but freebsd where the default set already has them enabled +ifneq ($(HOST),FreeBSD) + CFLAGS += -D_POSIX_C_SOURCE=200809L \ + -D_XOPEN_SOURCE=700 \ + -D_BSD_SOURCE \ + -D_DEFAULT_SOURCE \ + -D_NETBSD_SOURCE +endif + +# Windows flag setup ifeq ($(HOST),Windows_NT) CFLAGS += -U__STRICT_ANSI__ endif @@ -32,8 +50,8 @@ endif # ---------------------------------------------------------------------------- # 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 +S_FRONTEND := main.c output.c filetype.c schedule.c bitmap.c plot.c browser.c \ + download.c 401login.c layout.c dispatch.c fetch.c # This is the final source build list diff --git a/frontends/monkey/Makefile.defaults b/frontends/monkey/Makefile.defaults index d6a90a3dc..87b6f3ac4 100644 --- a/frontends/monkey/Makefile.defaults +++ b/frontends/monkey/Makefile.defaults @@ -9,5 +9,6 @@ NETSURF_USE_RSVG := NO NETSURF_USE_NSSVG := NO NETSURF_USE_ROSPRITE := NO NETSURF_USE_HARU_PDF := NO +NETSURF_FS_BACKING_STORE := YES CFLAGS += -O2 diff --git a/frontends/monkey/Makefile.tools b/frontends/monkey/Makefile.tools new file mode 100644 index 000000000..7546506ff --- /dev/null +++ b/frontends/monkey/Makefile.tools @@ -0,0 +1,15 @@ +# -*- mode: makefile-gmake -*- +## +## monkey target tool setup +## + +ifeq ($(origin GCCSDK_INSTALL_ENV),undefined) + PKG_CONFIG := pkg-config +else + PKG_CONFIG := PKG_CONFIG_LIBDIR="$(GCCSDK_INSTALL_ENV)/lib/pkgconfig" pkg-config +endif + +ifneq ($(origin GCCSDK_INSTALL_CROSSBIN),undefined) + CC := $(wildcard $(GCCSDK_INSTALL_CROSSBIN)/*gcc) + CXX := $(wildcard $(GCCSDK_INSTALL_CROSSBIN)/*g++) +endif diff --git a/frontends/monkey/bitmap.c b/frontends/monkey/bitmap.c index 83b8566b6..900dbca72 100644 --- a/frontends/monkey/bitmap.c +++ b/frontends/monkey/bitmap.c @@ -23,6 +23,7 @@ #include "utils/errors.h" #include "netsurf/bitmap.h" +#include "monkey/output.h" #include "monkey/bitmap.h" struct bitmap { @@ -30,26 +31,26 @@ struct bitmap { size_t rowstride; int width; int height; - unsigned int state; + bool opaque; }; -static void *bitmap_create(int width, int height, unsigned int state) +static void *bitmap_create(int width, int height, enum gui_bitmap_flags flags) { struct bitmap *ret = calloc(sizeof(*ret), 1); if (ret == NULL) return NULL; - + ret->width = width; ret->height = height; - ret->state = state; - + ret->opaque = (flags & BITMAP_OPAQUE) == BITMAP_OPAQUE; + ret->ptr = calloc(width, height * 4); - + if (ret->ptr == NULL) { free(ret); return NULL; } - + return ret; } @@ -63,23 +64,15 @@ static void bitmap_destroy(void *bitmap) 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; + bmap->opaque = opaque; } static bool bitmap_get_opaque(void *bitmap) { struct bitmap *bmap = bitmap; - - return (bmap->state & BITMAP_OPAQUE) == BITMAP_OPAQUE; + + return bmap->opaque; } static unsigned char *bitmap_get_buffer(void *bitmap) @@ -95,21 +88,9 @@ static size_t bitmap_get_rowstride(void *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; + return; } static int bitmap_get_width(void *bitmap) @@ -127,7 +108,7 @@ static int bitmap_get_height(void *bitmap) static nserror bitmap_render(struct bitmap *bitmap, struct hlcache_handle *content) { - fprintf(stdout, "GENERIC BITMAP RENDER\n"); + moutf(MOUT_GENERIC, "BITMAP RENDER"); return NSERROR_OK; } @@ -136,13 +117,10 @@ static struct gui_bitmap_table bitmap_table = { .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, }; diff --git a/frontends/monkey/browser.c b/frontends/monkey/browser.c index 1fbbbf0b1..49cc63c3b 100644 --- a/frontends/monkey/browser.c +++ b/frontends/monkey/browser.c @@ -32,6 +32,7 @@ #include "netsurf/browser_window.h" #include "netsurf/plotters.h" +#include "monkey/output.h" #include "monkey/browser.h" #include "monkey/plot.h" @@ -42,7 +43,7 @@ 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); + moutf(MOUT_WARNING, "%s %s", warning, detail); return NSERROR_OK; } @@ -50,14 +51,14 @@ 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; } @@ -77,28 +78,31 @@ gui_window_create(struct browser_window *bw, 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); - + + moutf(MOUT_WINDOW, + "NEW WIN %u FOR %p EXISTING %p NEWTAB %s CLONE %s", + ret->win_num, bw, existing, + flags & GW_CREATE_TAB ? "TRUE" : "FALSE", + flags & GW_CREATE_CLONE ? "TRUE" : "FALSE"); + moutf(MOUT_WINDOW, + "SIZE WIN %u WIDTH %d HEIGHT %d", + 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); + moutf(MOUT_WINDOW, "DESTROY WIN %u", g->win_num); RING_REMOVE(gw_ring, g); free(g); } @@ -106,7 +110,7 @@ gui_window_destroy(struct gui_window *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); + moutf(MOUT_WINDOW, "TITLE WIN %u STR %s", g->win_num, title); } /** @@ -115,43 +119,43 @@ gui_window_set_title(struct gui_window *g, const char *title) * \param g The gui window to measure content area of. * \param width receives width of window * \param height receives height of window - * \param scaled whether to return scaled values * \return NSERROR_OK on sucess and width and height updated. */ static nserror -gui_window_get_dimensions(struct gui_window *g, int *width, int *height, - bool scaled) +gui_window_get_dimensions(struct gui_window *g, int *width, int *height) { - 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; + moutf(MOUT_WINDOW, + "GET_DIMENSIONS WIN %u WIDTH %d HEIGHT %d", + g->win_num, *width, *height); + return NSERROR_OK; } static void gui_window_new_content(struct gui_window *g) { - fprintf(stdout, "WINDOW NEW_CONTENT WIN %u\n", g->win_num); + moutf(MOUT_WINDOW, "NEW_CONTENT WIN %u", g->win_num); } static void gui_window_set_icon(struct gui_window *g, struct hlcache_handle *icon) { - fprintf(stdout, "WINDOW NEW_ICON WIN %u\n", g->win_num); + moutf(MOUT_WINDOW, "NEW_ICON WIN %u", g->win_num); } static void gui_window_start_throbber(struct gui_window *g) { - fprintf(stdout, "WINDOW START_THROBBER WIN %u\n", g->win_num); + moutf(MOUT_WINDOW, "START_THROBBER WIN %u", g->win_num); } static void gui_window_stop_throbber(struct gui_window *g) { - fprintf(stdout, "WINDOW STOP_THROBBER WIN %u\n", g->win_num); + moutf(MOUT_WINDOW, "STOP_THROBBER WIN %u", g->win_num); } @@ -171,7 +175,7 @@ gui_window_set_scroll(struct gui_window *gw, const struct rect *rect) gw->scrollx = rect->x0; gw->scrolly = rect->y0; - fprintf(stdout, "WINDOW SET_SCROLL WIN %u X %d Y %d\n", + moutf(MOUT_WINDOW, "SET_SCROLL WIN %u X %d Y %d", gw->win_num, rect->x0, rect->y0); return NSERROR_OK; } @@ -187,15 +191,14 @@ gui_window_set_scroll(struct gui_window *gw, const struct rect *rect) static nserror monkey_window_invalidate_area(struct gui_window *gw, const struct rect *rect) { - fprintf(stdout, "WINDOW INVALIDATE_AREA WIN %u", gw->win_num); - if (rect != NULL) { - fprintf(stdout, - " X %d Y %d WIDTH %d HEIGHT %d\n", - rect->x0, rect->y0, - (rect->x1 - rect->x0), (rect->y1 - rect->y0)); + moutf(MOUT_WINDOW, + "INVALIDATE_AREA WIN %u X %d Y %d WIDTH %d HEIGHT %d", + gw->win_num, + rect->x0, rect->y0, + (rect->x1 - rect->x0), (rect->y1 - rect->y0)); } else { - fprintf(stdout," ALL\n"); + moutf(MOUT_WINDOW, "INVALIDATE_AREA WIN %u ALL", gw->win_num); } return NSERROR_OK; @@ -209,21 +212,21 @@ gui_window_update_extent(struct gui_window *g) 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); + moutf(MOUT_WINDOW, "UPDATE_EXTENT WIN %u WIDTH %d HEIGHT %d", + 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); + moutf(MOUT_WINDOW, "SET_STATUS WIN %u STR %s", 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"; @@ -285,21 +288,24 @@ gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) default: break; } - fprintf(stdout, "WINDOW SET_POINTER WIN %u POINTER %s\n", g->win_num, ptr_name); + + moutf(MOUT_WINDOW, "SET_POINTER WIN %u POINTER %s", + 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)); + moutf(MOUT_WINDOW, "SET_URL WIN %u URL %s", + 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); + moutf(MOUT_WINDOW, "GET_SCROLL WIN %u X %d Y %d", + g->win_num, g->scrollx, g->scrolly); *sx = g->scrollx; *sy = g->scrolly; return true; @@ -308,7 +314,7 @@ gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) static bool gui_window_scroll_start(struct gui_window *g) { - fprintf(stdout, "WINDOW SCROLL_START WIN %u\n", g->win_num); + moutf(MOUT_WINDOW, "SCROLL_START WIN %u", g->win_num); g->scrollx = g->scrolly = 0; return true; } @@ -318,33 +324,127 @@ 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); + moutf(MOUT_WINDOW, "PLACE_CARET WIN %u X %d Y %d HEIGHT %d", + 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); + moutf(MOUT_WINDOW, "REMOVE_CARET WIN %u", g->win_num); } static bool gui_window_drag_start(struct gui_window *g, gui_drag_type type, - const struct rect *rect) + const struct rect *rect) { - fprintf(stdout, "WINDOW SCROLL_START WIN %u TYPE %i\n", g->win_num, type); + moutf(MOUT_WINDOW, "SCROLL_START WIN %u TYPE %i", 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", + moutf(MOUT_WINDOW, "SAVE_LINK WIN %u URL %s TITLE %s", g->win_num, nsurl_access(url), title); return NSERROR_OK; } +static void +gui_window_console_log(struct gui_window *g, + browser_window_console_source src, + const char *msg, + size_t msglen, + browser_window_console_flags flags) +{ + bool foldable = !!(flags & BW_CS_FLAG_FOLDABLE); + const char *src_text; + const char *level_text; + + switch (src) { + case BW_CS_INPUT: + src_text = "client-input"; + break; + case BW_CS_SCRIPT_ERROR: + src_text = "scripting-error"; + break; + case BW_CS_SCRIPT_CONSOLE: + src_text = "scripting-console"; + break; + default: + assert(0 && "Unknown scripting source"); + src_text = "unknown"; + break; + } + + switch (flags & BW_CS_FLAG_LEVEL_MASK) { + case BW_CS_FLAG_LEVEL_DEBUG: + level_text = "DEBUG"; + break; + case BW_CS_FLAG_LEVEL_LOG: + level_text = "LOG"; + break; + case BW_CS_FLAG_LEVEL_INFO: + level_text = "INFO"; + break; + case BW_CS_FLAG_LEVEL_WARN: + level_text = "WARN"; + break; + case BW_CS_FLAG_LEVEL_ERROR: + level_text = "ERROR"; + break; + default: + assert(0 && "Unknown console logging level"); + level_text = "unknown"; + break; + } + + moutf(MOUT_WINDOW, "CONSOLE_LOG WIN %u SOURCE %s %sFOLDABLE %s %.*s", + g->win_num, src_text, foldable ? "" : "NOT-", level_text, + (int)msglen, msg); +} + +static void +gui_window_report_page_info(struct gui_window *g) +{ + const char *state = "***WAH***"; + + switch (browser_window_get_page_info_state(g->bw)) { + case PAGE_STATE_UNKNOWN: + state = "UNKNOWN"; + break; + + case PAGE_STATE_INTERNAL: + state = "INTERNAL"; + break; + + case PAGE_STATE_LOCAL: + state = "LOCAL"; + break; + + case PAGE_STATE_INSECURE: + state = "INSECURE"; + break; + + case PAGE_STATE_SECURE_OVERRIDE: + state = "SECURE_OVERRIDE"; + break; + case PAGE_STATE_SECURE_ISSUES: + state = "SECURE_ISSUES"; + break; + + case PAGE_STATE_SECURE: + state = "SECURE"; + break; + + default: + assert(0 && "Monkey needs some lovin' here"); + break; + } + moutf(MOUT_WINDOW, "PAGE_STATUS WIN %u STATUS %s", + g->win_num, state); +} /**** Handlers ****/ @@ -380,11 +480,11 @@ 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"); + moutf(MOUT_ERROR, "WINDOW NUM BAD"); } else { browser_window_destroy(gw->bw); } @@ -397,16 +497,16 @@ monkey_window_handle_go(int argc, char **argv) nsurl *url; nsurl *ref_url = NULL; nserror error; - + if (argc < 4 || argc > 5) { - fprintf(stdout, "ERROR WINDOW GO ARGS BAD\n"); + moutf(MOUT_ERROR, "WINDOW GO ARGS BAD"); return; } - + gw = monkey_find_window_by_num(atoi(argv[2])); - + if (gw == NULL) { - fprintf(stdout, "ERROR WINDOW NUM BAD\n"); + moutf(MOUT_ERROR, "WINDOW NUM BAD"); return; } @@ -436,6 +536,28 @@ monkey_window_handle_go(int argc, char **argv) } } +/** + * handle WINDOW STOP command + */ +static void +monkey_window_handle_stop(int argc, char **argv) +{ + struct gui_window *gw; + if (argc != 3) { + moutf(MOUT_ERROR, "WINDOW STOP ARGS BAD\n"); + return; + } + + gw = monkey_find_window_by_num(atoi(argv[2])); + + if (gw == NULL) { + moutf(MOUT_ERROR, "WINDOW NUM BAD"); + } else { + browser_window_stop(gw->bw); + } +} + + static void monkey_window_handle_redraw(int argc, char **argv) { @@ -446,35 +568,35 @@ monkey_window_handle_redraw(int argc, char **argv) .background_images = true, .plot = monkey_plotters }; - + if (argc != 3 && argc != 7) { - fprintf(stdout, "ERROR WINDOW REDRAW ARGS BAD\n"); + moutf(MOUT_ERROR, "WINDOW REDRAW ARGS BAD"); return; } gw = monkey_find_window_by_num(atoi(argv[2])); - + if (gw == NULL) { - fprintf(stdout, "ERROR WINDOW NUM BAD\n"); + moutf(MOUT_ERROR, "WINDOW NUM BAD"); 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]); } - + NSLOG(netsurf, INFO, "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])); + moutf(MOUT_WINDOW, "REDRAW WIN %d START", atoi(argv[2])); + browser_window_redraw(gw->bw, gw->scrollx, gw->scrolly, &clip, &ctx); + moutf(MOUT_WINDOW, "REDRAW WIN %d STOP", atoi(argv[2])); } static void @@ -482,39 +604,170 @@ 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"); + moutf(MOUT_ERROR, "WINDOW RELOAD ARGS BAD\n"); + return; } - + gw = monkey_find_window_by_num(atoi(argv[2])); - + if (gw == NULL) { - fprintf(stdout, "ERROR WINDOW NUM BAD\n"); + moutf(MOUT_ERROR, "WINDOW NUM BAD"); } else { browser_window_reload(gw->bw, argc == 4); } } +static void +monkey_window_handle_exec(int argc, char **argv) +{ + struct gui_window *gw; + if (argc < 5) { + moutf(MOUT_ERROR, "WINDOW EXEC ARGS BAD\n"); + } + + gw = monkey_find_window_by_num(atoi(argv[2])); + + if (gw == NULL) { + moutf(MOUT_ERROR, "WINDOW NUM BAD"); + } else { + /* Gather argv[4] onward into a string to pass to js_exec */ + int total = 0; + for (int i = 4; i < argc; ++i) { + total += strlen(argv[i]) + 1; + } + char *cmd = calloc(total, 1); + if (cmd == NULL) { + moutf(MOUT_ERROR, "JS WIN %d RET ENOMEM", atoi(argv[2])); + return; + } + strcpy(cmd, argv[4]); + for (int i = 5; i < argc; ++i) { + strcat(cmd, " "); + strcat(cmd, argv[i]); + } + /* Now execute the JS */ + + moutf(MOUT_WINDOW, "JS WIN %d RET %s", atoi(argv[2]), + browser_window_exec(gw->bw, cmd, total - 1) ? "TRUE" : "FALSE"); + + free(cmd); + } +} + + +static void +monkey_window_handle_click(int argc, char **argv) +{ + /* `WINDOW CLICK WIN` _%id%_ `X` _%num%_ `Y` _%num%_ `BUTTON` _%str%_ `KIND` _%str%_ */ + /* 0 1 2 3 4 5 6 7 8 9 10 11 */ + struct gui_window *gw; + if (argc != 12) { + moutf(MOUT_ERROR, "WINDOW CLICK ARGS BAD\n"); + } + + gw = monkey_find_window_by_num(atoi(argv[2])); + + if (gw == NULL) { + moutf(MOUT_ERROR, "WINDOW NUM BAD"); + } else { + int x = atoi(argv[5]); + int y = atoi(argv[7]); + browser_mouse_state mouse; + const char *button = argv[9]; + const char *kind = argv[11]; + if (strcmp(button, "LEFT") == 0) { + mouse = BROWSER_MOUSE_CLICK_1; + } else if (strcmp(button, "RIGHT") == 0) { + mouse = BROWSER_MOUSE_CLICK_2; + } else { + moutf(MOUT_ERROR, "WINDOW BUTTON BAD"); + return; + } + if (strcmp(kind, "SINGLE") == 0) { + /* Nothing */ + } else if (strcmp(kind, "DOUBLE") == 0) { + mouse |= BROWSER_MOUSE_DOUBLE_CLICK; + } else if (strcmp(kind, "TRIPLE") == 0) { + mouse |= BROWSER_MOUSE_TRIPLE_CLICK; + } else { + moutf(MOUT_ERROR, "WINDOW KIND BAD"); + return; + } + browser_window_mouse_click(gw->bw, mouse, x, y); + } +} 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], "STOP") == 0) { + monkey_window_handle_stop(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 if (strcmp(argv[1], "EXEC") == 0) { + monkey_window_handle_exec(argc, argv); + } else if (strcmp(argv[1], "CLICK") == 0) { + monkey_window_handle_click(argc, argv); } else { - fprintf(stdout, "ERROR WINDOW COMMAND UNKNOWN %s\n", argv[1]); + moutf(MOUT_ERROR, "WINDOW COMMAND UNKNOWN %s\n", argv[1]); } - + +} + +/** + * process miscellaneous window events + * + * \param gw The window receiving the event. + * \param event The event code. + * \return NSERROR_OK when processed ok + */ +static nserror +gui_window_event(struct gui_window *gw, enum gui_window_event event) +{ + switch (event) { + case GW_EVENT_UPDATE_EXTENT: + gui_window_update_extent(gw); + break; + + case GW_EVENT_REMOVE_CARET: + gui_window_remove_caret(gw); + break; + + case GW_EVENT_SCROLL_START: + gui_window_scroll_start(gw); + break; + + case GW_EVENT_NEW_CONTENT: + gui_window_new_content(gw); + break; + + case GW_EVENT_START_THROBBER: + gui_window_start_throbber(gw); + break; + + case GW_EVENT_STOP_THROBBER: + gui_window_stop_throbber(gw); + break; + + case GW_EVENT_PAGE_INFO_CHANGE: + gui_window_report_page_info(gw); + break; + + default: + break; + } + return NSERROR_OK; } static struct gui_window_table window_table = { @@ -524,7 +777,7 @@ static struct gui_window_table window_table = { .get_scroll = gui_window_get_scroll, .set_scroll = gui_window_set_scroll, .get_dimensions = gui_window_get_dimensions, - .update_extent = gui_window_update_extent, + .event = gui_window_event, .set_title = gui_window_set_title, .set_url = gui_window_set_url, @@ -532,13 +785,10 @@ static struct gui_window_table window_table = { .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_start = gui_window_scroll_start, - .new_content = gui_window_new_content, - .start_throbber = gui_window_start_throbber, - .stop_throbber = gui_window_stop_throbber, + + .console_log = gui_window_console_log, }; struct gui_window_table *monkey_window_table = &window_table; diff --git a/frontends/monkey/cert.c b/frontends/monkey/cert.c deleted file mode 100644 index a19975527..000000000 --- a/frontends/monkey/cert.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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; - -nserror -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) { - return NSERROR_NOMEM; - } - 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)); - - return NSERROR_OK; -} - - diff --git a/frontends/monkey/dispatch.c b/frontends/monkey/dispatch.c index e60325cf1..08bd352d5 100644 --- a/frontends/monkey/dispatch.c +++ b/frontends/monkey/dispatch.c @@ -29,7 +29,7 @@ typedef struct cmdhandler { struct cmdhandler *r_next, *r_prev; - const char *cmd; + char *cmd; handle_command_fn fn; } monkey_cmdhandler_t; @@ -50,6 +50,17 @@ monkey_register_handler(const char *cmd, handle_command_fn fn) } void +monkey_free_handlers(void) +{ + while (handler_ring != NULL) { + monkey_cmdhandler_t *handler = handler_ring; + RING_REMOVE(handler_ring, handler); + free(handler->cmd); + free(handler); + } +} + +void monkey_process_command(void) { char buffer[PATH_MAX]; diff --git a/frontends/monkey/dispatch.h b/frontends/monkey/dispatch.h index dc6e50a0b..11b1c0239 100644 --- a/frontends/monkey/dispatch.h +++ b/frontends/monkey/dispatch.h @@ -25,4 +25,6 @@ nserror monkey_register_handler(const char *cmd, handle_command_fn fn); void monkey_process_command(void); +void monkey_free_handlers(void); + #endif /* NETSURF_MONKEY_DISPATCH_H */ diff --git a/frontends/monkey/download.c b/frontends/monkey/download.c index 5c9ce1b53..b9ca1746f 100644 --- a/frontends/monkey/download.c +++ b/frontends/monkey/download.c @@ -25,6 +25,7 @@ #include "netsurf/download.h" #include "desktop/download.h" +#include "monkey/output.h" #include "monkey/browser.h" static uint32_t dwin_ctr = 0; @@ -33,6 +34,7 @@ struct gui_download_window { struct gui_download_window *r_next; struct gui_download_window *r_prev; struct gui_window *g; + download_context *dlctx; uint32_t dwin_num; char *host; /* ignore */ }; @@ -48,11 +50,12 @@ gui_download_window_create(download_context *ctx, return NULL; ret->g = parent; ret->dwin_num = dwin_ctr++; + ret->dlctx = ctx; RING_INSERT(dw_ring, ret); - fprintf(stdout, "DOWNLOAD_WINDOW CREATE DWIN %u WIN %u\n", - ret->dwin_num, parent->win_num); + moutf(MOUT_DOWNLOAD, "CREATE DWIN %u WIN %u", + ret->dwin_num, parent->win_num); return ret; } @@ -61,7 +64,7 @@ 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", + moutf(MOUT_DOWNLOAD, "DATA DWIN %u SIZE %u DATA %s", dw->dwin_num, size, data); return NSERROR_OK; } @@ -70,16 +73,15 @@ 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); + moutf(MOUT_DOWNLOAD, "ERROR DWIN %u ERROR %s", 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); + moutf(MOUT_DOWNLOAD, "DONE DWIN %u", dw->dwin_num); RING_REMOVE(dw_ring, dw); + download_context_destroy(dw->dlctx); free(dw); } diff --git a/frontends/monkey/farmer.py b/frontends/monkey/farmer.py deleted file mode 100644 index d4b4b1e21..000000000 --- a/frontends/monkey/farmer.py +++ /dev/null @@ -1,363 +0,0 @@ -#!/usr/bin/python - -# Copyright 2017 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/>. - -""" -Monkey Farmer - -The monkey farmer is a wrapper around `nsmonkey` which can be used to simplify -access to the monkey behaviours and ultimately to write useful tests in an -expressive but not overcomplicated DSLish way. Tests are, ultimately, still -Python code. - -""" - -import asyncore -import os -import socket -import subprocess -import time - -#monkey_cmd = ['./nsmonkey', '--accept_language=fr'] -monkey_cmd = ['./nsmonkey'] - -class MonkeyFarmer(asyncore.dispatcher): - def __init__(self, online, quiet=False): - (mine, monkeys) = socket.socketpair() - - asyncore.dispatcher.__init__(self, sock=mine) - - self.monkey = subprocess.Popen( - monkey_cmd, - stdin=monkeys, - stdout=monkeys, - close_fds=[mine]) - - monkeys.close() - - self.buffer = "" - self.incoming = "" - self.lines = [] - self.scheduled = [] - self.deadmonkey = False - self.online = online - self.quiet = quiet - - def handle_connect(self): - pass - - def handle_read(self): - got = self.recv(8192) - if got == "" or got is None: - self.deadmonkey = True - return - self.incoming += got - if "\n" in self.incoming: - lines = self.incoming.split("\n") - self.incoming = lines.pop() - self.lines = lines - - def writable(self): - return (len(self.buffer) > 0) - - def handle_write(self): - sent = self.send(self.buffer) - self.buffer = self.buffer[sent:] - - def tell_monkey(self, *args): - cmd = (" ".join(args)) - if not self.quiet: - print ">>> %s" % cmd - self.buffer += "%s\n" % cmd - - def monkey_says(self, line): - if not self.quiet: - print "<<< %s" % line - self.online(line) - - def schedule_event(self, event, secs=None, when=None): - assert(secs is not None or when is not None) - if when is None: - when = time.time() + secs - self.scheduled.append((when, event)) - self.scheduled.sort(lambda a,b: cmp(a[0],b[0])) - - def unschedule_event(self, event): - self.scheduled = [x for x in self.scheduled if x[1] != event] - - def loop(self, once=False): - if len(self.lines) > 0: - self.monkey_says(self.lines.pop(0)) - if once: - return - while not self.deadmonkey: - now = time.time() - while len(self.scheduled) > 0 and now >= self.scheduled[0][0]: - func = self.scheduled[0][1] - self.scheduled.pop(0) - func(self) - now = time.time() - if len(self.scheduled) > 0: - next = self.scheduled[0][0] - asyncore.loop(timeout=next-now, count=1) - else: - asyncore.loop(count=1) - if len(self.lines) > 0: - self.monkey_says(self.lines.pop(0)) - if once: - break - -class Browser: - def __init__(self, quiet=False): - self.farmer = MonkeyFarmer(online=self.on_monkey_line, quiet=quiet) - self.windows = {} - self.current_draw_target = None - - def pass_options(self, *opts): - if len(opts) > 0: - self.farmer.tell_monkey("OPTIONS " + (" ".join(opts))) - - def on_monkey_line(self, line): - parts = line.split(" ") - handler = getattr(self, "handle_" + parts[0], None) - if handler is not None: - handler(*parts[1:]) - - def quit(self): - self.farmer.tell_monkey("QUIT") - - def quit_and_wait(self): - self.quit() - self.farmer.loop() - - def handle_GENERIC(self, what, *args): - pass - - def handle_WINDOW(self, action, _win, winid, *args): - if action == "NEW": - new_win = BrowserWindow(self, winid, *args) - self.windows[winid] = new_win - else: - win = self.windows.get(winid, None) - if win is None: - print " Unknown window id %s" % winid - else: - win.handle(action, *args) - - def handle_PLOT(self, *args): - if self.current_draw_target is not None: - self.current_draw_target.handle_plot(*args) - - def new_window(self, url=None): - if url is None: - self.farmer.tell_monkey("WINDOW NEW") - else: - self.farmer.tell_monkey("WINDOW NEW %s" % url) - wins_known = set(self.windows.keys()) - while len(set(self.windows.keys()).difference(wins_known)) == 0: - self.farmer.loop(once=True) - poss_wins = set(self.windows.keys()).difference(wins_known) - return self.windows[poss_wins.pop()] - - -class BrowserWindow: - def __init__(self, browser, winid, _for, coreid, _existing, otherid, _newtab, newtab, _clone, clone): - self.alive = True - self.browser = browser - self.winid = winid - self.coreid = coreid - self.existing = browser.windows.get(otherid, None) - self.newtab = newtab == "TRUE" - self.clone = clone == "TRUE" - self.width = 0 - self.height = 0 - self.title = "" - self.throbbing = False - self.scrollx = 0 - self.scrolly = 0 - self.content_width = 0 - self.content_height = 0 - self.status = "" - self.pointer = "" - self.scale = 1.0 - self.url = "" - self.plotted = [] - self.plotting = False - - def kill(self): - self.browser.farmer.tell_monkey("WINDOW DESTROY %s" % self.winid) - - def go(self, url, referer = None): - if referer is None: - self.browser.farmer.tell_monkey("WINDOW GO %s %s" % ( - self.winid, url)) - else: - self.browser.farmer.tell_monkey("WINDOW GO %s %s %s" % ( - self.winid, url, referer)) - - def reload(self): - self.browser.farmer.tell_monkey("WINDOW RELOAD %s" % self.winid) - - def redraw(self, coords=None): - if coords is None: - self.browser.farmer.tell_monkey("WINDOW REDRAW %s" % self.winid) - else: - self.browser.farmer.tell_monkey("WINDOW REDRAW %s %s" % ( - self.winid, (" ".join(coords)))) - - def handle(self, action, *args): - handler = getattr(self, "handle_window_" + action, None) - if handler is not None: - handler(*args) - - def handle_window_SIZE(self, _width, width, _height, height): - self.width = int(width) - self.height = int(height) - - def handle_window_DESTROY(self): - self.alive = False - - def handle_window_TITLE(self, _str, *title): - self.title = " ".join(title) - - def handle_window_REDRAW(self): - pass - - def handle_window_GET_DIMENSIONS(self, _width, width, _height, height): - self.width = width - self.height = height - - def handle_window_NEW_CONTENT(self): - pass - - def handle_window_NEW_ICON(self): - pass - - def handle_window_START_THROBBER(self): - self.throbbing = True - - def handle_window_STOP_THROBBER(self): - self.throbbing = False - - def handle_window_SET_SCROLL(self, _x, x, _y, y): - self.scrollx = int(x) - self.scrolly = int(y) - - def handle_window_UPDATE_BOX(self, _x, x, _y, y, _width, width, _height, height): - x = int(x) - y = int(y) - width = int(width) - height = int(height) - pass - - def handle_window_UPDATE_EXTENT(self, _width, width, _height, height): - self.content_width = int(width) - self.content_height = int(height) - - def handle_window_SET_STATUS(self, _str, *status): - self.status = (" ".join(status)) - - def handle_window_SET_POINTER(self, _ptr, ptr): - self.pointer = ptr - - def handle_window_SET_SCALE(self, _scale, scale): - self.scale = float(scale) - - def handle_window_SET_URL(self, _url, url): - self.url = url - - def handle_window_GET_SCROLL(self, _x, x, _y, y): - self.scrollx = int(x) - self.scrolly = int(y) - - def handle_window_SCROLL_START(self): - self.scrollx = 0 - self.scrolly = 0 - - def handle_window_REDRAW(self, act): - if act == "START": - self.browser.current_draw_target = self - self.plotted = [] - self.plotting = True - else: - self.browser.current_draw_target = None - self.plotting = False - - def load_page(self, url=None, referer=None): - if url is not None: - self.go(url, referer) - self.wait_loaded() - - def reload(self): - self.browser.farmer.tell_monkey("WINDOW RELOAD %s" % self.winid) - self.wait_loaded() - - def wait_loaded(self): - while not self.throbbing: - self.browser.farmer.loop(once=True) - while self.throbbing: - self.browser.farmer.loop(once=True) - - def handle_plot(self, *args): - self.plotted.append(args) - - def redraw(self, coords=None): - if coords is None: - self.browser.farmer.tell_monkey("WINDOW REDRAW %s" % self.winid) - else: - self.browser.farmer.tell_monkey("WINDOW REDRAW %s %s" % ( - self.winid, (" ".join(coords)))) - while not self.plotting: - self.browser.farmer.loop(once=True) - while self.plotting: - self.browser.farmer.loop(once=True) - return self.plotted - - -# Simple test is as follows... - -browser = Browser(quiet=True) - -win = browser.new_window() - -fname = "test/js/inline-doc-write-simple.html" -full_fname = os.path.join(os.getcwd(), fname) - -browser.pass_options("--enable_javascript=0") -win.load_page("file://" + full_fname) - -print("Loaded, URL is %s" % win.url) - -cmds = win.redraw() -print("Received %d plot commands" % len(cmds)) -for cmd in cmds: - if cmd[0] == "TEXT": - print "%s %s -> %s" % (cmd[2], cmd[4], (" ".join(cmd[6:]))) - - -browser.pass_options("--enable_javascript=1") -win.load_page("file://" + full_fname) - -print("Loaded, URL is %s" % win.url) - -cmds = win.redraw() -print("Received %d plot commands" % len(cmds)) -for cmd in cmds: - if cmd[0] == "TEXT": - print "%s %s -> %s" % (cmd[2], cmd[4], (" ".join(cmd[6:]))) - -browser.quit_and_wait() diff --git a/frontends/monkey/fetch.h b/frontends/monkey/fetch.h index f146e2ef8..2881e92c5 100644 --- a/frontends/monkey/fetch.h +++ b/frontends/monkey/fetch.h @@ -19,6 +19,6 @@ #ifndef NS_MONKEY_FETCH_H #define NS_MONKEY_FETCH_H -struct gui_fetch_table *monkey_fetch_table; +extern struct gui_fetch_table *monkey_fetch_table; #endif /* NS_MONKEY_FETCH_H */ diff --git a/frontends/monkey/filetype.c b/frontends/monkey/filetype.c index 979796baf..37853a63d 100644 --- a/frontends/monkey/filetype.c +++ b/frontends/monkey/filetype.c @@ -32,6 +32,7 @@ #include <stdio.h> #include <stdbool.h> +#include <stdint.h> #include <string.h> #include <strings.h> #include <stdlib.h> @@ -68,8 +69,10 @@ void monkey_fetch_filetype_init(const char *mimefile) 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, "bmp", "image/bmp"); hash_add(mime_hash, "gif", "image/gif"); hash_add(mime_hash, "png", "image/png"); + hash_add(mime_hash, "ico", "image/ico"); hash_add(mime_hash, "jng", "image/jng"); hash_add(mime_hash, "mng", "image/mng"); hash_add(mime_hash, "webp", "image/webp"); @@ -107,9 +110,9 @@ void monkey_fetch_filetype_init(const char *mimefile) type = ptr; - /* search for the first non-whitespace char or NUL or + /* search for the first whitespace char or NUL or * NL */ - while (*ptr && (!ascii_is_space(*ptr)) && *ptr != '\n') + while (*ptr && (!ascii_is_space(*ptr))) ptr++; if (*ptr == '\0' || *ptr == '\n') { @@ -132,8 +135,7 @@ void monkey_fetch_filetype_init(const char *mimefile) /* search for the first whitespace char or * NUL or NL which is the end of the ext. */ - while (*ptr && (!ascii_is_space(*ptr)) && - *ptr != '\n') + while (*ptr && (!ascii_is_space(*ptr))) ptr++; if (*ptr == '\0' || *ptr == '\n') { diff --git a/frontends/monkey/layout.c b/frontends/monkey/layout.c index 7b7223144..0d6a3b4dc 100644 --- a/frontends/monkey/layout.c +++ b/frontends/monkey/layout.c @@ -33,7 +33,7 @@ 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; + *width = (fstyle->size * utf8_bounded_length(string, length)) / PLOT_STYLE_SCALE; return NSERROR_OK; } @@ -53,10 +53,10 @@ 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); + *char_offset = x / (fstyle->size / PLOT_STYLE_SCALE); if (*char_offset > length) *char_offset = length; - *actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE); + *actual_x = *char_offset * (fstyle->size / PLOT_STYLE_SCALE); return NSERROR_OK; } @@ -88,7 +88,7 @@ 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); + int c_off = *char_offset = x / (fstyle->size / PLOT_STYLE_SCALE); if (*char_offset > length) { *char_offset = length; } else { @@ -104,7 +104,7 @@ static nserror nsfont_split(const plot_font_style_t *fstyle, } } } - *actual_x = *char_offset * (fstyle->size / FONT_SIZE_SCALE); + *actual_x = *char_offset * (fstyle->size / PLOT_STYLE_SCALE); return NSERROR_OK; } diff --git a/frontends/monkey/main.c b/frontends/monkey/main.c index 53cde5a72..463f0bea6 100644 --- a/frontends/monkey/main.c +++ b/frontends/monkey/main.c @@ -23,6 +23,8 @@ #include <sys/types.h> #include <unistd.h> #include <string.h> +#include <errno.h> +#include <signal.h> #include "utils/config.h" #include "utils/sys_time.h" @@ -36,10 +38,11 @@ #include "netsurf/url_db.h" #include "netsurf/cookie_db.h" #include "content/fetch.h" +#include "content/backing_store.h" +#include "monkey/output.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" @@ -66,11 +69,12 @@ static bool monkey_done = false; */ static void die(const char * const error) { - fprintf(stderr, "DIE %s\n", error); + moutf(MOUT_DIE, "%s", error); exit(EXIT_FAILURE); } -/** obtain language from environment +/** + * obtain language from environment * * start with GNU extension LANGUAGE environment variable and then try * POSIX variables LC_ALL, LC_MESSAGES and LANG @@ -104,7 +108,8 @@ static const char *get_language(void) } -/** provide a string vector of languages in preference order +/** + * 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 @@ -171,7 +176,16 @@ static const char * const *get_languagev(void) return &langv[0]; } -/* Stolen from gtk/gui.c */ +/** + * Create an array of valid paths to search for resources. + * + * The idea is that all the complex path computation to find resources + * is performed here, once, rather than every time a resource is + * searched for. + * + * \param resource_path A shell style colon separated path list + * \return A string vector of valid paths where resources can be found + */ static char ** nsmonkey_init_resource(const char *resource_path) { @@ -199,7 +213,17 @@ static void monkey_quit(void) static nserror gui_launch_url(struct nsurl *url) { - fprintf(stdout, "GENERIC LAUNCH URL %s\n", nsurl_access(url)); + moutf(MOUT_GENERIC, "LAUNCH URL %s", nsurl_access(url)); + return NSERROR_OK; +} + +static nserror gui_present_cookies(const char *search_term) +{ + if (search_term != NULL) { + moutf(MOUT_GENERIC, "PRESENT_COOKIES %s", search_term); + } else { + moutf(MOUT_GENERIC, "PRESENT_COOKIES"); + } return NSERROR_OK; } @@ -243,12 +267,11 @@ static bool nslog_stream_configure(FILE *fptr) 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, + .present_cookies = gui_present_cookies, }; static void monkey_run(void) @@ -262,6 +285,9 @@ static void monkey_run(void) while (!monkey_done) { + /* discover the next scheduled event time */ + schedtm = monkey_schedule_run(); + /* clears fdset */ fetch_fdset(&read_fd_set, &write_fd_set, &exc_fd_set, &max_fd); @@ -272,14 +298,11 @@ static void monkey_run(void) 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: NSLOG(netsurf, INFO, "Iterate blocking"); - fprintf(stdout, "GENERIC POLL BLOCKING\n"); + moutf(MOUT_GENERIC, "POLL BLOCKING"); timeout = NULL; break; @@ -292,7 +315,7 @@ static void monkey_run(void) default: NSLOG(netsurf, INFO, "Iterate non-blocking"); - fprintf(stdout, "GENERIC POLL TIMED %d\n", schedtm); + moutf(MOUT_GENERIC, "POLL TIMED %d", schedtm); tv.tv_sec = schedtm / 1000; /* miliseconds to seconds */ tv.tv_usec = (schedtm % 1000) * 1000; /* remainder to microseconds */ timeout = &tv; @@ -305,6 +328,7 @@ static void monkey_run(void) &exc_fd_set, timeout); if (rdy_fd < 0) { + NSLOG(netsurf, CRITICAL, "Unable to select: %s", strerror(errno)); monkey_done = true; } else if (rdy_fd > 0) { if (FD_ISSET(0, &read_fd_set)) { @@ -314,6 +338,53 @@ static void monkey_run(void) } } +#if (!defined(NDEBUG) && defined(HAVE_EXECINFO)) +#include <execinfo.h> +static void *backtrace_buffer[4096]; + +void +__assert_fail(const char *__assertion, const char *__file, + unsigned int __line, const char *__function) +{ + int frames; + fprintf(stderr, + "MONKEY: Assertion failure!\n" + "%s:%d: %s: Assertion `%s` failed.\n", + __file, __line, __function, __assertion); + + frames = backtrace(&backtrace_buffer[0], 4096); + if (frames > 0 && frames < 4096) { + fprintf(stderr, "Backtrace:\n"); + fflush(stderr); + backtrace_symbols_fd(&backtrace_buffer[0], frames, 2); + } + + abort(); +} + +static void +signal_handler(int sig) +{ + int frames; + fprintf(stderr, "Caught signal %s (%d)\n", + ((sig == SIGSEGV) ? "SIGSEGV" : + ((sig == SIGILL) ? "SIGILL" : + ((sig == SIGFPE) ? "SIGFPE" : + ((sig == SIGBUS) ? "SIGBUS" : + "unknown signal")))), + sig); + frames = backtrace(&backtrace_buffer[0], 4096); + if (frames > 0 && frames < 4096) { + fprintf(stderr, "Backtrace:\n"); + fflush(stderr); + backtrace_symbols_fd(&backtrace_buffer[0], frames, 2); + } + + abort(); +} + +#endif + int main(int argc, char **argv) { @@ -328,8 +399,18 @@ main(int argc, char **argv) .fetch = monkey_fetch_table, .bitmap = monkey_bitmap_table, .layout = monkey_layout_table, + .llcache = filesystem_llcache_table, }; +#if (!defined(NDEBUG) && defined(HAVE_EXECINFO)) + /* Catch segfault, illegal instructions and fp exceptions */ + signal(SIGSEGV, signal_handler); + signal(SIGILL, signal_handler); + signal(SIGFPE, signal_handler); + /* It's unlikely, but SIGBUS could happen on some platforms */ + signal(SIGBUS, signal_handler); +#endif + ret = netsurf_register(&monkey_table); if (ret != NSERROR_OK) { die("NetSurf operation table failed registration"); @@ -377,6 +458,12 @@ main(int argc, char **argv) urldb_load(nsoption_charp(url_file)); urldb_load_cookies(nsoption_charp(cookie_file)); + /* Free resource paths now we're done finding resources */ + for (char **s = respaths; *s != NULL; s++) { + free(*s); + } + free(respaths); + ret = monkey_register_handler("QUIT", quit_handler); if (ret != NSERROR_OK) { die("quit handler failed to register"); @@ -392,14 +479,20 @@ main(int argc, char **argv) die("options handler failed to register"); } - fprintf(stdout, "GENERIC STARTED\n"); + ret = monkey_register_handler("LOGIN", monkey_login_handle_command); + if (ret != NSERROR_OK) { + die("login handler failed to register"); + } + + + moutf(MOUT_GENERIC, "STARTED"); monkey_run(); - fprintf(stdout, "GENERIC CLOSING_DOWN\n"); + moutf(MOUT_GENERIC, "CLOSING_DOWN"); monkey_kill_browser_windows(); netsurf_exit(); - fprintf(stdout, "GENERIC FINISHED\n"); + moutf(MOUT_GENERIC, "FINISHED"); /* finalise options */ nsoption_finalise(nsoptions, nsoptions_default); @@ -407,5 +500,8 @@ main(int argc, char **argv) /* finalise logging */ nslog_finalise(); + /* And free any monkey-specific bits */ + monkey_free_handlers(); + return 0; } diff --git a/frontends/monkey/options.h b/frontends/monkey/options.h index 57cce7e1f..8f6dd8b42 100644 --- a/frontends/monkey/options.h +++ b/frontends/monkey/options.h @@ -16,14 +16,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _NETSURF_MONKEY_OPTIONS_H_ -#define _NETSURF_MONKEY_OPTIONS_H_ +#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) @@ -31,7 +30,6 @@ 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) diff --git a/frontends/monkey/output.c b/frontends/monkey/output.c new file mode 100644 index 000000000..d7eb7cdb6 --- /dev/null +++ b/frontends/monkey/output.c @@ -0,0 +1,53 @@ +/* + * Copyright 2018 Vincent Sanders <vince@nexturf-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 <stdio.h> +#include <stdarg.h> + +#include "monkey/output.h" + +/** + * output type prefixes + */ +static const char *type_text[]={ + "DIE", + "ERROR", + "WARN", + "GENERIC", + "WINDOW", + "LOGIN", + "DOWNLOAD", + "PLOT", +}; + +/* exported interface documented in monkey/output.h */ +int moutf(enum monkey_output_type mout_type, const char *fmt, ...) +{ + va_list ap; + int res; + + res = fprintf(stdout, "%s ", type_text[mout_type]); + + va_start(ap, fmt); + res += vfprintf(stdout, fmt, ap); + va_end(ap); + + fputc('\n', stdout); + + return res + 1; +} diff --git a/frontends/monkey/cert.h b/frontends/monkey/output.h index 4470e2e72..8e6a0abd6 100644 --- a/frontends/monkey/cert.h +++ b/frontends/monkey/output.h @@ -1,5 +1,5 @@ /* - * Copyright 2012 Vincent Sanders <vince@netsurf-browser.org> + * Copyright 2018 Vincent Sanders <vince@netsurf-browser.org> * * This file is part of NetSurf, http://www.netsurf-browser.org/ * @@ -16,13 +16,20 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#ifndef _NETSURF_MONKEY_CERT_H_ -#define _NETSURF_MONKEY_CERT_H_ +#ifndef NS_MONKEY_OUTPUT_H +#define NS_MONKEY_OUTPUT_H -struct ssl_cert_info; +enum monkey_output_type { + MOUT_DIE, + MOUT_ERROR, + MOUT_WARNING, + MOUT_GENERIC, + MOUT_WINDOW, + MOUT_LOGIN, + MOUT_DOWNLOAD, + MOUT_PLOT, +}; -nserror gui_cert_verify(nsurl *url, const struct ssl_cert_info *certs, - unsigned long num, nserror (*cb)(bool proceed, void *pw), - void *cbpw); +int moutf(enum monkey_output_type mout_type, const char *fmt, ...); #endif diff --git a/frontends/monkey/plot.c b/frontends/monkey/plot.c index d00dca754..a8f0d61b6 100644 --- a/frontends/monkey/plot.c +++ b/frontends/monkey/plot.c @@ -22,6 +22,8 @@ #include "utils/errors.h" #include "netsurf/plotters.h" +#include "monkey/output.h" + /** * \brief Sets a clip rectangle for subsequent plot operations. * @@ -33,8 +35,7 @@ static nserror monkey_plot_clip(const struct redraw_context *ctx, const struct rect *clip) { - fprintf(stdout, - "PLOT CLIP X0 %d Y0 %d X1 %d Y1 %d\n", + moutf(MOUT_PLOT, "CLIP X0 %d Y0 %d X1 %d Y1 %d", clip->x0, clip->y0, clip->x1, clip->y1); return NSERROR_OK; } @@ -61,9 +62,8 @@ monkey_plot_arc(const struct redraw_context *ctx, const plot_style_t *style, int x, int y, int radius, int angle1, int angle2) { - fprintf(stdout, - "PLOT ARC X %d Y %d RADIUS %d ANGLE1 %d ANGLE2 %d\n", - x, y, radius, angle1, angle2); + moutf(MOUT_PLOT, "ARC X %d Y %d RADIUS %d ANGLE1 %d ANGLE2 %d", + x, y, radius, angle1, angle2); return NSERROR_OK; } @@ -85,9 +85,7 @@ monkey_plot_disc(const struct redraw_context *ctx, const plot_style_t *style, int x, int y, int radius) { - fprintf(stdout, - "PLOT DISC X %d Y %d RADIUS %d\n", - x, y, radius); + moutf(MOUT_PLOT, "DISC X %d Y %d RADIUS %d", x, y, radius); return NSERROR_OK; } @@ -108,8 +106,7 @@ monkey_plot_line(const struct redraw_context *ctx, const plot_style_t *style, const struct rect *line) { - fprintf(stdout, - "PLOT LINE X0 %d Y0 %d X1 %d Y1 %d\n", + moutf(MOUT_PLOT, "LINE X0 %d Y0 %d X1 %d Y1 %d", line->x0, line->y0, line->x1, line->y1); return NSERROR_OK; } @@ -133,8 +130,7 @@ monkey_plot_rectangle(const struct redraw_context *ctx, const plot_style_t *style, const struct rect *rect) { - fprintf(stdout, - "PLOT RECT X0 %d Y0 %d X1 %d Y1 %d\n", + moutf(MOUT_PLOT, "RECT X0 %d Y0 %d X1 %d Y1 %d", rect->x0, rect->y0, rect->x1, rect->y1); return NSERROR_OK; } @@ -160,9 +156,7 @@ monkey_plot_polygon(const struct redraw_context *ctx, const int *p, unsigned int n) { - fprintf(stdout, - "PLOT POLYGON VERTICIES %d\n", - n); + moutf(MOUT_PLOT, "POLYGON VERTICIES %d", n); return NSERROR_OK; } @@ -177,7 +171,6 @@ monkey_plot_polygon(const struct redraw_context *ctx, * \param pstyle Style controlling the path plot. * \param p elements of path * \param n nunber of elements on path - * \param width The width of the path * \param transform A transform to apply to the path. * \return NSERROR_OK on success else error code. */ @@ -186,12 +179,10 @@ monkey_plot_path(const struct redraw_context *ctx, const plot_style_t *pstyle, const float *p, unsigned int n, - float width, const float transform[6]) { - fprintf(stdout, - "PLOT PATH VERTICIES %d WIDTH %f\n", - n, width); + moutf(MOUT_PLOT, "PATH VERTICIES %d WIDTH %f", + n, plot_style_fixed_to_float(pstyle->stroke_width)); return NSERROR_OK; } @@ -229,9 +220,8 @@ monkey_plot_bitmap(const struct redraw_context *ctx, colour bg, bitmap_flags_t flags) { - fprintf(stdout, - "PLOT BITMAP X %d Y %d WIDTH %d HEIGHT %d\n", - x, y, width, height); + moutf(MOUT_PLOT, "BITMAP X %d Y %d WIDTH %d HEIGHT %d", + x, y, width, height); return NSERROR_OK; } @@ -255,9 +245,7 @@ monkey_plot_text(const struct redraw_context *ctx, const char *text, size_t length) { - fprintf(stdout, - "PLOT TEXT X %d Y %d STR %*s\n", - x, y, (int)length, text); + moutf(MOUT_PLOT, "TEXT X %d Y %d STR %.*s", x, y, (int)length, text); return NSERROR_OK; } @@ -273,7 +261,7 @@ static const struct plotter_table plotters = { .path = monkey_plot_path, .bitmap = monkey_plot_bitmap, .text = monkey_plot_text, - .option_knockout = true, + .option_knockout = true, }; const struct plotter_table* monkey_plotters = &plotters; diff --git a/frontends/monkey/schedule.c b/frontends/monkey/schedule.c index 3d76997f4..9d3ab7af8 100644 --- a/frontends/monkey/schedule.c +++ b/frontends/monkey/schedule.c @@ -43,6 +43,7 @@ struct nscallback * * \param callback callback function * \param p user parameter, passed to callback function + * \return NSERROR_OK if callback found and removed else NSERROR_NOT_FOUND * * All scheduled callbacks matching both callback and p are removed. */ @@ -51,10 +52,11 @@ static nserror schedule_remove(void (*callback)(void *p), void *p) struct nscallback *cur_nscb; struct nscallback *prev_nscb; struct nscallback *unlnk_nscb; + bool removed = false; /* check there is something on the list to remove */ if (schedule_list == NULL) { - return NSERROR_OK; + return NSERROR_NOT_FOUND; } NSLOG(schedule, DEBUG, "removing %p, %p", callback, p); @@ -80,6 +82,7 @@ static nserror schedule_remove(void (*callback)(void *p), void *p) prev_nscb->next = cur_nscb; } free (unlnk_nscb); + removed = true; } else { /* move to next element */ prev_nscb = cur_nscb; @@ -87,6 +90,9 @@ static nserror schedule_remove(void (*callback)(void *p), void *p) } } + if (removed == false) { + return NSERROR_NOT_FOUND; + } return NSERROR_OK; } @@ -99,7 +105,7 @@ nserror monkey_schedule(int tival, void (*callback)(void *p), void *p) /* ensure uniqueness of the callback and context */ ret = schedule_remove(callback, p); - if ((tival < 0) || (ret != NSERROR_OK)) { + if (tival < 0) { return ret; } |