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