2 * Copyright (c) 2018 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;
42 namespace WindowsPlatform
45 LRESULT CALLBACK WinProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
47 WindowImpl::ProcWinMessage( reinterpret_cast<uint64_t>( hWnd ), uMsg, wParam, lParam );
49 LRESULT ret = DefWindowProc( hWnd, uMsg, wParam, lParam );
56 const std::string DALI_WINDOW_CLASS_NAME = "DaliWindow";
58 uint32_t sNumWindows = 0;
60 void EnsureWindowClassRegistered()
67 cs.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
70 cs.hInstance = GetModuleHandle(NULL);
71 cs.lpfnWndProc = (WNDPROC)WinProc;
72 cs.lpszClassName = DALI_WINDOW_CLASS_NAME.c_str();
73 cs.lpszMenuName = NULL;
74 cs.style = CS_VREDRAW | CS_HREDRAW;
79 void EnsureWindowClassUnregistered()
83 UnregisterClass(DALI_WINDOW_CLASS_NAME.c_str(), GetModuleHandle(NULL));
87 std::map<uint64_t, WindowImpl*> sHWndToListener;
89 void RemoveListener(uint64_t hWnd)
91 std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find(hWnd);
92 if (sHWndToListener.end() != x)
94 sHWndToListener.erase(x);
100 const uint32_t WindowImpl::STYLE = WS_OVERLAPPED;
101 const int32_t WindowImpl::EDGE_WIDTH = 8;
102 const int32_t WindowImpl::EDGE_HEIGHT = 18;
104 WindowImpl::WindowImpl()
112 WindowImpl::~WindowImpl()
114 RemoveListener(mHWnd);
117 void WindowImpl::ProcWinMessage( uint64_t hWnd, uint32_t uMsg, uint64_t wParam, uint64_t lParam )
119 std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find( hWnd );
121 if( sHWndToListener.end() != x )
123 CallbackBase* listener = x->second->listener;
125 if( NULL != listener )
127 TWinEventInfo eventInfo( hWnd, uMsg, wParam, lParam );
128 CallbackBase::Execute( *listener, &eventInfo );
133 void WindowImpl::GetDPI( float &xDpi, float &yDpi )
135 HDC hdcScreen = GetDC( reinterpret_cast<HWND>( mHWnd ) );
137 int32_t iX = GetDeviceCaps( hdcScreen, HORZRES ); // pixel
138 int32_t iY = GetDeviceCaps( hdcScreen, VERTRES ); // pixel
139 int32_t iPhsX = GetDeviceCaps( hdcScreen, HORZSIZE ); // mm
140 int32_t iPhsY = GetDeviceCaps( hdcScreen, VERTSIZE ); // mm
142 xDpi = static_cast<float>( iX ) / static_cast<float>( iPhsX ) * INCH;
143 yDpi = static_cast<float>( iY ) / static_cast<float>( iPhsY ) * INCH;
146 int WindowImpl::GetColorDepth()
148 DALI_ASSERT_DEBUG( colorDepth >= 0 && "HWND hasn't been created, no color depth" );
152 uint64_t WindowImpl::CreateHwnd(
153 _In_opt_ const char *lpWindowName,
158 _In_opt_ uint64_t parent )
160 EnsureWindowClassRegistered();
163 HWND hWnd = CreateWindow( DALI_WINDOW_CLASS_NAME.c_str(), lpWindowName, STYLE, X, Y,
164 nWidth + 2 * EDGE_WIDTH, nHeight + 2 * EDGE_HEIGHT, NULL, NULL, GetModuleHandle(NULL), NULL );
165 ::ShowWindow( hWnd, SW_SHOW );
167 return reinterpret_cast<uint64_t>(hWnd);
170 void WindowImpl::DestroyHWnd(uint64_t hWnd)
174 ::DestroyWindow(reinterpret_cast<HWND>(hWnd));
177 EnsureWindowClassUnregistered();
181 void WindowImpl::SetListener( CallbackBase *callback )
186 bool WindowImpl::PostWinMessage(
188 _In_ uint64_t wParam,
189 _In_ uint64_t lParam )
191 return (bool)PostMessage( reinterpret_cast<HWND>( mHWnd ), Msg, wParam, lParam );
194 void WindowImpl::SetHWND( uint64_t inHWnd )
198 RemoveListener(mHWnd);
201 mHdc = reinterpret_cast<uint64_t>(GetDC(reinterpret_cast<HWND>(mHWnd)));
202 colorDepth = GetDeviceCaps(reinterpret_cast<HDC>(mHdc), BITSPIXEL) * GetDeviceCaps(reinterpret_cast<HDC>(mHdc), PLANES);
204 std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find(mHWnd);
205 if (sHWndToListener.end() == x)
207 sHWndToListener.insert(std::make_pair(mHWnd, this));
216 void WindowImpl::SetWinProc()
218 // Sets the WinProc function.
219 LONG_PTR ret = SetWindowLongPtr((HWND)mHWnd,
221 reinterpret_cast<LONG_PTR>(&WinProc));
225 DWORD error = GetLastError();
229 HMODULE module = GetModuleHandle(nullptr);
230 ret = SetWindowLongPtr((HWND)mHWnd,
232 reinterpret_cast<LONG_PTR>(&module));
235 bool PostWinThreadMessage(
237 _In_ uint64_t wParam,
238 _In_ uint64_t lParam,
239 _In_ uint64_t threadID/* = -1*/ )
243 threadID = GetCurrentThreadId();
246 return (bool)PostThreadMessage( threadID, Msg, wParam, lParam );
249 struct TTimerCallbackInfo
252 timerCallback callback;
256 void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT_PTR nTimerid, DWORD dwTime)
258 TTimerCallbackInfo *info = (TTimerCallbackInfo*)nTimerid;
259 info->callback( info->data );
262 intptr_t SetTimer(int interval, timerCallback callback, void *data)
264 HWND hwnd = GetActiveWindow();
267 hwnd = FindWindow(DALI_WINDOW_CLASS_NAME.c_str(), nullptr);
275 TTimerCallbackInfo *callbackInfo = new TTimerCallbackInfo;
276 callbackInfo->data = data;
277 callbackInfo->callback = callback;
278 callbackInfo->hWnd = hwnd;
280 INT_PTR timerID = (INT_PTR)callbackInfo;
281 ::SetTimer( hwnd, timerID, interval, TimerProc );
286 void KillTimer(intptr_t id)
288 TTimerCallbackInfo *info = (TTimerCallbackInfo*)id;
289 ::KillTimer( info->hWnd, id );
293 std::string GetKeyName( int keyCode )
375 if (keyCode > 0 && keyCode < 128)
377 return std::string(1u, static_cast<char>(keyCode));
386 static LARGE_INTEGER cpuFrequency;
387 static LARGE_INTEGER *pCpuFrequency = NULL;
389 uint64_t GetCurrentThreadId()
391 return ::GetCurrentThreadId();
394 void GetNanoseconds( uint64_t& timeInNanoseconds )
396 if( NULL == pCpuFrequency )
398 pCpuFrequency = &cpuFrequency;
399 QueryPerformanceFrequency( pCpuFrequency );
402 LARGE_INTEGER curTime;
403 QueryPerformanceCounter( &curTime );
405 timeInNanoseconds = static_cast<double>(curTime.QuadPart) / static_cast<double>(pCpuFrequency->QuadPart) * 1000000000;
408 unsigned int GetCurrentMilliSeconds( void )
410 if( NULL == pCpuFrequency )
412 pCpuFrequency = &cpuFrequency;
413 QueryPerformanceFrequency( pCpuFrequency );
416 LARGE_INTEGER curTime;
417 QueryPerformanceCounter( &curTime );
419 return curTime.QuadPart * 1000 / pCpuFrequency->QuadPart;
422 } // namespace WindowsPlatformImplement
424 } // namespace Adaptor
426 } // namespace internal