summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--frontends/amiga/Makefile2
-rw-r--r--frontends/amiga/corewindow.c798
-rw-r--r--frontends/amiga/corewindow.h155
-rw-r--r--frontends/amiga/gui.c33
-rw-r--r--frontends/amiga/gui.h14
-rwxr-xr-xfrontends/amiga/object.h1
-rw-r--r--frontends/amiga/sslcert.c350
-rw-r--r--frontends/amiga/sslcert.h22
-rw-r--r--frontends/amiga/tree.c2
9 files changed, 1335 insertions, 42 deletions
diff --git a/frontends/amiga/Makefile b/frontends/amiga/Makefile
index f3c178ee6..8115f2f74 100644
--- a/frontends/amiga/Makefile
+++ b/frontends/amiga/Makefile
@@ -46,7 +46,7 @@ S_FRONTEND := gui.c tree.c history.c hotlist.c schedule.c file.c \
stringview/stringview.c stringview/urlhistory.c rtg.c \
agclass/amigaguide_class.c os3support.c font_diskfont.c \
selectmenu.c hash/xxhash.c font_cache.c font_bullet.c \
- nsoption.c desktop-tree.c
+ nsoption.c desktop-tree.c corewindow.c
# This is the final source build list
# Note this is deliberately *not* expanded here as common and image
diff --git a/frontends/amiga/corewindow.c b/frontends/amiga/corewindow.c
new file mode 100644
index 000000000..38b980a28
--- /dev/null
+++ b/frontends/amiga/corewindow.c
@@ -0,0 +1,798 @@
+/*
+ * Copyright 2017 Chris Young <chris@unsatisfactorysoftware.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/>.
+ */
+
+/**
+ * \file
+ * Amiga core window interface.
+ *
+ * Provides interface for core renderers to the Amiga Intuition drawable area.
+ *
+ * This module is an object that must be encapsulated. Client users
+ * should embed a struct ami_corewindow at the beginning of their
+ * context for this display surface, fill in relevant data and then
+ * call ami_corewindow_init()
+ *
+ * The Amiga core window structure requires the callback for draw, key and
+ * mouse operations.
+ */
+
+#include "amiga/os3support.h"
+
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+
+#include "utils/log.h"
+#include "utils/utils.h"
+#include "utils/messages.h"
+#include "utils/utf8.h"
+#include "netsurf/keypress.h"
+#include "netsurf/mouse.h"
+#include "desktop/plot_style.h"
+
+#include <proto/exec.h>
+#include <proto/intuition.h>
+#include <proto/layout.h>
+#include <proto/utility.h>
+
+#include <classes/window.h>
+#include <gadgets/layout.h>
+#include <gadgets/scroller.h>
+#include <gadgets/space.h>
+#include <intuition/icclass.h>
+#include <reaction/reaction_macros.h>
+
+#include "amiga/corewindow.h"
+#include "amiga/memory.h"
+#include "amiga/misc.h"
+#include "amiga/object.h"
+#include "amiga/schedule.h"
+#include "amiga/utf8.h"
+
+static void
+ami_cw_scroller_top(struct ami_corewindow *ami_cw, ULONG *restrict x, ULONG *restrict y)
+{
+ ULONG xs = 0;
+ ULONG ys = 0;
+
+ if(ami_cw->scroll_x_visible == true) {
+ GetAttr(SCROLLER_Top, ami_cw->objects[GID_CW_HSCROLL], (ULONG *)&xs);
+ }
+
+ if(ami_cw->scroll_y_visible == true) {
+ GetAttr(SCROLLER_Top, ami_cw->objects[GID_CW_VSCROLL], (ULONG *)&ys);
+ }
+
+ *x = xs;
+ *y = ys;
+}
+
+
+/**
+ * Convert co-ordinates relative to space.gadget
+ * into document co-ordinates
+ *
+ * @param ami_cw core window
+ * @param x co-ordinate, will be updated to new x co-ordinate
+ * @param y co-ordinate, will be updated to new y co-ordinate
+ */
+static void
+ami_cw_coord_amiga_to_ns(struct ami_corewindow *ami_cw, int *restrict x, int *restrict y)
+{
+ ULONG xs = 0;
+ ULONG ys = 0;
+
+ ami_cw_scroller_top(ami_cw, &xs, &ys);
+
+ *x = *x + xs;
+ *y = *y + ys;
+}
+
+
+/* get current mouse position in the draw area, adjusted for scroll.
+ * @return true if the mouse was in the draw area and co-ordinates updated
+ */
+static bool
+ami_cw_mouse_pos(struct ami_corewindow *ami_cw, int *restrict x, int *restrict y)
+{
+ int16 xm, ym;
+ ULONG xs, ys;
+ struct IBox *bbox;
+
+ xm = ami_cw->win->MouseX;
+ ym = ami_cw->win->MouseY;
+
+ if(ami_gui_get_space_box((Object *)ami_cw->objects[GID_CW_DRAW], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return false;
+ }
+
+ xm -= bbox->Left;
+ ym -= bbox->Top;
+
+ ami_gui_free_space_box(bbox);
+
+ if((xm < 0) || (ym < 0) || (xm > bbox->Width) || (ym > bbox->Height))
+ return false;
+
+ ami_cw_scroller_top(ami_cw, &xs, &ys);
+
+ xm += xs;
+ ym += ys;
+ *x = xm;
+ *y = ym;
+
+ return true;
+}
+
+/* handle keypress */
+static void
+ami_cw_key(struct ami_corewindow *ami_cw, int nskey)
+{
+ ami_cw->key(ami_cw, nskey);
+
+ switch(nskey) {
+ case NS_KEY_COPY_SELECTION:
+ /* if we've copied a selection we need to clear it - style guide rules */
+ ami_cw->key(ami_cw, NS_KEY_CLEAR_SELECTION);
+ break;
+
+ /* we may need to deal with scroll-related keys here */
+ }
+}
+
+
+/**
+ * Redraw functions
+ *
+ * This is slightly over-engineered as it was taken from the main browser/old tree redraws
+ * and supports deferred drawing of rectangles and tiling
+ */
+
+/**
+ * Redraw an area of a core window
+ *
+ * \param g a struct ami_corewindow
+ * \param r rect (in document co-ordinates)
+ */
+
+static void
+ami_cw_redraw_rect(struct ami_corewindow *ami_cw, struct rect *r)
+{
+ struct IBox *bbox;
+ ULONG pos_x, pos_y;
+ struct rect draw_rect;
+ int tile_size_x = ami_cw->gg.width;
+ int tile_size_y = ami_cw->gg.height;
+ int tile_x, tile_y, tile_w, tile_h;
+ int x = r->x0;
+ int y = r->y0;
+ int width = r->x1 - r->x0;
+ int height = r->y1 - r->y0;
+
+ struct redraw_context ctx = {
+ .interactive = true,
+ .background_images = true,
+ .plot = &amiplot
+ };
+
+ if(ami_gui_get_space_box((Object *)ami_cw->objects[GID_CW_DRAW], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return;
+ }
+
+ ami_cw_scroller_top(ami_cw, &pos_x, &pos_y);
+
+ glob = &ami_cw->gg;
+
+ if(x - pos_x + width > bbox->Width) width = bbox->Width - (x - pos_x);
+ if(y - pos_y + height > bbox->Height) height = bbox->Height - (y - pos_y);
+
+ if(x < pos_x) {
+ width -= pos_x - x;
+ x = pos_x;
+ }
+
+ if(y < pos_y) {
+ height -= pos_y - y;
+ y = pos_y;
+ }
+
+ for(tile_y = y; tile_y < (y + height); tile_y += tile_size_y) {
+ tile_h = tile_size_y;
+ if(((y + height) - tile_y) < tile_size_y)
+ tile_h = (y + height) - tile_y;
+
+ for(tile_x = x; tile_x < (x + width); tile_x += tile_size_x) {
+ tile_w = tile_size_x;
+ if(((x + width) - tile_x) < tile_size_x)
+ tile_w = (x + width) - tile_x;
+
+ draw_rect.x0 = tile_x; // was -
+ draw_rect.y0 = tile_y; // was -
+ draw_rect.x1 = tile_x + tile_w;
+ draw_rect.y1 = tile_y + tile_h;
+
+ ami_cw->draw(ami_cw, -tile_x, -tile_y, &draw_rect, &ctx);
+
+#ifdef __amigaos4__
+ BltBitMapTags(BLITA_SrcType, BLITT_BITMAP,
+ BLITA_Source, ami_cw->gg.bm,
+ BLITA_SrcX, 0,
+ BLITA_SrcY, 0,
+ BLITA_DestType, BLITT_RASTPORT,
+ BLITA_Dest, ami_cw->win->RPort,
+ BLITA_DestX, bbox->Left + tile_x - pos_x,
+ BLITA_DestY, bbox->Top + tile_y - pos_y,
+ BLITA_Width, tile_w,
+ BLITA_Height, tile_h,
+ TAG_DONE);
+#else
+ BltBitMapRastPort(ami_cw->gg.bm, 0, 0,
+ ami_cw->win->RPort, bbox->Left + tile_x - pos_x, bbox->Top + tile_y - pos_y,
+ tile_w, tile_h, 0xC0);
+#endif
+ }
+ }
+
+ ami_gui_free_space_box(bbox);
+ ami_clearclipreg(glob);
+ ami_gui_set_default_gg();
+}
+
+
+/**
+ * Draw the deferred rectangles
+ *
+ * @param draw set to false to just delete the queue
+ */
+static void ami_cw_redraw_queue(struct ami_corewindow *ami_cw, bool draw)
+{
+ struct nsObject *node;
+ struct nsObject *nnode;
+ struct rect *rect;
+
+ if(IsMinListEmpty(ami_cw->deferred_rects)) return;
+
+ if(draw == false) {
+ LOG("Ignoring deferred box redraw queue");
+ } // else should probably show busy pointer
+
+ node = (struct nsObject *)GetHead((struct List *)ami_cw->deferred_rects);
+
+ do {
+ if(draw == true) {
+ rect = (struct rect *)node->objstruct;
+ ami_cw_redraw_rect(ami_cw, rect);
+ }
+ nnode = (struct nsObject *)GetSucc((struct Node *)node);
+ ami_memory_itempool_free(ami_cw->deferred_rects_pool, node->objstruct, sizeof(struct rect));
+ DelObjectNoFree(node);
+ } while((node = nnode));
+}
+
+static void
+ami_cw_redraw_cb(void *p)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)p;
+
+ ami_cw_redraw_queue(ami_cw, true);
+}
+
+/**
+ * Queue a redraw of a rectangle
+ *
+ * @param ami_cw the core window to redraw
+ * @param r the rectangle (in doc coords) to redraw, or NULL for full window
+ */
+
+static void
+ami_cw_redraw(struct ami_corewindow *ami_cw, const struct rect *restrict r)
+{
+ struct nsObject *nsobj;
+ struct rect *restrict deferred_rect;
+ struct rect new_rect;
+
+ if(r == NULL) {
+ struct IBox *bbox;
+ if(ami_gui_get_space_box((Object *)ami_cw->objects[GID_CW_DRAW], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return;
+ }
+
+ new_rect.x0 = 0;
+ new_rect.y0 = 0;
+ ami_cw_coord_amiga_to_ns(ami_cw, &new_rect.x0, &new_rect.y0);
+ new_rect.x1 = new_rect.x0 + bbox->Width;
+ new_rect.y1 = new_rect.y0 + bbox->Height;
+
+ ami_gui_free_space_box(bbox);
+
+ r = &new_rect;
+ }
+
+ if(ami_gui_window_update_box_deferred_check(ami_cw->deferred_rects, r,
+ ami_cw->deferred_rects_pool)) {
+ deferred_rect = ami_memory_itempool_alloc(ami_cw->deferred_rects_pool, sizeof(struct rect));
+ CopyMem(r, deferred_rect, sizeof(struct rect));
+ nsobj = AddObject(ami_cw->deferred_rects, AMINS_RECT);
+ nsobj->objstruct = deferred_rect;
+ } else {
+ LOG("Ignoring duplicate or subset of queued box redraw");
+ }
+ ami_schedule(1, ami_cw_redraw_cb, ami_cw);
+}
+
+static void
+ami_cw_toggle_scrollbar(struct ami_corewindow *ami_cw, bool vert, bool visible)
+{
+ Object *scroller;
+ Object *layout;
+ ULONG tag;
+
+ if(vert == true) {
+ if(visible == ami_cw->scroll_y_visible) {
+ return;
+ } else {
+ scroller = ami_cw->objects[GID_CW_VSCROLL];
+ layout = ami_cw->objects[GID_CW_VSCROLLLAYOUT];
+ tag = WINDOW_VertProp;
+ ami_cw->scroll_y_visible = visible;
+ }
+ } else {
+ if(visible == ami_cw->scroll_x_visible) {
+ return;
+ } else {
+ scroller = ami_cw->objects[GID_CW_HSCROLL];
+ layout = ami_cw->objects[GID_CW_HSCROLLLAYOUT];
+ tag = WINDOW_HorizProp;
+ ami_cw->scroll_x_visible = visible;
+ }
+ }
+
+ if(visible == true) {
+ if(ami_cw->in_border_scroll == true) {
+ SetAttrs(ami_cw->objects[GID_CW_WIN],
+ tag, 1,
+ TAG_DONE);
+ } else {
+#ifdef __amigaos4__
+ IDoMethod(layout, LM_ADDCHILD, ami_cw->win, scroller, NULL);
+#else
+ SetAttrs(layout, LAYOUT_AddChild, scroller, TAG_DONE);
+#endif
+ }
+ } else {
+ if(ami_cw->in_border_scroll == true) {
+ SetAttrs(ami_cw->objects[GID_CW_WIN],
+ tag, -1,
+ TAG_DONE);
+ } else {
+#ifdef __amigaos4__
+ IDoMethod(layout, LM_REMOVECHILD, ami_cw->win, scroller);
+#else
+ SetAttrs(layout, LAYOUT_RemoveChild, scroller, TAG_DONE);
+#endif
+ }
+ }
+
+#if 0
+ /* in-window scrollbars aren't getting hidden until the window is resized
+ * this code should fix it, but it isn't working */
+ if(ami_cw->in_border_scroll == false) {
+ FlushLayoutDomainCache((struct Gadget *)ami_cw->objects[GID_CW_WIN]);
+ RethinkLayout((struct Gadget *)ami_cw->objects[GID_CW_WIN],
+ ami_cw->win, NULL, TRUE);
+
+ /* probably need to redraw here */
+ ami_cw_redraw(ami_cw, NULL);
+ }
+#endif
+}
+
+static void
+ami_cw_close(void *w)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)w;
+
+ ami_cw->close(ami_cw);
+}
+
+HOOKF(void, ami_cw_idcmp_hook, Object *, object, struct IntuiMessage *)
+{
+ struct ami_corewindow *ami_cw = hook->h_Data;
+ struct IntuiWheelData *wheel;
+ ULONG gid = GetTagData( GA_ID, 0, msg->IAddress );
+
+ switch(msg->Class)
+ {
+ case IDCMP_IDCMPUPDATE:
+ switch(gid)
+ {
+ case GID_CW_HSCROLL:
+ case GID_CW_VSCROLL:
+ ami_cw_redraw(ami_cw, NULL);
+ break;
+ }
+ break;
+#ifdef __amigaos4__
+ case IDCMP_EXTENDEDMOUSE:
+ if(msg->Code == IMSGCODE_INTUIWHEELDATA)
+ {
+ wheel = (struct IntuiWheelData *)msg->IAddress;
+
+ //ami_tree_scroll(twin, (wheel->WheelX * 20), (wheel->WheelY * 20));
+ }
+ break;
+#endif
+ }
+}
+
+
+/**
+ * Main event loop for our core window
+ *
+ * \return TRUE if window destroyed
+ */
+static BOOL
+ami_cw_event(void *w)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)w;
+
+ ULONG result;
+ ULONG storage;
+ uint16 code;
+ struct InputEvent *ie;
+ int nskey;
+ int key_state = 0;
+ struct timeval curtime;
+ int x = 0, y = 0;
+
+ while((result = RA_HandleInput(ami_cw->objects[GID_CW_WIN], &code)) != WMHI_LASTMSG) {
+ switch(result & WMHI_CLASSMASK) {
+ case WMHI_MOUSEMOVE:
+ if(ami_cw_mouse_pos(ami_cw, &x, &y)) {
+ key_state = ami_gui_get_quals(ami_cw->objects[GID_CW_WIN]);
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ }
+ break;
+
+ case WMHI_MOUSEBUTTONS:
+ if(ami_cw_mouse_pos(ami_cw, &x, &y) == false)
+ break;
+
+ key_state = ami_gui_get_quals(ami_cw->objects[GID_CW_WIN]);
+
+ switch(code) {
+ case SELECTDOWN:
+ ami_cw->mouse_state = BROWSER_MOUSE_PRESS_1;
+ break;
+
+ case MIDDLEDOWN:
+ ami_cw->mouse_state = BROWSER_MOUSE_PRESS_2;
+ break;
+
+ case SELECTUP:
+ if(ami_cw->mouse_state & BROWSER_MOUSE_PRESS_1) {
+ CurrentTime((ULONG *)&curtime.tv_sec, (ULONG *)&curtime.tv_usec);
+
+ ami_cw->mouse_state = BROWSER_MOUSE_CLICK_1;
+
+ if(ami_cw->lastclick.tv_sec) {
+ if(DoubleClick(ami_cw->lastclick.tv_sec,
+ ami_cw->lastclick.tv_usec,
+ curtime.tv_sec, curtime.tv_usec))
+ ami_cw->mouse_state |= BROWSER_MOUSE_DOUBLE_CLICK;
+ }
+
+ if(ami_cw->mouse_state & BROWSER_MOUSE_DOUBLE_CLICK) {
+ ami_cw->lastclick.tv_sec = 0;
+ ami_cw->lastclick.tv_usec = 0;
+ } else {
+ ami_cw->lastclick.tv_sec = curtime.tv_sec;
+ ami_cw->lastclick.tv_usec = curtime.tv_usec;
+ }
+ }
+
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ ami_cw->mouse_state = BROWSER_MOUSE_HOVER;
+ break;
+
+ case MIDDLEUP:
+ if(ami_cw->mouse_state & BROWSER_MOUSE_PRESS_2)
+ ami_cw->mouse_state = BROWSER_MOUSE_CLICK_2;
+
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ ami_cw->mouse_state = BROWSER_MOUSE_HOVER;
+ break;
+ }
+ ami_cw->mouse(ami_cw, ami_cw->mouse_state | key_state, x, y);
+ break;
+
+ case WMHI_RAWKEY:
+ storage = result & WMHI_GADGETMASK;
+
+ GetAttr(WINDOW_InputEvent, ami_cw->objects[GID_CW_WIN], (ULONG *)&ie);
+ nskey = ami_key_to_nskey(storage, ie);
+
+ ami_cw_key(ami_cw, nskey);
+ break;
+
+ case WMHI_NEWSIZE:
+ ami_cw_redraw(ami_cw, NULL);
+ break;
+
+ case WMHI_CLOSEWINDOW:
+ ami_cw_close(ami_cw);
+ return TRUE;
+ break;
+
+ case WMHI_GADGETUP:
+ switch(result & WMHI_GADGETMASK) {
+ case GID_CW_HSCROLL:
+ case GID_CW_VSCROLL:
+ ami_cw_redraw(ami_cw, NULL);
+ break;
+
+ default:
+ /* pass the event to the window owner */
+ if(ami_cw->event != NULL)
+ if(ami_cw->event(ami_cw, result) == TRUE) {
+ return TRUE;
+ }
+ break;
+ }
+
+ default:
+ /* pass the event to the window owner */
+ if(ami_cw->event != NULL)
+ if(ami_cw->event(ami_cw, result) == TRUE) {
+ return TRUE;
+ }
+ break;
+ }
+ };
+
+ return FALSE;
+}
+
+static const struct ami_win_event_table ami_cw_table = {
+ ami_cw_event,
+ ami_cw_close,
+};
+
+/**
+ * callback from core to request a redraw
+ */
+static void
+ami_cw_redraw_request(struct core_window *cw, const struct rect *r)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+
+ ami_cw_redraw(ami_cw, r);
+}
+
+
+static void
+ami_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+ struct IBox *bbox;
+
+ if(ami_gui_get_space_box((Object *)ami_cw->objects[GID_CW_DRAW], &bbox) != NSERROR_OK) {
+ amiga_warn_user("NoMemory", "");
+ return;
+ }
+
+ *width = bbox->Width;
+ *height = bbox->Height;
+
+ ami_gui_free_space_box(bbox);
+}
+
+
+static void
+ami_cw_update_size(struct core_window *cw, int width, int height)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+ int win_w, win_h;
+
+ ami_cw_get_window_dimensions((struct core_window *)ami_cw, &win_w, &win_h);
+
+ if(width == -1) {
+ ami_cw_toggle_scrollbar(ami_cw, false, false);
+ return;
+ }
+
+ if(height == -1) {
+ ami_cw_toggle_scrollbar(ami_cw, true, false);
+ return;
+ }
+
+ if(ami_cw->objects[GID_CW_VSCROLL]) {
+ ami_cw_toggle_scrollbar(ami_cw, true, true);
+ RefreshSetGadgetAttrs((struct Gadget *)ami_cw->objects[GID_CW_VSCROLL], ami_cw->win, NULL,
+ SCROLLER_Total, (ULONG)height,
+ SCROLLER_Visible, win_h,
+ TAG_DONE);
+ }
+
+ if(ami_cw->objects[GID_CW_HSCROLL]) {
+ ami_cw_toggle_scrollbar(ami_cw, false, true);
+ RefreshSetGadgetAttrs((struct Gadget *)ami_cw->objects[GID_CW_HSCROLL], ami_cw->win, NULL,
+ SCROLLER_Total, (ULONG)width,
+ SCROLLER_Visible, win_w,
+ TAG_DONE);
+ }
+}
+
+
+static void
+ami_cw_scroll_visible(struct core_window *cw, const struct rect *r)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+
+ int scrollsetx;
+ int scrollsety;
+ int win_w = 0, win_h = 0;
+ ULONG win_x0, win_y0;
+ int win_x1, win_y1;
+
+ ami_cw_get_window_dimensions((struct core_window *)ami_cw, &win_w, &win_h);
+
+ ami_cw_scroller_top(ami_cw, &win_x0, &win_y0);
+
+ win_x1 = win_x0 + win_w;
+ win_y1 = win_y0 + win_h;
+
+ if(r->y1 > win_y1) scrollsety = r->y1 - win_h;
+ if(r->y0 < win_y0) scrollsety = r->y0;
+ if(r->x1 > win_x1) scrollsetx = r->x1 - win_w;
+ if(r->x0 < win_x0) scrollsetx = r->x0;
+
+ if(ami_cw->scroll_y_visible == true) {
+ RefreshSetGadgetAttrs((APTR)ami_cw->objects[GID_CW_VSCROLL], ami_cw->win, NULL,
+ SCROLLER_Top, scrollsety,
+ TAG_DONE);
+ }
+
+ if(ami_cw->scroll_x_visible == true) {
+ RefreshSetGadgetAttrs((APTR)ami_cw->objects[GID_CW_HSCROLL], ami_cw->win, NULL,
+ SCROLLER_Top, scrollsetx,
+ TAG_DONE);
+ }
+
+ /* probably need to redraw here */
+ ami_cw_redraw(ami_cw, NULL);
+}
+
+
+static void
+ami_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)cw;
+ ami_cw->drag_status = ds;
+}
+
+
+struct core_window_callback_table ami_cw_cb_table = {
+ .redraw_request = ami_cw_redraw_request,
+ .update_size = ami_cw_update_size,
+ .scroll_visible = ami_cw_scroll_visible,
+ .get_window_dimensions = ami_cw_get_window_dimensions,
+ .drag_status = ami_cw_drag_status
+};
+
+/* exported function documented example/corewindow.h */
+nserror ami_corewindow_init(struct ami_corewindow *ami_cw)
+{
+ /* setup the core window callback table */
+ ami_cw->cb_table = &ami_cw_cb_table;
+
+ /* clear some vars */
+ ami_cw->mouse_state = BROWSER_MOUSE_HOVER;
+ ami_cw->lastclick.tv_sec = 0;
+ ami_cw->lastclick.tv_usec = 0;
+ ami_cw->scroll_x_visible = true;
+ ami_cw->scroll_y_visible = true;
+ ami_cw->in_border_scroll = false;
+
+ /* allocate drawing area etc */
+ ami_init_layers(&ami_cw->gg, 0, 0, false);
+ ami_cw->gg.shared_pens = ami_AllocMinList();
+
+ ami_cw->deferred_rects = NewObjList();
+ ami_cw->deferred_rects_pool = ami_memory_itempool_create(sizeof(struct rect));
+
+ /* add the core window to our window list so we process events */
+ ami_gui_win_list_add(ami_cw, AMINS_COREWINDOW, &ami_cw_table);
+
+ /* set up the IDCMP hook for event processing (extended mouse, scrollbars) */
+ ami_cw->idcmp_hook.h_Entry = (void *)ami_cw_idcmp_hook;
+ ami_cw->idcmp_hook.h_Data = ami_cw;
+
+ /* open the window */
+ ami_cw->win = (struct Window *)RA_OpenWindow(ami_cw->objects[GID_CW_WIN]);
+
+ /* attach the scrollbars for event processing _if they are in the window border_ */
+ if(ami_cw->objects[GID_CW_HSCROLL] == NULL) {
+ GetAttr(WINDOW_HorizObject, ami_cw->objects[GID_CW_WIN],
+ (ULONG *)&ami_cw->objects[GID_CW_HSCROLL]);
+
+ RefreshSetGadgetAttrs((APTR)ami_cw->objects[GID_CW_HSCROLL], ami_cw->win, NULL,
+ GA_ID, GID_CW_HSCROLL,
+ ICA_TARGET, ICTARGET_IDCMP,
+ TAG_DONE);
+
+ ami_cw->in_border_scroll = true;
+ }
+
+ if(ami_cw->objects[GID_CW_VSCROLL] == NULL) {
+ GetAttr(WINDOW_VertObject, ami_cw->objects[GID_CW_WIN],
+ (ULONG *)&ami_cw->objects[GID_CW_VSCROLL]);
+
+ RefreshSetGadgetAttrs((APTR)ami_cw->objects[GID_CW_VSCROLL], ami_cw->win, NULL,
+ GA_ID, GID_CW_VSCROLL,
+ ICA_TARGET, ICTARGET_IDCMP,
+ TAG_DONE);
+
+ ami_cw->in_border_scroll = true;
+ }
+
+ return NSERROR_OK;
+}
+
+/* exported interface documented in example/corewindow.h */
+nserror ami_corewindow_fini(struct ami_corewindow *ami_cw)
+{
+ /* remove any pending redraws */
+ ami_schedule(-1, ami_cw_redraw_cb, ami_cw);
+ FreeObjList(ami_cw->deferred_rects);
+ ami_memory_itempool_delete(ami_cw->deferred_rects_pool);
+
+ /* destroy the window */
+ ami_cw->win = NULL;
+ DisposeObject(ami_cw->objects[GID_CW_WIN]);
+
+#if 0
+ /* ensure our scrollbars are destroyed */
+ /* it appears these are disposed anyway,
+ * even if the gadgets are no longer attached to the window */
+ if(ami_cw->in_border_scroll == false) {
+ if(ami_cw->scroll_x_visible == false) {
+ DisposeObject(ami_cw->objects[GID_CW_HSCROLL]);
+ }
+ if(ami_cw->scroll_y_visible == false) {
+ DisposeObject(ami_cw->objects[GID_CW_VSCROLL]);
+ }
+ }
+#endif
+
+ /* release off-screen bitmap stuff */
+ ami_plot_release_pens(ami_cw->gg.shared_pens);
+ ami_free_layers(&ami_cw->gg);
+
+ /* free the window title */
+ ami_utf8_free(ami_cw->wintitle);
+
+ /* remove the core window from our window list */
+ ami_gui_win_list_remove(ami_cw);
+
+ return NSERROR_OK;
+}
+
diff --git a/frontends/amiga/corewindow.h b/frontends/amiga/corewindow.h
new file mode 100644
index 000000000..8d93882d7
--- /dev/null
+++ b/frontends/amiga/corewindow.h
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2017 Chris Young <chris@unsatisfactorysoftware.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 AMIGA_COREWINDOW_H
+#define AMIGA_COREWINDOW_H
+
+#include "netsurf/core_window.h"
+
+#include "amiga/gui.h" /* need to know the size of ami_generic_window :( */
+#include "amiga/plotters.h"
+
+/**
+ * BOOPSI objects
+ */
+
+enum {
+ GID_CW_WIN = 0, /* window object */
+ GID_CW_MAIN, /* root layout object */
+ GID_CW_DRAW, /* drawing area (space.gadget) */
+ GID_CW_HSCROLL, /* horizontal scroller */
+ GID_CW_VSCROLL, /* vertical scroller */
+ GID_CW_HSCROLLLAYOUT, /* horizontal scroller container*/
+ GID_CW_VSCROLLLAYOUT, /* vertical scroller container */
+ GID_CW_LAST
+};
+
+/**
+ * Amiga core window state
+ */
+struct ami_corewindow {
+ /*
+ * Any variables common to any frontend window would go here.
+ * e.g. drawing area handles, toolkit pointers or other state
+ */
+ struct ami_generic_window w;
+ struct Window *win;
+ Object *objects[GID_CW_LAST];
+
+ struct Hook idcmp_hook;
+ struct timeval lastclick;
+
+ int mouse_state;
+
+ APTR deferred_rects_pool;
+ struct MinList *deferred_rects;
+
+ /** keep track of the scrollbar type we're using */
+ bool in_border_scroll;
+ bool scroll_x_visible;
+ bool scroll_y_visible;
+
+ /** window title, must be allocated wth ami_utf8 function */
+ char *wintitle;
+
+ /** stuff for our off-screen render bitmap */
+ struct gui_globals gg;
+ struct MinList *shared_pens;
+
+ /** drag status set by core */
+ core_window_drag_status drag_status;
+
+ /** table of callbacks for core window operations */
+ struct core_window_callback_table *cb_table;
+
+ /**
+ * callback to draw on drawable area of Amiga core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param x Plot origin (X)
+ * \param r Plot origin (Y)
+ * \param r The rectangle of the window that needs updating.
+ * \param ctx Redraw context
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+ nserror (*draw)(struct ami_corewindow *ami_cw, int x, int y, struct rect *r,
+ struct redraw_context *ctx);
+
+ /**
+ * callback for keypress on Amiga core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param nskey The netsurf key code.
+ * \return NSERROR_OK if key processed,
+ * NSERROR_NOT_IMPLEMENTED if key not processed
+ * otherwise apropriate error code
+ */
+ nserror (*key)(struct ami_corewindow *ami_cw, uint32_t nskey);
+
+ /**
+ * callback for mouse event on Amiga core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param mouse_state mouse state
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on sucess otherwise apropriate error code.
+ */
+ nserror (*mouse)(struct ami_corewindow *ami_cw, browser_mouse_state mouse_state, int x, int y);
+
+ /**
+ * callback for unknown events on Amiga core window
+ * eg. buttons in the ssl cert window
+ * (result & WMHI_CLASSMASK) gives the class of event (eg. WMHI_GADGETUP)
+ * (result & WMHI_GADGETMASK) gives the gadget ID (eg. GID_SSLCERT_ACCEPT)
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param result event as returned by RA_HandleInput()
+ * \return TRUE if window closed during event processing
+ */
+ BOOL (*event)(struct ami_corewindow *ami_cw, ULONG result);
+
+ /**
+ * callback to close an Amiga core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ */
+ void (*close)(struct ami_corewindow *ami_cw);
+
+};
+
+/**
+ * initialise elements of Amiga core window.
+ *
+ * As a pre-requisite the draw, key and mouse callbacks must be defined
+ *
+ * \param example_cw An Amiga core window structure to initialise
+ * \return NSERROR_OK on successful initialisation otherwise error code.
+ */
+nserror ami_corewindow_init(struct ami_corewindow *ami_cw);
+
+/**
+ * finalise elements of Amiga core window.
+ *
+ * \param ami_cw An Amiga core window structure to finialise
+ * \return NSERROR_OK on successful finalisation otherwise error code.
+ */
+nserror ami_corewindow_fini(struct ami_corewindow *ami_cw);
+
+#endif
+
diff --git a/frontends/amiga/gui.c b/frontends/amiga/gui.c
index ba0a786e3..f94090b75 100644
--- a/frontends/amiga/gui.c
+++ b/frontends/amiga/gui.c
@@ -1376,27 +1376,34 @@ int ami_key_to_nskey(ULONG keycode, struct InputEvent *ie)
return nskey;
}
-static void ami_update_quals(struct gui_window_2 *gwin)
+int ami_gui_get_quals(Object *win_obj)
{
uint32 quals = 0;
+ int key_state = 0;
#ifdef __amigaos4__
- GetAttr(WINDOW_Qualifier,gwin->objects[OID_MAIN],(uint32 *)&quals);
+ GetAttr(WINDOW_Qualifier, win_obj, (uint32 *)&quals);
#else
#warning qualifier needs fixing for OS3
#endif
- gwin->key_state = 0;
if(quals & NSA_QUAL_SHIFT) {
- gwin->key_state |= BROWSER_MOUSE_MOD_1;
+ key_state |= BROWSER_MOUSE_MOD_1;
}
if(quals & IEQUALIFIER_CONTROL) {
- gwin->key_state |= BROWSER_MOUSE_MOD_2;
+ key_state |= BROWSER_MOUSE_MOD_2;
}
if(quals & NSA_QUAL_ALT) {
- gwin->key_state |= BROWSER_MOUSE_MOD_3;
+ key_state |= BROWSER_MOUSE_MOD_3;
}
+
+ return key_state;
+}
+
+static void ami_update_quals(struct gui_window_2 *gwin)
+{
+ gwin->key_state = ami_gui_get_quals(gwin->objects[OID_MAIN]);
}
/* exported interface documented in amiga/gui.h */
@@ -1682,7 +1689,7 @@ static bool ami_gui_hscroll_remove(struct gui_window_2 *gwin)
IDoMethod(gwin->objects[GID_HSCROLLLAYOUT], LM_REMOVECHILD,
gwin->win, gwin->objects[GID_HSCROLL]);
#else
- SetAttrs(gwin->objects[GID_HSCROLLLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_HSCROLL]);
+ SetAttrs(gwin->objects[GID_HSCROLLLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_HSCROLL], TAG_DONE);
#endif
gwin->objects[GID_HSCROLL] = NULL;
@@ -1727,7 +1734,7 @@ static bool ami_gui_vscroll_remove(struct gui_window_2 *gwin)
IDoMethod(gwin->objects[GID_VSCROLLLAYOUT], LM_REMOVECHILD,
gwin->win, gwin->objects[GID_VSCROLL]);
#else
- SetAttrs(gwin->objects[GID_VSCROLLLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_VSCROLL]);
+ SetAttrs(gwin->objects[GID_VSCROLLLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_VSCROLL], TAG_DONE);
#endif
gwin->objects[GID_VSCROLL] = NULL;
@@ -3259,8 +3266,10 @@ static void ami_gui_hotlist_toolbar_remove(struct gui_window_2 *gwin)
IDoMethod(gwin->objects[GID_HOTLISTLAYOUT], LM_REMOVECHILD,
gwin->win, gwin->objects[GID_HOTLISTSEPBAR]);
#else
- SetAttrs(gwin->objects[GID_HOTLISTLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_HOTLIST]);
- SetAttrs(gwin->objects[GID_HOTLISTLAYOUT], LAYOUT_RemoveChild, gwin->objects[GID_HOTLISTSEPBAR]);
+ SetAttrs(gwin->objects[GID_HOTLISTLAYOUT],
+ LAYOUT_RemoveChild, gwin->objects[GID_HOTLIST], TAG_DONE);
+ SetAttrs(gwin->objects[GID_HOTLISTLAYOUT],
+ LAYOUT_RemoveChild, gwin->objects[GID_HOTLISTSEPBAR], TAG_DONE);
#endif
FlushLayoutDomainCache((struct Gadget *)gwin->objects[GID_MAIN]);
@@ -4734,7 +4743,7 @@ static void ami_gui_window_update_box_deferred(struct gui_window *g, bool draw)
if(draw == true) ami_reset_pointer(g->shared);
}
-static bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects,
+bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects,
const struct rect *restrict new_rect, APTR mempool)
{
struct nsObject *node;
@@ -5603,7 +5612,7 @@ static struct gui_misc_table amiga_misc_table = {
.quit = gui_quit,
.launch_url = gui_launch_url,
- .cert_verify = gui_cert_verify,
+ .cert_verify = ami_cert_verify,
.login = gui_401login_open,
};
diff --git a/frontends/amiga/gui.h b/frontends/amiga/gui.h
index eb39e9e47..4c3e586d7 100644
--- a/frontends/amiga/gui.h
+++ b/frontends/amiga/gui.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2008-2016 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ * Copyright 2008-2017 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -282,5 +282,17 @@ nserror ami_gui_win_list_add(void *win, int type, const struct ami_win_event_tab
* Remove a window from the NetSurf window list
*/
void ami_gui_win_list_remove(void *win);
+
+/**
+ * Get which qualifier keys are being pressed
+ */
+int ami_gui_get_quals(Object *win_obj);
+
+/**
+ * Check rect is not already queued for redraw
+ */
+bool ami_gui_window_update_box_deferred_check(struct MinList *deferred_rects,
+ const struct rect *restrict new_rect, APTR mempool);
+
#endif
diff --git a/frontends/amiga/object.h b/frontends/amiga/object.h
index be9650413..70bb550f8 100755
--- a/frontends/amiga/object.h
+++ b/frontends/amiga/object.h
@@ -33,6 +33,7 @@ enum
AMINS_HISTORYWINDOW,
AMINS_GUIOPTSWINDOW,
AMINS_PRINTWINDOW,
+ AMINS_COREWINDOW,
AMINS_FONT,
AMINS_MIME,
AMINS_RECT
diff --git a/frontends/amiga/sslcert.c b/frontends/amiga/sslcert.c
index 83798f2e2..d56a1fe13 100644
--- a/frontends/amiga/sslcert.c
+++ b/frontends/amiga/sslcert.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -16,39 +16,347 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <proto/exec.h>
+/**
+ * \file
+ * Implementation of Amiga certificate viewing using core windows.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+
+#include <proto/intuition.h>
+
+#include <classes/window.h>
+#include <gadgets/button.h>
+#include <gadgets/layout.h>
+#include <gadgets/scroller.h>
+#include <gadgets/space.h>
+#include <images/label.h>
+
+#include <reaction/reaction_macros.h>
-#include "utils/nsurl.h"
-#include "content/llcache.h"
-#include "netsurf/mouse.h"
-#include "netsurf/window.h"
+#include "utils/log.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
#include "desktop/sslcert_viewer.h"
+#include "utils/messages.h"
-#include "amiga/tree.h"
+#include "amiga/corewindow.h"
+#include "amiga/libs.h"
#include "amiga/sslcert.h"
+#include "amiga/utf8.h"
+
+
+/**
+ * Amiga certificate viewing window context
+ */
+enum {
+ GID_SSLCERT_ACCEPT = GID_CW_LAST,
+ GID_SSLCERT_REJECT,
+ GID_SSLCERT_LAST
+};
+
+#define GID_SSLCERT_SIZE GID_SSLCERT_LAST - GID_CW_LAST
+
+struct ami_crtvrfy_window {
+ /** Amiga core window context */
+ struct ami_corewindow core;
+
+ /** Amiga GUI stuff */
+ Object *sslcert_objects[GID_SSLCERT_LAST]; // technically wasting a few bytes here
+
+ char *sslerr;
+ char *sslaccept;
+ char *sslreject;
+
+ /** SSL certificate viewer context data */
+ struct sslcert_session_data *ssl_data;
+};
+
+/**
+ * destroy a previously created certificate view
+ */
+static nserror
+ami_crtvrfy_destroy(struct ami_crtvrfy_window *crtvrfy_win)
+{
+ nserror res;
+
+ res = sslcert_viewer_fini(crtvrfy_win->ssl_data);
+ if (res == NSERROR_OK) {
+ ami_utf8_free(crtvrfy_win->sslerr);
+ ami_utf8_free(crtvrfy_win->sslaccept);
+ ami_utf8_free(crtvrfy_win->sslreject);
+ res = ami_corewindow_fini(&crtvrfy_win->core); /* closes the window for us */
+ }
+ return res;
+}
-nserror gui_cert_verify(nsurl *url,
- const struct ssl_cert_info *certs, unsigned long num,
- nserror (*cb)(bool proceed, void *pw), void *cbpw)
+static void
+ami_crtvrfy_accept(struct ami_corewindow *ami_cw)
{
- struct sslcert_session_data *data;
- struct treeview_window *ssl_window;
+ struct ami_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
- sslcert_viewer_create_session_data(num, url, cb, cbpw,
- certs, &data);
- ssl_current_session = data;
+ sslcert_viewer_accept(crtvrfy_win->ssl_data);
- ssl_window = ami_tree_create(TREE_SSLCERT, data);
- if (!ssl_window) {
- return NSERROR_INIT_FAILED;
+ ami_crtvrfy_destroy(crtvrfy_win);
+}
+
+static void
+ami_crtvrfy_reject(struct ami_corewindow *ami_cw)
+{
+ struct ami_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
+
+ sslcert_viewer_reject(crtvrfy_win->ssl_data);
+
+ ami_crtvrfy_destroy(crtvrfy_win);
+}
+
+/**
+ * callback for unknown events on Amiga core window
+ * eg. buttons in the ssl cert window
+ * (result & WMHI_CLASSMASK) gives the class of event (eg. WMHI_GADGETUP)
+ * (result & WMHI_GADGETMASK) gives the gadget ID (eg. GID_SSLCERT_ACCEPT)
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param result event as returned by RA_HandleInput()
+ * \return TRUE if window closed during event processing
+ */
+static BOOL
+ami_crtvrfy_event(struct ami_corewindow *ami_cw, ULONG result)
+{
+ if((result & WMHI_CLASSMASK) == WMHI_GADGETUP) {
+ switch(result & WMHI_GADGETMASK) {
+ case GID_SSLCERT_ACCEPT:
+ ami_crtvrfy_accept(ami_cw);
+ return TRUE;
+ break;
+
+ case GID_SSLCERT_REJECT:
+ ami_crtvrfy_reject(ami_cw);
+ return TRUE;
+ break;
+ }
}
+ return FALSE;
+}
- ami_tree_open(ssl_window, AMI_TREE_SSLCERT);
+/**
+ * callback for mouse action for certificate verify on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param mouse_state netsurf mouse state on event
+ * \param x location of event
+ * \param y location of event
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_crtvrfy_mouse(struct ami_corewindow *ami_cw,
+ browser_mouse_state mouse_state,
+ int x, int y)
+{
+ struct ami_crtvrfy_window *crtvrfy_win;
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
+
+ sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
return NSERROR_OK;
}
-void ami_ssl_free(struct treeview_window *twin)
+/**
+ * callback for keypress for certificate verify on core window
+ *
+ * \param example_cw The Amiga core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_crtvrfy_key(struct ami_corewindow *ami_cw, uint32_t nskey)
{
- ami_tree_destroy(twin);
+ struct ami_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
+
+ if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
+ return NSERROR_OK;
+ }
+ return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback on draw event for certificate verify on core window
+ *
+ * \param ami_cw The Amiga core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \param ctx The drawing context
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+ami_crtvrfy_draw(struct ami_corewindow *ami_cw, int x, int y, struct rect *r, struct redraw_context *ctx)
+{
+ struct ami_crtvrfy_window *crtvrfy_win;
+
+ /* technically degenerate container of */
+ crtvrfy_win = (struct ami_crtvrfy_window *)ami_cw;
+
+ sslcert_viewer_redraw(crtvrfy_win->ssl_data, x, y, r, ctx);
+
+ return NSERROR_OK;
+}
+
+static nserror
+ami_crtvrfy_create_window(struct ami_crtvrfy_window *crtvrfy_win)
+{
+ struct ami_corewindow *ami_cw = (struct ami_corewindow *)&crtvrfy_win->core;
+
+ ami_cw->objects[GID_CW_WIN] = WindowObj,
+ WA_ScreenTitle, ami_gui_get_screen_title(),
+ WA_Title, ami_cw->wintitle,
+ WA_Activate, TRUE,
+ WA_DepthGadget, TRUE,
+ WA_DragBar, TRUE,
+ WA_CloseGadget, FALSE,
+ WA_SizeGadget, TRUE,
+ WA_SizeBBottom, TRUE,
+ WA_Height, scrn->Height / 2,
+ WA_PubScreen, scrn,
+ WA_ReportMouse, TRUE,
+ WA_IDCMP, IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_NEWSIZE |
+ IDCMP_RAWKEY | IDCMP_GADGETUP | IDCMP_IDCMPUPDATE |
+ IDCMP_EXTENDEDMOUSE | IDCMP_SIZEVERIFY,
+ WINDOW_IDCMPHook, &ami_cw->idcmp_hook,
+ WINDOW_IDCMPHookBits, IDCMP_IDCMPUPDATE | IDCMP_EXTENDEDMOUSE,
+ WINDOW_SharedPort, sport,
+ WINDOW_UserData, crtvrfy_win,
+ /* WINDOW_NewMenu, twin->menu, -> No menu for SSL Cert */
+ WINDOW_IconifyGadget, FALSE,
+ WINDOW_Position, WPOS_CENTERSCREEN,
+ WINDOW_ParentGroup, ami_cw->objects[GID_CW_MAIN] = LayoutVObj,
+ LAYOUT_AddImage, LabelObj,
+ LABEL_Text, crtvrfy_win->sslerr,
+ LabelEnd,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_HSCROLLLAYOUT] = LayoutVObj,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_VSCROLLLAYOUT] = LayoutHObj,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_DRAW] = SpaceObj,
+ GA_ID, GID_CW_DRAW,
+ SPACE_Transparent, TRUE,
+ SPACE_BevelStyle, BVS_DISPLAY,
+ GA_RelVerify, TRUE,
+ SpaceEnd,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_VSCROLL] = ScrollerObj,
+ GA_ID, GID_CW_VSCROLL,
+ GA_RelVerify, TRUE,
+ ScrollerEnd,
+ LayoutEnd,
+ LAYOUT_AddChild, ami_cw->objects[GID_CW_HSCROLL] = ScrollerObj,
+ GA_ID, GID_CW_HSCROLL,
+ GA_RelVerify, TRUE,
+ SCROLLER_Orientation, SORIENT_HORIZ,
+ ScrollerEnd,
+ LayoutEnd,
+ LAYOUT_AddChild, LayoutHObj,
+ LAYOUT_AddChild, crtvrfy_win->sslcert_objects[GID_SSLCERT_ACCEPT] = ButtonObj,
+ GA_ID, GID_SSLCERT_ACCEPT,
+ GA_Text, crtvrfy_win->sslaccept,
+ GA_RelVerify, TRUE,
+ ButtonEnd,
+ LAYOUT_AddChild, crtvrfy_win->sslcert_objects[GID_SSLCERT_REJECT] = ButtonObj,
+ GA_ID, GID_SSLCERT_REJECT,
+ GA_Text, crtvrfy_win->sslreject,
+ GA_RelVerify, TRUE,
+ ButtonEnd,
+ EndGroup,
+ CHILD_WeightedHeight, 0,
+ EndGroup,
+ EndWindow;
+
+ if(ami_cw->objects[GID_CW_WIN] == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ return NSERROR_OK;
}
+
+/* exported interface documented in amiga/ssl_cert.h */
+nserror ami_cert_verify(struct nsurl *url,
+ const struct ssl_cert_info *certs,
+ unsigned long num,
+ nserror (*cb)(bool proceed, void *pw),
+ void *cbpw)
+{
+ struct ami_crtvrfy_window *ncwin;
+ nserror res;
+
+ ncwin = calloc(1, sizeof(struct ami_crtvrfy_window));
+ if (ncwin == NULL) {
+ return NSERROR_NOMEM;
+ }
+
+ ncwin->core.wintitle = ami_utf8_easy((char *)messages_get("SSLCerts"));
+ ncwin->sslerr = ami_utf8_easy((char *)messages_get("SSLError"));
+ ncwin->sslaccept = ami_utf8_easy((char *)messages_get("SSL_Certificate_Accept"));
+ ncwin->sslreject = ami_utf8_easy((char *)messages_get("SSL_Certificate_Reject"));
+
+ res = ami_crtvrfy_create_window(ncwin);
+ if (res != NSERROR_OK) {
+ LOG("SSL UI builder init failed");
+ ami_utf8_free(ncwin->core.wintitle);
+ ami_utf8_free(ncwin->sslerr);
+ ami_utf8_free(ncwin->sslaccept);
+ ami_utf8_free(ncwin->sslreject);
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise example core window */
+ ncwin->core.draw = ami_crtvrfy_draw;
+ ncwin->core.key = ami_crtvrfy_key;
+ ncwin->core.mouse = ami_crtvrfy_mouse;
+ ncwin->core.close = ami_crtvrfy_reject;
+ ncwin->core.event = ami_crtvrfy_event;
+
+ res = ami_corewindow_init(&ncwin->core);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ ami_utf8_free(ncwin->sslerr);
+ ami_utf8_free(ncwin->sslaccept);
+ ami_utf8_free(ncwin->sslreject);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ /* initialise certificate viewing interface */
+ res = sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
+ &ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ ami_utf8_free(ncwin->sslerr);
+ ami_utf8_free(ncwin->sslaccept);
+ ami_utf8_free(ncwin->sslreject);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ res = sslcert_viewer_init(ncwin->core.cb_table,
+ (struct core_window *)ncwin,
+ ncwin->ssl_data);
+ if (res != NSERROR_OK) {
+ ami_utf8_free(ncwin->core.wintitle);
+ ami_utf8_free(ncwin->sslerr);
+ ami_utf8_free(ncwin->sslaccept);
+ ami_utf8_free(ncwin->sslreject);
+ DisposeObject(ncwin->core.objects[GID_CW_WIN]);
+ free(ncwin);
+ return res;
+ }
+
+ return NSERROR_OK;
+}
+
diff --git a/frontends/amiga/sslcert.h b/frontends/amiga/sslcert.h
index 86ce9c476..392989f02 100644
--- a/frontends/amiga/sslcert.h
+++ b/frontends/amiga/sslcert.h
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Chris Young <chris@unsatisfactorysoftware.co.uk>
+ * Copyright 2017 Chris Young <chris@unsatisfactorysoftware.co.uk>
*
* This file is part of NetSurf, http://www.netsurf-browser.org/
*
@@ -18,11 +18,21 @@
#ifndef AMIGA_SSLCERT_H
#define AMIGA_SSLCERT_H
+struct nsurl;
+struct ssl_cert_info;
-nserror gui_cert_verify(nsurl *url,
+/**
+ * Prompt the user to verify a certificate with issues.
+ *
+ * \param url The URL being verified.
+ * \param certs The certificate to be verified
+ * \param num The number of certificates to be verified.
+ * \param cb Callback upon user decision.
+ * \param cbpw Context pointer passed to cb
+ * \return NSERROR_OK or error code if prompt creation failed.
+ */
+nserror ami_cert_verify(struct nsurl *url,
const struct ssl_cert_info *certs, unsigned long num,
- nserror (*cb)(bool proceed, void *pw), void *cbpw);
-
-void ami_ssl_free(struct treeview_window *twin);
-
+ nserror (*cb)(bool proceed, void *pw), void *cbpw);
#endif
+
diff --git a/frontends/amiga/tree.c b/frontends/amiga/tree.c
index f1c5327c7..b9747c095 100644
--- a/frontends/amiga/tree.c
+++ b/frontends/amiga/tree.c
@@ -916,7 +916,7 @@ void ami_tree_close(void *w)
ami_utf8_free(twin->sslerr);
ami_utf8_free(twin->sslaccept);
ami_utf8_free(twin->sslreject);
- ami_ssl_free(twin);
+ //ami_ssl_free(twin);
}
if(twin->type == AMI_TREE_HOTLIST)