12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007 |
- /**
- * @file win32drv.c
- *
- */
- /*********************
- * INCLUDES
- *********************/
- #include "win32drv.h"
- #if USE_WIN32DRV
- #include <windowsx.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
- **********************/
- /**********************
- * 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_display_driver_rounder_callback(
- lv_disp_drv_t* disp_drv,
- lv_area_t* area);
- 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 LRESULT CALLBACK lv_win32_window_message_callback(
- HWND hWnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam);
- static void lv_win32_message_handler(
- lv_timer_t* param);
- /**********************
- * 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 HINSTANCE g_instance_handle = NULL;
- static HWND g_window_handle = NULL;
- static HDC g_buffer_dc_handle = NULL;
- static UINT32* g_pixel_buffer = NULL;
- static SIZE_T g_pixel_buffer_size = 0;
- static lv_disp_t* g_display = NULL;
- static bool volatile g_mouse_pressed = false;
- static LPARAM volatile g_mouse_value = 0;
- static bool volatile g_mousewheel_pressed = false;
- static int16_t volatile g_mousewheel_value = 0;
- static bool volatile g_keyboard_pressed = false;
- static WPARAM volatile g_keyboard_value = 0;
- static int volatile g_dpi_value = USER_DEFAULT_SCREEN_DPI;
- /**********************
- * 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 bool lv_win32_init(
- HINSTANCE instance_handle,
- int show_window_mode,
- lv_coord_t hor_res,
- lv_coord_t ver_res,
- HICON icon_handle)
- {
- WNDCLASSEXW WindowClass;
- WindowClass.cbSize = sizeof(WNDCLASSEX);
- WindowClass.style = 0;
- WindowClass.lpfnWndProc = lv_win32_window_message_callback;
- WindowClass.cbClsExtra = 0;
- WindowClass.cbWndExtra = 0;
- WindowClass.hInstance = instance_handle;
- WindowClass.hIcon = icon_handle;
- WindowClass.hCursor = LoadCursorW(NULL, IDC_ARROW);
- WindowClass.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- WindowClass.lpszMenuName = NULL;
- WindowClass.lpszClassName = L"lv_sim_visual_studio";
- WindowClass.hIconSm = icon_handle;
- if (!RegisterClassExW(&WindowClass))
- {
- return false;
- }
- g_instance_handle = instance_handle;
- g_window_handle = CreateWindowExW(
- WINDOW_EX_STYLE,
- WindowClass.lpszClassName,
- L"LVGL Simulator for Windows Desktop",
- WINDOW_STYLE,
- CW_USEDEFAULT,
- 0,
- CW_USEDEFAULT,
- 0,
- NULL,
- NULL,
- instance_handle,
- NULL);
- if (!g_window_handle)
- {
- return false;
- }
- g_dpi_value = lv_win32_get_dpi_for_window(g_window_handle);
- RECT WindowSize;
- WindowSize.left = 0;
- WindowSize.right = MulDiv(
- hor_res * WIN32DRV_MONITOR_ZOOM,
- g_dpi_value,
- USER_DEFAULT_SCREEN_DPI);
- WindowSize.top = 0;
- WindowSize.bottom = MulDiv(
- ver_res * WIN32DRV_MONITOR_ZOOM,
- g_dpi_value,
- USER_DEFAULT_SCREEN_DPI);
- AdjustWindowRectEx(
- &WindowSize,
- WINDOW_STYLE,
- FALSE,
- WINDOW_EX_STYLE);
- OffsetRect(
- &WindowSize,
- -WindowSize.left,
- -WindowSize.top);
- SetWindowPos(
- g_window_handle,
- NULL,
- 0,
- 0,
- WindowSize.right,
- WindowSize.bottom,
- SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOMOVE);
- lv_win32_register_touch_window(g_window_handle, 0);
- lv_timer_create(lv_win32_message_handler, 0, NULL);
- lv_win32_enable_child_window_dpi_message(g_window_handle);
- HDC hNewBufferDC = lv_win32_create_frame_buffer(
- g_window_handle,
- hor_res,
- ver_res,
- &g_pixel_buffer,
- &g_pixel_buffer_size);
- DeleteDC(g_buffer_dc_handle);
- g_buffer_dc_handle = hNewBufferDC;
- static lv_disp_draw_buf_t display_buffer;
- lv_disp_draw_buf_init(
- &display_buffer,
- (lv_color_t*)malloc(hor_res * ver_res * sizeof(lv_color_t)),
- NULL,
- hor_res * ver_res);
- static lv_disp_drv_t display_driver;
- lv_disp_drv_init(&display_driver);
- display_driver.hor_res = hor_res;
- display_driver.ver_res = ver_res;
- display_driver.flush_cb = lv_win32_display_driver_flush_callback;
- display_driver.draw_buf = &display_buffer;
- display_driver.rounder_cb = lv_win32_display_driver_rounder_callback;
- g_display = lv_disp_drv_register(&display_driver);
- static lv_indev_drv_t pointer_driver;
- lv_indev_drv_init(&pointer_driver);
- pointer_driver.type = LV_INDEV_TYPE_POINTER;
- pointer_driver.read_cb = lv_win32_pointer_driver_read_callback;
- lv_win32_pointer_device_object = lv_indev_drv_register(&pointer_driver);
- static lv_indev_drv_t keypad_driver;
- lv_indev_drv_init(&keypad_driver);
- keypad_driver.type = LV_INDEV_TYPE_KEYPAD;
- keypad_driver.read_cb = lv_win32_keypad_driver_read_callback;
- lv_win32_keypad_device_object = lv_indev_drv_register(&keypad_driver);
- static lv_indev_drv_t encoder_driver;
- lv_indev_drv_init(&encoder_driver);
- encoder_driver.type = LV_INDEV_TYPE_ENCODER;
- encoder_driver.read_cb = lv_win32_encoder_driver_read_callback;
- lv_win32_encoder_device_object = lv_indev_drv_register(&encoder_driver);
- ShowWindow(g_window_handle, show_window_mode);
- UpdateWindow(g_window_handle);
- 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)
- {
- #if (LV_COLOR_DEPTH == 32) || \
- (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP == 0) || \
- (LV_COLOR_DEPTH == 8) || \
- (LV_COLOR_DEPTH == 1)
- UNREFERENCED_PARAMETER(area);
- memcpy(g_pixel_buffer, color_p, g_pixel_buffer_size);
- #elif (LV_COLOR_DEPTH == 16 && LV_COLOR_16_SWAP != 0)
- SIZE_T count = g_pixel_buffer_size / sizeof(UINT16);
- PUINT16 source = (PUINT16)color_p;
- PUINT16 destination = (PUINT16)g_pixel_buffer;
- for (SIZE_T i = 0; i < count; ++i)
- {
- UINT16 current = *source;
- *destination = (LOBYTE(current) << 8) | HIBYTE(current);
- ++source;
- ++destination;
- }
- #else
- for (int y = area->y1; y <= area->y2; ++y)
- {
- for (int x = area->x1; x <= area->x2; ++x)
- {
- g_pixel_buffer[y * disp_drv->hor_res + x] = lv_color_to32(*color_p);
- color_p++;
- }
- }
- #endif
- HDC hWindowDC = GetDC(g_window_handle);
- if (hWindowDC)
- {
- int PreviousMode = SetStretchBltMode(
- hWindowDC,
- HALFTONE);
- StretchBlt(
- hWindowDC,
- 0,
- 0,
- MulDiv(
- disp_drv->hor_res * WIN32DRV_MONITOR_ZOOM,
- g_dpi_value,
- USER_DEFAULT_SCREEN_DPI),
- MulDiv(
- disp_drv->ver_res * WIN32DRV_MONITOR_ZOOM,
- g_dpi_value,
- USER_DEFAULT_SCREEN_DPI),
- g_buffer_dc_handle,
- 0,
- 0,
- disp_drv->hor_res,
- disp_drv->ver_res,
- SRCCOPY);
- SetStretchBltMode(
- hWindowDC,
- PreviousMode);
- ReleaseDC(g_window_handle, hWindowDC);
- }
- lv_disp_flush_ready(disp_drv);
- }
- static void lv_win32_display_driver_rounder_callback(
- lv_disp_drv_t* disp_drv,
- lv_area_t* area)
- {
- area->x1 = 0;
- area->x2 = disp_drv->hor_res - 1;
- area->y1 = 0;
- area->y2 = disp_drv->ver_res - 1;
- }
- static void lv_win32_pointer_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data)
- {
- UNREFERENCED_PARAMETER(indev_drv);
- data->state = (lv_indev_state_t)(
- g_mouse_pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
- data->point.x = MulDiv(
- GET_X_LPARAM(g_mouse_value),
- USER_DEFAULT_SCREEN_DPI,
- WIN32DRV_MONITOR_ZOOM * g_dpi_value);
- data->point.y = MulDiv(
- GET_Y_LPARAM(g_mouse_value),
- USER_DEFAULT_SCREEN_DPI,
- WIN32DRV_MONITOR_ZOOM * g_dpi_value);
- if (data->point.x < 0)
- {
- data->point.x = 0;
- }
- if (data->point.x > g_display->driver->hor_res - 1)
- {
- data->point.x = g_display->driver->hor_res - 1;
- }
- if (data->point.y < 0)
- {
- data->point.y = 0;
- }
- if (data->point.y > g_display->driver->ver_res - 1)
- {
- data->point.y = g_display->driver->ver_res - 1;
- }
- }
- static void lv_win32_keypad_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data)
- {
- UNREFERENCED_PARAMETER(indev_drv);
- data->state = (lv_indev_state_t)(
- g_keyboard_pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
- WPARAM KeyboardValue = g_keyboard_value;
- switch (KeyboardValue)
- {
- case VK_UP:
- data->key = LV_KEY_UP;
- break;
- case VK_DOWN:
- data->key = LV_KEY_DOWN;
- break;
- case VK_LEFT:
- data->key = LV_KEY_LEFT;
- break;
- case VK_RIGHT:
- data->key = LV_KEY_RIGHT;
- break;
- case VK_ESCAPE:
- data->key = LV_KEY_ESC;
- break;
- case VK_DELETE:
- data->key = LV_KEY_DEL;
- break;
- case VK_BACK:
- data->key = LV_KEY_BACKSPACE;
- break;
- case VK_RETURN:
- data->key = LV_KEY_ENTER;
- break;
- case VK_NEXT:
- data->key = LV_KEY_NEXT;
- break;
- case VK_PRIOR:
- data->key = LV_KEY_PREV;
- break;
- case VK_HOME:
- data->key = LV_KEY_HOME;
- break;
- case VK_END:
- data->key = LV_KEY_END;
- break;
- default:
- if (KeyboardValue >= 'A' && KeyboardValue <= 'Z')
- {
- KeyboardValue += 0x20;
- }
- data->key = (uint32_t)KeyboardValue;
- break;
- }
- }
- static void lv_win32_encoder_driver_read_callback(
- lv_indev_drv_t* indev_drv,
- lv_indev_data_t* data)
- {
- UNREFERENCED_PARAMETER(indev_drv);
- data->state = (lv_indev_state_t)(
- g_mousewheel_pressed ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
- data->enc_diff = g_mousewheel_value;
- g_mousewheel_value = 0;
- }
- static LRESULT CALLBACK lv_win32_window_message_callback(
- HWND hWnd,
- UINT uMsg,
- WPARAM wParam,
- LPARAM lParam)
- {
- switch (uMsg)
- {
- case WM_MOUSEMOVE:
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_MBUTTONDOWN:
- case WM_MBUTTONUP:
- {
- g_mouse_value = lParam;
- if (uMsg == WM_LBUTTONDOWN || uMsg == WM_LBUTTONUP)
- {
- g_mouse_pressed = (uMsg == WM_LBUTTONDOWN);
- }
- else if (uMsg == WM_MBUTTONDOWN || uMsg == WM_MBUTTONUP)
- {
- g_mousewheel_pressed = (uMsg == WM_MBUTTONDOWN);
- }
- return 0;
- }
- case WM_KEYDOWN:
- case WM_KEYUP:
- {
- g_keyboard_pressed = (uMsg == WM_KEYDOWN);
- g_keyboard_value = wParam;
- break;
- }
- case WM_MOUSEWHEEL:
- {
- g_mousewheel_value = -(GET_WHEEL_DELTA_WPARAM(wParam) / WHEEL_DELTA);
- break;
- }
- case WM_TOUCH:
- {
- 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;
- }
- uint16_t x = (uint16_t)(Point.x & 0xffff);
- uint16_t y = (uint16_t)(Point.y & 0xffff);
- DWORD MousePressedMask =
- TOUCHEVENTF_MOVE | TOUCHEVENTF_DOWN;
- g_mouse_value = (y << 16) | x;
- g_mouse_pressed = (pInputs[i].dwFlags & MousePressedMask);
- }
- }
- free(pInputs);
- }
- lv_win32_close_touch_input_handle(hTouchInput);
- break;
- }
- case WM_DPICHANGED:
- {
- g_dpi_value = 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(
- g_display->driver->hor_res * WIN32DRV_MONITOR_ZOOM,
- g_dpi_value,
- USER_DEFAULT_SCREEN_DPI);
- int WindowHeight = MulDiv(
- g_display->driver->ver_res * WIN32DRV_MONITOR_ZOOM,
- g_dpi_value,
- 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_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProcW(hWnd, uMsg, wParam, lParam);
- }
- return 0;
- }
- static void lv_win32_message_handler(
- lv_timer_t* param)
- {
- UNREFERENCED_PARAMETER(param);
- MSG Message;
- BOOL Result = PeekMessageW(&Message, NULL, 0, 0, TRUE);
- if (Result != 0 && Result != -1)
- {
- TranslateMessage(&Message);
- DispatchMessageW(&Message);
- if (Message.message == WM_QUIT)
- {
- lv_win32_quit_signal = true;
- }
- }
- }
- #endif /*USE_WIN32DRV*/
|