summaryrefslogtreecommitdiff
path: root/frontends/windows
diff options
context:
space:
mode:
authorVincent Sanders <vince@kyllikki.org>2019-05-09 23:27:59 +0100
committerVincent Sanders <vince@kyllikki.org>2019-05-09 23:27:59 +0100
commit8f9d434b1295215c377eab2ba7186ad8b2d92aa9 (patch)
tree0e7d40b5ecbb7a8abc6a8b081e8ad2d583ba5c08 /frontends/windows
parent95b8d129508ccdec5eadabf46eb313b49a6b4369 (diff)
downloadnetsurf-8f9d434b1295215c377eab2ba7186ad8b2d92aa9.tar.gz
netsurf-8f9d434b1295215c377eab2ba7186ad8b2d92aa9.tar.bz2
make win32 keyboard handling in browsing window functional
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.
Diffstat (limited to 'frontends/windows')
-rw-r--r--frontends/windows/drawable.c122
1 files changed, 86 insertions, 36 deletions
diff --git a/frontends/windows/drawable.c b/frontends/windows/drawable.c
index 939f4f946..e1fdbc84e 100644
--- a/frontends/windows/drawable.c
+++ b/frontends/windows/drawable.c
@@ -41,7 +41,7 @@
#include "windows/local_history.h"
#include "windows/drawable.h"
-static const char windowclassname_drawable[] = "nswsdrawablewindow";
+static const wchar_t *windowclassname_drawable = L"nswsdrawablewindow";
/**
@@ -223,19 +223,71 @@ nsws_drawable_resize(struct gui_window *gw)
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 key press messages.
+ * 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_key(struct gui_window *gw, HWND hwnd, WPARAM wparam)
+nsws_drawable_char(struct gui_window *gw, HWND hwnd, WPARAM wparam)
{
- if (GetFocus() != hwnd)
- return 0 ;
+ 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);
- bool capslock = ((GetKeyState(VK_CAPITAL) & 1) == 1);
switch(wparam) {
case VK_LEFT:
@@ -285,30 +337,18 @@ nsws_drawable_key(struct gui_window *gw, HWND hwnd, WPARAM wparam)
break;
case VK_NEXT:
- i = wparam;
- SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0),
- 0);
- break;
+ SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEDOWN, 0), 0);
+ return 1;
case VK_PRIOR:
- i = wparam;
- SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0),
- 0);
- break;
+ SendMessage(hwnd, WM_VSCROLL, MAKELONG(SB_PAGEUP, 0), 0);
+ return 1;
default:
- i = wparam;
- break;
- }
-
- if ((i >= 'A') &&
- (i <= 'Z') &&
- (((!capslock) && (!shift)) || ((capslock) && (shift)))) {
- i += 'a' - 'A';
+ return 1;
}
- if (gw != NULL)
- browser_window_key_press(gw->bw, i);
+ browser_window_key_press(gw->bw, i);
return 0;
}
@@ -544,7 +584,6 @@ nsws_window_drawable_event_callback(HWND hwnd,
BROWSER_MOUSE_PRESS_2);
SetFocus(hwnd);
return 0;
- break;
case WM_LBUTTONUP:
return nsws_drawable_mouseup(gw,
@@ -567,7 +606,16 @@ nsws_window_drawable_event_callback(HWND hwnd,
return nsws_drawable_paint(gw, hwnd);
case WM_KEYDOWN:
- return nsws_drawable_key(gw, hwnd, wparam);
+ 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);
@@ -618,14 +666,16 @@ nsws_window_create_drawable(HINSTANCE hinstance,
struct gui_window *gw)
{
HWND hwnd;
- hwnd = CreateWindow(windowclassname_drawable,
- NULL,
- WS_VISIBLE | WS_CHILD,
- 0, 0, 0, 0,
- hparent,
- NULL,
- hinstance,
- NULL);
+ hwnd = CreateWindowExW(0,
+ windowclassname_drawable,
+ NULL,
+ WS_VISIBLE | WS_CHILD,
+ 0, 0,
+ 0, 0,
+ hparent,
+ NULL,
+ hinstance,
+ NULL);
if (hwnd == NULL) {
win_perror("WindowCreateDrawable");
@@ -646,7 +696,7 @@ nsws_window_create_drawable(HINSTANCE hinstance,
nserror
nsws_create_drawable_class(HINSTANCE hinstance) {
nserror ret = NSERROR_OK;
- WNDCLASSEX w;
+ WNDCLASSEXW w;
/* drawable area */
w.cbSize = sizeof(WNDCLASSEX);
@@ -662,7 +712,7 @@ nsws_create_drawable_class(HINSTANCE hinstance) {
w.lpszClassName = windowclassname_drawable;
w.hIconSm = NULL;
- if (RegisterClassEx(&w) == 0) {
+ if (RegisterClassExW(&w) == 0) {
win_perror("DrawableClass");
ret = NSERROR_INIT_FAILED;
}