From af041657aa0d80e6da8fbb0ef7369871bd38b21d Mon Sep 17 00:00:00 2001 From: Liam <30486941+liamHowatt@users.noreply.github.com> Date: Mon, 8 Jul 2024 05:38:47 +0200 Subject: [PATCH] fix(Windows): use global lock (#6425) --- Kconfig | 1 + docs/integration/driver/windows.rst | 4 ++ src/drivers/windows/lv_windows_context.c | 56 +++++++++++++++++++----- src/drivers/windows/lv_windows_context.h | 15 ++++++- src/drivers/windows/lv_windows_input.c | 16 +------ tests/CMakeLists.txt | 1 + 6 files changed, 65 insertions(+), 28 deletions(-) diff --git a/Kconfig b/Kconfig index 3599a70d6..f71ffc5d1 100644 --- a/Kconfig +++ b/Kconfig @@ -1699,6 +1699,7 @@ menu "LVGL configuration" config LV_USE_WINDOWS bool "Use LVGL Windows backend" + depends on LV_OS_WINDOWS default n config LV_USE_OPENGLES diff --git a/docs/integration/driver/windows.rst b/docs/integration/driver/windows.rst index 1a2727f24..66e01eb52 100644 --- a/docs/integration/driver/windows.rst +++ b/docs/integration/driver/windows.rst @@ -79,6 +79,8 @@ Usage return -1; } + lv_lock(); + lv_indev_t* pointer_device = lv_windows_acquire_pointer_indev(display); if (!pointer_device) { @@ -99,6 +101,8 @@ Usage lv_demo_widgets(); + lv_unlock(); + while (1) { uint32_t time_till_next = lv_timer_handler(); diff --git a/src/drivers/windows/lv_windows_context.c b/src/drivers/windows/lv_windows_context.c index 61655039a..7bf20385a 100644 --- a/src/drivers/windows/lv_windows_context.c +++ b/src/drivers/windows/lv_windows_context.c @@ -36,6 +36,13 @@ static void lv_windows_delay_callback(uint32_t ms); static void lv_windows_check_display_existence_timer_callback( lv_timer_t * timer); +static bool lv_windows_window_message_callback_nolock( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam, + LRESULT * plResult); + static LRESULT CALLBACK lv_windows_window_message_callback( HWND hWnd, UINT uMsg, @@ -452,11 +459,12 @@ static BOOL lv_windows_enable_child_window_dpi_message( return function(WindowHandle, TRUE); } -static LRESULT CALLBACK lv_windows_window_message_callback( +static bool lv_windows_window_message_callback_nolock( HWND hWnd, UINT uMsg, WPARAM wParam, - LPARAM lParam) + LPARAM lParam, + LRESULT * plResult) { switch(uMsg) { case WM_CREATE: { @@ -646,15 +654,15 @@ static LRESULT CALLBACK lv_windows_window_message_callback( lv_windows_window_context_t * context = (lv_windows_window_context_t *)( lv_windows_get_window_context(hWnd)); if(context) { - LRESULT lResult = 0; if(context->pointer.indev && lv_windows_pointer_device_window_message_handler( hWnd, uMsg, wParam, lParam, - &lResult)) { - return lResult; + plResult)) { + // Handled + return true; } else if(context->keypad.indev && lv_windows_keypad_device_window_message_handler( @@ -662,8 +670,9 @@ static LRESULT CALLBACK lv_windows_window_message_callback( uMsg, wParam, lParam, - &lResult)) { - return lResult; + plResult)) { + // Handled + return true; } else if(context->encoder.indev && lv_windows_encoder_device_window_message_handler( @@ -671,16 +680,41 @@ static LRESULT CALLBACK lv_windows_window_message_callback( uMsg, wParam, lParam, - &lResult)) { - return lResult; + plResult)) { + // Handled + return true; } } - return DefWindowProcW(hWnd, uMsg, wParam, lParam); + // Not Handled + return false; } } - return 0; + // Handled + *plResult = 0; + return true; +} + +static LRESULT CALLBACK lv_windows_window_message_callback( + HWND hWnd, + UINT uMsg, + WPARAM wParam, + LPARAM lParam) +{ + lv_lock(); + + LRESULT lResult = 0; + bool Handled = lv_windows_window_message_callback_nolock( + hWnd, + uMsg, + wParam, + lParam, + &lResult); + + lv_unlock(); + + return Handled ? lResult : DefWindowProcW(hWnd, uMsg, wParam, lParam); } #endif // LV_USE_WINDOWS diff --git a/src/drivers/windows/lv_windows_context.h b/src/drivers/windows/lv_windows_context.h index 20e72af37..4517d9b54 100644 --- a/src/drivers/windows/lv_windows_context.h +++ b/src/drivers/windows/lv_windows_context.h @@ -1,4 +1,4 @@ -/** +/** * @file lv_windows_context.h * */ @@ -19,8 +19,20 @@ extern "C" { #if LV_USE_WINDOWS +#if LV_USE_OS != LV_OS_WINDOWS +#error [lv_windows] LV_OS_WINDOWS is required. Enable it in lv_conf.h (LV_USE_OS LV_OS_WINDOWS) +#endif + #include +#ifndef CREATE_WAITABLE_TIMER_MANUAL_RESET +#define CREATE_WAITABLE_TIMER_MANUAL_RESET 0x00000001 +#endif + +#ifndef CREATE_WAITABLE_TIMER_HIGH_RESOLUTION +#define CREATE_WAITABLE_TIMER_HIGH_RESOLUTION 0x00000002 +#endif + /********************* * DEFINES *********************/ @@ -41,7 +53,6 @@ typedef struct _lv_windows_keypad_queue_item_t { } lv_windows_keypad_queue_item_t; typedef struct _lv_windows_keypad_context_t { - CRITICAL_SECTION mutex; lv_ll_t queue; uint16_t utf16_high_surrogate; uint16_t utf16_low_surrogate; diff --git a/src/drivers/windows/lv_windows_input.c b/src/drivers/windows/lv_windows_input.c index baac01142..5611e3fb4 100644 --- a/src/drivers/windows/lv_windows_input.c +++ b/src/drivers/windows/lv_windows_input.c @@ -1,4 +1,4 @@ -/** +/** * @file lv_windows_input.c * */ @@ -128,7 +128,6 @@ lv_indev_t * lv_windows_acquire_keypad_indev(lv_display_t * display) } if(!context->keypad.indev) { - InitializeCriticalSection(&context->keypad.mutex); _lv_ll_init( &context->keypad.queue, sizeof(lv_windows_keypad_queue_item_t)); @@ -421,8 +420,6 @@ static void lv_windows_keypad_driver_read_callback( return; } - EnterCriticalSection(&context->keypad.mutex); - lv_windows_keypad_queue_item_t * current = (lv_windows_keypad_queue_item_t *)( _lv_ll_get_head(&context->keypad.queue)); if(current) { @@ -434,8 +431,6 @@ static void lv_windows_keypad_driver_read_callback( data->continue_reading = true; } - - LeaveCriticalSection(&context->keypad.mutex); } static void lv_windows_release_keypad_device_event_callback(lv_event_t * e) @@ -456,7 +451,6 @@ static void lv_windows_release_keypad_device_event_callback(lv_event_t * e) return; } - DeleteCriticalSection(&context->keypad.mutex); _lv_ll_clear(&context->keypad.queue); context->keypad.utf16_high_surrogate = 0; context->keypad.utf16_low_surrogate = 0; @@ -571,8 +565,6 @@ bool lv_windows_keypad_device_window_message_handler( lv_windows_window_context_t * context = (lv_windows_window_context_t *)( lv_windows_get_window_context(hWnd)); if(context) { - EnterCriticalSection(&context->keypad.mutex); - bool skip_translation = false; uint32_t translated_key = 0; @@ -627,8 +619,6 @@ bool lv_windows_keypad_device_window_message_handler( ? LV_INDEV_STATE_RELEASED : LV_INDEV_STATE_PRESSED)); } - - LeaveCriticalSection(&context->keypad.mutex); } break; @@ -637,8 +627,6 @@ bool lv_windows_keypad_device_window_message_handler( lv_windows_window_context_t * context = (lv_windows_window_context_t *)( lv_windows_get_window_context(hWnd)); if(context) { - EnterCriticalSection(&context->keypad.mutex); - uint16_t raw_code_point = (uint16_t)(wParam); if(raw_code_point >= 0x20 && raw_code_point != 0x7F) { @@ -677,8 +665,6 @@ bool lv_windows_keypad_device_window_message_handler( lvgl_code_point, LV_INDEV_STATE_RELEASED); } - - LeaveCriticalSection(&context->keypad.mutex); } break; diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 478987bfc..bdb440de1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -387,6 +387,7 @@ endif() if(WIN32) add_definitions(-DLV_USE_LINUX_FBDEV=0) add_definitions(-DLV_USE_WINDOWS=1) + add_definitions(-DLV_USE_OS=LV_OS_WINDOWS) endif() # disable test targets for build only tests