process unicode input in win32

This commit is contained in:
jacob 2024-04-04 14:51:32 -05:00
parent 354c372e26
commit e4ecc217e3
5 changed files with 55 additions and 21 deletions

View File

@ -402,17 +402,10 @@ struct buffer {
.text = (u8 *)(cstr_lit) \
}
#define STRING_FROM_ARRAY(a) \
( \
/* Must be array */ \
ASSERT(IS_ARRAY(a)), \
/* Must be array of bytes */ \
ASSERT(sizeof(a[0]) == sizeof(u8)), \
((struct string) { .len = ARRAY_COUNT(a), .text = (u8 *)(a) }) \
)
#define STRING_FROM_BUFFER(buff) ((struct string) { buff.size, buff.data })
#define STRING_FROM_ARRAY(a) STRING_FROM_BUFFER(BUFFER_FROM_ARRAY(a))
/* ========================== *
* Math types
* ========================== */

View File

@ -133,7 +133,7 @@ struct sys_event {
b32 is_repeat;
/* SYS_EVENT_KIND_TEXT */
u32 text_character;
u32 text_codepoint;
/* SYS_EVENT_KIND_CURSOR_MOVE */
struct v2 cursor_position;

View File

@ -59,6 +59,8 @@ struct win32_window {
u32 tid;
struct sync_flag ready_sf;
u16 utf16_high_surrogate_last_input;
struct sys_rw_mutex settings_rw_mutex;
struct sys_window_settings settings;
@ -914,19 +916,46 @@ INTERNAL LRESULT CALLBACK win32_window_proc(HWND hwnd, UINT msg, WPARAM wparam,
/* Text */
case WM_SYSCHAR:
case WM_CHAR: {
u32 character = (u32)wparam;
if (character == '\r') {
character = '\n'; /* Just treat all \r as newline */
u16 utf16_char = (u32)wparam;
/* Decode */
u32 codepoint = 0;
if (utf16_is_high_surrogate(utf16_char)) {
window->utf16_high_surrogate_last_input = utf16_char;
} else if (utf16_is_low_surrogate(utf16_char)) {
u16 high = window->utf16_high_surrogate_last_input;
u16 low = utf16_char;
if (high) {
u16 utf16_pair_bytes[2] = { high, low };
struct utf16_decode_result decoded = utf16_decode((struct string16) { .len = ARRAY_COUNT(utf16_pair_bytes), .text = utf16_pair_bytes });
if (decoded.advance16 == 2 && decoded.codepoint < U32_MAX) {
codepoint = decoded.codepoint;
} else {
codepoint = '?';
}
if((character >= 32 && character != 127) || character == '\t' || character == '\n') {
}
window->utf16_high_surrogate_last_input = 0;
} else {
window->utf16_high_surrogate_last_input = 0;
codepoint = utf16_char;
}
if (codepoint) {
if (codepoint == '\r') {
codepoint = '\n'; /* Just treat all \r as newline */
}
if((codepoint >= 32 && codepoint != 127) || codepoint == '\t' || codepoint == '\n') {
win32_window_process_event(
window,
(struct sys_event) {
.kind = SYS_EVENT_KIND_TEXT,
.text_character = character
.text_codepoint = codepoint
}
);
}
}
} break;
/* Mouse buttons */

View File

@ -154,6 +154,16 @@ struct utf16_encode_result utf16_encode(u32 codepoint)
return res;
}
b32 utf16_is_high_surrogate(u16 c)
{
return 0xD800 <= c && c < 0xDC00;
}
b32 utf16_is_low_surrogate(u16 c)
{
return 0xDC00 <= c && c < 0xE000;
}
/* ========================== *
* utf32
* ========================== */

View File

@ -34,6 +34,8 @@ struct utf16_encode_result {
struct utf16_decode_result utf16_decode(struct string16 str);
struct utf16_encode_result utf16_encode(u32 codepoint);
b32 utf16_is_high_surrogate(u16 c);
b32 utf16_is_low_surrogate(u16 c);
/* ========================== *
* utf32