2 * Copyright (c) 2023 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include <dali/internal/window-system/windows/platform-implement-win.h>
26 #include <dali/internal/window-system/windows/event-system-win.h>
30 constexpr float INCH = 25.4;
39 namespace WindowsPlatform
41 LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
43 WindowImpl::ProcWinMessage(reinterpret_cast<uint64_t>(hWnd), uMsg, wParam, lParam);
45 LRESULT ret = DefWindowProc(hWnd, uMsg, wParam, lParam);
51 const char* DALI_WINDOW_CLASS_NAME = "DaliWindow";
53 uint32_t sNumWindows = 0;
55 void EnsureWindowClassRegistered()
62 cs.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
65 cs.hInstance = GetModuleHandle(NULL);
66 cs.lpfnWndProc = (WNDPROC)WinProc;
67 cs.lpszClassName = DALI_WINDOW_CLASS_NAME.c_str();
68 cs.lpszMenuName = NULL;
69 cs.style = CS_VREDRAW | CS_HREDRAW;
74 void EnsureWindowClassUnregistered()
78 UnregisterClass(DALI_WINDOW_CLASS_NAME.c_str(), GetModuleHandle(NULL));
82 std::map<uint64_t, WindowImpl*> sHWndToListener;
84 void RemoveListener(uint64_t hWnd)
86 std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find(hWnd);
87 if(sHWndToListener.end() != x)
89 sHWndToListener.erase(x);
95 const uint32_t WindowImpl::STYLE = WS_OVERLAPPED;
96 const int32_t WindowImpl::EDGE_WIDTH = 8;
97 const int32_t WindowImpl::EDGE_HEIGHT = 18;
99 WindowImpl::WindowImpl()
107 WindowImpl::~WindowImpl()
109 RemoveListener(mHWnd);
112 void WindowImpl::ProcWinMessage(uint64_t hWnd, uint32_t uMsg, uint64_t wParam, uint64_t lParam)
114 std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find(hWnd);
116 if(sHWndToListener.end() != x)
118 CallbackBase* listener = x->second->listener;
122 TWinEventInfo eventInfo(hWnd, uMsg, wParam, lParam);
123 CallbackBase::Execute(*listener, &eventInfo);
128 void WindowImpl::GetDPI(float& xDpi, float& yDpi)
130 HDC hdcScreen = GetDC(reinterpret_cast<HWND>(mHWnd));
132 int32_t iX = GetDeviceCaps(hdcScreen, HORZRES); // pixel
133 int32_t iY = GetDeviceCaps(hdcScreen, VERTRES); // pixel
134 int32_t iPhsX = GetDeviceCaps(hdcScreen, HORZSIZE); // mm
135 int32_t iPhsY = GetDeviceCaps(hdcScreen, VERTSIZE); // mm
137 xDpi = static_cast<float>(iX) / static_cast<float>(iPhsX) * INCH;
138 yDpi = static_cast<float>(iY) / static_cast<float>(iPhsY) * INCH;
141 int WindowImpl::GetColorDepth()
143 DALI_ASSERT_DEBUG(colorDepth >= 0 && "HWND hasn't been created, no color depth");
147 uint64_t WindowImpl::CreateHwnd(
148 _In_opt_ const char* lpWindowName,
153 _In_opt_ uint64_t parent)
155 EnsureWindowClassRegistered();
158 HWND hWnd = CreateWindow(DALI_WINDOW_CLASS_NAME.c_str(), lpWindowName, STYLE, X, Y, nWidth + 2 * EDGE_WIDTH, nHeight + 2 * EDGE_HEIGHT, NULL, NULL, GetModuleHandle(NULL), NULL);
159 ::ShowWindow(hWnd, SW_SHOW);
161 return reinterpret_cast<uint64_t>(hWnd);
164 void WindowImpl::DestroyHWnd(uint64_t hWnd)
168 ::DestroyWindow(reinterpret_cast<HWND>(hWnd));
171 EnsureWindowClassUnregistered();
175 void WindowImpl::SetListener(CallbackBase* callback)
180 bool WindowImpl::PostWinMessage(
182 _In_ uint64_t wParam,
183 _In_ uint64_t lParam)
185 return (bool)PostMessage(reinterpret_cast<HWND>(mHWnd), Msg, wParam, lParam);
188 void WindowImpl::SetHWND(uint64_t inHWnd)
192 RemoveListener(mHWnd);
195 mHdc = reinterpret_cast<uint64_t>(GetDC(reinterpret_cast<HWND>(mHWnd)));
196 colorDepth = GetDeviceCaps(reinterpret_cast<HDC>(mHdc), BITSPIXEL) * GetDeviceCaps(reinterpret_cast<HDC>(mHdc), PLANES);
198 std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find(mHWnd);
199 if(sHWndToListener.end() == x)
201 sHWndToListener.insert(std::make_pair(mHWnd, this));
210 void WindowImpl::SetWinProc()
212 // Sets the WinProc function.
213 LONG_PTR ret = SetWindowLongPtr((HWND)mHWnd,
215 reinterpret_cast<LONG_PTR>(&WinProc));
219 DWORD error = GetLastError();
223 HMODULE module = GetModuleHandle(nullptr);
224 ret = SetWindowLongPtr((HWND)mHWnd,
226 reinterpret_cast<LONG_PTR>(&module));
229 bool PostWinThreadMessage(
231 _In_ uint64_t wParam,
232 _In_ uint64_t lParam,
233 _In_ uint64_t threadID /* = -1*/)
237 threadID = GetCurrentThreadId();
240 return (bool)PostThreadMessage(threadID, Msg, wParam, lParam);
243 struct TTimerCallbackInfo
246 timerCallback callback;
250 void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT_PTR nTimerid, DWORD dwTime)
252 TTimerCallbackInfo* info = (TTimerCallbackInfo*)nTimerid;
253 info->callback(info->data);
256 intptr_t SetTimer(int interval, timerCallback callback, void* data)
258 HWND hwnd = GetActiveWindow();
261 hwnd = FindWindow(DALI_WINDOW_CLASS_NAME.c_str(), nullptr);
269 TTimerCallbackInfo* callbackInfo = new TTimerCallbackInfo;
270 callbackInfo->data = data;
271 callbackInfo->callback = callback;
272 callbackInfo->hWnd = hwnd;
274 INT_PTR timerID = (INT_PTR)callbackInfo;
275 ::SetTimer(hwnd, timerID, interval, TimerProc);
280 void KillTimer(intptr_t id)
282 TTimerCallbackInfo* info = (TTimerCallbackInfo*)id;
283 ::KillTimer(info->hWnd, id);
287 std::string GetKeyName(int keyCode)
369 if(keyCode > 0 && keyCode < 128)
371 return std::string(1u, static_cast<char>(keyCode));
380 static LARGE_INTEGER cpuFrequency;
381 static LARGE_INTEGER* pCpuFrequency = NULL;
383 uint64_t GetCurrentThreadId()
385 return ::GetCurrentThreadId();
388 void GetNanoseconds(uint64_t& timeInNanoseconds)
390 if(NULL == pCpuFrequency)
392 pCpuFrequency = &cpuFrequency;
393 QueryPerformanceFrequency(pCpuFrequency);
396 LARGE_INTEGER curTime;
397 QueryPerformanceCounter(&curTime);
399 timeInNanoseconds = static_cast<double>(curTime.QuadPart) / static_cast<double>(pCpuFrequency->QuadPart) * 1000000000;
402 unsigned int GetCurrentMilliSeconds(void)
404 if(NULL == pCpuFrequency)
406 pCpuFrequency = &cpuFrequency;
407 QueryPerformanceFrequency(pCpuFrequency);
410 LARGE_INTEGER curTime;
411 QueryPerformanceCounter(&curTime);
413 return curTime.QuadPart * 1000 / pCpuFrequency->QuadPart;
416 } // namespace WindowsPlatform
418 } // namespace Adaptor
420 } // namespace Internal