1 /**
2  * @file lv_windows_display.c
3  *
4  */
5 
6 /*********************
7  *      INCLUDES
8  *********************/
9 
10 #include "lv_windows_display.h"
11 #if LV_USE_WINDOWS
12 
13 #include "lv_windows_context.h"
14 
15 #include <process.h>
16 
17 /*********************
18  *      DEFINES
19  *********************/
20 
21 /**********************
22  *      TYPEDEFS
23  **********************/
24 
25 /**********************
26  *  STATIC PROTOTYPES
27  **********************/
28 
29 static unsigned int __stdcall lv_windows_display_thread_entrypoint(
30     void * parameter);
31 
32 /**********************
33  *  STATIC VARIABLES
34  **********************/
35 
36 /**********************
37  *      MACROS
38  **********************/
39 
40 /**********************
41  *   GLOBAL FUNCTIONS
42  **********************/
43 
lv_windows_create_display(const wchar_t * title,int32_t hor_res,int32_t ver_res,int32_t zoom_level,bool allow_dpi_override,bool simulator_mode)44 lv_display_t * lv_windows_create_display(
45     const wchar_t * title,
46     int32_t hor_res,
47     int32_t ver_res,
48     int32_t zoom_level,
49     bool allow_dpi_override,
50     bool simulator_mode)
51 {
52     lv_windows_create_display_data_t data;
53 
54     lv_memzero(&data, sizeof(lv_windows_create_display_data_t));
55     data.title = title;
56     data.hor_res = hor_res;
57     data.ver_res = ver_res;
58     data.zoom_level = zoom_level;
59     data.allow_dpi_override = allow_dpi_override;
60     data.simulator_mode = simulator_mode;
61     data.mutex = CreateEventExW(NULL, NULL, 0, EVENT_ALL_ACCESS);
62     data.display = NULL;
63     if(!data.mutex) {
64         return NULL;
65     }
66 
67     HANDLE thread = (HANDLE)_beginthreadex(
68                         NULL,
69                         0,
70                         lv_windows_display_thread_entrypoint,
71                         &data,
72                         0,
73                         NULL);
74     LV_ASSERT(thread);
75 
76     WaitForSingleObjectEx(data.mutex, INFINITE, FALSE);
77 
78     if(thread) {
79         CloseHandle(thread);
80     }
81 
82     if(data.mutex) {
83         CloseHandle(data.mutex);
84     }
85 
86     return data.display;
87 }
88 
lv_windows_get_display_window_handle(lv_display_t * display)89 HWND lv_windows_get_display_window_handle(lv_display_t * display)
90 {
91     return (HWND)lv_display_get_driver_data(display);
92 }
93 
lv_windows_zoom_to_logical(int32_t physical,int32_t zoom_level)94 int32_t lv_windows_zoom_to_logical(int32_t physical, int32_t zoom_level)
95 {
96     return MulDiv(physical, LV_WINDOWS_ZOOM_BASE_LEVEL, zoom_level);
97 }
98 
lv_windows_zoom_to_physical(int32_t logical,int32_t zoom_level)99 int32_t lv_windows_zoom_to_physical(int32_t logical, int32_t zoom_level)
100 {
101     return MulDiv(logical, zoom_level, LV_WINDOWS_ZOOM_BASE_LEVEL);
102 }
103 
lv_windows_dpi_to_logical(int32_t physical,int32_t dpi)104 int32_t lv_windows_dpi_to_logical(int32_t physical, int32_t dpi)
105 {
106     return MulDiv(physical, USER_DEFAULT_SCREEN_DPI, dpi);
107 }
108 
lv_windows_dpi_to_physical(int32_t logical,int32_t dpi)109 int32_t lv_windows_dpi_to_physical(int32_t logical, int32_t dpi)
110 {
111     return MulDiv(logical, dpi, USER_DEFAULT_SCREEN_DPI);
112 }
113 
114 /**********************
115  *   STATIC FUNCTIONS
116  **********************/
117 
lv_windows_display_thread_entrypoint(void * parameter)118 static unsigned int __stdcall lv_windows_display_thread_entrypoint(
119     void * parameter)
120 {
121     lv_windows_create_display_data_t * data = parameter;
122     LV_ASSERT_NULL(data);
123 
124     DWORD window_style = WS_OVERLAPPEDWINDOW;
125     if(data->simulator_mode) {
126         window_style &= ~(WS_SIZEBOX | WS_MAXIMIZEBOX | WS_THICKFRAME);
127     }
128 
129     HWND window_handle = CreateWindowExW(
130                              WS_EX_CLIENTEDGE,
131                              L"LVGL.Window",
132                              data->title,
133                              window_style,
134                              CW_USEDEFAULT,
135                              0,
136                              data->hor_res,
137                              data->ver_res,
138                              NULL,
139                              NULL,
140                              NULL,
141                              data);
142     if(!window_handle) {
143         return 0;
144     }
145 
146     lv_windows_window_context_t * context = lv_windows_get_window_context(
147                                                 window_handle);
148     if(!context) {
149         return 0;
150     }
151 
152     data->display = context->display_device_object;
153 
154     ShowWindow(window_handle, SW_SHOW);
155     UpdateWindow(window_handle);
156 
157     LV_ASSERT(SetEvent(data->mutex));
158 
159     data = NULL;
160 
161     MSG message;
162     while(GetMessageW(&message, NULL, 0, 0)) {
163         TranslateMessage(&message);
164         DispatchMessageW(&message);
165     }
166 
167     return 0;
168 }
169 
170 #endif // LV_USE_WINDOWS
171