From 55162445db4c8ea46be671c2abed4ad4e77e1dcd Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 31 Jan 2010 00:36:02 +0000 Subject: Add Windows frontend svn path=/trunk/netsurf/; revision=9940 --- windows/gui.c | 2402 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 2402 insertions(+) create mode 100644 windows/gui.c (limited to 'windows/gui.c') 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 + * Copyright 2009 Mark Benjamin + * + * 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 . + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#define _WIN32_IE (0x0501) +#include + +#include + +#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); + } +} -- cgit v1.2.3