Merge "[Tizen] Add Finalize api for imf-manager" into tizen_4.0
authorSeoyeon Kim <seoyeon2.kim@samsung.com>
Thu, 28 Sep 2017 11:35:45 +0000 (11:35 +0000)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Thu, 28 Sep 2017 11:35:45 +0000 (11:35 +0000)
1  2 
adaptors/devel-api/adaptor-framework/imf-manager.cpp
adaptors/devel-api/adaptor-framework/imf-manager.h
adaptors/ecore/wayland/imf-manager-impl-ecore-wl.cpp
adaptors/ecore/wayland/imf-manager-impl.h
adaptors/integration-api/x11/imf-manager-impl.h
adaptors/wayland/input/text/imf/imf-manager-impl-wl.cpp
adaptors/wayland/input/text/imf/imf-manager-impl.h
adaptors/x11/imf-manager-impl-x.cpp

index 620fdd1,37019d9..8571653
mode 100644,100755..100755
@@@ -33,6 -33,11 +33,11 @@@ ImfManager::~ImfManager(
  {
  }
  
+ void ImfManager::Finalize()
+ {
+   Internal::Adaptor::ImfManager::GetImplementation(*this).Finalize();
+ }
  ImfManager ImfManager::Get()
  {
    return Internal::Adaptor::ImfManager::Get();
@@@ -108,14 -113,14 +113,14 @@@ void ImfManager::ApplyOptions( const In
    Internal::Adaptor::ImfManager::GetImplementation(*this).ApplyOptions( options );
  }
  
 -void ImfManager::SetInputPanelUserData( const std::string& data )
 +void ImfManager::SetInputPanelData( const std::string& data )
  {
 -  Internal::Adaptor::ImfManager::GetImplementation(*this).SetInputPanelUserData( data );
 +  Internal::Adaptor::ImfManager::GetImplementation(*this).SetInputPanelData( data );
  }
  
 -void ImfManager::GetInputPanelUserData( std::string& data )
 +void ImfManager::GetInputPanelData( std::string& data )
  {
 -  Internal::Adaptor::ImfManager::GetImplementation(*this).GetInputPanelUserData( data );
 +  Internal::Adaptor::ImfManager::GetImplementation(*this).GetInputPanelData( data );
  }
  
  Dali::ImfManager::State ImfManager::GetInputPanelState()
index 2780d9a,064ed0b..0efdeac
mode 100644,100755..100755
@@@ -170,6 -170,13 +170,13 @@@ public
  public:
  
    /**
+    * @brief Finalize the IMF.
+    *
+    * It means that the context will be deleted.
+    */
+   void Finalize();
+   /**
     * @brief Retrieve a handle to the instance of ImfManager.
     * @return A handle to the ImfManager.
     */
     * @brief Sets up the input-panel specific data.
     * @param[in] data The specific data to be set to the input panel
     */
 -  void SetInputPanelUserData( const std::string& data );
 +  void SetInputPanelData( const std::string& data );
  
    /**
     * @brief Gets the specific data of the current active input panel.
 +   *
 +   * Input Panel Data is not always the data which is set by SetInputPanelData().
 +   * Data can be changed internally in the input panel.
 +   * It is just used to get a specific data from the input panel to an application.
     * @param[in] data The specific data to be got from the input panel
     */
 -  void GetInputPanelUserData( std::string& data );
 +  void GetInputPanelData( std::string& data );
  
    /**
     * @brief Gets the state of the current active input panel.
index 69e5e41,0ae5603..942d96c
mode 100644,100755..100755
@@@ -258,6 -258,18 +258,18 @@@ TypeRegistration IMF_MANAGER_TYPE( type
  
  } // unnamed namespace
  
+ void ImfManager::Finalize()
+ {
+   DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::Finalize\n" );
+   if ( mInited )
+   {
+     DisconnectCallbacks();
+     DeleteContext();
+     ecore_imf_shutdown();
+     mInited = false;
+   }
+ }
  bool ImfManager::IsAvailable()
  {
    bool available( false );
  Dali::ImfManager ImfManager::Get()
  {
    Dali::ImfManager manager;
+   ImfManager *imfManager = NULL;
  
    Dali::SingletonService service( SingletonService::Get() );
    if ( service )
      if( handle )
      {
        // If so, downcast the handle
-       manager = Dali::ImfManager( dynamic_cast< ImfManager* >( handle.GetObjectPtr() ) );
+       imfManager = dynamic_cast< ImfManager* >( handle.GetObjectPtr() );
+       manager = Dali::ImfManager( imfManager );
      }
      else if ( Adaptor::IsAvailable() )
      {
        // Create instance and register singleton only if the adaptor is available
        Adaptor& adaptorImpl( Adaptor::GetImplementation( Adaptor::Get() ) );
        Any nativeWindow = adaptorImpl.GetNativeWindowHandle();
  
          // If we fail to get Ecore_Wl_Window, we can't use the ImfManager correctly.
          // Thus you have to call "ecore_imf_context_client_window_set" somewhere.
          // In EvasPlugIn, this function is called in EvasPlugin::ConnectEcoreEvent().
-         manager = Dali::ImfManager( new ImfManager( ecoreWwin ) );
+         imfManager = new ImfManager( ecoreWwin );
+         manager = Dali::ImfManager( imfManager );
          service.Register( typeid( manager ), manager );
        }
        else
      }
    }
  
+   if ( ( imfManager != NULL ) && !imfManager->mInited )
+   {
+     ecore_imf_init();
+     imfManager->CreateContext( imfManager->mEcoreWlwin );
+     imfManager->ConnectCallbacks();
+     imfManager->mInited = true;
+   }
    return manager;
  }
  
  ImfManager::ImfManager( Ecore_Wl_Window *ecoreWlwin )
  : mIMFContext(),
+   mEcoreWlwin( ecoreWlwin ),
    mIMFCursorPosition( 0 ),
    mSurroundingText(),
+   mInited( false ),
    mRestoreAfterFocusLost( false ),
    mIdleCallbackConnected( false )
  {
-   ecore_imf_init();
-   CreateContext( ecoreWlwin );
-   ConnectCallbacks();
  }
  
  ImfManager::~ImfManager()
  {
-   DisconnectCallbacks();
-   DeleteContext();
-   ecore_imf_shutdown();
+   Finalize();
  }
  
  void ImfManager::CreateContext( Ecore_Wl_Window *ecoreWlwin )
  {
    DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::CreateContext\n" );
    const char *contextId = ecore_imf_context_default_id_get();
    if( contextId )
    {
@@@ -760,9 -775,9 +775,9 @@@ void ImfManager::ApplyOptions( const In
    }
  }
  
 -void ImfManager::SetInputPanelUserData( const std::string& data )
 +void ImfManager::SetInputPanelData( const std::string& data )
  {
 -  DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetInputPanelUserData\n" );
 +  DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetInputPanelData\n" );
  
    if( mIMFContext )
    {
    }
  }
  
 -void ImfManager::GetInputPanelUserData( std::string& data )
 +void ImfManager::GetInputPanelData( std::string& data )
  {
 -  DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetInputPanelUserData\n" );
 +  DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetInputPanelData\n" );
  
    if( mIMFContext )
    {
 -    int length = 256;
 -    char* buffer = reinterpret_cast< char* >( calloc ( 1, length * sizeof ( char ) ) );
 -    if( buffer != NULL )
 -    {
 -      ecore_imf_context_input_panel_imdata_get( mIMFContext, buffer, &length );
 -      data = buffer;
 -      free( buffer );
 -    }
 +    int length = 4096; // The max length is 4096 bytes
 +    Dali::Vector< char > buffer;
 +    buffer.Resize( length );
 +    ecore_imf_context_input_panel_imdata_get( mIMFContext, &buffer[0], &length );
 +    data = std::string( buffer.Begin(), buffer.End() );
    }
  }
  
index e3a73ad,2d1638c..3d2d451
mode 100644,100755..100755
@@@ -53,6 -53,11 +53,11 @@@ public
  public:
  
    /**
+    * @copydoc Dali::ImfManager::Finalize()
+    */
+   void Finalize();
+   /**
     * Check whether the ImfManager is available.
     * @return true if available, false otherwise
     */
    void ApplyOptions( const InputMethodOptions& options );
  
    /**
 -   * @copydoc Dali::ImfManager::SetInputPanelUserData()
 +   * @copydoc Dali::ImfManager::SetInputPanelData()
     */
 -  void SetInputPanelUserData( const std::string& data );
 +  void SetInputPanelData( const std::string& data );
  
    /**
 -   * @copydoc Dali::ImfManager::GetInputPanelUserData()
 +   * @copydoc Dali::ImfManager::GetInputPanelData()
     */
 -  void GetInputPanelUserData( std::string& data );
 +  void GetInputPanelData( std::string& data );
  
    /**
     * @copydoc Dali::ImfManager::GetInputPanelState()
@@@ -283,9 -288,11 +288,11 @@@ private
  
  private:
    Ecore_IMF_Context* mIMFContext;
+   Ecore_Wl_Window *mEcoreWlwin;
    int mIMFCursorPosition;
    std::string mSurroundingText;
  
+   bool mInited:1;                            ///< Whether the imf is already inited.
    bool mRestoreAfterFocusLost:1;             ///< Whether the keyboard needs to be restored (activated ) after focus regained.
    bool mIdleCallbackConnected:1;             ///< Whether the idle callback is already connected.
  
index aab3f9f,2ad44b1..f069d42
mode 100644,100755..100755
@@@ -50,6 -50,11 +50,11 @@@ public
  public:
  
    /**
+    * @copydoc Dali::ImfManager::Finalize()
+    */
+   void Finalize();
+   /**
     * Check whether the ImfManager is available.
     * @return true if available, false otherwise
     */
@@@ -67,7 -72,7 +72,7 @@@
     * Constructor
     * @param[in] ecoreXwin, The window is created by application.
     */
-   ImfManager( Ecore_X_Window ecoreXwin );
+   ImfManager( Ecore_X_Window* ecoreXwin );
  
    /**
     * Connect Callbacks required for IMF.
    void ApplyOptions( const InputMethodOptions& options );
  
    /**
 -   * @copydoc Dali::ImfManager::SetInputPanelUserData()
 +   * @copydoc Dali::ImfManager::SetInputPanelData()
     */
 -  void SetInputPanelUserData( const std::string& data );
 +  void SetInputPanelData( const std::string& data );
  
    /**
 -   * @copydoc Dali::ImfManager::GetInputPanelUserData()
 +   * @copydoc Dali::ImfManager::GetInputPanelData()
     */
 -  void GetInputPanelUserData( std::string& data );
 +  void GetInputPanelData( std::string& data );
  
    /**
     * @copydoc Dali::ImfManager::GetInputPanelState()
@@@ -265,7 -270,7 +270,7 @@@ private
     * Context created the first time and kept until deleted.
     * @param[in] ecoreXwin, The window is created by application.
     */
-   void CreateContext( Ecore_X_Window ecoreXwin );
+   void CreateContext( Ecore_X_Window* ecoreXwin );
  
    /**
     * @copydoc Dali::ImfManager::DeleteContext()
@@@ -279,9 -284,11 +284,11 @@@ private
  
  private:
    Ecore_IMF_Context* mIMFContext;
+   Ecore_X_Window* mEcoreXWin;
    int mIMFCursorPosition;
    std::string mSurroundingText;
  
+   bool mInited:1;                            ///< Whether the imf is already inited.
    bool mRestoreAfterFocusLost:1;             ///< Whether the keyboard needs to be restored (activated ) after focus regained.
    bool mIdleCallbackConnected:1;             ///< Whether the idle callback is already connected.
    InputMethodOptions        mOptions;
index ec7cdc7,4ff043e..37a86e4
mode 100644,100755..100755
@@@ -104,8 -104,18 +104,18 @@@ BaseHandle Create(
  
  TypeRegistration IMF_MANAGER_TYPE( typeid(Dali::ImfManager), typeid(Dali::BaseHandle), Create );
  
+ }
  
+ void ImfManager::Finalize()
+ {
+   DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::Finalize\n" );
+   if ( mInited )
+   {
+     DisconnectCallbacks();
+     mInited = false;
+   }
  }
  bool ImfManager::IsAvailable()
  {
    bool available( false );
  Dali::ImfManager ImfManager::Get()
  {
    Dali::ImfManager manager;
+   ImfManager *imfManager = NULL;
  
    Dali::SingletonService service( SingletonService::Get() );
    if (! service )
    if( handle )
    {
      // If so, downcast the handle
-     manager = Dali::ImfManager( dynamic_cast< ImfManager* >( handle.GetObjectPtr() ) );
+     imfManager = dynamic_cast< ImfManager* >( handle.GetObjectPtr() );
+     manager = Dali::ImfManager( imfManager );
    }
    else if ( Adaptor::IsAvailable() )
    {
      // Create instance and register singleton only if the adaptor is available
-     manager = Dali::ImfManager( new ImfManager() );
+     imfManager = new ImfManager();
+     manager = Dali::ImfManager( imfManager );
      service.Register( typeid( manager ), manager );
    }
    else
    {
      DALI_LOG_ERROR("Failed to get native window handle\n");
    }
+   if ( ( imfManager != NULL ) && !imfManager->mInited )
+   {
+     imfManager->ConnectCallbacks();
+     imfManager->mInited = true;
+   }
    return manager;
  }
  ImfManager::ImfManager()
  : mTextInputManager( TextInputManager::Get() ),
    mPreEditCursorPosition( 0 ),
    mEditCursorPosition( 0 ),
+   mInited( false ),
    mRestoreAfterFocusLost( false )
  {
-   ConnectCallbacks();
  }
  ImfManager::~ImfManager()
  {
-   DisconnectCallbacks();
+   Finalize();
  }
  
  void ImfManager::ConnectCallbacks()
@@@ -317,11 -339,11 +339,11 @@@ void ImfManager::ApplyOptions(const Inp
  {
  }
  
 -void ImfManager::SetInputPanelUserData( const std::string& data )
 +void ImfManager::SetInputPanelData( const std::string& data )
  {
  }
  
 -void ImfManager::GetInputPanelUserData( std::string& data )
 +void ImfManager::GetInputPanelData( std::string& data )
  {
  }
  
index d0739a8,176e75c..8b4df80
mode 100644,100755..100755
@@@ -60,6 -60,10 +60,10 @@@ public
    typedef Dali::ImfManager::KeyboardTypeSignalType ImfKeyboardTypeSignalType;
  
  public:
+   /**
+    * @copydoc Dali::ImfManager::Finalize()
+    */
+   void Finalize();
  
    /**
     * @brief Check whether the ImfManager is available.
    void ApplyOptions( const InputMethodOptions& options );
  
    /**
 -   * @copydoc Dali::ImfManager::SetInputPanelUserData()
 +   * @copydoc Dali::ImfManager::SetInputPanelData()
     */
 -  void SetInputPanelUserData( const std::string& data );
 +  void SetInputPanelData( const std::string& data );
  
    /**
 -   * @copydoc Dali::ImfManager::GetInputPanelUserData()
 +   * @copydoc Dali::ImfManager::GetInputPanelData()
     */
 -  void GetInputPanelUserData( std::string& data );
 +  void GetInputPanelData( std::string& data );
  
    /**
     * @copydoc Dali::ImfManager::GetInputPanelState()
@@@ -306,6 -310,7 +310,7 @@@ private
    std::string mSurroundingText;
    int mPreEditCursorPosition;
    int mEditCursorPosition;
+   bool mInited:1;                 ///< Whether the imf is already inited.
    bool mRestoreAfterFocusLost:1;  ///< Whether the keyboard needs to be restored (activated ) after focus regained.
  
  public:
index 6d9d2a2,a46fa9d..1d9294f
mode 100644,100755..100755
@@@ -122,6 -122,19 +122,19 @@@ void ImfDeleteSurrounding( void *data, 
  
  } // unnamed namespace
  
+ void ImfManager::Finalize()
+ {
+   DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::Finalize\n" );
+   if ( mInited )
+   {
+     VirtualKeyboard::DisconnectCallbacks( mIMFContext );
+     DisconnectCallbacks();
+     DeleteContext();
+     ecore_imf_shutdown();
+     mInited = false;
+   }
+ }
  bool ImfManager::IsAvailable()
  {
    bool available( false );
  Dali::ImfManager ImfManager::Get()
  {
    Dali::ImfManager manager;
+   ImfManager *imfManager = NULL;
  
    Dali::SingletonService service( SingletonService::Get() );
    if ( service )
      if( handle )
      {
        // If so, downcast the handle
-       manager = Dali::ImfManager( dynamic_cast< ImfManager* >( handle.GetObjectPtr() ) );
+       imfManager = dynamic_cast< ImfManager* >( handle.GetObjectPtr() );
+       manager = Dali::ImfManager( imfManager );
      }
      else if ( Adaptor::IsAvailable() )
      {
  
        // The Ecore_X_Window needs to use the ImfManager.
        // Only when the render surface is window, we can get the Ecore_X_Window.
-       Ecore_X_Window ecoreXwin( AnyCast<Ecore_X_Window>(nativeWindow) );
-       if (ecoreXwin)
+       Ecore_X_Window *ecoreXwin( AnyCast< Ecore_X_Window* >( nativeWindow ) );
+       if ( ecoreXwin )
        {
          // If we fail to get Ecore_X_Window, we can't use the ImfManager correctly.
          // Thus you have to call "ecore_imf_context_client_window_set" somewhere.
          // In EvasPlugIn, this function is called in EvasPlugin::ConnectEcoreEvent().
-         manager = Dali::ImfManager( new ImfManager( ecoreXwin ) );
+         imfManager = new ImfManager( ecoreXwin );
+         manager = Dali::ImfManager( imfManager );
          service.Register( typeid( manager ), manager );
        }
        else
      }
    }
  
+   if ( ( imfManager != NULL ) !imfManager->mInited )
+   {
+     ecore_imf_init();
+     imfManager->CreateContext( imfManager->mEcoreXWin );
+     imfManager->ConnectCallbacks();
+     VirtualKeyboard::ConnectCallbacks( mIMFContext );
+     imfManager->mInited = true;
+   }
    return manager;
  }
  
- ImfManager::ImfManager( Ecore_X_Window ecoreXwin )
+ ImfManager::ImfManager( Ecore_X_Window* ecoreXwin )
  : mIMFContext(),
+   mEcoreXWin( ecoreXwin ),
    mIMFCursorPosition( 0 ),
    mSurroundingText(),
+   mInited( false ),
    mRestoreAfterFocusLost( false ),
    mIdleCallbackConnected( false )
  {
-   ecore_imf_init();
-   CreateContext( ecoreXwin );
-   ConnectCallbacks();
-   VirtualKeyboard::ConnectCallbacks( mIMFContext );
  }
  
  ImfManager::~ImfManager()
  {
-   VirtualKeyboard::DisconnectCallbacks( mIMFContext );
-   DisconnectCallbacks();
-   DeleteContext();
-   ecore_imf_shutdown();
+   Finalize();
  }
  
- void ImfManager::CreateContext( Ecore_X_Window ecoreXwin )
+ void ImfManager::CreateContext( Ecore_X_Window* ecoreXwin )
  {
    DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::CreateContext\n" );
  
@@@ -590,9 -608,9 +608,9 @@@ void ImfManager::ApplyOptions( const In
    }
  }
  
 -void ImfManager::SetInputPanelUserData( const std::string& data )
 +void ImfManager::SetInputPanelData( const std::string& data )
  {
 -  DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetInputPanelUserData\n" );
 +  DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetInputPanelData\n" );
  
    if( mIMFContext )
    {
    }
  }
  
 -void ImfManager::GetInputPanelUserData( std::string& data )
 +void ImfManager::GetInputPanelData( std::string& data )
  {
 -  DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetInputPanelUserData\n" );
 +  DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetInputPanelData\n" );
  
    if( mIMFContext )
    {
 -    int length = 256;
 -    char* buffer = reinterpret_cast< char* >( calloc ( 1, length * sizeof ( char ) ) );
 -    if( buffer != NULL )
 -    {
 -      ecore_imf_context_input_panel_imdata_get( mIMFContext, buffer, &length );
 -      data = buffer;
 -      free( buffer );
 -    }
 +    int length = 4096; // The max length is 4096 bytes
 +    Dali::Vector< char > buffer;
 +    buffer.Resize( length );
 +    ecore_imf_context_input_panel_imdata_get( mIMFContext, &buffer[0], &length );
 +    data = std::string( buffer.Begin(), buffer.End() );
    }
  }