[Tizen] Add a flag to check whether it is forced to enable
[platform/core/uifw/dali-adaptor.git] / dali / internal / window-system / windows / platform-implement-win.cpp
index e6075f3..3e51425 100755 (executable)
 #include <dali/internal/window-system/windows/platform-implement-win.h>
 
 // EXTERNAL INCLUDES
+#include <map>
 #include <windows.h>
 
 // INTERNAL INCLUDES
 #include <dali/internal/window-system/windows/event-system-win.h>
 
-static constexpr float INCH = 25.4;
-
-using namespace std;
+namespace
+{
+constexpr float INCH = 25.4;
+}
 
 namespace Dali
 {
@@ -37,34 +39,100 @@ namespace Internal
 namespace Adaptor
 {
 
-namespace WindowsPlatformImplementation
+namespace WindowsPlatform
+{
+
+LRESULT CALLBACK WinProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
+{
+  WindowImpl::ProcWinMessage( reinterpret_cast<uint64_t>( hWnd ), uMsg, wParam, lParam );
+
+  LRESULT ret = DefWindowProc( hWnd, uMsg, wParam, lParam );
+  return ret;
+}
+
+namespace
 {
 
-void RunLoop()
+const std::string DALI_WINDOW_CLASS_NAME = "DaliWindow";
+
+uint32_t sNumWindows = 0;
+
+void EnsureWindowClassRegistered()
 {
-  MSG nMsg = { 0 };
+  if (sNumWindows == 0)
+  {
+    WNDCLASS cs = { 0 };
+    cs.cbClsExtra = 0;
+    cs.cbWndExtra = 0;
+    cs.hbrBackground = (HBRUSH)(COLOR_WINDOW + 2);
+    cs.hCursor = NULL;
+    cs.hIcon = NULL;
+    cs.hInstance = GetModuleHandle(NULL);
+    cs.lpfnWndProc = (WNDPROC)WinProc;
+    cs.lpszClassName = DALI_WINDOW_CLASS_NAME.c_str();
+    cs.lpszMenuName = NULL;
+    cs.style = CS_VREDRAW | CS_HREDRAW;
+    RegisterClass(&cs);
+  }
+}
 
-  while( GetMessage( &nMsg, 0, NULL, NULL ) )
+void EnsureWindowClassUnregistered()
+{
+  if (sNumWindows == 0)
   {
-    if( WIN_CALLBACK_EVENT == nMsg.message )
-    {
-      Dali::CallbackBase *callback = ( Dali::CallbackBase* )nMsg.wParam;
-      Dali::CallbackBase::Execute( *callback );
-    }
+    UnregisterClass(DALI_WINDOW_CLASS_NAME.c_str(), GetModuleHandle(NULL));
+  }
+}
 
-    TranslateMessage( &nMsg );
-    DispatchMessage( &nMsg );
+std::map<uint64_t, WindowImpl*> sHWndToListener;
 
-    if( WM_CLOSE == nMsg.message )
+void RemoveListener(uint64_t hWnd)
+{
+  std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find(hWnd);
+  if (sHWndToListener.end() != x)
+  {
+    sHWndToListener.erase(x);
+  }
+}
+
+}
+
+const uint32_t WindowImpl::STYLE = WS_OVERLAPPED;
+const int32_t WindowImpl::EDGE_WIDTH = 8;
+const int32_t WindowImpl::EDGE_HEIGHT = 18;
+
+WindowImpl::WindowImpl()
+{
+  colorDepth = -1;
+  mHWnd = 0;
+  mHdc = 0;
+  listener = NULL;
+}
+
+WindowImpl::~WindowImpl()
+{
+  RemoveListener(mHWnd);
+}
+
+void WindowImpl::ProcWinMessage( uint64_t hWnd, uint32_t uMsg, uint64_t wParam, uint64_t lParam )
+{
+  std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find( hWnd );
+
+  if( sHWndToListener.end() != x )
+  {
+    CallbackBase* listener = x->second->listener;
+
+    if( NULL != listener )
     {
-      break;
+      TWinEventInfo eventInfo( hWnd, uMsg, wParam, lParam );
+      CallbackBase::Execute( *listener, &eventInfo );
     }
   }
 }
 
-void GetDPI( uint64_t hWnd, float &xDpi, float &yDpi )
+void WindowImpl::GetDPI( float &xDpi, float &yDpi )
 {
-  HDC hdcScreen = GetDC( reinterpret_cast<HWND>( hWnd ) );
+  HDC hdcScreen = GetDC( reinterpret_cast<HWND>( mHWnd ) );
 
   int32_t iX = GetDeviceCaps( hdcScreen, HORZRES );    // pixel
   int32_t iY = GetDeviceCaps( hdcScreen, VERTRES );    // pixel
@@ -75,140 +143,100 @@ void GetDPI( uint64_t hWnd, float &xDpi, float &yDpi )
   yDpi = static_cast<float>( iY ) / static_cast<float>( iPhsY ) * INCH;
 }
 
-int GetOrientation()
+int WindowImpl::GetColorDepth()
 {
-  return 0;
+  DALI_ASSERT_DEBUG( colorDepth >= 0 && "HWND hasn't been created, no color depth" );
+  return colorDepth;
 }
 
-CallbackBase *listener = NULL;
+uint64_t WindowImpl::CreateHwnd(
+  _In_opt_ const char *lpWindowName,
+  _In_ int X,
+  _In_ int Y,
+  _In_ int nWidth,
+  _In_ int nHeight,
+  _In_opt_ uint64_t parent )
+{
+  EnsureWindowClassRegistered();
+  ++sNumWindows;
 
-LRESULT CALLBACK WinProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
+  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 );
+  ::ShowWindow( hWnd, SW_SHOW );
+
+  return reinterpret_cast<uint64_t>(hWnd);
+}
+
+void WindowImpl::DestroyHWnd(uint64_t hWnd)
 {
-  if( NULL != listener )
+  if (hWnd != 0)
   {
-    TWinEventInfo eventInfo( reinterpret_cast<uint64_t>( hWnd ), uMsg, wParam, lParam);
-    CallbackBase::Execute( *listener, &eventInfo );
-  }
+    ::DestroyWindow(reinterpret_cast<HWND>(hWnd));
 
-  LRESULT ret = DefWindowProc( hWnd, uMsg, wParam, lParam );
-  return ret;
+    --sNumWindows;
+    EnsureWindowClassUnregistered();
+  }
 }
 
-DWORD windowStyle = WS_OVERLAPPED;
+void WindowImpl::SetListener( CallbackBase *callback )
+{
+  listener = callback;
+}
 
-int32_t GetEdgeWidth()
+bool WindowImpl::PostWinMessage(
+  _In_ uint32_t Msg,
+  _In_ uint64_t wParam,
+  _In_ uint64_t lParam )
 {
-  switch( windowStyle )
-  {
-    case WS_OVERLAPPED:
-    {
-      return 8;
-    }
-    default:
-    {
-      return 0;
-    }
-  }
+  return (bool)PostMessage( reinterpret_cast<HWND>( mHWnd ), Msg, wParam, lParam );
 }
 
-int32_t GetEdgeHeight()
+void WindowImpl::SetHWND( uint64_t inHWnd )
 {
-  switch( windowStyle )
+  if (mHWnd != inHWnd)
   {
-    case WS_OVERLAPPED:
+    RemoveListener(mHWnd);
+
+    mHWnd = inHWnd;
+    mHdc = reinterpret_cast<uint64_t>(GetDC(reinterpret_cast<HWND>(mHWnd)));
+    colorDepth = GetDeviceCaps(reinterpret_cast<HDC>(mHdc), BITSPIXEL) * GetDeviceCaps(reinterpret_cast<HDC>(mHdc), PLANES);
+
+    std::map<uint64_t, WindowImpl*>::iterator x = sHWndToListener.find(mHWnd);
+    if (sHWndToListener.end() == x)
     {
-      return 18;
+      sHWndToListener.insert(std::make_pair(mHWnd, this));
     }
-    default:
+    else
     {
-      return 0;
+      x->second = this;
     }
   }
 }
 
-class WindowsDisplayInfo
+void WindowImpl::SetWinProc()
 {
-public:
-  static int GetColorDepth()
-  {
-    DALI_ASSERT_DEBUG(colorDepth >= 0 && "HWND hasn't been created, no color depth");
-    return colorDepth;
-  }
+  // Sets the WinProc function.
+  LONG_PTR ret = SetWindowLongPtr((HWND)mHWnd,
+                                  GWLP_WNDPROC,
+                                  reinterpret_cast<LONG_PTR>(&WinProc));
 
-  static void SetHWND( HWND inHWnd )
+  if (0 == ret)
   {
-    if( hWnd != inHWnd )
-    {
-      hWnd = inHWnd;
-      hdc = GetDC( hWnd );
-      colorDepth = GetDeviceCaps( WindowsDisplayInfo::hdc, BITSPIXEL ) * GetDeviceCaps( WindowsDisplayInfo::hdc, PLANES );
-    }
+    DWORD error = GetLastError();
+    return;
   }
 
-private:
-  static int colorDepth;
-  static HWND hWnd;
-  static HDC hdc;
-};
-
-int WindowsDisplayInfo::colorDepth = -1;
-HWND WindowsDisplayInfo::hWnd = NULL;
-HDC WindowsDisplayInfo::hdc = NULL;
-
-int GetColorDepth()
-{
-  return WindowsDisplayInfo::GetColorDepth();
-}
-
-uint64_t CreateHwnd(
-    _In_opt_ const char *lpClassName,
-    _In_opt_ const char *lpWindowName,
-    _In_ int X,
-    _In_ int Y,
-    _In_ int nWidth,
-    _In_ int nHeight,
-    _In_opt_ uint64_t parent)
-{
-  WNDCLASS cs = { 0 };
-  cs.cbClsExtra = 0;
-  cs.cbWndExtra = 0;
-  cs.hbrBackground = (HBRUSH)( COLOR_WINDOW + 2 );
-  cs.hCursor = NULL;
-  cs.hIcon = NULL;
-  cs.hInstance = GetModuleHandle( NULL );
-  cs.lpfnWndProc = (WNDPROC)WinProc;
-  cs.lpszClassName = lpClassName;
-  cs.lpszMenuName = NULL;
-  cs.style = CS_VREDRAW | CS_HREDRAW;
-  RegisterClass( &cs );
-
-  HWND hWnd = CreateWindow( lpClassName, lpWindowName, windowStyle, X, Y, nWidth + 2 * GetEdgeWidth(), nHeight + 2 * GetEdgeHeight(), NULL, NULL, cs.hInstance, NULL );
-  ShowWindow( hWnd, SW_SHOW );
-
-  WindowsDisplayInfo::SetHWND( hWnd );
-
-  return reinterpret_cast<uint64_t>( hWnd );
-}
-
-void SetListener( CallbackBase *callback )
-{
-  listener = callback;
-}
-
-bool PostWinMessage(
-    _In_ uint32_t Msg,
-    _In_ uint32_t wParam,
-    _In_ uint64_t lParam,
-    _In_ uint64_t hWnd)
-{
-  return (bool)PostMessage( reinterpret_cast<HWND>( hWnd ), Msg, wParam, lParam );
+  HMODULE module = GetModuleHandle(nullptr);
+  ret = SetWindowLongPtr((HWND)mHWnd,
+                         GWLP_HINSTANCE,
+                         reinterpret_cast<LONG_PTR>(&module));
 }
 
 bool PostWinThreadMessage(
-    _In_ uint32_t Msg,
-    _In_ uint32_t wParam,
-    _In_ uint64_t lParam,
-    _In_ uint64_t threadID/* = -1*/ )
+  _In_ uint32_t Msg,
+  _In_ uint64_t wParam,
+  _In_ uint64_t lParam,
+  _In_ uint64_t threadID/* = -1*/ )
 {
   if( -1 == threadID )
   {
@@ -218,16 +246,6 @@ bool PostWinThreadMessage(
   return (bool)PostThreadMessage( threadID, Msg, wParam, lParam );
 }
 
-void ShowWindow( uint64_t hWnd)
-{
-  ::ShowWindow( reinterpret_cast<HWND>( hWnd ), SW_SHOW);
-}
-
-void HideWindow( uint64_t hWnd)
-{
-  ::ShowWindow( reinterpret_cast<HWND>( hWnd ), SW_HIDE);
-}
-
 struct TTimerCallbackInfo
 {
   void *data;
@@ -241,20 +259,20 @@ void CALLBACK TimerProc(HWND hWnd, UINT nMsg, UINT_PTR nTimerid, DWORD dwTime)
   info->callback( info->data );
 }
 
-int SetTimer(int interval, timerCallback callback, void *data)
+intptr_t SetTimer(int interval, timerCallback callback, void *data)
 {
   TTimerCallbackInfo *callbackInfo = new TTimerCallbackInfo;
   callbackInfo->data = data;
   callbackInfo->callback = callback;
   callbackInfo->hWnd = ::GetActiveWindow();
 
-  UINT_PTR timerID = (UINT_PTR)callbackInfo;
+  INT_PTR timerID = (INT_PTR)callbackInfo;
   ::SetTimer( callbackInfo->hWnd, timerID, interval, TimerProc );
 
   return timerID;
 }
 
-void KillTimer(int id)
+void KillTimer(intptr_t id)
 {
   TTimerCallbackInfo *info = (TTimerCallbackInfo*)id;
   ::KillTimer( info->hWnd, id );