Updates to ensure compilation with Visual Studio
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / windows / platform-implement-win.cpp
1 /*\r
2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.\r
3 *\r
4 * Licensed under the Apache License, Version 2.0 (the "License");\r
5 * you may not use this file except in compliance with the License.\r
6 * You may obtain a copy of the License at\r
7 *\r
8 * http://www.apache.org/licenses/LICENSE-2.0\r
9 *\r
10 * Unless required by applicable law or agreed to in writing, software\r
11 * distributed under the License is distributed on an "AS IS" BASIS,\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13 * See the License for the specific language governing permissions and\r
14 * limitations under the License.\r
15 *\r
16 */\r
17 \r
18 // CLASS HEADER\r
19 #include <dali/internal/window-system/windows/platform-implement-win.h>\r
20 \r
21 // EXTERNAL INCLUDES\r
22 #include <map>\r
23 #include <windows.h>\r
24 \r
25 // INTERNAL INCLUDES\r
26 #include <dali/internal/window-system/windows/event-system-win.h>\r
27 \r
28 static constexpr float INCH = 25.4;\r
29 \r
30 using namespace std;\r
31 \r
32 namespace Dali
33 {
34
35 namespace Internal
36 {
37
38 namespace Adaptor
39 {
40 \r
41 namespace WindowsPlatformImplementation\r
42 {\r
43 \r
44 void RunLoop()\r
45 {\r
46   MSG nMsg = { 0 };\r
47 \r
48   while( GetMessage( &nMsg, 0, NULL, NULL ) )\r
49   {\r
50     if( WIN_CALLBACK_EVENT == nMsg.message )\r
51     {\r
52       Dali::CallbackBase *callback = ( Dali::CallbackBase* )nMsg.wParam;\r
53       Dali::CallbackBase::Execute( *callback );\r
54     }\r
55 \r
56     TranslateMessage( &nMsg );\r
57     DispatchMessage( &nMsg );\r
58 \r
59     if( WM_CLOSE == nMsg.message )\r
60     {\r
61       break;\r
62     }\r
63   }\r
64 }\r
65 \r
66 LRESULT CALLBACK WinProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )\r
67 {\r
68   WindowImpl::ProcWinMessge( reinterpret_cast<uint64_t>( hWnd ), uMsg, wParam, lParam );\r
69 \r
70   LRESULT ret = DefWindowProc( hWnd, uMsg, wParam, lParam );\r
71   return ret;\r
72 }\r
73 \r
74 std::map<uint64_t, WindowImpl*> mHWndToListener;\r
75 \r
76 WindowImpl::WindowImpl()\r
77 {\r
78   colorDepth = -1;\r
79   mHWnd = 0;\r
80   mHdc = 0;\r
81   listener = NULL;\r
82   windowStyle = WS_OVERLAPPED;\r
83 }\r
84 \r
85 WindowImpl::~WindowImpl()\r
86 {\r
87   mHWndToListener.erase( mHWnd );\r
88 }\r
89 \r
90 void WindowImpl::ProcWinMessge( uint64_t hWnd, uint32_t uMsg, uint64_t wParam, uint64_t lParam )\r
91 {\r
92   std::map<uint64_t, WindowImpl*>::iterator x = mHWndToListener.find( hWnd );\r
93 \r
94   if( mHWndToListener.end() != x )\r
95   {\r
96     CallbackBase* listener = x->second->listener;\r
97 \r
98     if( NULL != listener )\r
99     {\r
100       TWinEventInfo eventInfo( hWnd, uMsg, wParam, lParam );\r
101       CallbackBase::Execute( *listener, &eventInfo );\r
102     }\r
103   }\r
104 }\r
105 \r
106 void WindowImpl::GetDPI( float &xDpi, float &yDpi )\r
107 {\r
108   HDC hdcScreen = GetDC( reinterpret_cast<HWND>( mHWnd ) );\r
109 \r
110   int32_t iX = GetDeviceCaps( hdcScreen, HORZRES );    // pixel\r
111   int32_t iY = GetDeviceCaps( hdcScreen, VERTRES );    // pixel\r
112   int32_t iPhsX = GetDeviceCaps( hdcScreen, HORZSIZE );    // mm\r
113   int32_t iPhsY = GetDeviceCaps( hdcScreen, VERTSIZE );    // mm\r
114 \r
115   xDpi = static_cast<float>( iX ) / static_cast<float>( iPhsX ) * INCH;\r
116   yDpi = static_cast<float>( iY ) / static_cast<float>( iPhsY ) * INCH;\r
117 }\r
118 \r
119 int WindowImpl::GetColorDepth()\r
120 {\r
121   DALI_ASSERT_DEBUG( colorDepth >= 0 && "HWND hasn't been created, no color depth" );\r
122   return colorDepth;\r
123 }\r
124 \r
125 uint64_t WindowImpl::CreateHwnd(\r
126   _In_opt_ const char *lpClassName,\r
127   _In_opt_ const char *lpWindowName,\r
128   _In_ int X,\r
129   _In_ int Y,\r
130   _In_ int nWidth,\r
131   _In_ int nHeight,\r
132   _In_opt_ uint64_t parent )\r
133 {\r
134   WNDCLASS cs = { 0 };\r
135   cs.cbClsExtra = 0;\r
136   cs.cbWndExtra = 0;\r
137   cs.hbrBackground = (HBRUSH)( COLOR_WINDOW + 2 );\r
138   cs.hCursor = NULL;\r
139   cs.hIcon = NULL;\r
140   cs.hInstance = GetModuleHandle( NULL );\r
141   cs.lpfnWndProc = (WNDPROC)WinProc;\r
142   cs.lpszClassName = lpClassName;\r
143   cs.lpszMenuName = NULL;\r
144   cs.style = CS_VREDRAW | CS_HREDRAW;\r
145   RegisterClass( &cs );\r
146 \r
147   HWND hWnd = CreateWindow( lpClassName, lpWindowName, windowStyle, X, Y, nWidth + 2 * GetEdgeWidth(), nHeight + 2 * GetEdgeHeight(), NULL, NULL, cs.hInstance, NULL );\r
148   ::ShowWindow( hWnd, SW_SHOW );\r
149 \r
150   SetHWND( reinterpret_cast<uint64_t>(hWnd) );\r
151 \r
152   return mHWnd;\r
153 }\r
154 \r
155 void WindowImpl::SetListener( CallbackBase *callback )\r
156 {\r
157   listener = callback;\r
158 }\r
159 \r
160 bool WindowImpl::PostWinMessage(\r
161   _In_ uint32_t Msg,\r
162   _In_ uint32_t wParam,\r
163   _In_ uint64_t lParam )\r
164 {\r
165   return (bool)PostMessage( reinterpret_cast<HWND>( mHWnd ), Msg, wParam, lParam );\r
166 }\r
167 \r
168 int32_t WindowImpl::GetEdgeWidth()\r
169 {\r
170   switch( windowStyle )\r
171   {\r
172   case WS_OVERLAPPED:\r
173   {\r
174     return 8;\r
175   }\r
176   default:\r
177   {\r
178     return 0;\r
179   }\r
180   }\r
181 }\r
182 \r
183 int32_t WindowImpl::GetEdgeHeight()\r
184 {\r
185   switch( windowStyle )\r
186   {\r
187   case WS_OVERLAPPED:\r
188   {\r
189     return 18;\r
190   }\r
191   default:\r
192   {\r
193     return 0;\r
194   }\r
195   }\r
196 }\r
197 \r
198 void WindowImpl::SetHWND( uint64_t inHWnd )\r
199 {\r
200   if( mHWnd != inHWnd )\r
201   {\r
202     mHWnd = inHWnd;\r
203     mHdc = reinterpret_cast<uint64_t>( GetDC( reinterpret_cast<HWND>( mHWnd ) ) );\r
204     colorDepth = GetDeviceCaps( reinterpret_cast<HDC>( mHdc ), BITSPIXEL ) * GetDeviceCaps( reinterpret_cast<HDC>( mHdc ), PLANES );\r
205 \r
206     std::map<uint64_t, WindowImpl*>::iterator x = mHWndToListener.find( mHWnd );\r
207 \r
208     if( mHWndToListener.end() == x )\r
209     {\r
210       mHWndToListener.insert( std::make_pair( mHWnd, this ) );\r
211     }\r
212     else\r
213     {\r
214       x->second = this;\r
215     }\r
216   }\r
217 }\r
218 \r
219 bool PostWinThreadMessage(\r
220   _In_ uint32_t Msg,\r
221   _In_ uint32_t wParam,\r
222   _In_ uint64_t lParam,\r
223   _In_ uint64_t threadID/* = -1*/ )\r
224 {\r
225   if( -1 == threadID )\r
226   {\r
227     threadID = GetCurrentThreadId();\r
228   }\r
229 \r
230   return (bool)PostThreadMessage( threadID, Msg, wParam, lParam );\r
231 }\r
232 \r
233 struct TTimerCallbackInfo\r
234 {\r
235   void *data;\r
236   timerCallback callback;\r
237   HWND hWnd;\r
238 };\r
239 \r
240 void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT_PTR nTimerid, DWORD dwTime)\r
241 {\r
242   TTimerCallbackInfo *info = (TTimerCallbackInfo*)nTimerid;\r
243   info->callback( info->data );\r
244 }\r
245 \r
246 int SetTimer(int interval, timerCallback callback, void *data)\r
247 {\r
248   TTimerCallbackInfo *callbackInfo = new TTimerCallbackInfo;\r
249   callbackInfo->data = data;\r
250   callbackInfo->callback = callback;\r
251   callbackInfo->hWnd = ::GetActiveWindow();\r
252 \r
253   UINT_PTR timerID = (UINT_PTR)callbackInfo;\r
254   ::SetTimer( callbackInfo->hWnd, timerID, interval, TimerProc );\r
255 \r
256   return timerID;\r
257 }\r
258 \r
259 void KillTimer(int id)\r
260 {\r
261   TTimerCallbackInfo *info = (TTimerCallbackInfo*)id;\r
262   ::KillTimer( info->hWnd, id );\r
263   delete info;\r
264 }\r
265 \r
266 const char* GetKeyName( int keyCode )\r
267 {\r
268   switch( keyCode )\r
269   {\r
270     case VK_BACK:\r
271     {\r
272       return "Backspace";\r
273     }\r
274     case VK_TAB:\r
275     {\r
276       return "Tab";\r
277     }\r
278     case VK_RETURN:\r
279     {\r
280       return "Return";\r
281     }\r
282     case VK_ESCAPE:\r
283     {\r
284       return "Escape";\r
285     }\r
286     case VK_SPACE:\r
287     {\r
288       return "Space";\r
289     }\r
290     case VK_LEFT:\r
291     {\r
292       return "Left";\r
293     }\r
294     case VK_UP:\r
295     {\r
296       return "Up";\r
297     }\r
298     case VK_RIGHT:\r
299     {\r
300       return "Right";\r
301     }\r
302     case VK_DOWN:\r
303     {\r
304       return "Down";\r
305     }\r
306     case 48:\r
307     {\r
308       return "0";\r
309     }\r
310     case 49:\r
311     {\r
312       return "1";\r
313     }\r
314     case 50:\r
315     {\r
316       return "2";\r
317     }\r
318     case 51:\r
319     {\r
320       return "3";\r
321     }\r
322     case 52:\r
323     {\r
324       return "4";\r
325     }\r
326     case 53:\r
327     {\r
328       return "5";\r
329     }\r
330     case 54:\r
331     {\r
332       return "6";\r
333     }\r
334     case 55:\r
335     {\r
336       return "7";\r
337     }\r
338     case 56:\r
339     {\r
340       return "8";\r
341     }\r
342     case 57:\r
343     {\r
344       return "9";\r
345     }\r
346     default:\r
347     {\r
348       break;\r
349     }\r
350   }\r
351 \r
352   return "";\r
353 }\r
354
355 static LARGE_INTEGER cpuFrequency;\r
356 static LARGE_INTEGER *pCpuFrequency = NULL;\r
357 \r
358 uint64_t GetCurrentThreadId()\r
359 {\r
360   return ::GetCurrentThreadId();\r
361 }\r
362 \r
363 void GetNanoseconds( uint64_t& timeInNanoseconds )\r
364 {\r
365   if( NULL == pCpuFrequency )\r
366   {\r
367     pCpuFrequency = &cpuFrequency;\r
368     QueryPerformanceFrequency( pCpuFrequency );\r
369   }\r
370 \r
371   LARGE_INTEGER curTime;\r
372   QueryPerformanceCounter( &curTime );\r
373 \r
374   timeInNanoseconds = static_cast<double>(curTime.QuadPart) / static_cast<double>(pCpuFrequency->QuadPart) * 1000000000;\r
375 }\r
376 \r
377 unsigned int GetCurrentMilliSeconds( void )\r
378 {\r
379   if( NULL == pCpuFrequency )\r
380   {\r
381     pCpuFrequency = &cpuFrequency;\r
382     QueryPerformanceFrequency( pCpuFrequency );\r
383   }\r
384 \r
385   LARGE_INTEGER curTime;\r
386   QueryPerformanceCounter( &curTime );\r
387 \r
388   return curTime.QuadPart * 1000 / pCpuFrequency->QuadPart;\r
389 }\r
390
391 } // namespace WindowsPlatformImplement
392
393 } // namespace Adaptor
394
395 } // namespace internal
396
397 } // namespace Dali\r