mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-12-24 13:06:49 +03:00
8f9d434b12
makes the drawable area widget for the browser display use windows unicode input and copes with surrogate pairs for full unicode input coverage. fixes the keydown handling to only the necessary navigation operations like left, right up and down etc.
722 lines
16 KiB
C
722 lines
16 KiB
C
/*
|
|
* Copyright 2011 Vincent Sanders <vince@simtec.co.uk>
|
|
*
|
|
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
|
*
|
|
* NetSurf is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* NetSurf is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
* win32 implementation of drawable window showing browser context
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include "utils/config.h"
|
|
|
|
#include <windows.h>
|
|
#include <windowsx.h>
|
|
|
|
#include "utils/errors.h"
|
|
#include "utils/log.h"
|
|
#include "netsurf/browser_window.h"
|
|
#include "netsurf/plotters.h"
|
|
#include "netsurf/keypress.h"
|
|
|
|
#include "windows/windbg.h"
|
|
#include "windows/plot.h"
|
|
#include "windows/window.h"
|
|
#include "windows/local_history.h"
|
|
#include "windows/drawable.h"
|
|
|
|
static const wchar_t *windowclassname_drawable = L"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;
|
|
|
|
NSLOG(netsurf, INFO, "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) {
|
|
struct rect rect;
|
|
rect.x0 = rect.x1 = gw->scrollx;
|
|
rect.y0 = rect.y1 = gw->scrolly + gw->requestscrolly + si.nPos - mem;
|
|
win32_window_set_scroll(gw, &rect);
|
|
}
|
|
|
|
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;
|
|
|
|
NSLOG(netsurf, INFO, "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) {
|
|
struct rect rect;
|
|
rect.x0 = rect.x1 = gw->scrollx + gw->requestscrollx + si.nPos - mem;
|
|
rect.y0 = rect.y1 = gw->scrolly;
|
|
win32_window_set_scroll(gw, &rect);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/**
|
|
* Handle resize events.
|
|
*/
|
|
static LRESULT
|
|
nsws_drawable_resize(struct gui_window *gw)
|
|
{
|
|
browser_window_schedule_reformat(gw->bw);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Handle unicode character messages.
|
|
*/
|
|
static LRESULT
|
|
nsws_drawable_unichar(struct gui_window *gw, HWND hwnd, WPARAM wparam)
|
|
{
|
|
uint32_t nskey;
|
|
|
|
if (wparam == UNICODE_NOCHAR) {
|
|
return 1;
|
|
}
|
|
|
|
nskey = wparam;
|
|
browser_window_key_press(gw->bw, nskey);
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Handle character messages.
|
|
*
|
|
* WM_CHAR is generated when WM_KEYDOWN message are passed to
|
|
* TranslateMessage; wParam is UTF-16. If the codepoint is 4
|
|
* bytes, there are 2 WM_CHAR message, one with the high
|
|
* surrogate and one with the low surrogate.
|
|
*/
|
|
static LRESULT
|
|
nsws_drawable_char(struct gui_window *gw, HWND hwnd, WPARAM wparam)
|
|
{
|
|
uint32_t nskey;
|
|
|
|
nskey = wparam;
|
|
|
|
const uint32_t utf16_hi_surrogate_start = 0xD800;
|
|
const uint32_t utf16_lo_surrogate_start = 0xDC00;
|
|
const uint32_t utf16_surrogate_end = 0xDFFF;
|
|
|
|
static uint32_t highSurrogate = 0;
|
|
|
|
if ((nskey >= utf16_hi_surrogate_start) &&
|
|
(nskey < utf16_lo_surrogate_start) ) {
|
|
highSurrogate = nskey;
|
|
} else {
|
|
if ((nskey >= utf16_lo_surrogate_start) &&
|
|
(nskey <= utf16_surrogate_end)) {
|
|
uint32_t lowSurrogate = nskey;
|
|
nskey = (highSurrogate - utf16_hi_surrogate_start) << 10;
|
|
nskey |= ( lowSurrogate - utf16_lo_surrogate_start );
|
|
nskey += 0x10000;
|
|
}
|
|
highSurrogate = 0;
|
|
|
|
browser_window_key_press(gw->bw, nskey);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Handle keydown messages.
|
|
*/
|
|
static LRESULT
|
|
nsws_drawable_keydown(struct gui_window *gw, HWND hwnd, WPARAM wparam)
|
|
{
|
|
uint32_t i;
|
|
bool shift = ((GetKeyState(VK_SHIFT) & 0x8000) == 0x8000);
|
|
|
|
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:
|
|
SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
|
|
return 1;
|
|
|
|
case VK_PRIOR:
|
|
SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
|
|
return 1;
|
|
|
|
default:
|
|
return 1;
|
|
}
|
|
|
|
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;
|
|
|
|
NSLOG(netsurf, INFO, "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) {
|
|
NSLOG(netsurf, INFO,
|
|
"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)) {
|
|
nsw32_local_history_hide();
|
|
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;
|
|
|
|
NSLOG(netsurf, INFO, "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)) {
|
|
|
|
NSLOG(netsurf, INFO, "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) {
|
|
NSLOG(netsurf, INFO,
|
|
"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);
|
|
nsw32_local_history_hide();
|
|
return 0;
|
|
|
|
case WM_RBUTTONDOWN:
|
|
nsws_drawable_mousedown(gw,
|
|
GET_X_LPARAM(lparam),
|
|
GET_Y_LPARAM(lparam),
|
|
BROWSER_MOUSE_PRESS_2);
|
|
SetFocus(hwnd);
|
|
return 0;
|
|
|
|
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:
|
|
if (nsws_drawable_keydown(gw, hwnd, wparam) == 0) {
|
|
return 0;
|
|
}
|
|
break;
|
|
|
|
case WM_CHAR:
|
|
return nsws_drawable_char(gw, hwnd, wparam);
|
|
|
|
case WM_UNICHAR:
|
|
return nsws_drawable_unichar(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);
|
|
|
|
case WM_PASTE:
|
|
browser_window_key_press(gw->bw, NS_KEY_PASTE);
|
|
return 0;
|
|
|
|
case WM_COPY:
|
|
browser_window_key_press(gw->bw, NS_KEY_COPY_SELECTION);
|
|
return 0;
|
|
|
|
case WM_CUT:
|
|
browser_window_key_press(gw->bw, NS_KEY_CUT_SELECTION);
|
|
return 0;
|
|
|
|
case WM_CLEAR:
|
|
/**
|
|
* \todo win32 clear operation deletes the contents of
|
|
* the selection but ns clear selection only
|
|
* removes the highlight.
|
|
*/
|
|
browser_window_key_press(gw->bw, NS_KEY_CLEAR_SELECTION);
|
|
return 0;
|
|
|
|
|
|
|
|
}
|
|
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 = CreateWindowExW(0,
|
|
windowclassname_drawable,
|
|
NULL,
|
|
WS_VISIBLE | WS_CHILD,
|
|
0, 0,
|
|
0, 0,
|
|
hparent,
|
|
NULL,
|
|
hinstance,
|
|
NULL);
|
|
|
|
if (hwnd == NULL) {
|
|
win_perror("WindowCreateDrawable");
|
|
NSLOG(netsurf, INFO, "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;
|
|
WNDCLASSEXW 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 (RegisterClassExW(&w) == 0) {
|
|
win_perror("DrawableClass");
|
|
ret = NSERROR_INIT_FAILED;
|
|
}
|
|
|
|
return ret;
|
|
}
|