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