diff options
| author | Andre Weissflog <floooh@gmail.com> | 2025-05-07 19:10:22 +0200 |
|---|---|---|
| committer | Andre Weissflog <floooh@gmail.com> | 2025-05-07 19:10:22 +0200 |
| commit | c8d1471165eab9527a17bfe1189bc45203ff670e (patch) | |
| tree | 1f7ae45ac60fdfdfbc2e149fe68aa9d59d69145f | |
| parent | 0be587fa2f57e50f20e21046efdf6af3175443f6 (diff) | |
sokol_app.h win32: make GetRawInputData() more robust by first polling the required size (same way GLFW does it)
| -rw-r--r-- | sokol_app.h | 43 |
1 files changed, 39 insertions, 4 deletions
diff --git a/sokol_app.h b/sokol_app.h index 75fda2ff..c858d53f 100644 --- a/sokol_app.h +++ b/sokol_app.h @@ -2675,7 +2675,10 @@ typedef struct { bool tracked; uint8_t capture_mask; } mouse; - RAWINPUT raw_input_data; + struct { + size_t size; + void* ptr; + } raw_input_data; } _sapp_win32_t; #if defined(SOKOL_GLCORE) @@ -7253,6 +7256,32 @@ _SOKOL_PRIVATE void _sapp_win32_lock_mouse(bool lock) { _sapp.win32.mouse.requested_lock = lock; } +_SOKOL_PRIVATE void _sapp_win32_free_raw_input_data(void) { + if (_sapp.win32.raw_input_data.ptr) { + _sapp_free(_sapp.win32.raw_input_data.ptr); + _sapp.win32.raw_input_data.ptr = 0; + _sapp.win32.raw_input_data.size = 0; + } +} + +_SOKOL_PRIVATE void _sapp_win32_alloc_raw_input_data(size_t size) { + SOKOL_ASSERT(!_sapp.win32.raw_input_data.ptr); + SOKOL_ASSERT(size > 0); + _sapp.win32.raw_input_data.ptr = _sapp_malloc(size); + _sapp.win32.raw_input_data.size = size; + SOKOL_ASSERT(_sapp.win32.raw_input_data.ptr); +} + +_SOKOL_PRIVATE void* _sapp_win32_ensure_raw_input_data(size_t required_size) { + if (required_size > _sapp.win32.raw_input_data.size) { + _sapp_win32_free_raw_input_data(); + _sapp_win32_alloc_raw_input_data(required_size); + } + // we expect that malloc() returns at least 8-byte aligned memory + SOKOL_ASSERT((((uintptr_t)_sapp.win32.raw_input_data.ptr) & 7) == 0); + return _sapp.win32.raw_input_data.ptr; +} + _SOKOL_PRIVATE void _sapp_win32_do_lock_mouse(void) { _sapp.mouse.locked = true; @@ -7668,13 +7697,18 @@ _SOKOL_PRIVATE LRESULT CALLBACK _sapp_win32_wndproc(HWND hWnd, UINT uMsg, WPARAM /* raw mouse input during mouse-lock */ if (_sapp.mouse.locked) { HRAWINPUT ri = (HRAWINPUT) lParam; - UINT size = sizeof(_sapp.win32.raw_input_data); // see: https://docs.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-getrawinputdata - if ((UINT)-1 == GetRawInputData(ri, RID_INPUT, &_sapp.win32.raw_input_data, &size, sizeof(RAWINPUTHEADER))) { + // also see: https://github.com/glfw/glfw/blob/e7ea71be039836da3a98cea55ae5569cb5eb885c/src/win32_window.c#L912-L924 + + // first poll for required size to alloc/grow input buffer, then get the actual data + UINT size = 0; + GetRawInputData(ri, RID_INPUT, NULL, &size, sizeof(RAWINPUTHEADER)); + void* raw_input_data_ptr = _sapp_win32_ensure_raw_input_data(size); + if ((UINT)-1 == GetRawInputData(ri, RID_INPUT, raw_input_data_ptr, &size, sizeof(RAWINPUTHEADER))) { _SAPP_ERROR(WIN32_GET_RAW_INPUT_DATA_FAILED); break; } - const RAWINPUT* raw_mouse_data = &_sapp.win32.raw_input_data; + const RAWINPUT* raw_mouse_data = (const RAWINPUT*) raw_input_data_ptr; if (raw_mouse_data->data.mouse.usFlags & MOUSE_MOVE_ABSOLUTE) { /* mouse only reports absolute position NOTE: This code is untested and will most likely behave wrong in Remote Desktop sessions. @@ -8215,6 +8249,7 @@ _SOKOL_PRIVATE void _sapp_win32_run(const sapp_desc* desc) { _sapp_win32_destroy_window(); _sapp_win32_destroy_icons(); _sapp_win32_restore_console(); + _sapp_win32_free_raw_input_data(); _sapp_discard_state(); } |