Gitweb links:

...log 
http://git.netsurf-browser.org/netsurf.git/shortlog/c1a0001226d918571006a87dd22e13dd32f80e84
...commit 
http://git.netsurf-browser.org/netsurf.git/commit/c1a0001226d918571006a87dd22e13dd32f80e84
...tree 
http://git.netsurf-browser.org/netsurf.git/tree/c1a0001226d918571006a87dd22e13dd32f80e84

The branch, master has been updated
       via  c1a0001226d918571006a87dd22e13dd32f80e84 (commit)
       via  f3a1b49dd83f31399ae5eadfd80744d0cbdeeb0a (commit)
      from  076e54e1e5bfabba7cf2cba02ba13a86f3dc9ba1 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commitdiff 
http://git.netsurf-browser.org/netsurf.git/commit/?id=c1a0001226d918571006a87dd22e13dd32f80e84
commit c1a0001226d918571006a87dd22e13dd32f80e84
Merge: 076e54e f3a1b49
Author: Michael Drake <[email protected]>
Commit: Michael Drake <[email protected]>

    Merge branch 'vince/win32-corewindow'



-----------------------------------------------------------------------

Summary of changes:
 frontends/windows/Makefile                  |    3 +-
 frontends/windows/cookies.c                 |  190 +++++++++++
 frontends/{gtk => windows}/cookies.h        |   24 +-
 frontends/windows/corewindow.c              |  472 +++++++++++++++++++++++++++
 frontends/windows/corewindow.h              |  110 +++++++
 frontends/windows/global_history.c          |  190 +++++++++++
 frontends/{gtk => windows}/global_history.h |   13 +-
 frontends/windows/hotlist.c                 |  195 +++++++++++
 frontends/{gtk => windows}/hotlist.h        |   14 +-
 frontends/windows/main.c                    |    5 +
 frontends/windows/res/resource.rc           |   12 +-
 frontends/windows/resourceid.h              |   84 ++---
 frontends/windows/ssl_cert.c                |  439 +++++++++++++++++++++++++
 frontends/{gtk => windows}/ssl_cert.h       |   22 +-
 frontends/windows/window.c                  |   14 +-
 15 files changed, 1716 insertions(+), 71 deletions(-)
 create mode 100644 frontends/windows/cookies.c
 copy frontends/{gtk => windows}/cookies.h (62%)
 create mode 100644 frontends/windows/corewindow.c
 create mode 100644 frontends/windows/corewindow.h
 create mode 100644 frontends/windows/global_history.c
 copy frontends/{gtk => windows}/global_history.h (74%)
 create mode 100644 frontends/windows/hotlist.c
 copy frontends/{gtk => windows}/hotlist.h (75%)
 create mode 100644 frontends/windows/ssl_cert.c
 copy frontends/{gtk => windows}/ssl_cert.h (63%)

diff --git a/frontends/windows/Makefile b/frontends/windows/Makefile
index baaf225..41c8b8c 100644
--- a/frontends/windows/Makefile
+++ b/frontends/windows/Makefile
@@ -46,7 +46,8 @@ S_RESOURCES := windows_resource.o
 # sources purely for the windows build
 S_FRONTEND := main.c window.c gui.c drawable.c plot.c findfile.c       \
          font.c bitmap.c about.c prefs.c download.c filetype.c file.c  \
-         localhistory.c schedule.c windbg.c pointers.c
+         localhistory.c schedule.c windbg.c pointers.c \
+         corewindow.c hotlist.c cookies.c global_history.c ssl_cert.c
 
 # This is the final source build list
 # Note this is deliberately *not* expanded here as common and image
diff --git a/frontends/windows/cookies.c b/frontends/windows/cookies.c
new file mode 100644
index 0000000..27949fa
--- /dev/null
+++ b/frontends/windows/cookies.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2016 Vincent Sanders <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Implementation of win32 cookie manager.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <windows.h>
+
+#include "utils/log.h"
+#include "utils/nsoption.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
+#include "desktop/cookie_manager.h"
+
+#include "windows/plot.h"
+#include "windows/corewindow.h"
+#include "windows/cookies.h"
+
+
+struct nsw32_cookie_window {
+       struct nsw32_corewindow core;
+};
+
+static struct nsw32_cookie_window *cookie_window = NULL;
+
+/**
+ * callback for keypress on cookie window
+ *
+ * \param nsw32_cw The nsw32 core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsw32_cookie_key(struct nsw32_corewindow *nsw32_cw, uint32_t nskey)
+{
+       if (cookie_manager_keypress(nskey)) {
+               return NSERROR_OK;
+       }
+       return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback for mouse action on cookie window
+ *
+ * \param nsw32_cw The nsw32 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
+nsw32_cookie_mouse(struct nsw32_corewindow *nsw32_cw,
+                   browser_mouse_state mouse_state,
+                   int x, int y)
+{
+       cookie_manager_mouse_action(mouse_state, x, y);
+
+       return NSERROR_OK;
+}
+
+/**
+ * callback on draw event for cookie window
+ *
+ * \param nsw32_cw The nsw32 core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsw32_cookie_draw(struct nsw32_corewindow *nsw32_cw,
+                 int scrollx,
+                 int scrolly,
+                 struct rect *r)
+{
+       struct redraw_context ctx = {
+               .interactive = true,
+               .background_images = true,
+               .plot = &win_plotters
+       };
+
+       cookie_manager_redraw(-scrollx, -scrolly, r, &ctx);
+
+       return NSERROR_OK;
+}
+
+
+static nserror
+nsw32_cookie_close(struct nsw32_corewindow *nsw32_cw)
+{
+       ShowWindow(nsw32_cw->hWnd, SW_HIDE);
+
+       return NSERROR_OK;
+}
+
+/**
+ * Creates the window for the cookie tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror nsw32_cookie_init(HINSTANCE hInstance)
+{
+       struct nsw32_cookie_window *ncwin;
+       nserror res;
+
+       if (cookie_window != NULL) {
+               return NSERROR_OK;
+       }
+
+       ncwin = malloc(sizeof(struct nsw32_cookie_window));
+       if (ncwin == NULL) {
+               return NSERROR_NOMEM;
+       }
+
+       ncwin->core.title = "NetSurf Cookies";
+       ncwin->core.draw = nsw32_cookie_draw;
+       ncwin->core.key = nsw32_cookie_key;
+       ncwin->core.mouse = nsw32_cookie_mouse;
+       ncwin->core.close = nsw32_cookie_close;
+
+       res = nsw32_corewindow_init(hInstance, NULL, &ncwin->core);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       res = cookie_manager_init(ncwin->core.cb_table,
+                                 (struct core_window *)ncwin);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       /* memoise window so it can be represented when necessary
+        * instead of recreating every time.
+        */
+       cookie_window = ncwin;
+
+       return NSERROR_OK;
+}
+
+
+/* exported interface documented in windows/cookie.h */
+nserror nsw32_cookies_present(HINSTANCE hInstance)
+{
+       nserror res;
+
+       res = nsw32_cookie_init(hInstance);
+       if (res == NSERROR_OK) {
+               ShowWindow(cookie_window->core.hWnd, SW_SHOWNORMAL);
+       }
+       return res;
+}
+
+/* exported interface documented in windows/cookie.h */
+nserror nsw32_cookies_finalise(void)
+{
+       nserror res;
+
+       if (cookie_window == NULL) {
+               return NSERROR_OK;
+       }
+
+       res = cookie_manager_fini();
+       if (res == NSERROR_OK) {
+               res = nsw32_corewindow_fini(&cookie_window->core);
+               DestroyWindow(cookie_window->core.hWnd);
+               free(cookie_window);
+               cookie_window = NULL;
+       }
+
+       return res;
+}
diff --git a/frontends/gtk/cookies.h b/frontends/windows/cookies.h
similarity index 62%
copy from frontends/gtk/cookies.h
copy to frontends/windows/cookies.h
index c1a68b7..8500c78 100644
--- a/frontends/gtk/cookies.h
+++ b/frontends/windows/cookies.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009 Paul Blokus <[email protected]>
+ * Copyright 2016 Vincent Sanders <[email protected]> 
  *
  * This file is part of NetSurf, http://www.netsurf-browser.org/
  *
@@ -16,26 +16,32 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-/** \file
- * Cookies (interface).
+/**
+ * \file
+ * Interface to win32 cookie viewing using nsw32 core windows.
+ *
+ * The interface assumes there is only a single cookie window which is
+ * presented (shown) when asked for and hidden by usual toolkit
+ * mechanics.
+ *
+ * The destructor is called once during browser shutdown
  */
 
-#ifndef __NSGTK_COOKIES_H__
-#define __NSGTK_COOKIES_H__
+#ifndef NETSURF_WINDOWS_COOKIES_H
+#define NETSURF_WINDOWS_COOKIES_H
 
 /**
  * make the cookie window visible.
  *
  * \return NSERROR_OK on success else appropriate error code on faliure.
  */
-nserror nsgtk_cookies_present(void);
+nserror nsw32_cookies_present(HINSTANCE hinstance);
 
 /**
  * Free any resources allocated for the cookie window.
  *
  * \return NSERROR_OK on success else appropriate error code on faliure.
  */
-nserror nsgtk_cookies_destroy(void);
-
+nserror nsw32_cookies_finalise(void);
 
-#endif /* __NSGTK_COOKIES_H__ */
+#endif /* NETSURF_WINDOWS_COOKIES_H */
diff --git a/frontends/windows/corewindow.c b/frontends/windows/corewindow.c
new file mode 100644
index 0000000..d1d761d
--- /dev/null
+++ b/frontends/windows/corewindow.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright 2016 Vincent Sanders <[email protected]>
+ *
+ * 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
+ * win32 generic core window interface.
+ *
+ * Provides interface for core renderers to a win32 api client area.
+ *
+ * This module is an object that must be encapsulated. Client users
+ * should embed a struct nsw32_corewindow at the beginning of their
+ * context for this display surface, fill in relevant data and then
+ * call nsw32_corewindow_init()
+ *
+ * The win32 core window structure requires the callback for draw, key
+ * and mouse operations.
+ */
+
+#include <assert.h>
+#include <string.h>
+#include <math.h>
+#include <windows.h>
+#include <windowsx.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 "windows/windbg.h"
+#include "windows/corewindow.h"
+#include "windows/plot.h"
+
+static const char windowclassname_corewindow[] = "nswscorewindowwindow";
+
+/**
+ * update the scrollbar visibility and size
+ */
+static void
+update_scrollbars(struct nsw32_corewindow *nsw32_cw)
+{
+       RECT rc;
+       SCROLLINFO si;
+
+       GetClientRect(nsw32_cw->hWnd, &rc);
+
+       if (nsw32_cw->content_width > rc.right) {
+               /* content wider than window area */
+               if (nsw32_cw->content_height > rc.bottom) {
+                       /* content higher than window area */
+                       ShowScrollBar(nsw32_cw->hWnd, SB_BOTH, TRUE);
+                       si.cbSize = sizeof(SCROLLINFO);
+                       si.fMask = SIF_RANGE | SIF_PAGE;
+                       si.nMin = 0;
+                       si.nMax = nsw32_cw->content_width;
+                       si.nPage = rc.right;
+                       SetScrollInfo(nsw32_cw->hWnd, SB_HORZ, &si, TRUE);
+                       si.cbSize = sizeof(SCROLLINFO);
+                       si.fMask = SIF_RANGE | SIF_PAGE;
+                       si.nMin = 0;
+                       si.nMax = nsw32_cw->content_height;
+                       si.nPage = rc.bottom;
+                       SetScrollInfo(nsw32_cw->hWnd, SB_VERT, &si, TRUE);
+               } else {
+                       /* content shorter than window area */
+                       ShowScrollBar(nsw32_cw->hWnd, SB_VERT, FALSE);
+                       ShowScrollBar(nsw32_cw->hWnd, SB_HORZ, TRUE);
+                       si.cbSize = sizeof(SCROLLINFO);
+                       si.fMask = SIF_RANGE | SIF_PAGE;
+                       si.nMin = 0;
+                       si.nMax = nsw32_cw->content_width;
+                       si.nPage = rc.right;
+                       SetScrollInfo(nsw32_cw->hWnd, SB_HORZ, &si, TRUE);
+               }
+       } else {
+               /* content narrower than window area */
+               if (nsw32_cw->content_height > rc.bottom) {
+                       /* content higher than window area */
+                       ShowScrollBar(nsw32_cw->hWnd, SB_HORZ, FALSE);
+                       ShowScrollBar(nsw32_cw->hWnd, SB_VERT, TRUE);
+                       si.cbSize = sizeof(SCROLLINFO);
+                       si.fMask = SIF_RANGE | SIF_PAGE;
+                       si.nMin = 0;
+                       si.nMax = nsw32_cw->content_height;
+                       si.nPage = rc.bottom;
+                       SetScrollInfo(nsw32_cw->hWnd, SB_VERT, &si, TRUE);
+               } else {
+                       /* content shorter than window area */
+                       ShowScrollBar(nsw32_cw->hWnd, SB_BOTH, FALSE);
+               }
+       }
+
+}
+
+
+/**
+ * Handle paint messages.
+ */
+static LRESULT
+nsw32_corewindow_paint(struct nsw32_corewindow *nsw32_cw, HWND hwnd)
+{
+       struct rect clip;
+       PAINTSTRUCT ps;
+       SCROLLINFO si; /* scroll information */
+       int scrollx;
+       int scrolly;
+
+       /* get scroll positions */
+       si.cbSize = sizeof(si);
+       si.fMask = SIF_POS;
+       GetScrollInfo(hwnd, SB_HORZ, &si);
+       scrollx = si.nPos;
+       GetScrollInfo(hwnd, SB_VERT, &si);
+       scrolly = si.nPos;
+
+       BeginPaint(hwnd, &ps);
+
+       plot_hdc = ps.hdc;
+
+       /* content clip rectangle setup */
+       clip.x0 = ps.rcPaint.left + scrollx;
+       clip.y0 = ps.rcPaint.top + scrolly;
+       clip.x1 = ps.rcPaint.right + scrollx;
+       clip.y1 = ps.rcPaint.bottom + scrolly;
+
+       nsw32_cw->draw(nsw32_cw, scrollx, scrolly, &clip);
+
+       EndPaint(hwnd, &ps);
+
+       return 0;
+}
+
+static LRESULT
+nsw32_corewindow_vscroll(struct nsw32_corewindow *nsw32_cw,
+                        HWND hwnd,
+                        WPARAM wparam)
+{
+       SCROLLINFO si; /* current scroll information */
+       SCROLLINFO usi; /* updated scroll infomation for scrollwindowex */
+
+       LOG("VSCROLL");
+
+       si.cbSize = sizeof(si);
+       si.fMask = SIF_ALL;
+       GetScrollInfo(hwnd, SB_VERT, &si);
+       usi = si;
+
+       switch (LOWORD(wparam)) {
+       case SB_TOP:
+               usi.nPos = si.nMin;
+               break;
+
+       case SB_BOTTOM:
+               usi.nPos = si.nMax;
+               break;
+
+       case SB_LINEUP:
+               usi.nPos -= 30;
+               break;
+
+       case SB_LINEDOWN:
+               usi.nPos += 30;
+               break;
+
+       case SB_PAGEUP:
+               usi.nPos -= si.nPage;
+               break;
+
+       case SB_PAGEDOWN:
+               usi.nPos += si.nPage;
+               break;
+
+       case SB_THUMBTRACK:
+               usi.nPos = si.nTrackPos;
+               break;
+
+       default:
+               break;
+       }
+
+       if (usi.nPos < si.nMin) {
+               usi.nPos = si.nMin;
+       }
+       if (usi.nPos > si.nMax) {
+               usi.nPos = si.nMax;
+       }
+
+       SetScrollInfo(hwnd, SB_VERT, &usi, TRUE);
+
+       ScrollWindowEx(hwnd,
+                      0,
+                      si.nPos - usi.nPos,
+                      NULL,
+                      NULL,
+                      NULL,
+                      NULL,
+                      SW_INVALIDATE);
+
+       /**
+        * /todo win32 corewindow vertical scrolling needs us to
+        * compute scroll values and call scrollwindowex()
+        */
+
+       return 0;
+}
+
+static LRESULT
+nsw32_corewindow_mousedown(struct nsw32_corewindow *nsw32_cw,
+                          int x, int y,
+                          browser_mouse_state button)
+{
+       nsw32_cw->mouse(nsw32_cw, button, x, y);
+       return 0;
+}
+
+static LRESULT
+nsw32_corewindow_mouseup(struct nsw32_corewindow *nsw32_cw,
+                        int x, int y,
+                        browser_mouse_state button)
+{
+       nsw32_cw->mouse(nsw32_cw, button, x, y);
+       return 0;
+}
+
+static LRESULT
+nsw32_corewindow_close(struct nsw32_corewindow *nsw32_cw)
+{
+       nsw32_cw->close(nsw32_cw);
+       return 0;
+}
+
+/**
+ * callback for hotlist window win32 events
+ *
+ * \param hwnd The win32 window handle
+ * \param msg The win32 message identifier
+ * \param wparam The w win32 parameter
+ * \param lparam The l win32 parameter
+ */
+static LRESULT CALLBACK
+nsw32_window_corewindow_event_callback(HWND hwnd,
+                                   UINT msg,
+                                   WPARAM wparam,
+                                   LPARAM lparam)
+{
+       struct nsw32_corewindow *nsw32_cw;
+
+       nsw32_cw = GetProp(hwnd, TEXT("CoreWnd"));
+       if (nsw32_cw != NULL) {
+               switch (msg) {
+               case WM_PAINT: /* redraw the exposed part of the window */
+                       return nsw32_corewindow_paint(nsw32_cw, hwnd);
+
+               case WM_SIZE:
+                       update_scrollbars(nsw32_cw);
+                       break;
+
+               case WM_VSCROLL:
+                       return nsw32_corewindow_vscroll(nsw32_cw, hwnd, wparam);
+
+               case WM_LBUTTONDOWN:
+                       return nsw32_corewindow_mousedown(nsw32_cw,
+                                                         GET_X_LPARAM(lparam),
+                                                         GET_Y_LPARAM(lparam),
+                                                         
BROWSER_MOUSE_PRESS_1);
+
+               case WM_RBUTTONDOWN:
+                       return nsw32_corewindow_mousedown(nsw32_cw,
+                                                          GET_X_LPARAM(lparam),
+                                                          GET_Y_LPARAM(lparam),
+                                                          
BROWSER_MOUSE_PRESS_2);
+
+               case WM_LBUTTONUP:
+                       return nsw32_corewindow_mouseup(nsw32_cw,
+                                                       GET_X_LPARAM(lparam),
+                                                       GET_Y_LPARAM(lparam),
+                                                       BROWSER_MOUSE_CLICK_1);
+
+               case WM_RBUTTONUP:
+                       return nsw32_corewindow_mouseup(nsw32_cw,
+                                                       GET_X_LPARAM(lparam),
+                                                       GET_Y_LPARAM(lparam),
+                                                       BROWSER_MOUSE_CLICK_2);
+
+               case WM_CLOSE:
+                       return nsw32_corewindow_close(nsw32_cw);
+               }
+       }
+
+       return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+/**
+ * callback from core to request a redraw
+ */
+static void
+nsw32_cw_redraw_request(struct core_window *cw, const struct rect *r)
+{
+       struct nsw32_corewindow *nsw32_cw = (struct nsw32_corewindow *)cw;
+       RECT wr;
+
+       wr.left = r->x0;
+       wr.top = r->y0;
+       wr.right = r->x1;
+       wr.bottom = r->y1;
+
+       RedrawWindow(nsw32_cw->hWnd, &wr, NULL, RDW_INVALIDATE | RDW_NOERASE);
+}
+
+
+/**
+ * Callback from the core to update the content area size
+ */
+static void
+nsw32_cw_update_size(struct core_window *cw, int width, int height)
+{
+       struct nsw32_corewindow *nsw32_cw = (struct nsw32_corewindow *)cw;
+
+       nsw32_cw->content_width = width;
+       nsw32_cw->content_height = height;
+       LOG("new content size w:%d h:%d", width, height);
+
+       update_scrollbars(nsw32_cw);
+}
+
+
+static void
+nsw32_cw_scroll_visible(struct core_window *cw, const struct rect *r)
+{
+       /** /todo call setscroll apropriately */
+}
+
+
+static void
+nsw32_cw_get_window_dimensions(struct core_window *cw, int *width, int *height)
+{
+       struct nsw32_corewindow *nsw32_cw = (struct nsw32_corewindow *)cw;
+
+       RECT rc;
+       GetClientRect(nsw32_cw->hWnd, &rc);
+       *width = rc.right;
+       *height = rc.bottom;
+}
+
+
+static void
+nsw32_cw_drag_status(struct core_window *cw, core_window_drag_status ds)
+{
+       struct nsw32_corewindow *nsw32_cw = (struct nsw32_corewindow *)cw;
+       nsw32_cw->drag_staus = ds;
+}
+
+
+struct core_window_callback_table nsw32_cw_cb_table = {
+       .redraw_request = nsw32_cw_redraw_request,
+       .update_size = nsw32_cw_update_size,
+       .scroll_visible = nsw32_cw_scroll_visible,
+       .get_window_dimensions = nsw32_cw_get_window_dimensions,
+       .drag_status = nsw32_cw_drag_status
+};
+
+/* exported function documented nsw32/corewindow.h */
+nserror
+nsw32_corewindow_init(HINSTANCE hInstance,
+                     HWND hWndParent,
+                     struct nsw32_corewindow *nsw32_cw)
+{
+       DWORD dwStyle;
+
+       /* setup the core window callback table */
+       nsw32_cw->cb_table = &nsw32_cw_cb_table;
+
+       /* start with the content area being as small as possible */
+       nsw32_cw->content_width = -1;
+       nsw32_cw->content_height = -1;
+
+       if (hWndParent != NULL) {
+               dwStyle = WS_CHILDWINDOW |
+                       WS_VISIBLE |
+                       CS_DBLCLKS;
+       } else {
+               dwStyle = WS_OVERLAPPEDWINDOW |
+                       WS_HSCROLL |
+                       WS_VSCROLL |
+                       WS_CLIPSIBLINGS |
+                       WS_CLIPCHILDREN |
+                       CS_DBLCLKS;
+       }
+
+       LOG("creating hInstance %p core window", hInstance);
+       nsw32_cw->hWnd = CreateWindowEx(0,
+                                       windowclassname_corewindow,
+                                       nsw32_cw->title,
+                                       dwStyle,
+                                       CW_USEDEFAULT,
+                                       CW_USEDEFAULT,
+                                       500,
+                                       400,
+                                       hWndParent,
+                                       NULL,
+                                       hInstance,
+                                       NULL);
+       if (nsw32_cw->hWnd == NULL) {
+               LOG("Window create failed");
+               return NSERROR_NOMEM;
+       }
+
+       SetProp(nsw32_cw->hWnd, TEXT("CoreWnd"), (HANDLE)nsw32_cw);
+
+       /* zero scroll offsets */
+       SCROLLINFO si;
+       si.cbSize = sizeof(si);
+       si.fMask = SIF_POS;
+       si.nPos = 0;
+       SetScrollInfo(nsw32_cw->hWnd, SB_VERT, &si, FALSE);
+       SetScrollInfo(nsw32_cw->hWnd, SB_HORZ, &si, FALSE);
+
+       return NSERROR_OK;
+}
+
+/* exported interface documented in nsw32/corewindow.h */
+nserror nsw32_corewindow_fini(struct nsw32_corewindow *nsw32_cw)
+{
+       return NSERROR_OK;
+}
+
+
+/* exported interface documented in windows/corewindow.h */
+nserror nsw32_create_corewindow_class(HINSTANCE hInstance)
+{
+       nserror ret = NSERROR_OK;
+       WNDCLASSEX wc;
+
+       /* drawable area */
+       wc.cbSize = sizeof(WNDCLASSEX);
+       wc.style = 0;
+       wc.lpfnWndProc = nsw32_window_corewindow_event_callback;
+       wc.cbClsExtra = 0;
+       wc.cbWndExtra = 0;
+       wc.hInstance = hInstance;
+       wc.hIcon = NULL;
+       wc.hCursor = NULL;
+       wc.hbrBackground = (HBRUSH)(COLOR_MENU + 1);
+       wc.lpszMenuName = NULL;
+       wc.lpszClassName = windowclassname_corewindow;
+       wc.hIconSm = NULL;
+
+       if (RegisterClassEx(&wc) == 0) {
+               win_perror("CorewindowClass");
+               ret = NSERROR_INIT_FAILED;
+       }
+
+       return ret;
+}
diff --git a/frontends/windows/corewindow.h b/frontends/windows/corewindow.h
new file mode 100644
index 0000000..b78c72e
--- /dev/null
+++ b/frontends/windows/corewindow.h
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2016 Vincent Sanders <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef NETSURF_WINDOWS_COREWINDOW_H
+#define NETSURF_WINDOWS_COREWINDOW_H
+
+#include "netsurf/core_window.h"
+
+/**
+ * nsw32 core window state
+ */
+struct nsw32_corewindow {
+       /** window handle */
+       HWND hWnd;
+
+       /** content width */
+       int content_width;
+
+       /** content height */
+       int content_height;
+
+       /** window title */
+       const char *title;
+       
+        /** drag status set by core */
+        core_window_drag_status drag_staus;
+
+        /** table of callbacks for core window operations */
+        struct core_window_callback_table *cb_table;
+       
+        /**
+         * callback to draw on drawable area of nsw32 core window
+         *
+         * \param nsw32_cw The nsw32 core window structure.
+         * \param r The rectangle of the window that needs updating.
+         * \return NSERROR_OK on success otherwise apropriate error code
+         */
+        nserror (*draw)(struct nsw32_corewindow *nsw32_cw, int scrollx, int 
scrolly, struct rect *r);
+
+        /**
+         * callback for keypress on nsw32 core window
+         *
+         * \param nsw32_cw The nsw32 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 nsw32_corewindow *nsw32_cw, uint32_t nskey);
+
+        /**
+         * callback for mouse event on nsw32 core window
+         *
+         * \param nsw32_cw The nsw32 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 nsw32_corewindow *nsw32_cw, 
browser_mouse_state mouse_state, int x, int y);
+
+       /**
+        * callback for window close event
+        *
+         * \param nsw32_cw The nsw32 core window structure.
+         * \return NSERROR_OK on sucess otherwise apropriate error code.
+        */
+       nserror (*close)(struct nsw32_corewindow *nsw32_cw);
+};
+
+/**
+ * initialise elements of nsw32 core window.
+ *
+ * As a pre-requisite the draw, key and mouse callbacks must be defined
+ *
+ * \param hInstance The instance to create the core window in
+ * \param hWndParent parent window handle may be NULL for top level window.
+ * \param nsw32_cw A nsw32 core window structure to initialise
+ * \return NSERROR_OK on successful initialisation otherwise error code.
+ */
+nserror nsw32_corewindow_init(HINSTANCE hInstance,
+                             HWND hWndParent,
+                             struct nsw32_corewindow *nsw32_cw);
+
+/**
+ * finalise elements of nsw32 core window.
+ *
+ * \param nsw32_cw A nsw32 core window structure to initialise
+ * \return NSERROR_OK on successful finalisation otherwise error code.
+ */
+nserror nsw32_corewindow_fini(struct nsw32_corewindow *nsw32_cw);
+
+nserror nsw32_create_corewindow_class(HINSTANCE hInstance);
+
+#endif
diff --git a/frontends/windows/global_history.c 
b/frontends/windows/global_history.c
new file mode 100644
index 0000000..0ef0963
--- /dev/null
+++ b/frontends/windows/global_history.c
@@ -0,0 +1,190 @@
+/*
+ * Copyright 2016 Vincent Sanders <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Implementation of win32 cookie manager.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <windows.h>
+
+#include "utils/log.h"
+#include "utils/nsoption.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
+#include "desktop/global_history.h"
+
+#include "windows/plot.h"
+#include "windows/corewindow.h"
+#include "windows/global_history.h"
+
+
+struct nsw32_global_history_window {
+       struct nsw32_corewindow core;
+};
+
+static struct nsw32_global_history_window *global_history_window = NULL;
+
+/**
+ * callback for keypress on global_history window
+ *
+ * \param nsw32_cw The nsw32 core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsw32_global_history_key(struct nsw32_corewindow *nsw32_cw, uint32_t nskey)
+{
+       if (global_history_keypress(nskey)) {
+               return NSERROR_OK;
+       }
+       return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback for mouse action on global_history window
+ *
+ * \param nsw32_cw The nsw32 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
+nsw32_global_history_mouse(struct nsw32_corewindow *nsw32_cw,
+                   browser_mouse_state mouse_state,
+                   int x, int y)
+{
+       global_history_mouse_action(mouse_state, x, y);
+
+       return NSERROR_OK;
+}
+
+/**
+ * callback on draw event for global_history window
+ *
+ * \param nsw32_cw The nsw32 core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsw32_global_history_draw(struct nsw32_corewindow *nsw32_cw,
+                         int scrollx,
+                         int scrolly,
+                         struct rect *r)
+{
+       struct redraw_context ctx = {
+               .interactive = true,
+               .background_images = true,
+               .plot = &win_plotters
+       };
+
+       global_history_redraw(-scrollx, -scrolly, r, &ctx);
+
+       return NSERROR_OK;
+}
+
+
+static nserror
+nsw32_global_history_close(struct nsw32_corewindow *nsw32_cw)
+{
+       ShowWindow(nsw32_cw->hWnd, SW_HIDE);
+
+       return NSERROR_OK;
+}
+
+/**
+ * Creates the window for the global_history tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror nsw32_global_history_init(HINSTANCE hInstance)
+{
+       struct nsw32_global_history_window *ncwin;
+       nserror res;
+
+       if (global_history_window != NULL) {
+               return NSERROR_OK;
+       }
+
+       ncwin = malloc(sizeof(struct nsw32_global_history_window));
+       if (ncwin == NULL) {
+               return NSERROR_NOMEM;
+       }
+
+       ncwin->core.title = "NetSurf Global History";
+       ncwin->core.draw = nsw32_global_history_draw;
+       ncwin->core.key = nsw32_global_history_key;
+       ncwin->core.mouse = nsw32_global_history_mouse;
+       ncwin->core.close = nsw32_global_history_close;
+
+       res = nsw32_corewindow_init(hInstance, NULL, &ncwin->core);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       res = global_history_init(ncwin->core.cb_table,
+                                 (struct core_window *)ncwin);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       /* memoise window so it can be represented when necessary
+        * instead of recreating every time.
+        */
+       global_history_window = ncwin;
+
+       return NSERROR_OK;
+}
+
+
+/* exported interface documented in windows/global_history.h */
+nserror nsw32_global_history_present(HINSTANCE hInstance)
+{
+       nserror res;
+
+       res = nsw32_global_history_init(hInstance);
+       if (res == NSERROR_OK) {
+               ShowWindow(global_history_window->core.hWnd, SW_SHOWNORMAL);
+       }
+       return res;
+}
+
+/* exported interface documented in windows/global_history.h */
+nserror nsw32_global_history_finalise(void)
+{
+       nserror res;
+
+       if (global_history_window == NULL) {
+               return NSERROR_OK;
+       }
+
+       res = global_history_fini();
+       if (res == NSERROR_OK) {
+               res = nsw32_corewindow_fini(&global_history_window->core);
+               DestroyWindow(global_history_window->core.hWnd);
+               free(global_history_window);
+               global_history_window = NULL;
+       }
+
+       return res;
+}
diff --git a/frontends/gtk/global_history.h b/frontends/windows/global_history.h
similarity index 74%
copy from frontends/gtk/global_history.h
copy to frontends/windows/global_history.h
index 996e0fd..bd986aa 100644
--- a/frontends/gtk/global_history.h
+++ b/frontends/windows/global_history.h
@@ -1,6 +1,5 @@
 /*
- * Copyright 2006 Rob Kendrick <[email protected]>
- * Copyright 2009 Paul Blokus <[email protected]> 
+ * Copyright 2016 Vincent Sanders <[email protected]> 
  *
  * This file is part of NetSurf, http://www.netsurf-browser.org/
  *
@@ -19,23 +18,23 @@
 
 /**
  * \file
- * Interface to GTK global history manager
+ * Interface to win32 global history manager using nsw32 core window
  */
 
-#ifndef __NSGTK_HISTORY_H__
-#define __NSGTK_HISTORY_H__
+#ifndef NETSURF_WINDOWS_GLOBAL_HISTORY_H
+#define NETSURF_WINDOWS_GLOBAL_HISTORY_H
 
 /**
  * make the global history window visible.
  *
  * \return NSERROR_OK on success else appropriate error code on faliure.
  */
-nserror nsgtk_global_history_present(void);
+nserror nsw32_global_history_present(HINSTANCE hinstance);
 
 /**
  * Destroys the global history window and performs any other necessary cleanup
  * actions.
  */
-nserror nsgtk_global_history_destroy(void);
+nserror nsw32_global_history_finalise(void);
 
 #endif
diff --git a/frontends/windows/hotlist.c b/frontends/windows/hotlist.c
new file mode 100644
index 0000000..2d236f7
--- /dev/null
+++ b/frontends/windows/hotlist.c
@@ -0,0 +1,195 @@
+/*
+ * Copyright 2016 Vincent Sanders <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Implementation of win32 bookmark (hotlist) manager.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <windows.h>
+
+#include "utils/log.h"
+#include "utils/nsoption.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
+#include "desktop/hotlist.h"
+
+#include "windows/plot.h"
+#include "windows/corewindow.h"
+#include "windows/hotlist.h"
+
+
+struct nsw32_hotlist_window {
+       struct nsw32_corewindow core;
+
+       const char *path; /**< path to users bookmarks */
+};
+
+static struct nsw32_hotlist_window *hotlist_window = NULL;
+
+/**
+ * callback for keypress on hotlist window
+ *
+ * \param nsw32_cw The nsw32 core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsw32_hotlist_key(struct nsw32_corewindow *nsw32_cw, uint32_t nskey)
+{
+       if (hotlist_keypress(nskey)) {
+               return NSERROR_OK;
+       }
+       return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback for mouse action on hotlist window
+ *
+ * \param nsw32_cw The nsw32 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
+nsw32_hotlist_mouse(struct nsw32_corewindow *nsw32_cw,
+                   browser_mouse_state mouse_state,
+                   int x, int y)
+{
+       hotlist_mouse_action(mouse_state, x, y);
+
+       return NSERROR_OK;
+}
+
+/**
+ * callback on draw event for hotlist window
+ *
+ * \param nsw32_cw The nsw32 core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsw32_hotlist_draw(struct nsw32_corewindow *nsw32_cw,
+                  int scrollx,
+                  int scrolly,
+                  struct rect *r)
+{
+       struct redraw_context ctx = {
+               .interactive = true,
+               .background_images = true,
+               .plot = &win_plotters
+       };
+
+       hotlist_redraw(-scrollx, -scrolly, r, &ctx);
+
+       return NSERROR_OK;
+}
+
+
+static nserror
+nsw32_hotlist_close(struct nsw32_corewindow *nsw32_cw)
+{
+       ShowWindow(nsw32_cw->hWnd, SW_HIDE);
+
+       return NSERROR_OK;
+}
+
+/**
+ * Creates the window for the hotlist tree.
+ *
+ * \return NSERROR_OK on success else appropriate error code on faliure.
+ */
+static nserror nsw32_hotlist_init(HINSTANCE hInstance)
+{
+       struct nsw32_hotlist_window *ncwin;
+       nserror res;
+
+       if (hotlist_window != NULL) {
+               return NSERROR_OK;
+       }
+
+       ncwin = malloc(sizeof(struct nsw32_hotlist_window));
+       if (ncwin == NULL) {
+               return NSERROR_NOMEM;
+       }
+
+       ncwin->core.title = "NetSurf Bookmarks";
+       ncwin->core.draw = nsw32_hotlist_draw;
+       ncwin->core.key = nsw32_hotlist_key;
+       ncwin->core.mouse = nsw32_hotlist_mouse;
+       ncwin->core.close = nsw32_hotlist_close;
+       
+       res = nsw32_corewindow_init(hInstance, NULL, &ncwin->core);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       ncwin->path = nsoption_charp(hotlist_path);
+
+       res = hotlist_init(ncwin->core.cb_table,
+                          (struct core_window *)ncwin,
+                          ncwin->path);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       /* memoise window so it can be represented when necessary
+        * instead of recreating every time.
+        */
+       hotlist_window = ncwin;
+       
+       return NSERROR_OK;
+}
+
+
+/* exported interface documented in windows/hotlist.h */
+nserror nsw32_hotlist_present(HINSTANCE hInstance)
+{
+       nserror res;
+
+       res = nsw32_hotlist_init(hInstance);
+       if (res == NSERROR_OK) {
+               ShowWindow(hotlist_window->core.hWnd, SW_SHOWNORMAL);
+       }
+       return res;
+}
+
+/* exported interface documented in windows/hotlist.h */
+nserror nsw32_hotlist_finalise(void)
+{
+       nserror res;
+
+       if (hotlist_window == NULL) {
+               return NSERROR_OK;
+       }
+
+       res = hotlist_fini(hotlist_window->path);
+       if (res == NSERROR_OK) {
+               res = nsw32_corewindow_fini(&hotlist_window->core);
+               DestroyWindow(hotlist_window->core.hWnd);
+               free(hotlist_window);
+               hotlist_window = NULL;
+       }
+
+       return res;
+}
diff --git a/frontends/gtk/hotlist.h b/frontends/windows/hotlist.h
similarity index 75%
copy from frontends/gtk/hotlist.h
copy to frontends/windows/hotlist.h
index 3170027..e5aa2d8 100644
--- a/frontends/gtk/hotlist.h
+++ b/frontends/windows/hotlist.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2009 Paul Blokus <[email protected]>
+ * Copyright 2016 Vincent Sanders <[email protected]> 
  *
  * This file is part of NetSurf, http://www.netsurf-browser.org/
  *
@@ -18,24 +18,24 @@
 
 /**
  * \file
- * Interface to GTK bookmarks (hotlist).
+ * Interface to win32 bookmark manager (hotlist).
  */
 
-#ifndef __NSGTK_HOTLIST_H__
-#define __NSGTK_HOTLIST_H__
+#ifndef NETSURF_WINDOWS_HOTLIST_H
+#define NETSURF_WINDOWS_HOTLIST_H
 
 /**
  * make the hotlist window visible.
  *
  * \return NSERROR_OK on success else appropriate error code on faliure.
  */
-nserror nsgtk_hotlist_present(void);
+nserror nsw32_hotlist_present(HINSTANCE hinstance);
 
 /**
  * Free any resources allocated for the hotlist window.
  *
  * \return NSERROR_OK on success else appropriate error code on faliure.
  */
-nserror nsgtk_hotlist_destroy(void);
+nserror nsw32_hotlist_finalise(void);
 
-#endif /* __NSGTK_HOTLIST_H__ */
+#endif /* NETSURF_WINDOWS_HOTLIST_H */
diff --git a/frontends/windows/main.c b/frontends/windows/main.c
index 7c94c06..da0fcc1 100644
--- a/frontends/windows/main.c
+++ b/frontends/windows/main.c
@@ -42,6 +42,8 @@
 #include "windows/findfile.h"
 #include "windows/file.h"
 #include "windows/drawable.h"
+#include "windows/corewindow.h"
+#include "windows/ssl_cert.h"
 #include "windows/download.h"
 #include "windows/localhistory.h"
 #include "windows/window.h"
@@ -269,6 +271,7 @@ static nserror nsw32_option_init(int *pargc, char** argv)
 static struct gui_misc_table win32_misc_table = {
        .schedule = win32_schedule,
        .warning = win32_warning,
+       .cert_verify = nsw32_cert_verify,
 };
 
 /**
@@ -371,6 +374,8 @@ WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR 
lpcli, int ncmd)
        ret = nsws_create_main_class(hInstance);
        ret = nsws_create_drawable_class(hInstance);
        ret = nsws_create_localhistory_class(hInstance);
+       ret = nsw32_create_corewindow_class(hInstance);
+       ret = nsws_create_cert_verify_class(hInstance);
 
        nsoption_set_bool(target_blank, false);
 
diff --git a/frontends/windows/res/resource.rc 
b/frontends/windows/res/resource.rc
index b83205f..192cd57 100644
--- a/frontends/windows/res/resource.rc
+++ b/frontends/windows/res/resource.rc
@@ -67,20 +67,24 @@ BEGIN
     MENUITEM SEPARATOR
     MENUITEM "Page S&ource",IDM_VIEW_SOURCE
     MENUITEM "&Full Screen",IDM_VIEW_FULLSCREEN
+    MENUITEM SEPARATOR
+    MENUITEM "Save size and location",IDM_VIEW_SAVE_WIN_METRICS
   END
-  POPUP "&History"
+  POPUP "&Navigate"
   BEGIN
     MENUITEM "Back",IDM_NAV_BACK
     MENUITEM "Forward",IDM_NAV_FORWARD
     MENUITEM "Home",IDM_NAV_HOME
     MENUITEM SEPARATOR
     MENUITEM "Local History",IDM_NAV_LOCALHISTORY
-    MENUITEM "Global History",IDM_NAV_GLOBALHISTORY,GRAYED
+    MENUITEM "Global History",IDM_NAV_GLOBALHISTORY
+    MENUITEM SEPARATOR
+    MENUITEM "Show Bookmarks",IDM_NAV_BOOKMARKS
   END
   POPUP "&Tools"
   BEGIN
-    MENUITEM "&Downloads",IDM_VIEW_DOWNLOADS
-    MENUITEM "Save size and location",IDM_VIEW_SAVE_WIN_METRICS
+    MENUITEM "&Downloads",IDM_TOOLS_DOWNLOADS
+    MENUITEM "&Show Cookies",IDM_TOOLS_COOKIES
     POPUP "Debugging"
     BEGIN
       MENUITEM "Debug rendering",IDM_VIEW_TOGGLE_DEBUG_RENDERING
diff --git a/frontends/windows/resourceid.h b/frontends/windows/resourceid.h
index bdec80a..605a77c 100644
--- a/frontends/windows/resourceid.h
+++ b/frontends/windows/resourceid.h
@@ -93,45 +93,53 @@
 #define IDC_PREFS_ANIMATIONDELAY 1228
 #define IDC_PREFS_ANIMATIONDELAY_SPIN 1229
 
+#define IDD_DLG_SSLCERT 1600
+#define IDC_SSLCERT_IMG1 1601
+#define IDC_SSLCERT_BTN_ACCEPT 1602
+#define IDC_SSLCERT_BTN_REJECT 1603
+
+
 #define IDR_MENU_MAIN 10000
-#define IDM_FILE_OPEN_WINDOW 10001
-#define IDM_FILE_OPEN_LOCATION 10002
-#define IDM_FILE_CLOSE_WINDOW 10003
-#define IDM_FILE_SAVE_PAGE 10004
-#define IDM_FILE_SAVEAS_TEXT 10005
-#define IDM_FILE_SAVEAS_PDF 10006
-#define IDM_FILE_SAVEAS_POSTSCRIPT 10007
-#define IDM_FILE_PRINT_PREVIEW 10008
-#define IDM_FILE_PRINT 10009
-#define IDM_FILE_QUIT 10010
-#define IDM_EDIT_CUT 10011
-#define IDM_EDIT_COPY 10012
-#define IDM_EDIT_PASTE 10013
-#define IDM_EDIT_DELETE 10014
-#define IDM_EDIT_SELECT_ALL 10015
-#define IDM_EDIT_SEARCH 10016
-#define IDM_NAV_STOP 10017
-#define IDM_NAV_RELOAD 10018
-#define IDM_VIEW_ZOOMPLUS 10019
-#define IDM_VIEW_ZOOMMINUS 10020
-#define IDM_VIEW_ZOOMNORMAL 10021
-#define IDM_VIEW_SOURCE 10022
-#define IDM_VIEW_FULLSCREEN 10023
-#define IDM_NAV_BACK 10024
-#define IDM_NAV_FORWARD 10025
-#define IDM_NAV_HOME 10026
-#define IDM_NAV_LOCALHISTORY 10027
-#define IDM_NAV_GLOBALHISTORY 10028
-#define IDM_VIEW_DOWNLOADS 10029
-#define IDM_VIEW_SAVE_WIN_METRICS 10030
-#define IDM_VIEW_TOGGLE_DEBUG_RENDERING 10031
-#define IDM_VIEW_DEBUGGING_SAVE_BOXTREE 10032
-#define IDM_VIEW_DEBUGGING_SAVE_DOMTREE 10033
-#define IDM_EDIT_PREFERENCES 10034
-#define IDM_HELP_CONTENTS 10035
-#define IDM_HELP_GUIDE 10036
-#define IDM_HELP_INFO 10037
-#define IDM_HELP_ABOUT 10038
+#define IDM_FILE_OPEN_WINDOW 10101
+#define IDM_FILE_OPEN_LOCATION 10102
+#define IDM_FILE_CLOSE_WINDOW 10103
+#define IDM_FILE_SAVE_PAGE 10104
+#define IDM_FILE_SAVEAS_TEXT 10105
+#define IDM_FILE_SAVEAS_PDF 10106
+#define IDM_FILE_SAVEAS_POSTSCRIPT 10107
+#define IDM_FILE_PRINT_PREVIEW 10108
+#define IDM_FILE_PRINT 10109
+#define IDM_FILE_QUIT 10110
+#define IDM_EDIT_CUT 10211
+#define IDM_EDIT_COPY 10212
+#define IDM_EDIT_PASTE 10213
+#define IDM_EDIT_DELETE 10214
+#define IDM_EDIT_SELECT_ALL 10215
+#define IDM_EDIT_SEARCH 10216
+#define IDM_NAV_STOP 10301
+#define IDM_NAV_RELOAD 10302
+#define IDM_VIEW_ZOOMPLUS 10303
+#define IDM_VIEW_ZOOMMINUS 10304
+#define IDM_VIEW_ZOOMNORMAL 10305
+#define IDM_VIEW_SOURCE 10306
+#define IDM_VIEW_FULLSCREEN 10307
+#define IDM_VIEW_SAVE_WIN_METRICS 10308
+#define IDM_NAV_BACK 10309
+#define IDM_NAV_FORWARD 10310
+#define IDM_NAV_HOME 10311
+#define IDM_NAV_LOCALHISTORY 10312
+#define IDM_NAV_GLOBALHISTORY 10313
+#define IDM_NAV_BOOKMARKS 10314
+#define IDM_TOOLS_DOWNLOADS 10430
+#define IDM_TOOLS_COOKIES 10431
+#define IDM_VIEW_TOGGLE_DEBUG_RENDERING 10432
+#define IDM_VIEW_DEBUGGING_SAVE_BOXTREE 10433
+#define IDM_VIEW_DEBUGGING_SAVE_DOMTREE 10434
+#define IDM_EDIT_PREFERENCES 10435
+#define IDM_HELP_CONTENTS 10536
+#define IDM_HELP_GUIDE 10537
+#define IDM_HELP_INFO 10538
+#define IDM_HELP_ABOUT 10539
 
 #define IDR_MENU_CONTEXT 11000
 
diff --git a/frontends/windows/ssl_cert.c b/frontends/windows/ssl_cert.c
new file mode 100644
index 0000000..72d1d3b
--- /dev/null
+++ b/frontends/windows/ssl_cert.c
@@ -0,0 +1,439 @@
+/*
+ * Copyright 2016 Vincent Sanders <[email protected]>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * \file
+ * Implementation of win32 certificate viewing using nsw32 core windows.
+ */
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <windows.h>
+
+#include "utils/log.h"
+#include "utils/nsoption.h"
+#include "netsurf/keypress.h"
+#include "netsurf/plotters.h"
+#include "desktop/sslcert_viewer.h"
+
+#include "windows/windbg.h"
+#include "windows/plot.h"
+#include "windows/corewindow.h"
+#include "windows/gui.h"
+#include "windows/resourceid.h"
+#include "windows/ssl_cert.h"
+
+/* spacing and sizes for dialog elements from
+ * 
https://msdn.microsoft.com/en-us/library/windows/desktop/dn742486(v=vs.85).aspx#sizingandspacing
+ */
+#define DLG_MRGN 11
+#define WRN_ICO_H 32
+#define CMD_BTN_W 75
+#define CMD_BTN_H 23
+
+static const char windowclassname_sslcert[] = "nswssslcertwindow";
+
+struct nsw32_sslcert_window {
+       struct nsw32_corewindow core;
+
+       /** SSL certificate viewer context data */
+       struct sslcert_session_data *ssl_data;
+
+       /** dialog window handle */
+       HWND hWnd;
+
+       /** accept button handle */
+       HWND hAccept;
+
+       /** reject button handle */
+       HWND hReject;
+
+       /** warning text  handle */
+       HWND hTxt;
+
+};
+
+/**
+ * callback for keypress on hotlist window
+ *
+ * \param nsw32_cw The nsw32 core window structure.
+ * \param nskey The netsurf key code
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsw32_sslcert_viewer_key(struct nsw32_corewindow *nsw32_cw, uint32_t nskey)
+{
+       struct nsw32_sslcert_window *crtvrfy_win;
+
+       /* technically degenerate container of */
+       crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw;
+
+       if (sslcert_viewer_keypress(crtvrfy_win->ssl_data, nskey)) {
+               return NSERROR_OK;
+       }
+       return NSERROR_NOT_IMPLEMENTED;
+}
+
+/**
+ * callback for mouse action on hotlist window
+ *
+ * \param nsw32_cw The nsw32 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
+nsw32_sslcert_viewer_mouse(struct nsw32_corewindow *nsw32_cw,
+                   browser_mouse_state mouse_state,
+                   int x, int y)
+{
+       struct nsw32_sslcert_window *crtvrfy_win;
+
+       /* technically degenerate container of */
+       crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw;
+
+       sslcert_viewer_mouse_action(crtvrfy_win->ssl_data, mouse_state, x, y);
+
+       return NSERROR_OK;
+}
+
+/**
+ * callback on draw event for hotlist window
+ *
+ * \param nsw32_cw The nsw32 core window structure.
+ * \param r The rectangle of the window that needs updating.
+ * \return NSERROR_OK on success otherwise apropriate error code
+ */
+static nserror
+nsw32_sslcert_viewer_draw(struct nsw32_corewindow *nsw32_cw,
+                         int scrollx,
+                         int scrolly,
+                         struct rect *r)
+{
+       struct nsw32_sslcert_window *crtvrfy_win;
+       struct redraw_context ctx = {
+               .interactive = true,
+               .background_images = true,
+               .plot = &win_plotters
+       };
+
+       /* technically degenerate container of */
+       crtvrfy_win = (struct nsw32_sslcert_window *)nsw32_cw;
+
+       sslcert_viewer_redraw(crtvrfy_win->ssl_data,
+                             -scrollx, -scrolly,
+                             r, &ctx);
+
+       return NSERROR_OK;
+}
+
+
+static nserror
+nsw32_sslcert_viewer_close(struct nsw32_corewindow *nsw32_cw)
+{
+       DestroyWindow(nsw32_cw->hWnd);
+
+       return NSERROR_OK;
+}
+
+
+/* exported interface documented in nsw32/ssl_cert.h */
+nserror nsw32_cert_verify(struct nsurl *url,
+                       const struct ssl_cert_info *certs,
+                       unsigned long num,
+                       nserror (*cb)(bool proceed, void *pw),
+                       void *cbpw)
+{
+       struct nsw32_sslcert_window *ncwin;
+       nserror res;
+
+       ncwin = malloc(sizeof(struct nsw32_sslcert_window));
+       if (ncwin == NULL) {
+               return NSERROR_NOMEM;
+       }
+
+       /* initialise certificate viewing interface */
+       res = sslcert_viewer_create_session_data(num, url, cb, cbpw, certs,
+                                                &ncwin->ssl_data);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       LOG("creating hInstance %p SSL window", hinst);
+       ncwin->hWnd = CreateWindowEx(0,
+                                    windowclassname_sslcert,
+                                    "SSL Certificate viewer",
+                                    WS_OVERLAPPEDWINDOW |
+                                    WS_CLIPSIBLINGS |
+                                    WS_CLIPCHILDREN |
+                                    CS_DBLCLKS,
+                                    CW_USEDEFAULT,
+                                    CW_USEDEFAULT,
+                                    500,
+                                    400,
+                                    NULL,
+                                    NULL,
+                                    hinst,
+                                    NULL);
+       if (ncwin->hWnd == NULL) {
+               LOG("Window create failed");
+               return NSERROR_NOMEM;
+       }
+
+       ncwin->core.title = NULL;
+       ncwin->core.draw = nsw32_sslcert_viewer_draw;
+       ncwin->core.key = nsw32_sslcert_viewer_key;
+       ncwin->core.mouse = nsw32_sslcert_viewer_mouse;
+       ncwin->core.close = nsw32_sslcert_viewer_close;
+
+       res = nsw32_corewindow_init(hinst, ncwin->hWnd, &ncwin->core);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       res = sslcert_viewer_init(ncwin->core.cb_table,
+                                 (struct core_window *)ncwin,
+                                 ncwin->ssl_data);
+       if (res != NSERROR_OK) {
+               free(ncwin);
+               return res;
+       }
+
+       ncwin->hAccept = CreateWindowEx(0,
+                                       "BUTTON",
+                                       "Accept",
+                                       WS_TABSTOP|WS_VISIBLE|
+                                       WS_CHILD|BS_DEFPUSHBUTTON,
+                                       CW_USEDEFAULT,
+                                       CW_USEDEFAULT,
+                                       CMD_BTN_W,
+                                       CMD_BTN_H,
+                                       ncwin->hWnd,
+                                       (HMENU)IDC_SSLCERT_BTN_ACCEPT,
+                                       hinst,
+                                       NULL);
+       HGDIOBJ hfDefault=GetStockObject(DEFAULT_GUI_FONT);
+       SendMessage(ncwin->hAccept, WM_SETFONT, (WPARAM)hfDefault, 
MAKELPARAM(FALSE,0));
+       ncwin->hReject = CreateWindowEx(0,
+                                       "BUTTON",
+                                       "Reject",
+                                       WS_TABSTOP|WS_VISIBLE|
+                                       WS_CHILD|BS_DEFPUSHBUTTON,
+                                       CW_USEDEFAULT,
+                                       CW_USEDEFAULT,
+                                       CMD_BTN_W,
+                                       CMD_BTN_H,
+                                       ncwin->hWnd,
+                                       (HMENU)IDC_SSLCERT_BTN_REJECT,
+                                       hinst,
+                                       NULL);
+       SendMessage(ncwin->hReject, WM_SETFONT, (WPARAM)hfDefault, 
MAKELPARAM(FALSE,0));
+
+       CreateWindowEx(0,
+                      "STATIC",
+                      IDI_WARNING,
+                      WS_VISIBLE | WS_CHILD | SS_ICON,
+                      DLG_MRGN,
+                      DLG_MRGN,
+                      CMD_BTN_W,
+                      CMD_BTN_H,
+                      ncwin->hWnd,
+                      NULL,
+                      NULL,
+                      NULL);
+       ncwin->hTxt = CreateWindowEx(0,
+                      "STATIC",
+                      "NetSurf failed to verify the authenticity of an SSL 
certificate. Verify the certificate details",
+                      WS_VISIBLE | WS_CHILD | SS_LEFT,
+                      DLG_MRGN + WRN_ICO_H + DLG_MRGN,
+                      DLG_MRGN + 5,
+                      400,
+                      WRN_ICO_H - 5,
+                      ncwin->hWnd,
+                      NULL,
+                      NULL,
+                      NULL);
+       SendMessage(ncwin->hTxt, WM_SETFONT, (WPARAM)hfDefault, 
MAKELPARAM(FALSE,0));
+
+       SetProp(ncwin->hWnd, TEXT("CertWnd"), (HANDLE)ncwin);
+
+       ShowWindow(ncwin->hWnd, SW_SHOWNORMAL);
+
+       return NSERROR_OK;
+}
+
+/**
+ * position and size ssl cert window widgets.
+ */
+static void
+nsw32_window_ssl_cert_size(HWND hwnd, struct nsw32_sslcert_window *certwin)
+{
+       RECT rc;
+       GetClientRect(hwnd, &rc);
+       /* position certificate drawable */
+       MoveWindow(certwin->core.hWnd,
+                  DLG_MRGN,
+                  DLG_MRGN + WRN_ICO_H + DLG_MRGN,
+                  rc.right - (DLG_MRGN + DLG_MRGN),
+                  rc.bottom - (DLG_MRGN + WRN_ICO_H + DLG_MRGN + DLG_MRGN + 
CMD_BTN_H + DLG_MRGN),
+                  TRUE);
+       /* position accept button */
+       MoveWindow(certwin->hAccept,
+                  rc.right - (DLG_MRGN + CMD_BTN_W),
+                  rc.bottom - (DLG_MRGN + CMD_BTN_H),
+                  CMD_BTN_W,
+                  CMD_BTN_H,
+                  TRUE);
+       /* position reject button */
+       MoveWindow(certwin->hReject,
+                  rc.right - (DLG_MRGN + CMD_BTN_W + 7 + CMD_BTN_W),
+                  rc.bottom - (DLG_MRGN + CMD_BTN_H),
+                  CMD_BTN_W,
+                  CMD_BTN_H,
+                  TRUE);
+       /* position text */
+       MoveWindow(certwin->hTxt,
+                  DLG_MRGN + WRN_ICO_H + DLG_MRGN,
+                  DLG_MRGN + 5,
+                  rc.right - (DLG_MRGN + WRN_ICO_H + DLG_MRGN + DLG_MRGN),
+                  WRN_ICO_H - 5,
+                  TRUE);
+}
+
+static nserror nsw32_crtvrfy_destroy(struct nsw32_sslcert_window *crtwin)
+{
+       nserror res;
+
+       res = sslcert_viewer_fini(crtwin->ssl_data);
+       if (res == NSERROR_OK) {
+               res = nsw32_corewindow_fini(&crtwin->core);
+               DestroyWindow(crtwin->hWnd);
+               free(crtwin);
+       }
+       return res;
+}
+
+/**
+ * handle command message on main browser window
+ *
+ * \param hwnd The win32 window handle
+ * \param gw win32 gui window
+ * \param notification_code notifiction code
+ * \param identifier notification identifier
+ * \param ctrl_window The win32 control window handle
+ * \return apropriate response for command
+ */
+static LRESULT
+nsw32_window_ssl_cert_command(HWND hwnd,
+                   struct nsw32_sslcert_window *crtwin,
+                   int notification_code,
+                   int identifier,
+                   HWND ctrl_window)
+{
+       LOG("notification_code %x identifier %x ctrl_window %p",
+           notification_code, identifier, ctrl_window);
+
+       switch(identifier) {
+       case IDC_SSLCERT_BTN_ACCEPT:
+               sslcert_viewer_accept(crtwin->ssl_data);
+               nsw32_crtvrfy_destroy(crtwin);
+               break;
+
+       case IDC_SSLCERT_BTN_REJECT:
+               sslcert_viewer_reject(crtwin->ssl_data);
+               nsw32_crtvrfy_destroy(crtwin);
+               break;
+
+       default:
+               return 1; /* unhandled */
+       }
+       return 0; /* control message handled */
+}
+
+/**
+ * callback for SSL certificate window win32 events
+ *
+ * \param hwnd The win32 window handle
+ * \param msg The win32 message identifier
+ * \param wparam The w win32 parameter
+ * \param lparam The l win32 parameter
+ */
+static LRESULT CALLBACK
+nsw32_window_ssl_cert_event_callback(HWND hwnd,
+                                   UINT msg,
+                                   WPARAM wparam,
+                                   LPARAM lparam)
+{
+       struct nsw32_sslcert_window *crtwin;
+       crtwin = GetProp(hwnd, TEXT("CertWnd"));
+       if (crtwin != NULL) {
+               switch (msg) {
+               case WM_SIZE:
+                       nsw32_window_ssl_cert_size(hwnd, crtwin);
+                       break;
+
+               case WM_COMMAND:
+                       if (nsw32_window_ssl_cert_command(hwnd,
+                                                         crtwin,
+                                                         HIWORD(wparam),
+                                                         LOWORD(wparam),
+                                                         (HWND)lparam) == 0) {
+                               return 0;
+                       }
+                       break;
+
+               case WM_CLOSE:
+                       sslcert_viewer_reject(crtwin->ssl_data);
+                       nsw32_crtvrfy_destroy(crtwin);
+                       return 0;
+               }
+       }
+
+       return DefWindowProc(hwnd, msg, wparam, lparam);
+}
+
+/* exported interface documented in nsw32/ssl_cert.h */
+nserror nsws_create_cert_verify_class(HINSTANCE hInstance)
+{
+       nserror ret = NSERROR_OK;
+       WNDCLASSEX wc;
+
+       /* drawable area */
+       wc.cbSize = sizeof(WNDCLASSEX);
+       wc.style = 0;
+       wc.lpfnWndProc = nsw32_window_ssl_cert_event_callback;
+       wc.cbClsExtra = 0;
+       wc.cbWndExtra = 0;
+       wc.hInstance = hInstance;
+       wc.hIcon = NULL;
+       wc.hCursor = NULL;
+       wc.hbrBackground = (HBRUSH)(COLOR_MENU + 1);
+       wc.lpszMenuName = NULL;
+       wc.lpszClassName = windowclassname_sslcert;
+       wc.hIconSm = NULL;
+
+       if (RegisterClassEx(&wc) == 0) {
+               win_perror("CertVerifyClass");
+               ret = NSERROR_INIT_FAILED;
+       }
+
+       return ret;
+}
diff --git a/frontends/gtk/ssl_cert.h b/frontends/windows/ssl_cert.h
similarity index 63%
copy from frontends/gtk/ssl_cert.h
copy to frontends/windows/ssl_cert.h
index 1712756..6c1f041 100644
--- a/frontends/gtk/ssl_cert.h
+++ b/frontends/windows/ssl_cert.h
@@ -1,5 +1,5 @@
 /*
- * Copyright 2005 James Bursa <[email protected]>
+ * Copyright 2016 Vincent Sanders <[email protected]>
  *
  * This file is part of NetSurf, http://www.netsurf-browser.org/
  *
@@ -16,8 +16,13 @@
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  */
 
-#ifndef NETSURF_GTK_SSL_CERT_H
-#define NETSURF_GTK_SSL_CERT_H 1
+/**
+ * \file
+ * Interface to win32 certificate viewing using nsw32 core windows.
+ */
+
+#ifndef NETSURF_WINDOWS_SSL_CERT_H
+#define NETSURF_WINDOWS_SSL_CERT_H 1
 
 struct nsurl;
 struct ssl_cert_info;
@@ -32,6 +37,15 @@ struct ssl_cert_info;
  * \param cbpw Context pointer passed to cb
  * \return NSERROR_OK or error code if prompt creation failed.
  */
-nserror gtk_cert_verify(struct nsurl *url, const struct ssl_cert_info *certs, 
unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+nserror nsw32_cert_verify(struct nsurl *url, const struct ssl_cert_info 
*certs, unsigned long num, nserror (*cb)(bool proceed, void *pw), void *cbpw);
+
+/**
+ * Create the ssl viewer window class.
+ *
+ * \param hinstance The application instance
+ * \return NSERROR_OK on success or NSERROR_INIT_FAILED if the class
+ *         creation failed.
+ */
+nserror nsws_create_cert_verify_class(HINSTANCE hinstance);
 
 #endif
diff --git a/frontends/windows/window.c b/frontends/windows/window.c
index b8c2b39..94dc7c1 100644
--- a/frontends/windows/window.c
+++ b/frontends/windows/window.c
@@ -50,6 +50,9 @@
 #include "windows/font.h"
 #include "windows/prefs.h"
 #include "windows/localhistory.h"
+#include "windows/hotlist.h"
+#include "windows/cookies.h"
+#include "windows/global_history.h"
 #include "windows/window.h"
 
 /** List of all our gui windows */
@@ -1130,6 +1133,15 @@ nsws_window_command(HWND hwnd,
                break;
 
        case IDM_NAV_GLOBALHISTORY:
+               nsw32_global_history_present(hinst);
+               break;
+
+       case IDM_TOOLS_COOKIES:
+               nsw32_cookies_present(hinst);
+               break;
+
+       case IDM_NAV_BOOKMARKS:
+               nsw32_hotlist_present(hinst);
                break;
 
        case IDM_VIEW_ZOOMPLUS:
@@ -1197,7 +1209,7 @@ nsws_window_command(HWND hwnd,
                break;
        }
 
-       case IDM_VIEW_DOWNLOADS:
+       case IDM_TOOLS_DOWNLOADS:
                break;
 
        case IDM_VIEW_TOGGLE_DEBUG_RENDERING:


-- 
NetSurf Browser

_______________________________________________
netsurf-commits mailing list
[email protected]
http://listmaster.pepperfish.net/cgi-bin/mailman/listinfo/netsurf-commits-netsurf-browser.org

Reply via email to