1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366 |
- /**
- * @file win32drv.c
- *
- */
- /*********************
- * INCLUDES
- *********************/
- #include "win32drv.h"
- #if USE_WIN32DRV
- #include <windowsx.h>
- #include <malloc.h>
- #include <process.h>
- #include <stdbool.h>
- #include <stdint.h>
- /*********************
- * DEFINES
- *********************/
- #define WINDOW_EX_STYLE \
- WS_EX_CLIENTEDGE
- #define WINDOW_STYLE \
- (WS_OVERLAPPEDWINDOW & ~(WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME))
- #ifndef WIN32DRV_MONITOR_ZOOM
- #define WIN32DRV_MONITOR_ZOOM 1
- #endif
- #ifndef USER_DEFAULT_SCREEN_DPI
- #define USER_DEFAULT_SCREEN_DPI 96
- #endif
- /**********************
- * TYPEDEFS
- **********************/
- typedef struct _WINDOW_THREAD_PARAMETER
- {
- HANDLE window_mutex;
- HINSTANCE instance_handle;
- HICON icon_handle;
- lv_coord_t hor_res;
- lv_coord_t ver_res;
- int show_window_mode;
- } WINDOW_THREAD_PARAMETER, * PWINDOW_THREAD_PARAMETER;
- /**********************
- * STATIC PROTOTYPES
- **********************/
- /**
- * @brief Creates a B8G8R8A8 frame buffer.
- * @param WindowHandle A handle to the window for the creation of the frame
- * buffer. If this value is NULL, the entire screen will be
- * referenced.
- * @param Width The width of the frame buffer.
- * @param Height The height of the frame buffer.
- * @param PixelBuffer The raw pixel buffer of the frame buffer you created.
- * @param PixelBufferSize The size of the frame buffer you created.
- * @return If the function succeeds, the return value is a handle to the device
- * context (DC) for the frame buffer. If the function fails, the return
- * value is NULL, and PixelBuffer parameter is NULL.
- */
- static HDC lv_win32_create_frame_buffer(
- _In_opt_ HWND WindowHandle,
- _In_ LONG Width,
- _In_ LONG Height,
- _Out_ UINT32** PixelBuffer,
- _Out_ SIZE_T* PixelBufferSize);
- /**
- * @brief Enables WM_DPICHANGED message for child window for the associated
- * window.
- * @param WindowHandle The window you want to enable WM_DPICHANGED message for
- * child window.
- * @return If the function succeeds, the return value is non-zero. If the
- * function fails, the return value is zero.
- * @remarks You need to use this function in Windows 10 Threshold 1 or Windows
- * 10 Threshold 2.
- */
- static BOOL lv_win32_enable_child_window_dpi_message(
- _In_ HWND WindowHandle);
- /**
- * @brief Registers a window as being touch-capable.
- * @param hWnd The handle of the window being registered.
- * @param ulFlags A set of bit flags that specify optional modifications.
- * @return If the function succeeds, the return value is nonzero. If the
- * function fails, the return value is zero.
- * @remark For more information, see RegisterTouchWindow.
- */
- static BOOL lv_win32_register_touch_window(
- HWND hWnd,
- ULONG ulFlags);
- /**
- * @brief Retrieves detailed information about touch inputs associated with a
- * particular touch input handle.
- * @param hTouchInput The touch input handle received in the LPARAM of a touch
- * message.
- * @param cInputs The number of structures in the pInputs array.
- * @param pInputs A pointer to an array of TOUCHINPUT structures to receive
- * information about the touch points associated with the
- * specified touch input handle.
- * @param cbSize The size, in bytes, of a single TOUCHINPUT structure.
- * @return If the function succeeds, the return value is nonzero. If the
- * function fails, the return value is zero.
- * @remark For more information, see GetTouchInputInfo.
- */
- static BOOL lv_win32_get_touch_input_info(
- HTOUCHINPUT hTouchInput,
- UINT cInputs,
- PTOUCHINPUT pInputs,
- int cbSize);
- /**
- * @brief Closes a touch input handle, frees process memory associated with it,
- and invalidates the handle.
- * @param hTouchInput The touch input handle received in the LPARAM of a touch
- * message.
- * @return If the function succeeds, the return value is nonzero. If the
- * function fails, the return value is zero.
- * @remark For more information, see CloseTouchInputHandle.
- */
- static BOOL lv_win32_close_touch_input_handle(
- HTOUCHINPUT hTouchInput);
- /**
- * @brief Returns the dots per inch (dpi) value for the associated window.
- * @param WindowHandle The window you want to get information about.
- * @return The DPI for the window.
- */
- static UINT lv_win32_get_dpi_for_window(
- _In_ HWND WindowHandle);
- static void lv_win32_display_driver_flush_callback(
- lv_disp_drv_t* disp_drv,
- const lv_area_t* area,
- lv_color_t* color_p);
- static void lv_win32_pointer_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data);
- static void lv_win32_keypad_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data);
- static void lv_win32_encoder_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data);
- static lv_win32_window_context_t* lv_win32_get_display_context(
- lv_disp_t* display);
- static LRESULT CALLBACK lv_win32_window_message_callback(
- HWND hWnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
- static unsigned int __stdcall lv_win32_window_thread_entrypoint(
- void* raw_parameter);
- static void lv_win32_push_key_to_keyboard_queue(
- lv_win32_window_context_t* context,
- uint32_t key,
- lv_indev_state_t state)
- {
- lv_win32_keyboard_queue_item_t* current =
- (lv_win32_keyboard_queue_item_t*)(_aligned_malloc(
- sizeof(lv_win32_keyboard_queue_item_t),
- MEMORY_ALLOCATION_ALIGNMENT));
- if (current)
- {
- current->key = key;
- current->state = state;
- InterlockedPushEntrySList(
- context->keyboard_queue,
- ¤t->ItemEntry);
- }
- }
- /**********************
- * GLOBAL VARIABLES
- **********************/
- EXTERN_C bool lv_win32_quit_signal = false;
- EXTERN_C lv_indev_t* lv_win32_pointer_device_object = NULL;
- EXTERN_C lv_indev_t* lv_win32_keypad_device_object = NULL;
- EXTERN_C lv_indev_t* lv_win32_encoder_device_object = NULL;
- /**********************
- * STATIC VARIABLES
- **********************/
- static HWND g_window_handle = NULL;
- /**********************
- * MACROS
- **********************/
- /**********************
- * GLOBAL FUNCTIONS
- **********************/
- EXTERN_C void lv_win32_add_all_input_devices_to_group(
- lv_group_t* group)
- {
- if (!group)
- {
- LV_LOG_WARN(
- "The group object is NULL. Get the default group object instead.");
- group = lv_group_get_default();
- if (!group)
- {
- LV_LOG_WARN(
- "The default group object is NULL. Create a new group object "
- "and set it to default instead.");
- group = lv_group_create();
- if (group)
- {
- lv_group_set_default(group);
- }
- }
- }
- LV_ASSERT_MSG(group, "Cannot obtain an available group object.");
- lv_indev_set_group(lv_win32_pointer_device_object, group);
- lv_indev_set_group(lv_win32_keypad_device_object, group);
- lv_indev_set_group(lv_win32_encoder_device_object, group);
- }
- EXTERN_C lv_win32_window_context_t* lv_win32_get_window_context(
- HWND window_handle)
- {
- return (lv_win32_window_context_t*)(
- GetPropW(window_handle, L"LVGL.SimulatorWindow.WindowContext"));
- }
- EXTERN_C bool lv_win32_init_window_class()
- {
- WNDCLASSEXW window_class;
- window_class.cbSize = sizeof(WNDCLASSEXW);
- window_class.style = 0;
- window_class.lpfnWndProc = lv_win32_window_message_callback;
- window_class.cbClsExtra = 0;
- window_class.cbWndExtra = 0;
- window_class.hInstance = NULL;
- window_class.hIcon = NULL;
- window_class.hCursor = LoadCursorW(NULL, IDC_ARROW);
- window_class.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- window_class.lpszMenuName = NULL;
- window_class.lpszClassName = LVGL_SIMULATOR_WINDOW_CLASS;
- window_class.hIconSm = NULL;
- return RegisterClassExW(&window_class);
- }
- EXTERN_C HWND lv_win32_create_display_window(
- const wchar_t* window_title,
- lv_coord_t hor_res,
- lv_coord_t ver_res,
- HINSTANCE instance_handle,
- HICON icon_handle,
- int show_window_mode)
- {
- HWND display_window_handle = CreateWindowExW(
- WINDOW_EX_STYLE,
- LVGL_SIMULATOR_WINDOW_CLASS,
- window_title,
- WINDOW_STYLE,
- CW_USEDEFAULT,
- 0,
- hor_res,
- ver_res,
- NULL,
- NULL,
- instance_handle,
- NULL);
- if (display_window_handle)
- {
- SendMessageW(
- display_window_handle,
- WM_SETICON,
- TRUE,
- (LPARAM)icon_handle);
- SendMessageW(
- display_window_handle,
- WM_SETICON,
- FALSE,
- (LPARAM)icon_handle);
- ShowWindow(display_window_handle, show_window_mode);
- UpdateWindow(display_window_handle);
- }
- return display_window_handle;
- }
- EXTERN_C bool lv_win32_init(
- HINSTANCE instance_handle,
- int show_window_mode,
- lv_coord_t hor_res,
- lv_coord_t ver_res,
- HICON icon_handle)
- {
- if (!lv_win32_init_window_class())
- {
- return false;
- }
- PWINDOW_THREAD_PARAMETER parameter =
- (PWINDOW_THREAD_PARAMETER)malloc(sizeof(WINDOW_THREAD_PARAMETER));
- parameter->window_mutex = CreateEventExW(NULL, NULL, 0, EVENT_ALL_ACCESS);
- parameter->instance_handle = instance_handle;
- parameter->icon_handle = icon_handle;
- parameter->hor_res = hor_res;
- parameter->ver_res = ver_res;
- parameter->show_window_mode = show_window_mode;
- _beginthreadex(
- NULL,
- 0,
- lv_win32_window_thread_entrypoint,
- parameter,
- 0,
- NULL);
- WaitForSingleObjectEx(parameter->window_mutex, INFINITE, FALSE);
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context(g_window_handle));
- if (!context)
- {
- return false;
- }
- lv_win32_pointer_device_object = context->mouse_device_object;
- lv_win32_keypad_device_object = context->keyboard_device_object;
- lv_win32_encoder_device_object = context->mousewheel_device_object;
- return true;
- }
- /**********************
- * STATIC FUNCTIONS
- **********************/
- static HDC lv_win32_create_frame_buffer(
- HWND WindowHandle,
- LONG Width,
- LONG Height,
- UINT32** PixelBuffer,
- SIZE_T* PixelBufferSize)
- {
- HDC hFrameBufferDC = NULL;
- if (PixelBuffer && PixelBufferSize)
- {
- HDC hWindowDC = GetDC(WindowHandle);
- if (hWindowDC)
- {
- hFrameBufferDC = CreateCompatibleDC(hWindowDC);
- ReleaseDC(WindowHandle, hWindowDC);
- }
- if (hFrameBufferDC)
- {
- #if LV_COLOR_DEPTH == 32
- BITMAPINFO BitmapInfo = { 0 };
- #elif LV_COLOR_DEPTH == 16
- typedef struct _BITMAPINFO_16BPP {
- BITMAPINFOHEADER bmiHeader;
- DWORD bmiColorMask[3];
- } BITMAPINFO_16BPP, *PBITMAPINFO_16BPP;
- BITMAPINFO_16BPP BitmapInfo = { 0 };
- #elif LV_COLOR_DEPTH == 8
- typedef struct _BITMAPINFO_8BPP {
- BITMAPINFOHEADER bmiHeader;
- RGBQUAD bmiColors[256];
- } BITMAPINFO_8BPP, *PBITMAPINFO_8BPP;
- BITMAPINFO_8BPP BitmapInfo = { 0 };
- #elif LV_COLOR_DEPTH == 1
- typedef struct _BITMAPINFO_1BPP {
- BITMAPINFOHEADER bmiHeader;
- RGBQUAD bmiColors[2];
- } BITMAPINFO_1BPP, *PBITMAPINFO_1BPP;
- BITMAPINFO_1BPP BitmapInfo = { 0 };
- #else
- BITMAPINFO BitmapInfo = { 0 };
- #endif
- BitmapInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- BitmapInfo.bmiHeader.biWidth = Width;
- BitmapInfo.bmiHeader.biHeight = -Height;
- BitmapInfo.bmiHeader.biPlanes = 1;
- #if LV_COLOR_DEPTH == 32
- BitmapInfo.bmiHeader.biBitCount = 32;
- BitmapInfo.bmiHeader.biCompression = BI_RGB;
- #elif LV_COLOR_DEPTH == 16
- BitmapInfo.bmiHeader.biBitCount = 16;
- BitmapInfo.bmiHeader.biCompression = BI_BITFIELDS;
- BitmapInfo.bmiColorMask[0] = 0xF800;
- BitmapInfo.bmiColorMask[1] = 0x07E0;
- BitmapInfo.bmiColorMask[2] = 0x001F;
- #elif LV_COLOR_DEPTH == 8
- BitmapInfo.bmiHeader.biBitCount = 8;
- BitmapInfo.bmiHeader.biCompression = BI_RGB;
- for (size_t i = 0; i < 256; ++i)
- {
- lv_color8_t color;
- color.full = i;
- BitmapInfo.bmiColors[i].rgbRed = LV_COLOR_GET_R(color) * 36;
- BitmapInfo.bmiColors[i].rgbGreen = LV_COLOR_GET_G(color) * 36;
- BitmapInfo.bmiColors[i].rgbBlue = LV_COLOR_GET_B(color) * 85;
- BitmapInfo.bmiColors[i].rgbReserved = 0xFF;
- }
- #elif LV_COLOR_DEPTH == 1
- BitmapInfo.bmiHeader.biBitCount = 8;
- BitmapInfo.bmiHeader.biCompression = BI_RGB;
- BitmapInfo.bmiHeader.biClrUsed = 2;
- BitmapInfo.bmiHeader.biClrImportant = 2;
- BitmapInfo.bmiColors[0].rgbRed = 0x00;
- BitmapInfo.bmiColors[0].rgbGreen = 0x00;
- BitmapInfo.bmiColors[0].rgbBlue = 0x00;
- BitmapInfo.bmiColors[0].rgbReserved = 0xFF;
- BitmapInfo.bmiColors[1].rgbRed = 0xFF;
- BitmapInfo.bmiColors[1].rgbGreen = 0xFF;
- BitmapInfo.bmiColors[1].rgbBlue = 0xFF;
- BitmapInfo.bmiColors[1].rgbReserved = 0xFF;
- #else
- BitmapInfo.bmiHeader.biBitCount = 32;
- BitmapInfo.bmiHeader.biCompression = BI_RGB;
- #endif
- HBITMAP hBitmap = CreateDIBSection(
- hFrameBufferDC,
- (PBITMAPINFO)(&BitmapInfo),
- DIB_RGB_COLORS,
- (void**)PixelBuffer,
- NULL,
- 0);
- if (hBitmap)
- {
- #if LV_COLOR_DEPTH == 32
- *PixelBufferSize = Width * Height * sizeof(UINT32);
- #elif LV_COLOR_DEPTH == 16
- *PixelBufferSize = Width * Height * sizeof(UINT16);
- #elif LV_COLOR_DEPTH == 8
- *PixelBufferSize = Width * Height * sizeof(UINT8);
- #elif LV_COLOR_DEPTH == 1
- *PixelBufferSize = Width * Height * sizeof(UINT8);
- #else
- *PixelBufferSize = Width * Height * sizeof(UINT32);
- #endif
- DeleteObject(SelectObject(hFrameBufferDC, hBitmap));
- DeleteObject(hBitmap);
- }
- else
- {
- DeleteDC(hFrameBufferDC);
- hFrameBufferDC = NULL;
- }
- }
- }
- return hFrameBufferDC;
- }
- static BOOL lv_win32_enable_child_window_dpi_message(
- HWND WindowHandle)
- {
- // This hack is only for Windows 10 TH1/TH2 only.
- // We don't need this hack if the Per Monitor Aware V2 is existed.
- OSVERSIONINFOEXW OSVersionInfoEx = { 0 };
- OSVersionInfoEx.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEXW);
- OSVersionInfoEx.dwMajorVersion = 10;
- OSVersionInfoEx.dwMinorVersion = 0;
- OSVersionInfoEx.dwBuildNumber = 14393;
- if (!VerifyVersionInfoW(
- &OSVersionInfoEx,
- VER_MAJORVERSION | VER_MINORVERSION | VER_BUILDNUMBER,
- VerSetConditionMask(
- VerSetConditionMask(
- VerSetConditionMask(
- 0,
- VER_MAJORVERSION,
- VER_GREATER_EQUAL),
- VER_MINORVERSION,
- VER_GREATER_EQUAL),
- VER_BUILDNUMBER,
- VER_LESS)))
- {
- return FALSE;
- }
- HMODULE ModuleHandle = GetModuleHandleW(L"user32.dll");
- if (!ModuleHandle)
- {
- return FALSE;
- }
- typedef BOOL(WINAPI* FunctionType)(HWND, BOOL);
- FunctionType pFunction = (FunctionType)(
- GetProcAddress(ModuleHandle, "EnableChildWindowDpiMessage"));
- if (!pFunction)
- {
- return FALSE;
- }
- return pFunction(WindowHandle, TRUE);
- }
- static BOOL lv_win32_register_touch_window(
- HWND hWnd,
- ULONG ulFlags)
- {
- HMODULE ModuleHandle = GetModuleHandleW(L"user32.dll");
- if (!ModuleHandle)
- {
- return FALSE;
- }
- typedef BOOL(WINAPI* FunctionType)(HWND, ULONG);
- FunctionType pFunction = (FunctionType)(
- GetProcAddress(ModuleHandle, "RegisterTouchWindow"));
- if (!pFunction)
- {
- return FALSE;
- }
- return pFunction(hWnd, ulFlags);
- }
- static BOOL lv_win32_get_touch_input_info(
- HTOUCHINPUT hTouchInput,
- UINT cInputs,
- PTOUCHINPUT pInputs,
- int cbSize)
- {
- HMODULE ModuleHandle = GetModuleHandleW(L"user32.dll");
- if (!ModuleHandle)
- {
- return FALSE;
- }
- typedef BOOL(WINAPI* FunctionType)(HTOUCHINPUT, UINT, PTOUCHINPUT, int);
- FunctionType pFunction = (FunctionType)(
- GetProcAddress(ModuleHandle, "GetTouchInputInfo"));
- if (!pFunction)
- {
- return FALSE;
- }
- return pFunction(hTouchInput, cInputs, pInputs, cbSize);
- }
- static BOOL lv_win32_close_touch_input_handle(
- HTOUCHINPUT hTouchInput)
- {
- HMODULE ModuleHandle = GetModuleHandleW(L"user32.dll");
- if (!ModuleHandle)
- {
- return FALSE;
- }
- typedef BOOL(WINAPI* FunctionType)(HTOUCHINPUT);
- FunctionType pFunction = (FunctionType)(
- GetProcAddress(ModuleHandle, "CloseTouchInputHandle"));
- if (!pFunction)
- {
- return FALSE;
- }
- return pFunction(hTouchInput);
- }
- static UINT lv_win32_get_dpi_for_window(
- _In_ HWND WindowHandle)
- {
- UINT Result = (UINT)(-1);
- HMODULE ModuleHandle = LoadLibraryW(L"SHCore.dll");
- if (ModuleHandle)
- {
- typedef enum MONITOR_DPI_TYPE_PRIVATE {
- MDT_EFFECTIVE_DPI = 0,
- MDT_ANGULAR_DPI = 1,
- MDT_RAW_DPI = 2,
- MDT_DEFAULT = MDT_EFFECTIVE_DPI
- } MONITOR_DPI_TYPE_PRIVATE;
- typedef HRESULT(WINAPI* FunctionType)(
- HMONITOR, MONITOR_DPI_TYPE_PRIVATE, UINT*, UINT*);
- FunctionType pFunction = (FunctionType)(
- GetProcAddress(ModuleHandle, "GetDpiForMonitor"));
- if (pFunction)
- {
- HMONITOR MonitorHandle = MonitorFromWindow(
- WindowHandle,
- MONITOR_DEFAULTTONEAREST);
- UINT dpiX = 0;
- UINT dpiY = 0;
- if (SUCCEEDED(pFunction(
- MonitorHandle,
- MDT_EFFECTIVE_DPI,
- &dpiX,
- &dpiY)))
- {
- Result = dpiX;
- }
- }
- FreeLibrary(ModuleHandle);
- }
- if (Result == (UINT)(-1))
- {
- HDC hWindowDC = GetDC(WindowHandle);
- if (hWindowDC)
- {
- Result = GetDeviceCaps(hWindowDC, LOGPIXELSX);
- ReleaseDC(WindowHandle, hWindowDC);
- }
- }
- if (Result == (UINT)(-1))
- {
- Result = USER_DEFAULT_SCREEN_DPI;
- }
- return Result;
- }
- static void lv_win32_display_driver_flush_callback(
- lv_disp_drv_t* disp_drv,
- const lv_area_t* area,
- lv_color_t* color_p)
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context((HWND)disp_drv->user_data));
- if (context)
- {
- if (lv_disp_flush_is_last(disp_drv))
- {
- #if (LV_COLOR_DEPTH == 32) || \
- (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0) || \
- (LV_COLOR_DEPTH == 8) || \
- (LV_COLOR_DEPTH == 1)
- UNREFERENCED_PARAMETER(color_p);
- #elif (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP != 0)
- SIZE_T count = context->display_framebuffer_size / sizeof(UINT16);
- PUINT16 source = (PUINT16)color_p;
- PUINT16 destination = (PUINT16)context->display_framebuffer_base;
- for (SIZE_T i = 0; i < count; ++i)
- {
- UINT16 current = *source;
- *destination = (LOBYTE(current) << 8) | HIBYTE(current);
- ++source;
- ++destination;
- }
- #else
- uint32_t* destination = context->display_framebuffer_base;
- for (int y = area->y1; y <= area->y2; ++y)
- {
- for (int x = area->x1; x <= area->x2; ++x)
- {
- destination[y * disp_drv->hor_res + x] =
- lv_color_to32(*color_p);
- color_p++;
- }
- }
- #endif
- InvalidateRect(disp_drv->user_data, NULL, FALSE);
- }
- }
- lv_disp_flush_ready(disp_drv);
- }
- static void lv_win32_pointer_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data)
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_display_context(indev_drv->disp));
- if (!context)
- {
- return;
- }
- data->state = context->mouse_state;
- data->point = context->mouse_point;
- }
- static void lv_win32_keypad_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data)
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_display_context(indev_drv->disp));
- if (!context)
- {
- return;
- }
- EnterCriticalSection(&context->keyboard_mutex);
- lv_win32_keyboard_queue_item_t* current =
- (lv_win32_keyboard_queue_item_t*)(InterlockedPopEntrySList(
- context->keyboard_queue));
- if (current)
- {
- data->key = current->key;
- data->state = current->state;
- _aligned_free(current);
- data->continue_reading = true;
- }
- LeaveCriticalSection(&context->keyboard_mutex);
- }
- static void lv_win32_encoder_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data)
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_display_context(indev_drv->disp));
- if (!context)
- {
- return;
- }
- data->state = context->mousewheel_state;
- data->enc_diff = context->mousewheel_enc_diff;
- context->mousewheel_enc_diff = 0;
- }
- static lv_win32_window_context_t* lv_win32_get_display_context(
- lv_disp_t* display)
- {
- if (display)
- {
- return lv_win32_get_window_context((HWND)display->driver->user_data);
- }
- return NULL;
- }
- static LRESULT CALLBACK lv_win32_window_message_callback(
- HWND hWnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_CREATE:
- {
- // Note: Return -1 directly because WM_DESTROY message will be sent
- // when destroy the window automatically. We free the resource when
- // processing the WM_DESTROY message of this window.
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- malloc(sizeof(lv_win32_window_context_t)));
- if (!context)
- {
- return -1;
- }
- RECT request_content_size;
- GetWindowRect(hWnd, &request_content_size);
- context->display_hor_res =
- request_content_size.right - request_content_size.left;
- context->display_ver_res =
- request_content_size.bottom - request_content_size.top;
- context->display_dpi = lv_win32_get_dpi_for_window(hWnd);
- context->display_framebuffer_context_handle =
- lv_win32_create_frame_buffer(
- hWnd,
- context->display_hor_res,
- context->display_ver_res,
- &context->display_framebuffer_base,
- &context->display_framebuffer_size);
- #if (LV_COLOR_DEPTH == 32) || \
- (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0) || \
- (LV_COLOR_DEPTH == 8) || \
- (LV_COLOR_DEPTH == 1)
- lv_disp_draw_buf_init(
- &context->display_buffer,
- (lv_color_t*)context->display_framebuffer_base,
- NULL,
- context->display_hor_res * context->display_ver_res);
- #else
- size_t draw_buffer_size = sizeof(lv_color_t);
- draw_buffer_size *= context->display_hor_res;
- draw_buffer_size *= context->display_ver_res;
- lv_disp_draw_buf_init(
- &context->display_buffer,
- (lv_color_t*)malloc(draw_buffer_size),
- NULL,
- context->display_hor_res * context->display_ver_res);
- #endif
- lv_disp_drv_init(&context->display_driver);
- context->display_driver.hor_res = context->display_hor_res;
- context->display_driver.ver_res = context->display_ver_res;
- context->display_driver.flush_cb =
- lv_win32_display_driver_flush_callback;
- context->display_driver.draw_buf = &context->display_buffer;
- context->display_driver.direct_mode = 1;
- context->display_driver.user_data = hWnd;
- context->display_device_object =
- lv_disp_drv_register(&context->display_driver);
- if (!context->display_device_object)
- {
- return -1;
- }
- context->mouse_state = LV_INDEV_STATE_REL;
- context->mouse_point.x = 0;
- context->mouse_point.y = 0;
- lv_indev_drv_init(&context->mouse_driver);
- context->mouse_driver.type = LV_INDEV_TYPE_POINTER;
- context->mouse_driver.disp = context->display_device_object;
- context->mouse_driver.read_cb =
- lv_win32_pointer_driver_read_callback;
- context->mouse_device_object =
- lv_indev_drv_register(&context->mouse_driver);
- if (!context->mouse_device_object)
- {
- return -1;
- }
- context->mousewheel_state = LV_INDEV_STATE_REL;
- context->mousewheel_enc_diff = 0;
- lv_indev_drv_init(&context->mousewheel_driver);
- context->mousewheel_driver.type = LV_INDEV_TYPE_ENCODER;
- context->mousewheel_driver.disp = context->display_device_object;
- context->mousewheel_driver.read_cb =
- lv_win32_encoder_driver_read_callback;
- context->mousewheel_device_object =
- lv_indev_drv_register(&context->mousewheel_driver);
- if (!context->mousewheel_device_object)
- {
- return -1;
- }
- InitializeCriticalSection(&context->keyboard_mutex);
- context->keyboard_queue = _aligned_malloc(
- sizeof(SLIST_HEADER),
- MEMORY_ALLOCATION_ALIGNMENT);
- if (!context->keyboard_queue)
- {
- return -1;
- }
- InitializeSListHead(context->keyboard_queue);
- context->keyboard_utf16_high_surrogate = 0;
- context->keyboard_utf16_low_surrogate = 0;
- lv_indev_drv_init(&context->keyboard_driver);
- context->keyboard_driver.type = LV_INDEV_TYPE_KEYPAD;
- context->keyboard_driver.disp = context->display_device_object;
- context->keyboard_driver.read_cb =
- lv_win32_keypad_driver_read_callback;
- context->keyboard_device_object =
- lv_indev_drv_register(&context->keyboard_driver);
- if (!context->keyboard_device_object)
- {
- return -1;
- }
- if (!SetPropW(
- hWnd,
- L"LVGL.SimulatorWindow.WindowContext",
- (HANDLE)(context)))
- {
- return -1;
- }
- RECT calculated_window_size;
- calculated_window_size.left = 0;
- calculated_window_size.right = MulDiv(
- context->display_hor_res * WIN32DRV_MONITOR_ZOOM,
- context->display_dpi,
- USER_DEFAULT_SCREEN_DPI);
- calculated_window_size.top = 0;
- calculated_window_size.bottom = MulDiv(
- context->display_ver_res * WIN32DRV_MONITOR_ZOOM,
- context->display_dpi,
- USER_DEFAULT_SCREEN_DPI);
- AdjustWindowRectEx(
- &calculated_window_size,
- WINDOW_STYLE,
- FALSE,
- WINDOW_EX_STYLE);
- OffsetRect(
- &calculated_window_size,
- -calculated_window_size.left,
- -calculated_window_size.top);
- SetWindowPos(
- hWnd,
- NULL,
- 0,
- 0,
- calculated_window_size.right,
- calculated_window_size.bottom,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
- lv_win32_register_touch_window(hWnd, 0);
- lv_win32_enable_child_window_dpi_message(hWnd);
- break;
- }
- case WM_MOUSEMOVE:
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_MBUTTONDOWN:
- case WM_MBUTTONUP:
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context(hWnd));
- if (!context)
- {
- return 0;
- }
- context->mouse_point.x = MulDiv(
- GET_X_LPARAM(lParam),
- USER_DEFAULT_SCREEN_DPI,
- WIN32DRV_MONITOR_ZOOM * context->display_dpi);
- context->mouse_point.y = MulDiv(
- GET_Y_LPARAM(lParam),
- USER_DEFAULT_SCREEN_DPI,
- WIN32DRV_MONITOR_ZOOM * context->display_dpi);
- if (context->mouse_point.x < 0)
- {
- context->mouse_point.x = 0;
- }
- if (context->mouse_point.x > context->display_hor_res - 1)
- {
- context->mouse_point.x = context->display_hor_res - 1;
- }
- if (context->mouse_point.y < 0)
- {
- context->mouse_point.y = 0;
- }
- if (context->mouse_point.y > context->display_ver_res - 1)
- {
- context->mouse_point.y = context->display_ver_res - 1;
- }
- if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
- {
- context->mouse_state = (
- uMsg == WM_LBUTTONDOWN
- ? LV_INDEV_STATE_PR
- : LV_INDEV_STATE_REL);
- }
- else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)
- {
- context->mousewheel_state = (
- uMsg == WM_MBUTTONDOWN
- ? LV_INDEV_STATE_PR
- : LV_INDEV_STATE_REL);
- }
- return 0;
- }
- case WM_KEYDOWN:
- case WM_KEYUP:
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context(hWnd));
- if (context)
- {
- EnterCriticalSection(&context->keyboard_mutex);
- bool skip_translation = false;
- uint32_t translated_key = 0;
- switch (wParam)
- {
- case VK_UP:
- translated_key = LV_KEY_UP;
- break;
- case VK_DOWN:
- translated_key = LV_KEY_DOWN;
- break;
- case VK_LEFT:
- translated_key = LV_KEY_LEFT;
- break;
- case VK_RIGHT:
- translated_key = LV_KEY_RIGHT;
- break;
- case VK_ESCAPE:
- translated_key = LV_KEY_ESC;
- break;
- case VK_DELETE:
- translated_key = LV_KEY_DEL;
- break;
- case VK_BACK:
- translated_key = LV_KEY_BACKSPACE;
- break;
- case VK_RETURN:
- translated_key = LV_KEY_ENTER;
- break;
- case VK_TAB:
- case VK_NEXT:
- translated_key = LV_KEY_NEXT;
- break;
- case VK_PRIOR:
- translated_key = LV_KEY_PREV;
- break;
- case VK_HOME:
- translated_key = LV_KEY_HOME;
- break;
- case VK_END:
- translated_key = LV_KEY_END;
- break;
- default:
- skip_translation = true;
- break;
- }
- if (!skip_translation)
- {
- lv_win32_push_key_to_keyboard_queue(
- context,
- translated_key,
- ((uMsg == WM_KEYUP)
- ? LV_INDEV_STATE_REL
- : LV_INDEV_STATE_PR));
- }
- LeaveCriticalSection(&context->keyboard_mutex);
- }
- break;
- }
- case WM_CHAR:
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context(hWnd));
- if (context)
- {
- EnterCriticalSection(&context->keyboard_mutex);
- uint16_t raw_code_point = (uint16_t)(wParam);
- if (raw_code_point >= 0x20 && raw_code_point != 0x7F)
- {
- if (IS_HIGH_SURROGATE(raw_code_point))
- {
- context->keyboard_utf16_high_surrogate = raw_code_point;
- }
- else if (IS_LOW_SURROGATE(raw_code_point))
- {
- context->keyboard_utf16_low_surrogate = raw_code_point;
- }
- uint32_t code_point = raw_code_point;
- if (context->keyboard_utf16_high_surrogate &&
- context->keyboard_utf16_low_surrogate)
- {
- uint16_t high_surrogate =
- context->keyboard_utf16_high_surrogate;
- uint16_t low_surrogate =
- context->keyboard_utf16_low_surrogate;
- code_point = (low_surrogate & 0x03FF);
- code_point += (((high_surrogate & 0x03FF) + 0x40) << 10);
- context->keyboard_utf16_high_surrogate = 0;
- context->keyboard_utf16_low_surrogate = 0;
- }
- uint32_t lvgl_code_point =
- _lv_txt_unicode_to_encoded(code_point);
- lv_win32_push_key_to_keyboard_queue(
- context,
- lvgl_code_point,
- LV_INDEV_STATE_PR);
- lv_win32_push_key_to_keyboard_queue(
- context,
- lvgl_code_point,
- LV_INDEV_STATE_REL);
- }
- LeaveCriticalSection(&context->keyboard_mutex);
- }
- break;
- }
- case WM_MOUSEWHEEL:
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context(hWnd));
- if (context)
- {
- context->mousewheel_enc_diff =
- -(GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA);
- }
- break;
- }
- case WM_TOUCH:
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context(hWnd));
- if (context)
- {
- UINT cInputs = LOWORD(wParam);
- HTOUCHINPUT hTouchInput = (HTOUCHINPUT)(lParam);
- PTOUCHINPUT pInputs = malloc(cInputs * sizeof(TOUCHINPUT));
- if (pInputs)
- {
- if (lv_win32_get_touch_input_info(
- hTouchInput,
- cInputs,
- pInputs,
- sizeof(TOUCHINPUT)))
- {
- for (UINT i = 0; i < cInputs; ++i)
- {
- POINT Point;
- Point.x = TOUCH_COORD_TO_PIXEL(pInputs[i].x);
- Point.y = TOUCH_COORD_TO_PIXEL(pInputs[i].y);
- if (!ScreenToClient(hWnd, &Point))
- {
- continue;
- }
- context->mouse_point.x = MulDiv(
- Point.x,
- USER_DEFAULT_SCREEN_DPI,
- WIN32DRV_MONITOR_ZOOM * context->display_dpi);
- context->mouse_point.y = MulDiv(
- Point.y,
- USER_DEFAULT_SCREEN_DPI,
- WIN32DRV_MONITOR_ZOOM * context->display_dpi);
- DWORD MousePressedMask =
- TOUCHEVENTF_MOVE | TOUCHEVENTF_DOWN;
- context->mouse_state = (
- pInputs[i].dwFlags & MousePressedMask
- ? LV_INDEV_STATE_PR
- : LV_INDEV_STATE_REL);
- }
- }
- free(pInputs);
- }
- lv_win32_close_touch_input_handle(hTouchInput);
- }
- break;
- }
- case WM_DPICHANGED:
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context(hWnd));
- if (context)
- {
- context->display_dpi = HIWORD(wParam);
- LPRECT SuggestedRect = (LPRECT)lParam;
- SetWindowPos(
- hWnd,
- NULL,
- SuggestedRect->left,
- SuggestedRect->top,
- SuggestedRect->right,
- SuggestedRect->bottom,
- SWP_NOZORDER | SWP_NOACTIVATE);
- RECT ClientRect;
- GetClientRect(hWnd, &ClientRect);
- int WindowWidth = MulDiv(
- context->display_hor_res * WIN32DRV_MONITOR_ZOOM,
- context->display_dpi,
- USER_DEFAULT_SCREEN_DPI);
- int WindowHeight = MulDiv(
- context->display_ver_res * WIN32DRV_MONITOR_ZOOM,
- context->display_dpi,
- USER_DEFAULT_SCREEN_DPI);
- SetWindowPos(
- hWnd,
- NULL,
- SuggestedRect->left,
- SuggestedRect->top,
- SuggestedRect->right + (WindowWidth - ClientRect.right),
- SuggestedRect->bottom + (WindowHeight - ClientRect.bottom),
- SWP_NOZORDER | SWP_NOACTIVATE);
- }
- break;
- }
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- HDC hdc = BeginPaint(hWnd, &ps);
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- lv_win32_get_window_context(hWnd));
- if (context)
- {
- if (context->display_framebuffer_context_handle)
- {
- SetStretchBltMode(hdc, HALFTONE);
- StretchBlt(
- hdc,
- ps.rcPaint.left,
- ps.rcPaint.top,
- ps.rcPaint.right - ps.rcPaint.left,
- ps.rcPaint.bottom - ps.rcPaint.top,
- context->display_framebuffer_context_handle,
- 0,
- 0,
- MulDiv(
- ps.rcPaint.right - ps.rcPaint.left,
- USER_DEFAULT_SCREEN_DPI,
- WIN32DRV_MONITOR_ZOOM * context->display_dpi),
- MulDiv(
- ps.rcPaint.bottom - ps.rcPaint.top,
- USER_DEFAULT_SCREEN_DPI,
- WIN32DRV_MONITOR_ZOOM * context->display_dpi),
- SRCCOPY);
- }
- }
- EndPaint(hWnd, &ps);
- break;
- }
- case WM_DESTROY:
- {
- lv_win32_window_context_t* context = (lv_win32_window_context_t*)(
- RemovePropW(hWnd, L"LVGL.SimulatorWindow.WindowContext"));
- if (context)
- {
- lv_disp_t* display_device_object = context->display_device_object;
- context->display_device_object = NULL;
- lv_disp_remove(display_device_object);
- #if (LV_COLOR_DEPTH == 32) || \
- (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0) || \
- (LV_COLOR_DEPTH == 8) || \
- (LV_COLOR_DEPTH == 1)
- #else
- free(context->display_buffer.buf1);
- #endif
- DeleteDC(context->display_framebuffer_context_handle);
- lv_indev_t* mouse_device_object =
- context->mouse_device_object;
- context->mouse_device_object = NULL;
- lv_indev_delete(mouse_device_object);
- lv_indev_t* mousewheel_device_object =
- context->mousewheel_device_object;
- context->mousewheel_device_object = NULL;
- lv_indev_delete(mousewheel_device_object);
- lv_indev_t* keyboard_device_object =
- context->keyboard_device_object;
- context->keyboard_device_object = NULL;
- lv_indev_delete(keyboard_device_object);
- do
- {
- PSLIST_ENTRY current = InterlockedPopEntrySList(
- context->keyboard_queue);
- if (!current)
- {
- _aligned_free(context->keyboard_queue);
- context->keyboard_queue = NULL;
- break;
- }
- _aligned_free(current);
- } while (true);
- DeleteCriticalSection(&context->keyboard_mutex);
- free(context);
- }
- PostQuitMessage(0);
- break;
- }
- default:
- return DefWindowProcW(hWnd, uMsg, wParam, lParam);
- }
- return 0;
- }
- static unsigned int __stdcall lv_win32_window_thread_entrypoint(
- void* raw_parameter)
- {
- PWINDOW_THREAD_PARAMETER parameter =
- (PWINDOW_THREAD_PARAMETER)raw_parameter;
- g_window_handle = lv_win32_create_display_window(
- L"LVGL Simulator for Windows Desktop (Display 1)",
- parameter->hor_res,
- parameter->ver_res,
- parameter->instance_handle,
- parameter->icon_handle,
- parameter->show_window_mode);
- if (!g_window_handle)
- {
- return 0;
- }
- SetEvent(parameter->window_mutex);
- MSG message;
- while (GetMessageW(&message, NULL, 0, 0))
- {
- TranslateMessage(&message);
- DispatchMessageW(&message);
- }
- lv_win32_quit_signal = true;
- return 0;
- }
- #endif /*USE_WIN32DRV*/
|