From d21447d096a320a08b3efb2b8768fad0dcdcfd64 Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Thu, 5 May 2016 22:28:51 +0100 Subject: move frontends into sub directory --- frontends/windows/drawable.c | 625 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 625 insertions(+) create mode 100644 frontends/windows/drawable.c (limited to 'frontends/windows/drawable.c') diff --git a/frontends/windows/drawable.c b/frontends/windows/drawable.c new file mode 100644 index 000000000..4480eeaaa --- /dev/null +++ b/frontends/windows/drawable.c @@ -0,0 +1,625 @@ +/* + * Copyright 2011 Vincent Sanders + * + * 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 "utils/config.h" + +#include +#include + +#include "desktop/browser.h" +#include "desktop/textinput.h" +#include "desktop/plotters.h" +#include "utils/errors.h" +#include "utils/log.h" +#include "utils/utils.h" + +#include "windows/windbg.h" +#include "windows/plot.h" +#include "windows/window.h" +#include "windows/localhistory.h" +#include "windows/drawable.h" + +static const char windowclassname_drawable[] = "nswsdrawablewindow"; + +/** + * Handle wheel scroll messages. + */ +static LRESULT +nsws_drawable_wheel(struct gui_window *gw, HWND hwnd, WPARAM wparam) +{ + int i, z = GET_WHEEL_DELTA_WPARAM(wparam) / WHEEL_DELTA; + int 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); + } + + return 0; +} + +/** + * Handle vertical scroll messages. + */ +static LRESULT +nsws_drawable_vscroll(struct gui_window *gw, HWND hwnd, WPARAM wparam) +{ + int width, height; + SCROLLINFO si; + int mem; + + LOG("VSCROLL %d", gw->requestscrolly); + + if (gw->requestscrolly != 0) + return 0; + + 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 -= gw->height; + break; + + case SB_PAGEDOWN: + si.nPos += gw->height; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + si.fMask = SIF_POS; + if ((gw->bw != NULL) && + (browser_window_get_extents(gw->bw, true, + &width, &height) == NSERROR_OK)) { + si.nPos = min(si.nPos, height - gw->height); + } + + si.nPos = max(si.nPos, 0); + SetScrollInfo(hwnd, SB_VERT, &si, TRUE); + GetScrollInfo(hwnd, SB_VERT, &si); + if (si.nPos != mem) { + win32_window_set_scroll(gw, gw->scrollx, gw->scrolly + + gw->requestscrolly + si.nPos - mem); + } + + return 0; +} + + +/** + * Handle horizontal scroll messages. + */ +static LRESULT +nsws_drawable_hscroll(struct gui_window *gw, HWND hwnd, WPARAM wparam) +{ + int width, height; + SCROLLINFO si; + int mem; + + LOG("HSCROLL %d", gw->requestscrollx); + + if (gw->requestscrollx != 0) + return 0; + + 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 -= gw->width; + break; + + case SB_PAGERIGHT: + si.nPos += gw->width; + break; + + case SB_THUMBTRACK: + si.nPos = si.nTrackPos; + break; + + default: + break; + } + + si.fMask = SIF_POS; + + if ((gw->bw != NULL) && + (browser_window_get_extents(gw->bw, true, + &width, &height) == NSERROR_OK)) { + si.nPos = min(si.nPos, width - gw->width); + } + si.nPos = max(si.nPos, 0); + SetScrollInfo(hwnd, SB_HORZ, &si, TRUE); + GetScrollInfo(hwnd, SB_HORZ, &si); + if (si.nPos != mem) { + win32_window_set_scroll(gw, + gw->scrollx + gw->requestscrollx + si.nPos - mem, + gw->scrolly); + } + + return 0; +} + +/** + * Handle resize events. + */ +static LRESULT +nsws_drawable_resize(struct gui_window *gw) +{ + browser_window_schedule_reformat(gw->bw); + return 0; +} + +/** + * Handle key press messages. + */ +static LRESULT +nsws_drawable_key(struct gui_window *gw, HWND hwnd, WPARAM wparam) +{ + if (GetFocus() != hwnd) + return 0 ; + + uint32_t i; + bool shift = ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000); + bool capslock = ((GetKeyState(VK_CAPITAL) & 1) == 1); + + switch(wparam) { + case VK_LEFT: + i = NS_KEY_LEFT; + if (shift) + SendMessage(hwnd, WM_HSCROLL, + MAKELONG(SB_LINELEFT, 0), 0); + break; + + case VK_RIGHT: + i = NS_KEY_RIGHT; + if (shift) + SendMessage(hwnd, WM_HSCROLL, + MAKELONG(SB_LINERIGHT, 0), 0); + break; + + case VK_UP: + i = NS_KEY_UP; + if (shift) + SendMessage(hwnd, WM_VSCROLL, + MAKELONG(SB_LINEUP, 0), 0); + break; + + case VK_DOWN: + i = NS_KEY_DOWN; + if (shift) + SendMessage(hwnd, WM_VSCROLL, + MAKELONG(SB_LINEDOWN, 0), 0); + break; + + case VK_HOME: + i = NS_KEY_LINE_START; + if (shift) + SendMessage(hwnd, WM_HSCROLL, + MAKELONG(SB_PAGELEFT, 0), 0); + break; + + case VK_END: + i = NS_KEY_LINE_END; + if (shift) + SendMessage(hwnd, WM_HSCROLL, + MAKELONG(SB_PAGERIGHT, 0), 0); + break; + + case VK_DELETE: + i = NS_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 (gw != NULL) + browser_window_key_press(gw->bw, i); + + return 0; +} + + +/** + * Handle paint messages. + */ +static LRESULT +nsws_drawable_paint(struct gui_window *gw, HWND hwnd) +{ + struct rect clip; + PAINTSTRUCT ps; + struct redraw_context ctx = { + .interactive = true, + .background_images = true, + .plot = &win_plotters + }; + + BeginPaint(hwnd, &ps); + + if (gw != NULL) { + plot_hdc = ps.hdc; + + clip.x0 = ps.rcPaint.left; + clip.y0 = ps.rcPaint.top; + clip.x1 = ps.rcPaint.right; + clip.y1 = ps.rcPaint.bottom; + + browser_window_redraw(gw->bw, + -gw->scrollx / gw->scale, + -gw->scrolly / gw->scale, + &clip, &ctx); + } + + EndPaint(hwnd, &ps); + + return 0; +} + + +/** + * Handle mouse button up messages. + */ +static LRESULT +nsws_drawable_mouseup(struct gui_window *gw, + int x, + int y, + browser_mouse_state press, + browser_mouse_state click) +{ + bool shift = ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000); + bool ctrl = ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000); + bool alt = ((GetKeyState(VK_MENU) & 0x8000) == 0x8000); + + if ((gw == NULL) || + (gw->mouse == NULL) || + (gw->bw == NULL)) + return 0; + + LOG("state 0x%x, press 0x%x", gw->mouse->state, press); + if ((gw->mouse->state & press) != 0) { + gw->mouse->state &= ~press; + gw->mouse->state |= click; + } + + if (((gw->mouse->state & BROWSER_MOUSE_MOD_1) != 0) && !shift) + gw->mouse->state &= ~BROWSER_MOUSE_MOD_1; + if (((gw->mouse->state & BROWSER_MOUSE_MOD_2) != 0) && !ctrl) + gw->mouse->state &= ~BROWSER_MOUSE_MOD_2; + if (((gw->mouse->state & BROWSER_MOUSE_MOD_3) != 0) && !alt) + gw->mouse->state &= ~BROWSER_MOUSE_MOD_3; + + if ((gw->mouse->state & click) != 0) { + LOG("mouse click bw %p, state 0x%x, x %f, y %f", gw->bw, gw->mouse->state, (x + gw->scrollx) / gw->scale, (y + gw->scrolly) / gw->scale); + + browser_window_mouse_click(gw->bw, + gw->mouse->state, + (x + gw->scrollx) / gw->scale, + (y + gw->scrolly) / gw->scale); + } else { + browser_window_mouse_track(gw->bw, + 0, + (x + gw->scrollx) / gw->scale, + (y + gw->scrolly) / gw->scale); + } + + gw->mouse->state = 0; + return 0; +} + + +/** + * Handle mouse button down messages. + */ +static LRESULT +nsws_drawable_mousedown(struct gui_window *gw, + int x, int y, + browser_mouse_state button) +{ + if ((gw == NULL) || + (gw->mouse == NULL) || + (gw->bw == NULL)) { + nsws_localhistory_close(gw); + return 0; + } + + gw->mouse->state = button; + if ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000) + gw->mouse->state |= BROWSER_MOUSE_MOD_1; + if ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000) + gw->mouse->state |= BROWSER_MOUSE_MOD_2; + if ((GetKeyState(VK_MENU) & 0x8000) == 0x8000) + gw->mouse->state |= BROWSER_MOUSE_MOD_3; + + gw->mouse->pressed_x = (x + gw->scrollx) / gw->scale; + gw->mouse->pressed_y = (y + gw->scrolly) / gw->scale; + + LOG("mouse click bw %p, state %x, x %f, y %f", gw->bw, gw->mouse->state, (x + gw->scrollx) / gw->scale, (y + gw->scrolly) / gw->scale); + + browser_window_mouse_click(gw->bw, gw->mouse->state, + (x + gw->scrollx) / gw->scale, + (y + gw->scrolly) / gw->scale); + + return 0; +} + +/** + * Handle mouse movement messages. + */ +static LRESULT +nsws_drawable_mousemove(struct gui_window *gw, int x, int y) +{ + bool shift = ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000); + bool ctrl = ((GetKeyState(VK_CONTROL) & 0x8000) == 0x8000); + bool alt = ((GetKeyState(VK_MENU) & 0x8000) == 0x8000); + + if ((gw == NULL) || (gw->mouse == NULL) || (gw->bw == NULL)) + return 0; + + /* scale co-ordinates */ + x = (x + gw->scrollx) / gw->scale; + y = (y + gw->scrolly) / gw->scale; + + /* if mouse button held down and pointer moved more than + * minimum distance drag is happening */ + if (((gw->mouse->state & (BROWSER_MOUSE_PRESS_1 | BROWSER_MOUSE_PRESS_2)) != 0) && + (abs(x - gw->mouse->pressed_x) >= 5) && + (abs(y - gw->mouse->pressed_y) >= 5)) { + + LOG("Drag start state 0x%x", gw->mouse->state); + + if ((gw->mouse->state & BROWSER_MOUSE_PRESS_1) != 0) { + browser_window_mouse_click(gw->bw, BROWSER_MOUSE_DRAG_1, + gw->mouse->pressed_x, + gw->mouse->pressed_y); + gw->mouse->state &= ~BROWSER_MOUSE_PRESS_1; + gw->mouse->state |= BROWSER_MOUSE_HOLDING_1 | + BROWSER_MOUSE_DRAG_ON; + } + else if ((gw->mouse->state & BROWSER_MOUSE_PRESS_2) != 0) { + browser_window_mouse_click(gw->bw, BROWSER_MOUSE_DRAG_2, + gw->mouse->pressed_x, + gw->mouse->pressed_y); + gw->mouse->state &= ~BROWSER_MOUSE_PRESS_2; + gw->mouse->state |= BROWSER_MOUSE_HOLDING_2 | + BROWSER_MOUSE_DRAG_ON; + } + } + + if (((gw->mouse->state & BROWSER_MOUSE_MOD_1) != 0) && !shift) + gw->mouse->state &= ~BROWSER_MOUSE_MOD_1; + if (((gw->mouse->state & BROWSER_MOUSE_MOD_2) != 0) && !ctrl) + gw->mouse->state &= ~BROWSER_MOUSE_MOD_2; + if (((gw->mouse->state & BROWSER_MOUSE_MOD_3) != 0) && !alt) + gw->mouse->state &= ~BROWSER_MOUSE_MOD_3; + + + browser_window_mouse_track(gw->bw, gw->mouse->state, x, y); + + return 0; +} + +/** + * Called when activity occours within the drawable window. + */ +static LRESULT CALLBACK +nsws_window_drawable_event_callback(HWND hwnd, + UINT msg, + WPARAM wparam, + LPARAM lparam) +{ + struct gui_window *gw; + + LOG_WIN_MSG(hwnd, msg, wparam, lparam); + + gw = nsws_get_gui_window(hwnd); + if (gw == NULL) { + LOG("Unable to find gui window structure for hwnd %p", hwnd); + return DefWindowProc(hwnd, msg, wparam, lparam); + } + + switch(msg) { + + case WM_MOUSEMOVE: + return nsws_drawable_mousemove(gw, + GET_X_LPARAM(lparam), + GET_Y_LPARAM(lparam)); + + case WM_LBUTTONDOWN: + nsws_drawable_mousedown(gw, + GET_X_LPARAM(lparam), + GET_Y_LPARAM(lparam), + BROWSER_MOUSE_PRESS_1); + SetFocus(hwnd); + nsws_localhistory_close(gw); + return 0; + break; + + case WM_RBUTTONDOWN: + nsws_drawable_mousedown(gw, + GET_X_LPARAM(lparam), + GET_Y_LPARAM(lparam), + BROWSER_MOUSE_PRESS_2); + SetFocus(hwnd); + return 0; + break; + + case WM_LBUTTONUP: + return nsws_drawable_mouseup(gw, + GET_X_LPARAM(lparam), + GET_Y_LPARAM(lparam), + BROWSER_MOUSE_PRESS_1, + BROWSER_MOUSE_CLICK_1); + + case WM_RBUTTONUP: + return nsws_drawable_mouseup(gw, + GET_X_LPARAM(lparam), + GET_Y_LPARAM(lparam), + BROWSER_MOUSE_PRESS_2, + BROWSER_MOUSE_CLICK_2); + + case WM_ERASEBKGND: /* ignore as drawable window is redrawn on paint */ + return 0; + + case WM_PAINT: /* redraw the exposed part of the window */ + return nsws_drawable_paint(gw, hwnd); + + case WM_KEYDOWN: + return nsws_drawable_key(gw, hwnd, wparam); + + case WM_SIZE: + return nsws_drawable_resize(gw); + + case WM_HSCROLL: + return nsws_drawable_hscroll(gw, hwnd, wparam); + + case WM_VSCROLL: + return nsws_drawable_vscroll(gw, hwnd, wparam); + + case WM_MOUSEWHEEL: + return nsws_drawable_wheel(gw, hwnd, wparam); + + } + return DefWindowProc(hwnd, msg, wparam, lparam); +} + +/** + * Create a drawable window. + */ +HWND +nsws_window_create_drawable(HINSTANCE hinstance, + HWND hparent, + struct gui_window *gw) +{ + HWND hwnd; + hwnd = CreateWindow(windowclassname_drawable, + NULL, + WS_VISIBLE | WS_CHILD, + 0, 0, 0, 0, + hparent, + NULL, + hinstance, + NULL); + + if (hwnd == NULL) { + win_perror("WindowCreateDrawable"); + LOG("Window creation failed"); + return NULL; + } + + /* set the gui window associated with this toolbar */ + SetProp(hwnd, TEXT("GuiWnd"), (HANDLE)gw); + + return hwnd; +} + +/** + * Create the drawable window class. + */ +nserror +nsws_create_drawable_class(HINSTANCE hinstance) { + nserror ret = NSERROR_OK; + WNDCLASSEX w; + + /* drawable area */ + w.cbSize = sizeof(WNDCLASSEX); + w.style = 0; + w.lpfnWndProc = nsws_window_drawable_event_callback; + w.cbClsExtra = 0; + w.cbWndExtra = 0; + w.hInstance = hinstance; + w.hIcon = NULL; + w.hCursor = NULL; + w.hbrBackground = (HBRUSH)(COLOR_MENU + 1); + w.lpszMenuName = NULL; + w.lpszClassName = windowclassname_drawable; + w.hIconSm = NULL; + + if (RegisterClassEx(&w) == 0) { + win_perror("DrawableClass"); + ret = NSERROR_INIT_FAILED; + } + + return ret; +} -- cgit v1.2.3