summaryrefslogtreecommitdiff
path: root/windows/gui.c
diff options
context:
space:
mode:
Diffstat (limited to 'windows/gui.c')
-rw-r--r--windows/gui.c2402
1 files changed, 2402 insertions, 0 deletions
diff --git a/windows/gui.c b/windows/gui.c
new file mode 100644
index 000000000..3eeb9fbfa
--- /dev/null
+++ b/windows/gui.c
@@ -0,0 +1,2402 @@
+/*
+ * Copyright 2008 Vincent Sanders <vince@simtec.co.uk>
+ * Copyright 2009 Mark Benjamin <netsurf-browser.org.MarkBenjamin@dfgh.net>
+ *
+ * This file is part of NetSurf, http://www.netsurf-browser.org/
+ *
+ * NetSurf is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * NetSurf is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <unistd.h>
+#include <string.h>
+#include <stdbool.h>
+
+#include <windows.h>
+#include <windowsx.h>
+#define _WIN32_IE (0x0501)
+#include <commctrl.h>
+
+#include <hubbub/hubbub.h>
+
+#include "content/urldb.h"
+#include "content/fetch.h"
+#include "css/utils.h"
+#include "desktop/gui.h"
+#include "desktop/history_core.h"
+#include "desktop/plotters.h"
+#include "desktop/netsurf.h"
+#include "desktop/options.h"
+#include "desktop/save_complete.h"
+#include "desktop/selection.h"
+#include "desktop/textinput.h"
+#include "render/html.h"
+#include "utils/log.h"
+#include "utils/messages.h"
+#include "utils/utils.h"
+
+#include "windows/about.h"
+#include "windows/gui.h"
+#include "windows/findfile.h"
+#include "windows/font.h"
+#include "windows/localhistory.h"
+#include "windows/plot.h"
+#include "windows/prefs.h"
+#include "windows/resourceid.h"
+
+char *default_stylesheet_url;
+char *adblock_stylesheet_url;
+char *quirks_stylesheet_url;
+char *options_file_location;
+
+struct gui_window *input_window = NULL;
+struct gui_window *search_current_window;
+struct gui_window *window_list = NULL;
+
+FARPROC urlproc;
+FARPROC toolproc;
+
+static char default_page[] = "http://www.netsurf-browser.org/welcome/";
+static HICON hIcon, hIconS;
+static int open_windows = 0;
+
+#define NTOOLBUTTONS 5
+#define NSWS_THROBBER_WIDTH 24
+#define NSWS_URL_ENTER (WM_USER)
+
+struct gui_window {
+ /* The front's private data connected to a browser window */
+ /* currently 1<->1 gui_window<->windows window [non-tabbed] */
+ struct browser_window *bw; /** the browser_window */
+ HWND main; /**< handle to the actual window */
+ HWND toolbar; /**< toolbar handle */
+ HWND urlbar; /**< url bar handle */
+ HWND throbber; /** throbber handle */
+ HWND drawingarea; /**< drawing area handle */
+ HWND statusbar; /**< status bar handle */
+ HWND vscroll; /**< vertical scrollbar handle */
+ HWND hscroll; /**< horizontal scrollbar handle */
+ HMENU mainmenu; /**< the main menu */
+ HMENU rclick; /**< the right-click menu */
+ HDC bufferdc; /**< the screen buffer */
+ HBITMAP bufferbm; /**< the buffer bitmap */
+ struct nsws_localhistory *localhistory; /**< handle to local history window */
+ int width; /**< width of window */
+ int height; /**< height of drawing area */
+ int urlbarwidth; /**< width of url bar */
+ int ntoolbuttons; /**< number of toolbar buttons */
+ int toolbuttondimension; /**< width, height of buttons */
+ int voffset; /**< height of toolbar */
+ bool throbbing; /**< whether currently throbbing */
+ TBBUTTON buttons[NTOOLBUTTONS + 1]; /* 1 = url bar */
+ HBITMAP hbmp[NTOOLBUTTONS]; /**< tool button images */
+
+ struct browser_mouse *mouse; /**< mouse state */
+
+ HACCEL acceltable; /**< accelerators */
+
+ float scale; /**< scale of content */
+
+ int scrollx; /**< current scroll location */
+ int scrolly; /**< current scroll location */
+
+ RECT *fullscreen; /**< memorize non-fullscreen area */
+ RECT redraw; /**< Area needing redraw. */
+ RECT clip; /**< current clip rectangle */
+ int requestscrollx, requestscrolly; /**< scolling requested. */
+ struct gui_window *next, *prev; /**< global linked list */
+};
+
+static struct nsws_pointers nsws_pointer;
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+typedef enum {
+ NSWS_ID_TOOLBAR = 1111,
+ NSWS_ID_URLBAR,
+ NSWS_ID_THROBBER,
+ NSWS_ID_DRAWINGAREA,
+ NSWS_ID_STATUSBAR,
+ NSWS_ID_LAUNCH_URL,
+} nsws_constants ;
+
+LRESULT CALLBACK nsws_window_url_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
+LRESULT CALLBACK nsws_window_toolbar_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
+LRESULT CALLBACK nsws_window_event_callback(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
+
+HINSTANCE hinstance;
+
+void gui_multitask(void)
+{
+/* LOG(("gui_multitask")); */
+}
+
+/**
+ * called synchronously to handle all redraw events
+ */
+static void redraw(void)
+{
+ struct gui_window *w = window_list;
+ struct browser_window *bw;
+ struct content *c;
+ HDC hdc;
+
+ while (w != NULL) {
+ if ((w->redraw.right - w->redraw.left <= 0) ||
+ (w->redraw.bottom - w->redraw.top <= 0)) {
+ w = w->next;
+ continue;
+ }
+
+ bw = w->bw;
+ if (bw == NULL) {
+ w = w->next;
+ continue;
+ }
+
+ c = bw->current_content;
+
+ if ((c == NULL) || (c->locked)) {
+ w = w->next;
+ continue;
+ }
+ current_hwnd = w->main;
+ PostMessage(w->toolbar, WM_PAINT, 0, 0);
+ PostMessage(w->urlbar, WM_PAINT, 0, 0);
+ w->scrolly += w->requestscrolly;
+ w->scrollx += w->requestscrollx;
+ w->scrolly = MAX(w->scrolly, 0);
+ w->scrolly = MIN(w->scrolly, c->height * w->bw->scale
+ - w->height);
+ w->scrollx = MAX(w->scrollx, 0);
+ w->scrollx = MIN(w->scrollx, c->width * w->bw->scale
+ - w->width);
+ /* redraw */
+/* w->redraw.left = MIN(w->redraw.left, w->scrollx);
+ w->redraw.top = MIN(w->redraw.top, w->scrolly + w->voffset );
+ w->redraw.right = MAX(w->redraw.right, w->scrollx + w->width);
+ w->redraw.bottom = MAX(w->redraw.bottom, w->scrolly +
+ w->height + w->voffset );
+*/
+ current_redraw_browser = bw;
+ nsws_plot_set_scale(bw->scale);
+
+/* doublebuffering = true; */
+ hdc = GetDC(w->main);
+ if (w->bufferbm == NULL) {
+ w->bufferbm = CreateCompatibleBitmap(hdc, w->width,
+ w->height + w->voffset);
+ SelectObject(w->bufferdc, w->bufferbm);
+ }
+
+
+ if ((w->bufferbm == NULL) || (w->bufferdc == NULL) ||
+ (hdc == NULL))
+ doublebuffering = false;
+ if (doublebuffering)
+ bufferdc = w->bufferdc;
+ content_redraw(c, -w->scrollx / w->bw->scale,
+ -w->scrolly / w->bw->scale,
+ w->width, w->height,
+ w->redraw.left - w->scrollx / w->bw->scale,
+ w->redraw.top - w->scrolly / w->bw->scale,
+ w->redraw.right - w->scrollx / w->bw->scale,
+ w->redraw.bottom - w->scrolly / w->bw->scale,
+ bw->scale, 0xFFFFFF);
+ if (doublebuffering)
+ /* blit buffer to screen */
+ BitBlt(hdc, 0, w->voffset, w->width, w->height,
+ w->bufferdc, 0, w->voffset,
+ SRCCOPY);
+ ReleaseDC(w->main, hdc);
+ doublebuffering = false;
+
+ w->requestscrolly = 0;
+ w->requestscrollx = 0;
+ w->redraw.left = w->redraw.top = INT_MAX;
+ w->redraw.right = w->redraw.bottom = -(INT_MAX);
+ w = w->next;
+ }
+}
+
+void gui_poll(bool active)
+{
+ MSG Msg;
+ if (PeekMessage(&Msg, NULL, 0, 0, PM_REMOVE) != 0) {
+ if (!((current_gui == NULL) ||
+ (TranslateAccelerator(current_gui->main,
+ current_gui->acceltable, &Msg))))
+ TranslateMessage(&Msg);
+ DispatchMessage(&Msg);
+ }
+
+ schedule_run();
+
+}
+
+
+
+/**
+ * callback for url bar events
+ */
+LRESULT CALLBACK nsws_window_url_callback(HWND hwnd, UINT msg, WPARAM wparam,
+ LPARAM lparam)
+{
+ DWORD i, ii;
+ SendMessage(hwnd, EM_GETSEL, (WPARAM)&i, (LPARAM)&ii);
+ int x,y;
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+
+ if (msg == WM_PAINT) {
+ SendMessage(hwnd, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
+ SendMessage(hwnd, EM_SETSEL, (WPARAM)i, (LPARAM)ii);
+ }
+ return CallWindowProc((WNDPROC) urlproc, hwnd, msg, wparam, lparam);
+}
+
+/**
+ * callback for toolbar events
+ */
+LRESULT CALLBACK nsws_window_toolbar_callback(HWND hwnd, UINT msg,
+ WPARAM wparam, LPARAM lparam)
+{
+ bool match = false;
+ struct gui_window *w = window_list;
+ while (w != NULL) {
+ if (w->toolbar == hwnd) {
+ match = true;
+ break;
+ }
+ w = w->next;
+ }
+
+ if (match == false) { /* during initial window creation */
+ w = window_list;
+ while (w != NULL) {
+ if (w->toolbar == NULL) {
+ w->toolbar = hwnd;
+ break;
+ }
+ w = w->next;
+ }
+ }
+
+ if ((msg == WM_LBUTTONUP) ||
+ (msg == WM_LBUTTONDOWN) ||
+ (msg == WM_MOUSEMOVE)) {
+ int x,y;
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+ if ((w != NULL) &&
+ (x > w->ntoolbuttons * w->toolbuttondimension)
+ && (y < w->voffset)) {
+ if (msg == WM_LBUTTONDOWN)
+ SetFocus(w->urlbar);
+ return CallWindowProc((WNDPROC)
+ nsws_window_url_callback,
+ w->urlbar, msg, wparam,
+ MAKELONG(x - w->ntoolbuttons *
+ w->toolbuttondimension, y));
+ }
+ }
+ return CallWindowProc((WNDPROC) toolproc, hwnd, msg, wparam, lparam);
+}
+
+/**
+ * update state of forward/back buttons/menu items when page changes
+ */
+static void nsws_window_update_forward_back(struct gui_window *w)
+{
+ if (w->bw == NULL)
+ return;
+ bool forward = history_forward_available(w->bw->history);
+ bool back = history_back_available(w->bw->history);
+ if (w->mainmenu != NULL) {
+ EnableMenuItem(w->mainmenu, NSWS_ID_NAV_FORWARD,
+ (forward ? MF_ENABLED : MF_GRAYED));
+ EnableMenuItem(w->mainmenu, NSWS_ID_NAV_BACK,
+ (back ? MF_ENABLED : MF_GRAYED));
+ EnableMenuItem(w->rclick, NSWS_ID_NAV_FORWARD,
+ (forward ? MF_ENABLED : MF_GRAYED));
+ EnableMenuItem(w->rclick, NSWS_ID_NAV_BACK,
+ (back ? MF_ENABLED : MF_GRAYED));
+ }
+ if (w->toolbar != NULL) {
+ SendMessage(w->toolbar, TB_SETSTATE,
+ (WPARAM) NSWS_ID_NAV_FORWARD,
+ MAKELONG((forward ? TBSTATE_ENABLED :
+ TBSTATE_INDETERMINATE), 0));
+ SendMessage(w->toolbar, TB_SETSTATE,
+ (WPARAM) NSWS_ID_NAV_BACK,
+ MAKELONG((back ? TBSTATE_ENABLED :
+ TBSTATE_INDETERMINATE), 0));
+ }
+}
+
+static void nsws_update_edit(struct gui_window *w)
+{
+ bool paste, copy, del;
+ if (GetFocus() == w->urlbar) {
+ DWORD i, ii;
+ SendMessage(w->urlbar, EM_GETSEL, (WPARAM)&i,
+ (LPARAM)&ii);
+ paste = true;
+ copy = (i != ii);
+ del = (i != ii);
+
+ } else if ((w->bw != NULL) && (w->bw->sel != NULL)){
+ paste = (w->bw->paste_callback != NULL);
+ copy = w->bw->sel->defined;
+ del = ((w->bw->sel->defined) &&
+ (w->bw->caret_callback != NULL));
+ } else {
+ paste = false;
+ copy = false;
+ del = false;
+ }
+ EnableMenuItem(w->mainmenu,
+ NSWS_ID_EDIT_PASTE,
+ (paste ? MF_ENABLED : MF_GRAYED));
+
+ EnableMenuItem(w->rclick,
+ NSWS_ID_EDIT_PASTE,
+ (paste ? MF_ENABLED : MF_GRAYED));
+
+
+ EnableMenuItem(w->mainmenu,
+ NSWS_ID_EDIT_COPY,
+ (copy ? MF_ENABLED : MF_GRAYED));
+
+
+ EnableMenuItem(w->rclick,
+ NSWS_ID_EDIT_COPY,
+ (copy ? MF_ENABLED : MF_GRAYED));
+
+
+ if (del == true) {
+ EnableMenuItem(w->mainmenu, NSWS_ID_EDIT_CUT, MF_ENABLED);
+ EnableMenuItem(w->mainmenu, NSWS_ID_EDIT_DELETE, MF_ENABLED);
+ EnableMenuItem(w->rclick, NSWS_ID_EDIT_CUT, MF_ENABLED);
+ EnableMenuItem(w->rclick, NSWS_ID_EDIT_DELETE, MF_ENABLED);
+ } else {
+ EnableMenuItem(w->mainmenu, NSWS_ID_EDIT_CUT, MF_GRAYED);
+ EnableMenuItem(w->mainmenu, NSWS_ID_EDIT_DELETE, MF_GRAYED);
+ EnableMenuItem(w->rclick, NSWS_ID_EDIT_CUT, MF_GRAYED);
+ EnableMenuItem(w->rclick, NSWS_ID_EDIT_DELETE, MF_GRAYED);
+ }
+}
+
+static bool
+nsws_ctx_menu(struct gui_window *w, HWND hwnd, int x, int y)
+{
+ RECT rc; /* client area of window */
+ POINT pt = { x, y }; /* location of mouse click */
+
+ /* Get the bounding rectangle of the client area. */
+ GetClientRect(hwnd, &rc);
+
+ /* Convert the mouse position to client coordinates. */
+ ScreenToClient(hwnd, &pt);
+
+ /* If the position is in the client area, display a shortcut menu. */
+ if (PtInRect(&rc, pt)) {
+ ClientToScreen(hwnd, &pt);
+ nsws_update_edit(w);
+ TrackPopupMenu(GetSubMenu(w->rclick, 0),
+ TPM_CENTERALIGN | TPM_TOPALIGN,
+ x,
+ y,
+ 0,
+ hwnd,
+ NULL);
+
+ return true;
+ }
+
+ /* Return false if no menu is displayed. */
+ return false;
+}
+
+/**
+ * set accelerators
+ */
+static void nsws_window_set_accels(struct gui_window *w)
+{
+ int i, nitems = 13;
+ ACCEL accels[nitems];
+ for (i = 0; i < nitems; i++)
+ accels[i].fVirt = FCONTROL | FVIRTKEY;
+ accels[0].key = 0x51; /* Q */
+ accels[0].cmd = NSWS_ID_FILE_QUIT;
+ accels[1].key = 0x4E; /* N */
+ accels[1].cmd = NSWS_ID_FILE_OPEN_WINDOW;
+ accels[2].key = VK_LEFT;
+ accels[2].cmd = NSWS_ID_NAV_BACK;
+ accels[3].key = VK_RIGHT;
+ accels[3].cmd = NSWS_ID_NAV_FORWARD;
+ accels[4].key = VK_UP;
+ accels[4].cmd = NSWS_ID_NAV_HOME;
+ accels[5].key = VK_BACK;
+ accels[5].cmd = NSWS_ID_NAV_STOP;
+ accels[6].key = VK_SPACE;
+ accels[6].cmd = NSWS_ID_NAV_RELOAD;
+ accels[7].key = 0x4C; /* L */
+ accels[7].cmd = NSWS_ID_FILE_OPEN_LOCATION;
+ accels[8].key = 0x57; /* w */
+ accels[8].cmd = NSWS_ID_FILE_CLOSE_WINDOW;
+ accels[9].key = 0x41; /* A */
+ accels[9].cmd = NSWS_ID_EDIT_SELECT_ALL;
+ accels[10].key = VK_F8;
+ accels[10].cmd = NSWS_ID_VIEW_SOURCE;
+ accels[11].key = VK_RETURN;
+ accels[11].fVirt = FVIRTKEY;
+ accels[11].cmd = NSWS_ID_LAUNCH_URL;
+ accels[12].key = VK_F11;
+ accels[12].fVirt = FVIRTKEY;
+ accels[12].cmd = NSWS_ID_VIEW_FULLSCREEN;
+
+ w->acceltable = CreateAcceleratorTable(accels, nitems);
+}
+
+/**
+ * set window icons
+ */
+static void nsws_window_set_ico(struct gui_window *w)
+{
+ char ico[PATH_MAX];
+ nsws_find_resource(ico, "NetSurf32.ico", "windows/res/NetSurf32.ico");
+ LOG(("setting ico as %s", ico));
+ hIcon = LoadImage(NULL, ico, IMAGE_ICON, 32, 32, LR_LOADFROMFILE);
+ if (hIcon != NULL)
+ SendMessage(w->main, WM_SETICON, ICON_BIG, (LPARAM) hIcon);
+ nsws_find_resource(ico, "NetSurf16.ico", "windows/res/NetSurf16.ico");
+ LOG(("setting ico as %s", ico));
+ hIconS = LoadImage(NULL, ico, IMAGE_ICON, 16, 16, LR_LOADFROMFILE);
+ if (hIconS != NULL)
+ SendMessage(w->main, WM_SETICON, ICON_SMALL, (LPARAM)hIconS);
+}
+
+/**
+ * creation of url bar
+ */
+static void nsws_window_urlbar_create(struct gui_window *w)
+{
+ HWND hwnd = CreateWindow("EDIT",
+ "",
+ WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL | ES_OEMCONVERT,
+ w->toolbuttondimension * w->ntoolbuttons + 4,
+ 10,
+ w->urlbarwidth - 8,
+ w->toolbuttondimension - 12,
+ w->main,
+ (HMENU) NSWS_ID_URLBAR,
+ hinstance,
+ NULL);
+ /*urlproc = (FARPROC) SetWindowLong(hwnd, GWL_WNDPROC, (DWORD)
+ nsws_window_url_callback);*/
+ w->urlbar = hwnd;
+}
+
+/**
+ * creation of throbber
+ */
+static void nsws_window_throbber_create(struct gui_window *w)
+{
+ HWND hwnd;
+ char avi[PATH_MAX];
+
+ hwnd = CreateWindow(ANIMATE_CLASS,
+ "",
+ WS_CHILD | WS_VISIBLE | ACS_TRANSPARENT,
+ w->width - NSWS_THROBBER_WIDTH - 4, 8,
+ NSWS_THROBBER_WIDTH, NSWS_THROBBER_WIDTH, w->main,
+ (HMENU) NSWS_ID_THROBBER, hinstance, NULL);
+
+ nsws_find_resource(avi, "throbber.avi", "windows/res/throbber.avi");
+ LOG(("setting throbber avi as %s", avi));
+ Animate_Open(hwnd, avi);
+ if (w->throbbing)
+ Animate_Play(hwnd, 0, -1, -1);
+ else
+ Animate_Seek(hwnd, 0);
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ w->throbber = hwnd;
+}
+
+/**
+ * creation of toolbar
+ */
+static void
+nsws_window_toolbar_create(struct gui_window *w)
+{
+ unsigned int listid = 0;
+ char imagepath[PATH_MAX];
+ /* NB there is currently an immediate window close at
+ * netsurf launch in real/virtual - as distinct from
+ * emulation - windows whose probable cause is the
+ * location of the url bar to the right of the buttons;
+ * really the way forward would quite possibly be to
+ * implement an active bitmap as the button bar, sensitive
+ * to hover / click events; the immediate window close
+ * behaviour was observed during development when testing
+ * the arrangements of url bar / buttons although much has
+ * changed since then */
+
+ HWND hwnd = CreateWindow(TOOLBARCLASSNAME, NULL, WS_CHILD |
+ WS_VISIBLE | WS_BORDER | WS_CLIPSIBLINGS,
+ 0, 0, w->width,
+ w->toolbuttondimension + 12, w->main,
+ (HMENU) NSWS_ID_TOOLBAR, hinstance, NULL);
+ HIMAGELIST hImageList = ImageList_Create(w->toolbuttondimension - 8,
+ w->toolbuttondimension - 8, 0, w->ntoolbuttons, 0);
+ SendMessage(hwnd, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
+
+ ZeroMemory(w->buttons, sizeof(w->buttons));
+
+ w->buttons[5].iBitmap = w->urlbarwidth;
+ w->buttons[5].fsStyle = TBSTYLE_SEP;
+ w->buttons[5].iString = -1;
+/* w->buttons[0].fsState = TBSTATE_ENABLED; */
+
+/* keep bitmaps in cache memory for re-creation of toolbar */
+
+#define MAKE_BUTTON(p, q, r) \
+ if (w->hbmp[p] == NULL) { \
+ nsws_find_resource(imagepath, #r ".bmp", "windows/res/" \
+ #r ".bmp"); \
+ LOG(("loading toolbutton image %s", imagepath)); \
+ w->hbmp[p] = LoadImage(NULL, imagepath, IMAGE_BITMAP, \
+ w->toolbuttondimension - 8, \
+ w->toolbuttondimension - 8, LR_SHARED | \
+ LR_LOADFROMFILE | LR_LOADTRANSPARENT); \
+ } \
+ ImageList_Add(hImageList, w->hbmp[p], NULL); \
+ w->buttons[p].iBitmap = MAKELONG(p, 0); \
+ w->buttons[p].idCommand = NSWS_ID_NAV_##q; \
+ w->buttons[p].fsState = TBSTATE_ENABLED; \
+ w->buttons[p].fsStyle = TBSTYLE_BUTTON
+ MAKE_BUTTON(0, BACK, back);
+ MAKE_BUTTON(1, FORWARD, forward);
+ MAKE_BUTTON(2, HOME, home);
+ MAKE_BUTTON(3, STOP, stop);
+ MAKE_BUTTON(4, RELOAD, reload);
+#undef MAKE_BUTTON
+ SendMessage(hwnd, TB_SETIMAGELIST, (WPARAM) listid, (LPARAM)
+ hImageList);
+ SendMessage(hwnd, TB_ADDBUTTONS, w->ntoolbuttons + 1,
+ (LPARAM) &(w->buttons));
+ w->toolbar = hwnd;
+ DeleteObject(hImageList);
+ nsws_window_urlbar_create(w);
+ nsws_window_throbber_create(w);
+ SendMessage(hwnd, WM_SIZE, 0,
+ MAKELONG(w->width, w->toolbuttondimension + 12));
+ toolproc = (FARPROC) SetWindowLong(hwnd, GWL_WNDPROC, (DWORD)
+ nsws_window_toolbar_callback);
+}
+
+/**
+ * creation of status bar
+ */
+static void nsws_window_statusbar_create(struct gui_window *w)
+{
+ HWND hwnd = CreateWindowEx(0, STATUSCLASSNAME, NULL, WS_CHILD |
+ WS_VISIBLE, 0, 0, 0, 0, w->main,
+ (HMENU) NSWS_ID_STATUSBAR, hinstance, NULL);
+ SendMessage(hwnd, SB_SETTEXT, 0, (LPARAM)"NetSurf");
+ w->statusbar = hwnd;
+}
+
+static void nsws_window_drawingarea_create(struct gui_window *w)
+{
+ /* potentially make drawingarea window from frameless window
+ + scrollbars here */
+}
+
+/**
+ * creation of vertical scrollbar
+ */
+static void nsws_window_vscroll_create(struct gui_window *w)
+{
+ w->vscroll = CreateWindow("SCROLLBAR", NULL, WS_CHILD | SBS_VERT,
+ 0, 0, CW_USEDEFAULT, 300, w->main, NULL, hinstance,
+ NULL);
+}
+
+/**
+ * creation of horizontal scrollbar
+ */
+static void nsws_window_hscroll_create(struct gui_window *w)
+{
+ w->hscroll = CreateWindow("SCROLLBAR", NULL, WS_CHILD | SBS_HORZ,
+ 0, 0, 200, CW_USEDEFAULT, w->main, NULL, hinstance,
+ NULL);
+}
+
+/**
+ * callback for window events generally
+ */
+LRESULT CALLBACK nsws_window_event_callback(HWND hwnd, UINT msg, WPARAM wparam,
+ LPARAM lparam)
+{
+ bool match = false;
+ bool historyactive = false;
+ struct gui_window *w = window_list;
+ while (w != NULL) {
+ if (w->main == hwnd) {
+ match = true;
+ break;
+ }
+ w = w->next;
+ }
+ if (!match) { /* during initial window creation */
+ w = window_list;
+ while (w != NULL) {
+ if (w->main == NULL) {
+ w->main = hwnd;
+ break;
+ }
+ w = w->next;
+ }
+ }
+ if ((match) && (current_gui == NULL)) {
+ /* local history window is active */
+ if ((msg == WM_LBUTTONDOWN) || (msg == WM_PAINT))
+ historyactive = true;
+ else if ((msg == WM_NCHITTEST) || (msg == WM_SETCURSOR))
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ else
+ return 0;
+ }
+ current_gui = w;
+ switch(msg) {
+ case WM_KEYDOWN: {
+ if (GetFocus() != hwnd)
+ break;
+ uint32_t i;
+ bool shift = ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000);
+ bool capslock = ((GetKeyState(VK_CAPITAL) & 1) == 1);
+ switch(wparam) {
+ case VK_LEFT:
+ i = KEY_LEFT;
+ if (shift)
+ SendMessage(hwnd, WM_HSCROLL,
+ MAKELONG(SB_LINELEFT, 0), 0);
+ break;
+ case VK_RIGHT:
+ i = KEY_RIGHT;
+ if (shift)
+ SendMessage(hwnd, WM_HSCROLL,
+ MAKELONG(SB_LINERIGHT, 0), 0);
+ break;
+ case VK_UP:
+ i = KEY_UP;
+ if (shift)
+ SendMessage(hwnd, WM_VSCROLL,
+ MAKELONG(SB_LINEUP, 0), 0);
+ break;
+ case VK_DOWN:
+ i = KEY_DOWN;
+ if (shift)
+ SendMessage(hwnd, WM_VSCROLL,
+ MAKELONG(SB_LINEDOWN, 0), 0);
+ break;
+ case VK_HOME:
+ i = KEY_LINE_START;
+ if (shift)
+ SendMessage(hwnd, WM_HSCROLL,
+ MAKELONG(SB_PAGELEFT, 0), 0);
+ break;
+ case VK_END:
+ i = KEY_LINE_END;
+ if (shift)
+ SendMessage(hwnd, WM_HSCROLL,
+ MAKELONG(SB_PAGERIGHT, 0), 0);
+ break;
+ case VK_DELETE:
+ i = KEY_DELETE_RIGHT;
+ break;
+ case VK_NEXT:
+ i = wparam;
+ SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0),
+ 0);
+ break;
+ case VK_PRIOR:
+ i = wparam;
+ SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0),
+ 0);
+ break;
+ default:
+ i = wparam;
+ break;
+ }
+ if ((i >= 'A') && (i <= 'Z') &&
+ (((!capslock) && (!shift)) ||
+ ((capslock) && (shift))))
+ i += 'a' - 'A';
+ if (w != NULL)
+ browser_window_key_press(w->bw, i);
+ break;
+ }
+ case WM_MOUSEMOVE: {
+ int x,y;
+ bool shift = ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000);
+ bool ctrl = ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000);
+ bool alt = ((GetKeyState(VK_MENU) & 0x8000) == 0x8000);
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+ if ((w == NULL) || (w->mouse == NULL) || (w->bw == NULL)
+ || (y < w->voffset))
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+
+ if ((w->mouse->state & BROWSER_MOUSE_PRESS_1) != 0) {
+ browser_window_mouse_click(w->bw, BROWSER_MOUSE_DRAG_1,
+ w->mouse->pressed_x,
+ w->mouse->pressed_y);
+ w->mouse->state &= ~BROWSER_MOUSE_PRESS_1;
+ w->mouse->state |= BROWSER_MOUSE_HOLDING_1 |
+ BROWSER_MOUSE_DRAG_ON;
+ }
+ else if ((w->mouse->state & BROWSER_MOUSE_PRESS_2) != 0) {
+ browser_window_mouse_click(w->bw, BROWSER_MOUSE_DRAG_2,
+ w->mouse->pressed_x,
+ w->mouse->pressed_y);
+ w->mouse->state &= ~BROWSER_MOUSE_PRESS_2;
+ w->mouse->state |= BROWSER_MOUSE_HOLDING_2 |
+ BROWSER_MOUSE_DRAG_ON;
+ }
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_1) != 0) && !shift)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_1;
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_2) != 0) && !ctrl)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_2;
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_3) != 0) && !alt)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_3;
+
+ browser_window_mouse_track(w->bw, w->mouse->state,
+ (x + w->scrollx) / w->bw->scale,
+ (y - w->voffset + w->scrolly) / w->bw->scale);
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ }
+ case WM_LBUTTONDOWN: {
+ int x,y;
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+ if ((w == NULL) || (w->mouse == NULL) || (w->bw == NULL)
+ || (y < w->voffset)) {
+ nsws_localhistory_close(w);
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ }
+ w->mouse->state = BROWSER_MOUSE_PRESS_1;
+ if ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000)
+ w->mouse->state |= BROWSER_MOUSE_MOD_1;
+ if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000)
+ w->mouse->state |= BROWSER_MOUSE_MOD_2;
+ if ((GetKeyState(VK_MENU) & 0x8000) == 0x8000)
+ w->mouse->state |= BROWSER_MOUSE_MOD_3;
+ w->mouse->pressed_x = (x + w->scrollx) / w->bw->scale;
+ w->mouse->pressed_y = (y - w->voffset + w->scrolly)
+ / w->bw->scale;
+
+ SetFocus(hwnd);
+ browser_window_mouse_click(w->bw, w->mouse->state,
+ (x + w->scrollx) / w->bw->scale ,
+ (y - w->voffset + w->scrolly) /
+ w->bw->scale);
+ nsws_localhistory_close(w);
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ }
+ case WM_RBUTTONDOWN: {
+ int x,y;
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+ if ((w == NULL) || (w->mouse == NULL) || (w->bw == NULL) ||
+ (y < w->voffset))
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+
+ w->mouse->state = BROWSER_MOUSE_PRESS_2;
+ if ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000)
+ w->mouse->state |= BROWSER_MOUSE_MOD_1;
+ if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000)
+ w->mouse->state |= BROWSER_MOUSE_MOD_2;
+ if ((GetKeyState(VK_MENU) & 0x8000) == 0x8000)
+ w->mouse->state |= BROWSER_MOUSE_MOD_3;
+ w->mouse->pressed_x = (x + w->scrollx) / w->bw->scale;
+ w->mouse->pressed_y = (y - w->voffset + w->scrolly)
+ / w->bw->scale;
+ SetFocus(hwnd);
+ browser_window_mouse_click(w->bw, w->mouse->state,
+ (x + w->scrollx) / w->bw->scale ,
+ (y - w->voffset + w->scrolly) /
+ w->bw->scale);
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ }
+ case WM_LBUTTONUP: {
+ int x,y;
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+ if ((w == NULL) || (w->mouse == NULL) || (w->bw == NULL)
+ || (y < w->voffset))
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+
+ bool shift = ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000);
+ bool ctrl = ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000);
+ bool alt = ((GetKeyState(VK_MENU) & 0x8000) == 0x8000);
+
+ if ((w->mouse->state & BROWSER_MOUSE_PRESS_1) != 0) {
+ w->mouse->state &= ~BROWSER_MOUSE_PRESS_1;
+ w->mouse->state |= BROWSER_MOUSE_CLICK_1;
+ }
+
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_1) != 0) && !shift)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_1;
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_2) != 0) && !ctrl)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_2;
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_3) != 0) && !alt)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_3;
+
+ if ((w->mouse->state & BROWSER_MOUSE_CLICK_1) != 0)
+ browser_window_mouse_click(w->bw, w->mouse->state,
+ (x + w->scrollx) / w->bw->scale,
+ (y - w->voffset + w->scrolly) /
+ w->bw->scale);
+ else
+ browser_window_mouse_drag_end(w->bw, 0,
+ (x + w->scrollx) / w->bw->scale,
+ (y - w->voffset + w->scrolly) /
+ w->bw->scale);
+
+ w->mouse->state = 0;
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ }
+ case WM_RBUTTONUP: {
+ int x,y;
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+ if ((w == NULL) || (w->mouse == NULL) || (w->bw == NULL) ||
+ (y < w->voffset))
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ bool shift = ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000);
+ bool ctrl = ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000);
+ bool alt = ((GetKeyState(VK_MENU) & 0x8000) == 0x8000);
+
+ if ((w->mouse->state & BROWSER_MOUSE_PRESS_2) != 0) {
+ w->mouse->state &= ~BROWSER_MOUSE_PRESS_2;
+ w->mouse->state |= BROWSER_MOUSE_CLICK_2;
+ }
+
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_1) != 0) && !shift)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_1;
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_2) != 0) && !ctrl)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_2;
+ if (((w->mouse->state & BROWSER_MOUSE_MOD_3) != 0) && !alt)
+ w->mouse->state &= ~BROWSER_MOUSE_MOD_3;
+
+ if ((w->mouse->state & BROWSER_MOUSE_CLICK_2) != 0)
+ browser_window_mouse_click(w->bw, w->mouse->state,
+ (x + w->scrollx) / w->bw->scale,
+ (y - w->voffset + w->scrolly) /
+ w->bw->scale);
+ else
+ browser_window_mouse_drag_end(w->bw, 0,
+ (x + w->scrollx) / w->bw->scale,
+ (y - w->voffset + w->scrolly) /
+ w->bw->scale);
+
+ w->mouse->state = 0;
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ }
+ case WM_LBUTTONDBLCLK: {
+ int x,y;
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+ if ((w != NULL) && (w->bw != NULL) && (y > w->voffset))
+ browser_window_mouse_click(w->bw,
+ BROWSER_MOUSE_DOUBLE_CLICK,
+ (x + w->scrollx) / w->bw->scale,
+ (y - w->voffset + w->scrolly) /
+ w->bw->scale);
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ }
+ case WM_NCLBUTTONDOWN: {
+ int x,y;
+ x = GET_X_LPARAM(lparam);
+ y = GET_Y_LPARAM(lparam);
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ }
+ case WM_ENTERMENULOOP:
+ nsws_update_edit(w);
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+
+ case WM_CONTEXTMENU:
+ if (!nsws_ctx_menu(w, hwnd, GET_X_LPARAM(lparam), GET_Y_LPARAM(lparam)))
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+
+
+ break;
+
+ case WM_COMMAND:
+ {
+ switch(LOWORD(wparam)) {
+ case NSWS_ID_FILE_QUIT:
+ w = window_list;
+ while (w != NULL) {
+ PostMessage(w->main, WM_CLOSE, 0, 0);
+ w = w->next;
+ }
+ netsurf_quit = true;
+ break;
+ case NSWS_ID_FILE_OPEN_LOCATION:
+ SetFocus(w->urlbar);
+ break;
+ case NSWS_ID_FILE_OPEN_WINDOW:
+ break;
+ case NSWS_ID_FILE_CLOSE_WINDOW:
+ PostMessage(hwnd, WM_CLOSE, 0, 0);
+ break;
+ case NSWS_ID_FILE_SAVE_PAGE:
+ break;
+ case NSWS_ID_FILE_SAVEAS_TEXT:
+ break;
+ case NSWS_ID_FILE_SAVEAS_PDF:
+ break;
+ case NSWS_ID_FILE_SAVEAS_DRAWFILE:
+ break;
+ case NSWS_ID_FILE_SAVEAS_POSTSCRIPT:
+ break;
+ case NSWS_ID_FILE_PRINT_PREVIEW:
+ break;
+ case NSWS_ID_FILE_PRINT:
+ break;
+ case NSWS_ID_EDIT_CUT:
+ OpenClipboard(hwnd);
+ EmptyClipboard();
+ CloseClipboard();
+ if (GetFocus() == w->urlbar)
+ SendMessage(w->urlbar, WM_CUT, 0, 0);
+ else if (w->bw != NULL)
+ browser_window_key_press(w->bw,
+ KEY_CUT_SELECTION);
+ break;
+ case NSWS_ID_EDIT_COPY:
+ OpenClipboard(hwnd);
+ EmptyClipboard();
+ CloseClipboard();
+ if (GetFocus() == w->urlbar)
+ SendMessage(w->urlbar, WM_COPY, 0, 0);
+ else if (w->bw != NULL)
+ gui_copy_to_clipboard(w->bw->sel);
+ break;
+ case NSWS_ID_EDIT_PASTE: {
+ OpenClipboard(hwnd);
+ HANDLE h = GetClipboardData(CF_TEXT);
+ if (h != NULL) {
+ char *content = GlobalLock(h);
+ LOG(("pasting %s\n", content));
+ GlobalUnlock(h);
+ }
+ CloseClipboard();
+ if (GetFocus() == w->urlbar)
+ SendMessage(w->urlbar, WM_PASTE, 0, 0);
+ else
+ gui_paste_from_clipboard(w, 0, 0);
+ break;
+ }
+ case NSWS_ID_EDIT_DELETE:
+ if (GetFocus() == w->urlbar)
+ SendMessage(w->urlbar, WM_CUT, 0, 0);
+ else
+ browser_window_key_press(w->bw,
+ KEY_DELETE_RIGHT);
+ break;
+ case NSWS_ID_EDIT_SELECT_ALL:
+ if (GetFocus() == w->urlbar)
+ SendMessage(w->urlbar, EM_SETSEL, 0, -1);
+ else
+ selection_select_all(w->bw->sel);
+ break;
+ case NSWS_ID_EDIT_SEARCH:
+ break;
+ case NSWS_ID_EDIT_PREFERENCES:
+ nsws_prefs_dialog_init(w->main);
+ break;
+ case NSWS_ID_NAV_BACK:
+ if ((w->bw != NULL) && (history_back_available(
+ w->bw->history))) {
+ history_back(w->bw, w->bw->history);
+ }
+ nsws_window_update_forward_back(w);
+ break;
+ case NSWS_ID_NAV_FORWARD:
+ if ((w->bw != NULL) && (history_forward_available(
+ w->bw->history))) {
+ history_forward(w->bw, w->bw->history);
+ }
+ nsws_window_update_forward_back(w);
+ break;
+ case NSWS_ID_NAV_HOME:
+ browser_window_go(w->bw, default_page, 0, true);
+ break;
+ case NSWS_ID_NAV_STOP:
+ browser_window_stop(w->bw);
+ break;
+ case NSWS_ID_NAV_RELOAD:
+ browser_window_reload(w->bw, true);
+ break;
+ case NSWS_ID_NAV_LOCALHISTORY:
+ nsws_localhistory_init(w);
+ break;
+ case NSWS_ID_NAV_GLOBALHISTORY:
+ break;
+ case NSWS_ID_VIEW_ZOOMPLUS: {
+ int x, y;
+ gui_window_get_scroll(w, &x, &y);
+ if (w->bw != NULL) {
+ browser_window_set_scale(w->bw,
+ w->bw->scale * 1.1, true);
+ browser_window_reformat(w->bw, w->width,
+ w->height);
+ }
+ gui_window_redraw_window(w);
+ gui_window_set_scroll(w, x, y);
+ break;
+ }
+ case NSWS_ID_VIEW_ZOOMMINUS: {
+ int x, y;
+ gui_window_get_scroll(w, &x, &y);
+ if (w->bw != NULL) {
+ browser_window_set_scale(w->bw,
+ w->bw->scale * 0.9, true);
+ browser_window_reformat(w->bw, w->width,
+ w->height);
+ }
+ gui_window_redraw_window(w);
+ gui_window_set_scroll(w, x, y);
+ break;
+ }
+ case NSWS_ID_VIEW_ZOOMNORMAL: {
+ int x, y;
+ gui_window_get_scroll(w, &x, &y);
+ if (w->bw != NULL) {
+ browser_window_set_scale(w->bw,
+ 1.0, true);
+ browser_window_reformat(w->bw, w->width,
+ w->height);
+ }
+ gui_window_redraw_window(w);
+ gui_window_set_scroll(w, x, y);
+ break;
+ }
+ case NSWS_ID_VIEW_SOURCE:
+ break;
+ case NSWS_ID_VIEW_SAVE_WIN_METRICS: {
+ RECT r;
+ GetWindowRect(hwnd, &r);
+ option_window_x = r.left;
+ option_window_y = r.top;
+ option_window_width = r.right - r.left;
+ option_window_height = r.bottom - r.top;
+ options_write(options_file_location);
+ break;
+ }
+ case NSWS_ID_VIEW_FULLSCREEN: {
+ RECT rdesk;
+ if (w->fullscreen == NULL) {
+ HWND desktop = GetDesktopWindow();
+ w->fullscreen = malloc(sizeof(RECT));
+ if ((desktop == NULL) ||
+ (w->fullscreen == NULL)) {
+ warn_user("NoMemory", 0);
+ break;
+ }
+ GetWindowRect(desktop, &rdesk);
+ GetWindowRect(hwnd, w->fullscreen);
+ DeleteObject(desktop);
+ SetWindowLong(hwnd, GWL_STYLE, 0);
+ SetWindowPos(hwnd, HWND_TOPMOST, 0, 0,
+ rdesk.right - rdesk.left,
+ rdesk.bottom - rdesk.top,
+ SWP_SHOWWINDOW);
+ } else {
+ SetWindowLong(hwnd, GWL_STYLE,
+ WS_OVERLAPPEDWINDOW |
+ WS_HSCROLL | WS_VSCROLL |
+ WS_CLIPCHILDREN |
+ WS_CLIPSIBLINGS | CS_DBLCLKS);
+ SetWindowPos(hwnd, HWND_TOPMOST,
+ w->fullscreen->left,
+ w->fullscreen->top,
+ w->fullscreen->right -
+ w->fullscreen->left,
+ w->fullscreen->bottom -
+ w->fullscreen->top,
+ SWP_SHOWWINDOW |
+ SWP_FRAMECHANGED);
+ free(w->fullscreen);
+ w->fullscreen = NULL;
+ }
+ break;
+ }
+ case NSWS_ID_VIEW_DOWNLOADS:
+ break;
+ case NSWS_ID_VIEW_TOGGLE_DEBUG_RENDERING:
+ html_redraw_debug = !html_redraw_debug;
+ if (w->bw != NULL) {
+ browser_window_reformat(
+ w->bw, w->width, w->height);
+ redraw();
+ }
+ break;
+ case NSWS_ID_VIEW_DEBUGGING_SAVE_BOXTREE:
+ break;
+ case NSWS_ID_VIEW_DEBUGGING_SAVE_DOMTREE:
+ break;
+ case NSWS_ID_HELP_CONTENTS:
+ break;
+ case NSWS_ID_HELP_GUIDE:
+ break;
+ case NSWS_ID_HELP_INFO:
+ break;
+ case NSWS_ID_HELP_ABOUT:
+ nsws_about_dialog_init(hinstance, hwnd);
+ break;
+ case NSWS_ID_LAUNCH_URL:
+ {
+ if (GetFocus() != w->urlbar)
+ break;
+ int len = SendMessage(w->urlbar, WM_GETTEXTLENGTH, 0,
+ 0);
+ char addr[len + 1];
+ SendMessage(w->urlbar, WM_GETTEXT, (WPARAM) (len + 1),
+ (LPARAM) addr);
+ LOG(("launching %s\n", addr));
+ browser_window_go(w->bw, addr, 0, true);
+ break;
+ }
+ case NSWS_ID_URLBAR:
+ /* main message should already have been handled */
+ break;
+ default:
+ break;
+ }
+ break;
+ }
+ case WM_HSCROLL:
+ {
+ if (w->requestscrollx != 0)
+ break;
+ SCROLLINFO si;
+ int mem;
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+ GetScrollInfo(hwnd, SB_HORZ, &si);
+ mem = si.nPos;
+ switch (LOWORD(wparam))
+ {
+ case SB_LINELEFT:
+ si.nPos -= 30;
+ break;
+ case SB_LINERIGHT:
+ si.nPos += 30;
+ break;
+ case SB_PAGELEFT:
+ si.nPos -= w->width;
+ break;
+ case SB_PAGERIGHT:
+ si.nPos += w->width;
+ break;
+ case SB_THUMBTRACK:
+ si.nPos = si.nTrackPos;
+ break;
+ default:
+ break;
+ }
+ si.fMask = SIF_POS;
+ if ((w->bw != NULL) && (w->bw->current_content != NULL))
+ si.nPos = MIN(si.nPos,
+ w->bw->current_content->width *
+ w->bw->scale - w->width);
+ si.nPos = MAX(si.nPos, 0);
+ SetScrollInfo(hwnd, SB_HORZ, &si, TRUE);
+ GetScrollInfo(hwnd, SB_HORZ, &si);
+ if (si.nPos != mem)
+ gui_window_set_scroll(w, w->scrollx +
+ w->requestscrollx + si.nPos - mem, w->scrolly);
+ break;
+ }
+ case WM_VSCROLL:
+ {
+ if (w->requestscrolly != 0)
+ break;
+ SCROLLINFO si;
+ int mem;
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+ GetScrollInfo(hwnd, SB_VERT, &si);
+ mem = si.nPos;
+ switch (LOWORD(wparam))
+ {
+ case SB_TOP:
+ si.nPos = si.nMin;
+ break;
+ case SB_BOTTOM:
+ si.nPos = si.nMax;
+ break;
+ case SB_LINEUP:
+ si.nPos -= 30;
+ break;
+ case SB_LINEDOWN:
+ si.nPos += 30;
+ break;
+ case SB_PAGEUP:
+ si.nPos -= w->height;
+ break;
+ case SB_PAGEDOWN:
+ si.nPos += w->height;
+ break;
+ case SB_THUMBTRACK:
+ si.nPos = si.nTrackPos;
+ break;
+ default:
+ break;
+ }
+ si.fMask = SIF_POS;
+ if ((w->bw != NULL) && (w->bw->current_content != NULL))
+ si.nPos = MIN(si.nPos,
+ w->bw->current_content->height *
+ w->bw->scale - w->height);
+ si.nPos = MAX(si.nPos, 0);
+ SetScrollInfo(hwnd, SB_VERT, &si, TRUE);
+ GetScrollInfo(hwnd, SB_VERT, &si);
+ if (si.nPos != mem)
+ gui_window_set_scroll(w, w->scrollx, w->scrolly +
+ w->requestscrolly + si.nPos - mem);
+ break;
+ }
+ case WM_MOUSEWHEEL:
+#ifdef MSH_MOUSEWHEEL
+ case MSH_MOUSEWHEEL: /* w95 additional module MSWheel */
+#endif
+ {
+ int i, z = GET_WHEEL_DELTA_WPARAM(wparam) / WHEEL_DELTA,
+ key = LOWORD(wparam);
+ DWORD command;
+ unsigned int newmessage = WM_VSCROLL;
+ if (key == MK_SHIFT) {
+ command = (z > 0) ? SB_LINERIGHT : SB_LINELEFT;
+ newmessage = WM_HSCROLL;
+ } else
+ /* add MK_CONTROL -> zoom */
+ command = (z > 0) ? SB_LINEUP : SB_LINEDOWN;
+ z = (z < 0) ? -1 * z : z;
+ for (i = 0; i < z; i++)
+ SendMessage(hwnd, newmessage, MAKELONG(command, 0), 0);
+ break;
+ }
+ case WM_CREATE:
+ {
+ HDC hdc = GetDC(hwnd);
+ int dpi = GetDeviceCaps(hdc,LOGPIXELSY);
+ if (dpi > 10)
+ nscss_screen_dpi = INTTOFIX(dpi);
+ ReleaseDC(hwnd, hdc);
+
+ nsws_window_set_accels(w);
+ nsws_window_set_ico(w);
+ nsws_window_toolbar_create(w);
+ nsws_window_statusbar_create(w);
+ nsws_window_drawingarea_create(w);
+ nsws_window_vscroll_create(w);
+ nsws_window_hscroll_create(w);
+ break;
+ }
+ case WM_PAINT:
+ {
+ if ((w->toolbar == NULL) || (w->urlbar == NULL) ||
+ (w->statusbar == NULL) || (w->vscroll == NULL)
+ || (w->hscroll == NULL))
+ break;
+ HWND focuswnd = GetFocus();
+ SetFocus(w->urlbar);
+ SetFocus(focuswnd);
+ current_hwnd = hwnd;
+ current_gui = w;
+ PAINTSTRUCT ps;
+ BeginPaint(hwnd, &ps);
+/* printf("repaint dc %p erase %d from %ld,%ld to %ld,%ld\n",
+ ps.hdc, (int)ps.fErase, ps.rcPaint.left,
+ ps.rcPaint.top, ps.rcPaint.right,
+ ps.rcPaint.bottom);
+*/ PostMessage(w->toolbar, WM_PAINT, 0, 0);
+ PostMessage(w->urlbar, WM_PAINT, 0, 0);
+ PostMessage(w->statusbar, WM_PAINT, 0, 0);
+ PostMessage(w->main, WM_NCPAINT, 0, 0);
+/* PostMessage(w->vscroll, WM_PAINT, 0, 0);
+ PostMessage(w->hscroll, WM_PAINT, 0, 0);
+*/
+ RECT r, rstatus, rtool;
+ GetClientRect(hwnd, &r);
+ GetWindowRect(w->toolbar, &rtool);
+ GetWindowRect(w->statusbar, &rstatus);
+
+ w->voffset = rtool.bottom - rtool.top - 1;
+ /* 1 seems necessary */
+
+ w->height = r.bottom - w->voffset - (rstatus.bottom -
+ rstatus.top) + 1;
+
+ w->width = r.right + 1;
+
+ w->redraw.left = MAX(ps.rcPaint.left, 0);
+ w->redraw.top = MAX(ps.rcPaint.top - w->voffset, 0);
+ w->redraw.right = MIN(ps.rcPaint.right, w->width);
+ w->redraw.bottom = MIN(ps.rcPaint.bottom, w->height);
+ redraw();
+ EndPaint(hwnd, &ps);
+ plot.clip(0, 0, w->width, w->height);
+ DWORD ret = DefWindowProc(hwnd, msg, wparam, lparam);
+ if (historyactive)
+ current_gui = NULL;
+ return ret;
+ break;
+ }
+ case WM_NCPAINT:
+ PostMessage(w->toolbar, WM_PAINT, 0, 0);
+ PostMessage(w->urlbar, WM_PAINT, 0, 0);
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ case WM_MOVE:
+ DefWindowProc(hwnd, msg, wparam, lparam);
+ gui_window_redraw_window(w);
+ break;
+ case WM_SIZE:
+ {
+ if ((w->toolbar == NULL) || (w->urlbar == NULL) ||
+ (w->statusbar == NULL))
+ break;
+ int x, y;
+ RECT rmain, rstatus, rtool;
+ GetClientRect(hwnd, &rmain);
+ GetClientRect(w->toolbar, &rtool);
+ GetWindowRect(w->statusbar, &rstatus);
+ gui_window_get_scroll(w, &x, &y);
+ w->voffset = rtool.bottom - rtool.top;
+ w->height = HIWORD(lparam) - w->voffset - (rstatus.bottom -
+ rstatus.top);
+ w->width = LOWORD(lparam);
+ HDC hdc = GetDC(hwnd);
+ if (w->bufferdc == NULL)
+ w->bufferdc = CreateCompatibleDC(hdc);
+ if (w->bufferbm != NULL) {
+ DeleteObject(w->bufferbm);
+ w->bufferbm = CreateCompatibleBitmap(hdc, w->width,
+ w->height + w->voffset);
+ SelectObject(w->bufferdc, w->bufferbm);
+ }
+ ReleaseDC(hwnd, hdc);
+ w->urlbarwidth = w->width - w->ntoolbuttons *
+ w->toolbuttondimension - 8 -
+ NSWS_THROBBER_WIDTH;
+ if (w->bw != NULL) {
+ browser_window_reformat(
+ w->bw, w->width, w->height);
+ redraw();
+ }
+ gui_window_set_scroll(w, x, y);
+
+ /* re-create toolbar to adjust width of url bar holder */
+ DestroyWindow(w->toolbar);
+ DestroyWindow(w->throbber);
+ /* memorize url */
+ int len = SendMessage(w->urlbar, WM_GETTEXTLENGTH, 0, 0);
+ char temp[len + 1];
+ SendMessage(w->urlbar, WM_GETTEXT, (WPARAM) (len + 1),
+ (LPARAM) temp);
+ DestroyWindow(w->urlbar);
+ nsws_window_toolbar_create(w);
+ SendMessage(w->urlbar, WM_SETTEXT, 0, (LPARAM) temp);
+/* SendMessage(w->toolbar, TB_AUTOSIZE, 0, 0);
+ */
+ SendMessage(w->statusbar, WM_SIZE, 0, MAKELONG(w->width, 0));
+ nsws_window_update_forward_back(w);
+
+ if (w->toolbar != NULL)
+ SendMessage(w->toolbar, TB_SETSTATE,
+ (WPARAM) NSWS_ID_NAV_STOP,
+ MAKELONG(TBSTATE_INDETERMINATE, 0));
+
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ break;
+ }
+ case WM_CLOSE:
+ if (--open_windows == 0) {
+ netsurf_quit = true;
+ }
+ DestroyWindow(hwnd);
+ break;
+ case WM_DESTROY:
+ PostQuitMessage(0);
+ break;
+ default:
+ return DefWindowProc(hwnd, msg, wparam, lparam);
+ }
+ return 0;
+}
+
+/**
+ * creation of a new window
+ */
+static void nsws_window_create(struct gui_window *gw)
+{
+ if (gw == NULL)
+ return;
+ LOG(("nsws_window_create %p", gw));
+ const char windowclassname[] = "nsws_window";
+ WNDCLASSEX w;
+ HWND hwnd;
+ INITCOMMONCONTROLSEX icc;
+
+ icc.dwSize = sizeof(icc);
+ icc.dwICC = ICC_BAR_CLASSES | ICC_WIN95_CLASSES;
+#if WINVER > 0x0501
+ icc.dwICC |= ICC_STANDARD_CLASSES;
+#endif
+ InitCommonControlsEx(&icc);
+
+ w.cbSize = sizeof(WNDCLASSEX);
+ w.style = 0;
+ w.lpfnWndProc = nsws_window_event_callback;
+ w.cbClsExtra = 0;
+ w.cbWndExtra = 0;
+ w.hInstance = hinstance;
+ w.hIcon = LoadIcon(NULL, IDI_APPLICATION); /* -> NetSurf */
+ w.hCursor = LoadCursor(NULL, IDC_ARROW);
+ w.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
+ w.lpszMenuName = NULL;
+ w.lpszClassName = windowclassname;
+ w.hIconSm = LoadIcon(NULL, IDI_APPLICATION); /* -> NetSurf */
+ RegisterClassEx(&w);
+
+ gw->mainmenu = LoadMenu(hinstance, MAKEINTRESOURCE(NSWS_ID_MAINMENU));
+ gw->rclick = LoadMenu(hinstance, MAKEINTRESOURCE(NSWS_ID_CTXMENU));
+
+ LOG(("creating window for hInstance %p", hinstance));
+ hwnd = CreateWindow(windowclassname,
+ "NetSurf Browser",
+ WS_OVERLAPPEDWINDOW | WS_HSCROLL | WS_VSCROLL |
+ WS_CLIPCHILDREN | WS_CLIPSIBLINGS | CS_DBLCLKS,
+ CW_USEDEFAULT,
+ CW_USEDEFAULT,
+ gw->width,
+ gw->height,
+ NULL,
+ gw->mainmenu,
+ hinstance,
+ NULL);
+
+ if ((option_window_width >= 100) &&
+ (option_window_height >= 100) &&
+ (option_window_x >= 0) &&
+ (option_window_y >= 0))
+ SetWindowPos(hwnd, HWND_TOPMOST, option_window_x,
+ option_window_y, option_window_width,
+ option_window_height, SWP_SHOWWINDOW);
+
+ ShowWindow(hwnd, SW_SHOWNORMAL);
+ UpdateWindow(hwnd);
+ gw->main = hwnd;
+}
+
+/**
+ * create a new gui_window to contain a browser_window
+ * \param bw the browser_window to connect to the new gui_window
+ */
+struct gui_window *
+gui_create_browser_window(struct browser_window *bw,
+ struct browser_window *clone,
+ bool new_tab)
+{
+ struct gui_window *w;
+
+ w = calloc(1, sizeof(struct gui_window));
+
+ if (w == NULL)
+ return NULL;
+
+ /* connect gui window to browser window */
+ w->bw = bw;
+
+ w->width = 600;
+ w->height = 600;
+ w->ntoolbuttons = NTOOLBUTTONS;
+ w->toolbuttondimension = 32; /* includes padding of 4 every side */
+ w->urlbarwidth = w->width - w->toolbuttondimension * w->ntoolbuttons
+ - 8 - NSWS_THROBBER_WIDTH;
+ w->requestscrollx = 0;
+ w->requestscrolly = 0;
+ w->localhistory = NULL;
+
+ w->mouse = malloc(sizeof(struct browser_mouse));
+ if (w->mouse == NULL) {
+ free(w);
+ return NULL;
+ }
+ w->mouse->gui = w;
+ w->mouse->state = 0;
+ w->mouse->pressed_x = 0;
+ w->mouse->pressed_y = 0;
+
+ if (bw != NULL)
+ switch(bw->browser_window_type) {
+ case BROWSER_WINDOW_NORMAL:
+ break;
+
+ case BROWSER_WINDOW_FRAME:
+ LOG(("create frame"));
+ break;
+
+ default:
+ LOG(("unhandled type"));
+ }
+
+ if (window_list != NULL)
+ window_list->prev = w;
+ w->next = window_list;
+ window_list = w;
+
+ input_window = w;
+
+ open_windows++;
+ nsws_window_create(w);
+
+ return w;
+}
+
+
+
+
+HICON nsws_window_get_ico(bool large)
+{
+ return large ? hIcon : hIconS;
+}
+
+
+
+
+/**
+ * cache pointers for quick swapping
+ */
+static void nsws_window_init_pointers(void)
+{
+ nsws_pointer.hand = LoadCursor(NULL, IDC_HAND);
+ nsws_pointer.ibeam = LoadCursor(NULL, IDC_IBEAM);
+ nsws_pointer.cross = LoadCursor(NULL, IDC_CROSS);
+ nsws_pointer.sizeall = LoadCursor(NULL, IDC_SIZEALL);
+ nsws_pointer.sizewe = LoadCursor(NULL, IDC_SIZEWE);
+ nsws_pointer.sizens = LoadCursor(NULL, IDC_SIZENS);
+ nsws_pointer.sizenesw = LoadCursor(NULL, IDC_SIZENESW);
+ nsws_pointer.sizenwse = LoadCursor(NULL, IDC_SIZENWSE);
+ nsws_pointer.wait = LoadCursor(NULL, IDC_WAIT);
+ nsws_pointer.appstarting = LoadCursor(NULL, IDC_APPSTARTING);
+ nsws_pointer.no = LoadCursor(NULL, IDC_NO);
+ nsws_pointer.help = LoadCursor(NULL, IDC_HELP);
+ nsws_pointer.arrow = LoadCursor(NULL, IDC_ARROW);
+}
+
+
+
+HWND gui_window_main_window(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return w->main;
+}
+
+HWND gui_window_toolbar(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return w->toolbar;
+}
+
+HWND gui_window_urlbar(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return w->urlbar;
+}
+
+HWND gui_window_statusbar(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return w->statusbar;
+}
+
+HWND gui_window_drawingarea(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return w->drawingarea;
+}
+
+struct nsws_localhistory *gui_window_localhistory(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return w->localhistory;
+}
+
+void gui_window_set_localhistory(struct gui_window *w,
+ struct nsws_localhistory *l)
+{
+ if (w != NULL)
+ w->localhistory = l;
+}
+
+RECT *gui_window_redraw_rect(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return &(w->redraw);
+}
+
+RECT *gui_window_clip_rect(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return &(w->clip);
+}
+
+int gui_window_voffset(struct gui_window *w)
+{
+ if (w == NULL)
+ return 0;
+ return w->voffset;
+}
+
+int gui_window_width(struct gui_window *w)
+{
+ if (w == NULL)
+ return 0;
+ return w->width;
+}
+
+int gui_window_height(struct gui_window *w)
+{
+ if (w == NULL)
+ return 0;
+ return w->height;
+}
+
+int gui_window_scrollingx(struct gui_window *w)
+{
+ if (w == NULL)
+ return 0;
+ return w->requestscrollx;
+}
+
+int gui_window_scrollingy(struct gui_window *w)
+{
+ if (w == NULL)
+ return 0;
+ return w->requestscrolly;
+}
+
+struct gui_window *gui_window_iterate(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return w->next;
+}
+
+struct browser_window *gui_window_browser_window(struct gui_window *w)
+{
+ if (w == NULL)
+ return NULL;
+ return w->bw;
+}
+
+/**
+ * window cleanup code
+ */
+void gui_window_destroy(struct gui_window *w)
+{
+ if (w == NULL)
+ return;
+
+ if (w->prev != NULL)
+ w->prev->next = w->next;
+ else
+ window_list = w->next;
+
+ if (w->next != NULL)
+ w->next->prev = w->prev;
+
+ DestroyAcceleratorTable(w->acceltable);
+
+ free(w);
+ w = NULL;
+}
+
+/**
+ * set window title
+ * \param title the [url]
+ */
+void gui_window_set_title(struct gui_window *w, const char *title)
+{
+ if (w == NULL)
+ return;
+ LOG(("%p, title %s", w, title));
+ char *fulltitle = malloc(strlen(title) +
+ SLEN(" - NetSurf") + 1);
+ if (fulltitle == NULL) {
+ warn_user("NoMemory", 0);
+ return;
+ }
+ strcpy(fulltitle, title);
+ strcat(fulltitle, " - NetSurf");
+ SendMessage(w->main, WM_SETTEXT, 0, (LPARAM)fulltitle);
+ free(fulltitle);
+}
+
+/**
+ * redraw a rectangle of the window
+ */
+void gui_window_redraw(struct gui_window *w, int x0, int y0, int x1, int y1)
+{
+ LOG(("redraw %p %d,%d %d,%d", w, x0, y0, x1, y1));
+ if (w == NULL)
+ return;
+ w->redraw.left = x0;
+ w->redraw.top = y0;
+ w->redraw.right = x1;
+ w->redraw.bottom = y1;
+ redraw();
+}
+
+/**
+ * redraw the whole window
+ */
+void gui_window_redraw_window(struct gui_window *w)
+{
+ LOG(("redraw window %p w=%d,h=%d", w, w->width, w->height));
+ if (w == NULL)
+ return;
+ w->redraw.left = 0;
+ w->redraw.top = 0;
+ w->redraw.right = w->width;
+ w->redraw.bottom = w->height;
+ redraw();
+}
+
+void gui_window_update_box(struct gui_window *w,
+ const union content_msg_data *data)
+{
+ if (w == NULL)
+ return;
+ w->redraw.left = (long)data->redraw.x;
+ w->redraw.top = (long)data->redraw.y;
+ w->redraw.right =(long)(data->redraw.x + data->redraw.width);
+ w->redraw.bottom = (long)(data->redraw.y + data->redraw.height);
+ redraw();
+}
+
+bool gui_window_get_scroll(struct gui_window *w, int *sx, int *sy)
+{
+ LOG(("get scroll"));
+ if (w == NULL)
+ return false;
+ *sx = w->scrollx;
+ *sy = w->scrolly;
+
+ return true;
+}
+
+/**
+ * scroll the window
+ * \param sx the new 'absolute' scroll location
+ * \param sy the new 'absolute' scroll location
+ */
+void gui_window_set_scroll(struct gui_window *w, int sx, int sy)
+{
+ SCROLLINFO si;
+ POINT p;
+
+ if ((w == NULL) ||
+ (w->bw == NULL) ||
+ (w->bw->current_content == NULL))
+ return;
+
+ /* limit scale range */
+ if (abs(w->bw->scale - 0.0) < 0.00001)
+ w->bw->scale = 1.0;
+
+ w->requestscrollx = sx - w->scrollx;
+ w->requestscrolly = sy - w->scrolly;
+
+ /* set the vertical scroll offset */
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+ si.nMin = 0;
+ si.nMax = w->bw->current_content->height * w->bw->scale;
+ si.nPage = w->height;
+ si.nPos = MAX(w->scrolly + w->requestscrolly, 0);
+ si.nPos = MIN(si.nPos, w->bw->current_content->height * w->bw->scale
+ - w->height);
+ SetScrollInfo(w->main, SB_VERT, &si, TRUE);
+
+ /* set the horizontal scroll offset */
+ si.cbSize = sizeof(si);
+ si.fMask = SIF_ALL;
+ si.nMin = 0;
+ si.nMax = w->bw->current_content->width * w->bw->scale;
+ si.nPage = w->width;
+ si.nPos = MAX(w->scrollx + w->requestscrollx, 0);
+ si.nPos = MIN(si.nPos, w->bw->current_content->width * w->bw->scale
+ - w->width);
+ SetScrollInfo(w->main, SB_HORZ, &si, TRUE);
+
+ /* Set caret position */
+ GetCaretPos(&p);
+ HideCaret(w->main);
+ SetCaretPos(p.x - w->requestscrollx, p.y - w->requestscrolly);
+ ShowCaret(w->main);
+
+ RECT r, redraw;
+ r.top = w->voffset - 1;
+ r.bottom = w->voffset + w->height + 1;
+ r.left = 0;
+ r.right = w->width + 1;
+ ScrollWindowEx(w->main, - w->requestscrollx, - w->requestscrolly, &r,
+ NULL, NULL, &redraw, SW_INVALIDATE);
+ gui_window_redraw(w, redraw.left + (w->requestscrollx + w->scrollx)
+ / w->bw->scale - 1,
+ redraw.top + (w->requestscrolly + w->scrolly)
+ / w->bw->scale - w->voffset - 1,
+ redraw.right + (w->requestscrollx + w->scrollx)
+ / w->bw->scale + 1,
+ redraw.bottom + (w->requestscrolly + w->scrolly)
+ / w->bw->scale - w->voffset + 1);
+}
+
+void gui_window_scroll_visible(struct gui_window *w, int x0, int y0,
+ int x1, int y1)
+{
+ LOG(("scroll visible %s:(%p, %d, %d, %d, %d)", __func__, w, x0,
+ y0, x1, y1));
+}
+
+void gui_window_position_frame(struct gui_window *w, int x0, int y0,
+ int x1, int y1)
+{
+ LOG(("position frame %s: %d, %d, %d, %d", w->bw->name,
+ x0, y0, x1, y1));
+
+}
+
+void gui_window_get_dimensions(struct gui_window *w, int *width, int *height,
+ bool scaled)
+{
+ LOG(("get dimensions %p w=%d h=%d", w, w->width, w->height));
+ if (w == NULL)
+ return;
+ *width = w->width;
+ *height = w->height;
+}
+
+void gui_window_update_extent(struct gui_window *w)
+{
+
+}
+
+/**
+ * set the status bar message
+ */
+void gui_window_set_status(struct gui_window *w, const char *text)
+{
+ if (w == NULL)
+ return;
+ SendMessage(w->statusbar, WM_SETTEXT, 0, (LPARAM)text);
+}
+
+/**
+ * set the pointer shape
+ */
+void gui_window_set_pointer(struct gui_window *w, gui_pointer_shape shape)
+{
+ if (w == NULL)
+ return;
+ switch (shape) {
+ case GUI_POINTER_POINT: /* link */
+ case GUI_POINTER_MENU:
+ SetCursor(nsws_pointer.hand);
+ break;
+
+ case GUI_POINTER_CARET: /* input */
+ SetCursor(nsws_pointer.ibeam);
+ break;
+
+ case GUI_POINTER_CROSS:
+ SetCursor(nsws_pointer.cross);
+ break;
+
+ case GUI_POINTER_MOVE:
+ SetCursor(nsws_pointer.sizeall);
+ break;
+
+ case GUI_POINTER_RIGHT:
+ case GUI_POINTER_LEFT:
+ SetCursor(nsws_pointer.sizewe);
+ break;
+
+ case GUI_POINTER_UP:
+ case GUI_POINTER_DOWN:
+ SetCursor(nsws_pointer.sizens);
+ break;
+
+ case GUI_POINTER_RU:
+ case GUI_POINTER_LD:
+ SetCursor(nsws_pointer.sizenesw);
+ break;
+
+ case GUI_POINTER_RD:
+ case GUI_POINTER_LU:
+ SetCursor(nsws_pointer.sizenwse);
+ break;
+
+ case GUI_POINTER_WAIT:
+ SetCursor(nsws_pointer.wait);
+ break;
+
+ case GUI_POINTER_PROGRESS:
+ SetCursor(nsws_pointer.appstarting);
+ break;
+
+ case GUI_POINTER_NO_DROP:
+ case GUI_POINTER_NOT_ALLOWED:
+ SetCursor(nsws_pointer.no);
+ break;
+
+ case GUI_POINTER_HELP:
+ SetCursor(nsws_pointer.help);
+ break;
+
+ default:
+ SetCursor(nsws_pointer.arrow);
+ break;
+ }
+}
+
+struct nsws_pointers *nsws_get_pointers(void)
+{
+ return &nsws_pointer;
+}
+
+void gui_window_hide_pointer(struct gui_window *w)
+{
+}
+
+void gui_window_set_url(struct gui_window *w, const char *url)
+{
+ if (w == NULL)
+ return;
+ SendMessage(w->urlbar, WM_SETTEXT, 0, (LPARAM) url);
+}
+
+
+void gui_window_start_throbber(struct gui_window *w)
+{
+ if (w == NULL)
+ return;
+ nsws_window_update_forward_back(w);
+
+ if (w->mainmenu != NULL) {
+ EnableMenuItem(w->mainmenu, NSWS_ID_NAV_STOP, MF_ENABLED);
+ EnableMenuItem(w->mainmenu, NSWS_ID_NAV_RELOAD, MF_GRAYED);
+ }
+ if (w->rclick != NULL) {
+ EnableMenuItem(w->rclick, NSWS_ID_NAV_STOP, MF_ENABLED);
+ EnableMenuItem(w->rclick, NSWS_ID_NAV_RELOAD, MF_GRAYED);
+ }
+ if (w->toolbar != NULL) {
+ SendMessage(w->toolbar, TB_SETSTATE, (WPARAM) NSWS_ID_NAV_STOP,
+ MAKELONG(TBSTATE_ENABLED, 0));
+ SendMessage(w->toolbar, TB_SETSTATE,
+ (WPARAM) NSWS_ID_NAV_RELOAD,
+ MAKELONG(TBSTATE_INDETERMINATE, 0));
+ }
+ w->throbbing = true;
+ Animate_Play(w->throbber, 0, -1, -1);
+}
+
+void gui_window_stop_throbber(struct gui_window *w)
+{
+ if (w == NULL)
+ return;
+ nsws_window_update_forward_back(w);
+ if (w->mainmenu != NULL) {
+ EnableMenuItem(w->mainmenu, NSWS_ID_NAV_STOP, MF_GRAYED);
+ EnableMenuItem(w->mainmenu, NSWS_ID_NAV_RELOAD, MF_ENABLED);
+ }
+ if (w->rclick != NULL) {
+ EnableMenuItem(w->rclick, NSWS_ID_NAV_STOP, MF_GRAYED);
+ EnableMenuItem(w->rclick, NSWS_ID_NAV_RELOAD, MF_ENABLED);
+ }
+ if (w->toolbar != NULL) {
+ SendMessage(w->toolbar, TB_SETSTATE, (WPARAM) NSWS_ID_NAV_STOP,
+ MAKELONG(TBSTATE_INDETERMINATE, 0));
+ SendMessage(w->toolbar, TB_SETSTATE,
+ (WPARAM) NSWS_ID_NAV_RELOAD,
+ MAKELONG(TBSTATE_ENABLED, 0));
+ }
+ w->throbbing = false;
+ Animate_Stop(w->throbber);
+ Animate_Seek(w->throbber, 0);
+}
+
+/**
+ * place caret in window
+ */
+void gui_window_place_caret(struct gui_window *w, int x, int y, int height)
+{
+ if (w == NULL)
+ return;
+ CreateCaret(w->main, (HBITMAP)NULL, 1, height * w->bw->scale);
+ SetCaretPos(x * w->bw->scale - w->scrollx,
+ y * w->bw->scale + w->voffset - w->scrolly);
+ ShowCaret(w->main);
+}
+
+/**
+ * clear window caret
+ */
+void
+gui_window_remove_caret(struct gui_window *w)
+{
+ if (w == NULL)
+ return;
+ HideCaret(w->main);
+}
+
+void
+gui_window_set_icon(struct gui_window *g, struct content *icon)
+{
+}
+
+void
+gui_window_set_search_ico(struct content *ico)
+{
+}
+
+bool
+save_complete_gui_save(const char *path,
+ const char *filename,
+ size_t len,
+ const char *sourcedata,
+ content_type type)
+{
+ return false;
+}
+
+int
+save_complete_htmlSaveFileFormat(const char *path,
+ const char *filename,
+ xmlDocPtr cur,
+ const char *encoding,
+ int format)
+{
+ return 0;
+}
+
+
+void gui_window_new_content(struct gui_window *w)
+{
+}
+
+bool gui_window_scroll_start(struct gui_window *w)
+{
+ return true;
+}
+
+bool gui_window_box_scroll_start(struct gui_window *w,
+ int x0, int y0, int x1, int y1)
+{
+ return true;
+}
+
+bool gui_window_frame_resize_start(struct gui_window *w)
+{
+ LOG(("resize frame\n"));
+ return true;
+}
+
+void gui_window_save_as_link(struct gui_window *w, struct content *c)
+{
+}
+
+void gui_window_set_scale(struct gui_window *w, float scale)
+{
+ if (w == NULL)
+ return;
+ w->scale = scale;
+ LOG(("%.2f\n", scale));
+}
+
+void gui_drag_save_object(gui_save_type type, struct content *c,
+ struct gui_window *w)
+{
+}
+
+void gui_drag_save_selection(struct selection *s, struct gui_window *w)
+{
+}
+
+void gui_start_selection(struct gui_window *w)
+{
+}
+
+void gui_paste_from_clipboard(struct gui_window *w, int x, int y)
+{
+ HANDLE clipboard_handle;
+ char *content;
+
+ clipboard_handle = GetClipboardData(CF_TEXT);
+ if (clipboard_handle != NULL) {
+ content = GlobalLock(clipboard_handle);
+ LOG(("pasting %s", content));
+ GlobalUnlock(clipboard_handle);
+ }
+}
+
+bool gui_empty_clipboard(void)
+{
+ return false;
+}
+
+bool gui_add_to_clipboard(const char *text, size_t length, bool space)
+{
+ HANDLE hnew;
+ char *new, *original;
+ HANDLE h = GetClipboardData(CF_TEXT);
+ if (h == NULL)
+ original = (char *)"";
+ else
+ original = GlobalLock(h);
+
+ size_t len = strlen(original) + 1;
+ hnew = GlobalAlloc(GHND, length + len);
+ new = (char *)GlobalLock(hnew);
+ snprintf(new, length + len, "%s%s", original, text);
+
+ if (h != NULL) {
+ GlobalUnlock(h);
+ EmptyClipboard();
+ }
+ GlobalUnlock(hnew);
+ SetClipboardData(CF_TEXT, hnew);
+ return true;
+}
+
+bool gui_commit_clipboard(void)
+{
+ return false;
+}
+
+static bool
+gui_selection_traverse_handler(const char *text,
+ size_t length,
+ struct box *box,
+ void *handle,
+ const char *space_text,
+ size_t space_length)
+{
+ if (space_text) {
+ if (!gui_add_to_clipboard(space_text, space_length, false)) {
+ return false;
+ }
+ }
+
+ if (!gui_add_to_clipboard(text, length, box->space))
+ return false;
+
+ return true;
+}
+
+bool gui_copy_to_clipboard(struct selection *s)
+{
+ if ((s->defined) && (s->bw != NULL) && (s->bw->window != NULL) &&
+ (s->bw->window->main != NULL)) {
+ OpenClipboard(s->bw->window->main);
+ EmptyClipboard();
+ if (selection_traverse(s, gui_selection_traverse_handler,
+ NULL)) {
+ CloseClipboard();
+ return true;
+ }
+ }
+ return false;
+}
+
+
+void gui_create_form_select_menu(struct browser_window *bw,
+ struct form_control *control)
+{
+}
+
+void gui_launch_url(const char *url)
+{
+}
+
+void gui_cert_verify(struct browser_window *bw, struct content *c,
+ const struct ssl_cert_info *certs, unsigned long num)
+{
+}
+
+int WINAPI
+WinMain(HINSTANCE hInstance, HINSTANCE hLastInstance, LPSTR lpcli, int ncmd)
+{
+ char **argv = NULL;
+ int argc = 0, argctemp = 0;
+ size_t len;
+ LPWSTR * argvw;
+
+ if (SLEN(lpcli) > 0) {
+ argvw = CommandLineToArgvW(GetCommandLineW(), &argc);
+ }
+
+ hinstance = hInstance;
+ setbuf(stderr, NULL);
+
+ /* Construct a unix style argc/argv */
+ argv = malloc(sizeof(char *) * argc);
+ while (argctemp < argc) {
+ len = wcstombs(NULL, argvw[argctemp], 0) + 1;
+ if (len > 0)
+ argv[argctemp] = malloc(len);
+ if (argv[argctemp] != NULL) {
+ wcstombs(argv[argctemp], argvw[argctemp], len);
+ /* alter windows-style forward slash flags to
+ * hypen flags.
+ */
+ if (argv[argctemp][0] == '/')
+ argv[argctemp][0] = '-';
+ }
+ argctemp++;
+ }
+ return netsurf_main(argc, argv);
+}
+
+
+static void *myrealloc(void *ptr, size_t len, void *pw)
+{
+ return realloc(ptr, len);
+}
+
+void gui_quit(void)
+{
+ LOG(("gui_quit"));
+
+ hubbub_finalise(myrealloc, NULL);
+}
+
+void gui_init(int argc, char** argv)
+{
+ char buf[PATH_MAX], sbuf[PATH_MAX];
+ int len;
+
+ LOG(("argc %d, argv %p", argc, argv));
+
+ nsws_find_resource(buf, "Aliases", "./windows/res/Aliases");
+ LOG(("Using '%s' as Aliases file", buf));
+
+ hubbub_error he = hubbub_initialise(buf, myrealloc, NULL);
+ LOG(("hubbub init %d", he));
+ if (he != HUBBUB_OK)
+ die("Unable to initialise HTML parsing library.\n");
+
+ /* load browser messages */
+ nsws_find_resource(buf, "messages", "./windows/res/messages");
+ LOG(("Using '%s' as Messages file", buf));
+ messages_load(buf);
+
+ /* load browser options */
+ nsws_find_resource(buf, "preferences", "~/.netsurf/preferences");
+ LOG(("Using '%s' as Preferences file", buf));
+ options_file_location = strdup(buf);
+ options_read(buf);
+
+ /* set up stylesheet urls */
+ getcwd(sbuf, PATH_MAX);
+ len = strlen(sbuf);
+ strncat(sbuf, "windows/res/default.css", PATH_MAX - len);
+ nsws_find_resource(buf, "default.css", sbuf);
+ default_stylesheet_url = path_to_url(buf);
+ LOG(("Using '%s' as Default CSS URL", default_stylesheet_url));
+
+ getcwd(sbuf, PATH_MAX);
+ len = strlen(sbuf);
+ strncat(sbuf, "windows/res/quirks.css", PATH_MAX - len);
+ nsws_find_resource(buf, "quirks.css", sbuf);
+ quirks_stylesheet_url = path_to_url(buf);
+ LOG(("Using '%s' as quirks stylesheet url", quirks_stylesheet_url ));
+
+ option_target_blank = false;
+
+}
+
+void gui_init2(int argc, char** argv)
+{
+ struct browser_window *bw;
+ const char *addr = NETSURF_HOMEPAGE;
+
+ nsws_window_init_pointers();
+ LOG(("argc %d, argv %p", argc, argv));
+
+ if (argc > 1)
+ addr = argv[1];
+ else if (option_homepage_url != NULL && option_homepage_url[0]
+ != '\0')
+ addr = option_homepage_url;
+ else
+ addr = default_page;
+
+ LOG(("calling browser_window_create"));
+ bw = browser_window_create(addr, 0, 0, true, false);
+}
+
+void gui_stdout(void)
+{
+ /* mwindows compile flag normally invalidates stdout unless
+ already redirected */
+ if (_get_osfhandle(fileno(stdout)) == -1) {
+ AllocConsole();
+ freopen("CONOUT$", "w", stdout);
+ }
+}