Add keycode for Ecore_IMF_Event_Key value
[platform/core/uifw/dali-adaptor.git] / dali / internal / input / tizen-wayland / input-method-context-impl-ecore-wl.cpp
index b043d32..663eb39 100755 (executable)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2018 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2019 Samsung Electronics Co., Ltd.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  */
 
 // CLASS HEADER
-// Ecore is littered with C style cast
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
 
 #include <dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.h>
 
 // EXTERNAL INCLUDES
 #include <Ecore_Input.h>
 
+#ifdef ECORE_WAYLAND2
+#include <Ecore_Wl2.h>
+#else
+#include <Ecore_Wayland.h>
+#endif
+
 #include <dali/public-api/events/key-event.h>
 #include <dali/public-api/adaptor-framework/key.h>
 #include <dali/public-api/object/type-registry.h>
@@ -32,6 +35,7 @@
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor.h>
+#include <dali/integration-api/scene-holder.h>
 #include <dali/internal/system/common/locale-utils.h>
 #include <dali/internal/system/common/singleton-service-impl.h>
 #include <dali/public-api/adaptor-framework/input-method.h>
@@ -94,6 +98,8 @@ namespace
 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_INPUT_METHOD_CONTEXT");
 #endif
 
+const int kUninitializedWindowId = 0;
+
 // Currently this code is internal to dali/dali/internal/event/text/utf8.h but should be made Public and used from there instead.
 size_t Utf8SequenceLength(const unsigned char leadByte)
 {
@@ -120,21 +126,21 @@ size_t Utf8SequenceLength(const unsigned char leadByte)
 }
 
 // Static function calls used by ecore 'c' style callback registration
-void Commit( void *data, Ecore_IMF_Context *imfContext, void *event_info )
+void Commit( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
 {
   if ( data )
   {
-    InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
-    inputMethodContext->CommitReceived( data, imfContext, event_info );
+    InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
+    inputMethodContext->CommitReceived( data, imfContext, eventInfo );
   }
 }
 
-void PreEdit( void *data, Ecore_IMF_Context *imfContext, void *event_info )
+void PreEdit( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
 {
   if ( data )
   {
-    InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
-    inputMethodContext->PreEditChanged( data, imfContext, event_info );
+    InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
+    inputMethodContext->PreEditChanged( data, imfContext, eventInfo );
   }
 }
 
@@ -142,7 +148,7 @@ Eina_Bool ImfRetrieveSurrounding(void *data, Ecore_IMF_Context *imfContext, char
 {
   if ( data )
   {
-    InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
+    InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
     return inputMethodContext->RetrieveSurrounding( data, imfContext, text, cursorPosition );
   }
   else
@@ -157,7 +163,7 @@ void InputPanelStateChangeCallback( void* data, Ecore_IMF_Context* context, int
   {
     return;
   }
-  InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
+  InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
   switch (value)
   {
     case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
@@ -187,7 +193,7 @@ void InputPanelLanguageChangeCallback( void* data, Ecore_IMF_Context* context, i
   {
     return;
   }
-  InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
+  InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
   // Emit the signal that the language has changed
   inputMethodContext->LanguageChangedSignal().Emit(value);
 }
@@ -198,7 +204,7 @@ void InputPanelGeometryChangedCallback ( void *data, Ecore_IMF_Context *context,
   {
     return;
   }
-  InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
+  InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
   // Emit signal that the keyboard is resized
   inputMethodContext->ResizedSignal().Emit(value);
 }
@@ -210,7 +216,7 @@ void InputPanelKeyboardTypeChangedCallback( void *data, Ecore_IMF_Context *conte
     return;
   }
 
-  InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
+  InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
   switch (value)
   {
     case ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE:
@@ -232,55 +238,74 @@ void InputPanelKeyboardTypeChangedCallback( void *data, Ecore_IMF_Context *conte
  * Called when an IMF delete surrounding event is received.
  * Here we tell the application that it should delete a certain range.
  */
-void ImfDeleteSurrounding( void *data, Ecore_IMF_Context *imfContext, void *event_info )
+void ImfDeleteSurrounding( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
 {
   if ( data )
   {
-    InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
-    inputMethodContext->DeleteSurrounding( data, imfContext, event_info );
+    InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
+    inputMethodContext->DeleteSurrounding( data, imfContext, eventInfo );
   }
 }
 
 /**
  * Called when the input method sends a private command.
  */
-void PrivateCommand( void *data, Ecore_IMF_Context *imfContext, void *event_info )
+void PrivateCommand( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
+{
+  if ( data )
+  {
+    InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
+    inputMethodContext->SendPrivateCommand( data, imfContext, eventInfo );
+  }
+}
+
+/**
+ * Called when the input method commits content, such as an image.
+ */
+void CommitContent( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
 {
   if ( data )
   {
-    InputMethodContextEcoreWl* inputMethodContext = reinterpret_cast< InputMethodContextEcoreWl* > ( data );
-    inputMethodContext->SendPrivateCommand( data, imfContext, event_info );
+    InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
+    inputMethodContext->SendCommitContent( data, imfContext, eventInfo );
+  }
+}
+
+int GetWindowIdFromActor( Dali::Actor actor )
+{
+  int windowId = kUninitializedWindowId;
+
+  if( actor.OnStage() )
+  {
+    Any nativeWindowHandle = Dali::Integration::SceneHolder::Get( actor ).GetNativeHandle();
+
+#ifdef ECORE_WAYLAND2
+    windowId = ecore_wl2_window_id_get( AnyCast< Ecore_Wl2_Window* >( nativeWindowHandle ) );
+#else
+    windowId = ecore_wl_window_id_get( AnyCast< Ecore_Wl_Window* >( nativeWindowHandle ) );
+#endif
   }
+
+  return windowId;
 }
 
 BaseHandle Create()
 {
-  return Dali::InputMethodContext::New();
+  return Dali::InputMethodContext::New( Dali::Actor() );
 }
 
 Dali::TypeRegistration type( typeid(Dali::InputMethodContext), typeid(Dali::BaseHandle), Create );
 
 } // unnamed namespace
 
-InputMethodContextPtr InputMethodContextEcoreWl::New()
+InputMethodContextPtr InputMethodContextEcoreWl::New( Dali::Actor actor )
 {
   InputMethodContextPtr inputMethodContext;
 
-  // Create instance only if the adaptor is available
-  if ( Dali::Adaptor::IsAvailable() )
+  // Create instance only if the adaptor is available and the valid actor exists
+  if ( actor && Dali::Adaptor::IsAvailable() )
   {
-    Any nativeWindow = Dali::Adaptor::Get().GetNativeWindowHandle();
-
-    // The window needs to use the InputMethodContext.
-    // Only when the render surface is window, we can get the window.
-    if( !nativeWindow.Empty() )
-    {
-      inputMethodContext = new InputMethodContextEcoreWl();
-    }
-    else
-    {
-      DALI_LOG_ERROR("Failed to get native window handle, can't create InputMethodContext instance.\n");
-    }
+    inputMethodContext = new InputMethodContextEcoreWl( actor );
   }
   return inputMethodContext;
 }
@@ -293,14 +318,17 @@ void InputMethodContextEcoreWl::Finalize()
   DeleteContext();
 }
 
-InputMethodContextEcoreWl::InputMethodContextEcoreWl()
+InputMethodContextEcoreWl::InputMethodContextEcoreWl( Dali::Actor actor )
 : mIMFContext(),
   mIMFCursorPosition( 0 ),
   mSurroundingText(),
   mRestoreAfterFocusLost( false ),
-  mIdleCallbackConnected( false )
+  mIdleCallbackConnected( false ),
+  mWindowId( GetWindowIdFromActor( actor ) )
 {
   ecore_imf_init();
+
+  actor.OnStageSignal().Connect( this, &InputMethodContextEcoreWl::OnStaged );
 }
 
 InputMethodContextEcoreWl::~InputMethodContextEcoreWl()
@@ -319,6 +347,11 @@ void InputMethodContextEcoreWl::CreateContext()
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContext::CreateContext\n" );
 
+  if( mWindowId == kUninitializedWindowId )
+  {
+    return;
+  }
+
   const char *contextId = ecore_imf_context_default_id_get();
   if( contextId )
   {
@@ -326,26 +359,16 @@ void InputMethodContextEcoreWl::CreateContext()
 
     if( mIMFContext )
     {
-      // If we fail to get window id, we can't use the InputMethodContext correctly.
-      // Thus you have to call "ecore_imf_context_client_window_set" somewhere.
-      // In EvasPlugIn, this function is called in EvasPlugin::ConnectEcoreEvent().
-      RenderSurface& renderSurface = Dali::Adaptor::Get().GetSurface();
-      WindowRenderSurface& windowRenderSurface = static_cast< WindowRenderSurface& >( renderSurface );
-
-      int windowId = windowRenderSurface.GetNativeWindowId();
-      if( windowId != 0 )
-      {
-        ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast< void* >( windowId ) );
-      }
+      ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast< void* >( mWindowId ) );
     }
     else
     {
-      DALI_LOG_WARNING("InputMethodContext Unable to get IMFContext\n");
+      DALI_LOG_WARNING( "InputMethodContext Unable to get IMFContext\n" );
     }
   }
   else
   {
-    DALI_LOG_WARNING("InputMethodContext Unable to get IMFContext\n");
+    DALI_LOG_WARNING( "InputMethodContext Unable to get IMFContext\n" );
   }
 }
 
@@ -371,6 +394,7 @@ void InputMethodContextEcoreWl::ConnectCallbacks()
     ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_COMMIT,               Commit,     this );
     ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_DELETE_SURROUNDING,   ImfDeleteSurrounding, this );
     ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, PrivateCommand, this );
+    ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_COMMIT_CONTENT,       CommitContent, this );
 
     ecore_imf_context_input_panel_event_callback_add( mIMFContext, ECORE_IMF_INPUT_PANEL_STATE_EVENT,    InputPanelStateChangeCallback, this );
     ecore_imf_context_input_panel_event_callback_add( mIMFContext, ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, InputPanelLanguageChangeCallback, this );
@@ -391,6 +415,7 @@ void InputMethodContextEcoreWl::DisconnectCallbacks()
     ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_COMMIT,               Commit );
     ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_DELETE_SURROUNDING,   ImfDeleteSurrounding );
     ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, PrivateCommand );
+    ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_COMMIT_CONTENT,       CommitContent );
 
     ecore_imf_context_input_panel_event_callback_del( mIMFContext, ECORE_IMF_INPUT_PANEL_STATE_EVENT,    InputPanelStateChangeCallback     );
     ecore_imf_context_input_panel_event_callback_del( mIMFContext, ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, InputPanelLanguageChangeCallback  );
@@ -464,10 +489,10 @@ void InputMethodContextEcoreWl::SetRestoreAfterFocusLost( bool toggle )
  * We are still predicting what the user is typing.  The latest string is what the InputMethodContext module thinks
  * the user wants to type.
  */
-void InputMethodContextEcoreWl::PreEditChanged( void*, ImfContext* imfContext, void* event_info )
+void InputMethodContextEcoreWl::PreEditChanged( void*, ImfContext* imfContext, void* eventInfo )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::PreEditChanged\n" );
-  auto context = reinterpret_cast<Ecore_IMF_Context*>(imfContext);
+  auto context = static_cast<Ecore_IMF_Context*>( imfContext );
 
   char* preEditString( NULL );
   int cursorPosition( 0 );
@@ -542,13 +567,13 @@ void InputMethodContextEcoreWl::PreEditChanged( void*, ImfContext* imfContext, v
   free( preEditString );
 }
 
-void InputMethodContextEcoreWl::CommitReceived( void*, ImfContext* imfContext, void* event_info )
+void InputMethodContextEcoreWl::CommitReceived( void*, ImfContext* imfContext, void* eventInfo )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::CommitReceived\n" );
 
   if ( Dali::Adaptor::IsAvailable() )
   {
-    const std::string keyString( static_cast<char*>( event_info ) );
+    const std::string keyString( static_cast<char*>( eventInfo ) );
 
     Dali::InputMethodContext handle( this );
     Dali::InputMethodContext::EventData eventData( Dali::InputMethodContext::COMMIT, keyString, 0, 0 );
@@ -579,33 +604,49 @@ bool InputMethodContextEcoreWl::RetrieveSurrounding( void* data, ImfContext* imf
 
   if( callbackData.update )
   {
-    if( text )
-    {
-      // The memory allocated by strdup() can be freed by ecore_imf_context_surrounding_get() internally.
-      *text = strdup( callbackData.currentText.c_str() );
-    }
-
     if( cursorPosition )
     {
       mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
       *cursorPosition = mIMFCursorPosition;
     }
+
+    if( text )
+    {
+      const char* plainText = callbackData.currentText.c_str();
+
+      if( plainText )
+      {
+        // The memory allocated by strdup() can be freed by ecore_imf_context_surrounding_get() internally.
+        *text = strdup( plainText );
+
+        // If the current input panel is password mode, dali should replace the plain text with '*' (Asterisk) character.
+        if( ecore_imf_context_input_hint_get( mIMFContext ) & ECORE_IMF_INPUT_HINT_SENSITIVE_DATA )
+        {
+          for( char* iter = *text; *iter; ++iter )
+          {
+            *iter = '*';
+          }
+        }
+
+        return EINA_TRUE;
+      }
+    }
   }
 
-  return EINA_TRUE;
+  return EINA_FALSE;
 }
 
 /**
  * Called when an InputMethodContext delete surrounding event is received.
  * Here we tell the application that it should delete a certain range.
  */
-void InputMethodContextEcoreWl::DeleteSurrounding( void* data, ImfContext* imfContext, void* event_info )
+void InputMethodContextEcoreWl::DeleteSurrounding( void* data, ImfContext* imfContext, void* eventInfo )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::DeleteSurrounding\n" );
 
   if( Dali::Adaptor::IsAvailable() )
   {
-    Ecore_IMF_Event_Delete_Surrounding* deleteSurroundingEvent = static_cast<Ecore_IMF_Event_Delete_Surrounding*>( event_info );
+    Ecore_IMF_Event_Delete_Surrounding* deleteSurroundingEvent = static_cast<Ecore_IMF_Event_Delete_Surrounding*>( eventInfo );
 
     Dali::InputMethodContext::EventData imfData( Dali::InputMethodContext::DELETE_SURROUNDING, std::string(), deleteSurroundingEvent->offset, deleteSurroundingEvent->n_chars );
     Dali::InputMethodContext handle( this );
@@ -616,13 +657,13 @@ void InputMethodContextEcoreWl::DeleteSurrounding( void* data, ImfContext* imfCo
 /**
  * Called when the input method sends a private command.
  */
-void InputMethodContextEcoreWl::SendPrivateCommand( void* data, ImfContext* imfContext, void* event_info )
+void InputMethodContextEcoreWl::SendPrivateCommand( void* data, ImfContext* imfContext, void* eventInfo )
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SendPrivateCommand\n" );
 
   if( Dali::Adaptor::IsAvailable() )
   {
-    const char* privateCommandSendEvent = static_cast<const char*>( event_info );
+    const char* privateCommandSendEvent = static_cast<const char*>( eventInfo );
 
     Dali::InputMethodContext::EventData imfData( Dali::InputMethodContext::PRIVATE_COMMAND, privateCommandSendEvent, 0, 0 );
     Dali::InputMethodContext handle( this );
@@ -630,6 +671,25 @@ void InputMethodContextEcoreWl::SendPrivateCommand( void* data, ImfContext* imfC
   }
 }
 
+/**
+ * Called when the input method commits content, such as an image.
+ */
+void InputMethodContextEcoreWl::SendCommitContent( void* data, ImfContext* imfContext, void* eventInfo )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SendCommitContent\n" );
+
+  if( Dali::Adaptor::IsAvailable() )
+  {
+    Ecore_IMF_Event_Commit_Content* commitContent = static_cast<Ecore_IMF_Event_Commit_Content *>( eventInfo );
+    if( commitContent )
+    {
+      DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SendCommitContent commit content : %s, description : %s, mime type : %s\n",
+                                                 commitContent->content_uri, commitContent->description, commitContent->mime_types );
+      mContentReceivedSignal.Emit( commitContent->content_uri, commitContent->description, commitContent->mime_types );
+    }
+  }
+}
+
 void InputMethodContextEcoreWl::NotifyCursorPosition()
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::NotifyCursorPosition\n" );
@@ -670,11 +730,14 @@ const std::string& InputMethodContextEcoreWl::GetSurroundingText() const
 
 void InputMethodContextEcoreWl::NotifyTextInputMultiLine( bool multiLine )
 {
-  Ecore_IMF_Input_Hints currentHint = ecore_imf_context_input_hint_get(mIMFContext);
-  ecore_imf_context_input_hint_set( mIMFContext,
-                                    static_cast< Ecore_IMF_Input_Hints >( multiLine ?
-                                      (currentHint | ECORE_IMF_INPUT_HINT_MULTILINE) :
-                                      (currentHint & ~ECORE_IMF_INPUT_HINT_MULTILINE)));
+  if( mIMFContext )
+  {
+    Ecore_IMF_Input_Hints currentHint = ecore_imf_context_input_hint_get(mIMFContext);
+    ecore_imf_context_input_hint_set( mIMFContext,
+                                      static_cast< Ecore_IMF_Input_Hints >( multiLine ?
+                                        (currentHint | ECORE_IMF_INPUT_HINT_MULTILINE) :
+                                        (currentHint & ~ECORE_IMF_INPUT_HINT_MULTILINE)));
+  }
 }
 
 Dali::InputMethodContext::TextDirection InputMethodContextEcoreWl::GetTextDirection()
@@ -721,25 +784,35 @@ void InputMethodContextEcoreWl::ApplyOptions( const InputMethodOptions& options
 
   int index;
 
-  if (mIMFContext == NULL)
+  if( mIMFContext == NULL )
   {
     DALI_LOG_WARNING("VKB Unable to excute ApplyOptions with Null ImfContext\n");
     return;
   }
 
-  if ( mOptions.CompareAndSet(PANEL_LAYOUT, options, index) )
+  if( mOptions.CompareAndSet(PANEL_LAYOUT, options, index) )
   {
     ecore_imf_context_input_panel_layout_set( mIMFContext, panelLayoutMap[index] );
+
+    // Sets the input hint which allows input methods to fine-tune their behavior.
+    if( panelLayoutMap[index] == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD )
+    {
+      ecore_imf_context_input_hint_set( mIMFContext, static_cast< Ecore_IMF_Input_Hints >( ecore_imf_context_input_hint_get( mIMFContext ) | ECORE_IMF_INPUT_HINT_SENSITIVE_DATA ) );
+    }
+    else
+    {
+      ecore_imf_context_input_hint_set( mIMFContext, static_cast< Ecore_IMF_Input_Hints >( ecore_imf_context_input_hint_get( mIMFContext ) & ~ECORE_IMF_INPUT_HINT_SENSITIVE_DATA ) );
+    }
   }
-  if ( mOptions.CompareAndSet(BUTTON_ACTION, options, index) )
+  if( mOptions.CompareAndSet(BUTTON_ACTION, options, index) )
   {
     ecore_imf_context_input_panel_return_key_type_set( mIMFContext, returnKeyTypeMap[index] );
   }
-  if ( mOptions.CompareAndSet(AUTO_CAPITALIZE, options, index) )
+  if( mOptions.CompareAndSet(AUTO_CAPITALIZE, options, index) )
   {
     ecore_imf_context_autocapital_type_set( mIMFContext, autoCapitalMap[index] );
   }
-  if ( mOptions.CompareAndSet(VARIATION, options, index) )
+  if( mOptions.CompareAndSet(VARIATION, options, index) )
   {
     ecore_imf_context_input_panel_layout_variation_set( mIMFContext, index );
   }
@@ -852,7 +925,6 @@ Dali::InputMethodContext::KeyboardType InputMethodContextEcoreWl::GetKeyboardTyp
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetKeyboardType\n" );
 
-#ifdef OVER_TIZEN_VERSION_4
   if( mIMFContext )
   {
     int value;
@@ -872,7 +944,7 @@ Dali::InputMethodContext::KeyboardType InputMethodContextEcoreWl::GetKeyboardTyp
       }
     }
   }
-#endif // OVER_TIZEN_VERSION_4
+
   return Dali::InputMethodContext::KeyboardType::SOFTWARE_KEYBOARD;
 }
 
@@ -899,6 +971,16 @@ std::string InputMethodContextEcoreWl::GetInputPanelLocale()
   return locale;
 }
 
+void InputMethodContextEcoreWl::SetContentMIMETypes( const std::string& mimeTypes )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetContentMIMETypes\n" );
+
+  if( mIMFContext )
+  {
+    ecore_imf_context_mime_type_accept_set( mIMFContext, mimeTypes.c_str() );
+  }
+}
+
 bool InputMethodContextEcoreWl::FilterEventKey( const Dali::KeyEvent& keyEvent )
 {
   bool eventHandled( false );
@@ -941,18 +1023,77 @@ bool InputMethodContextEcoreWl::IsTextPredictionAllowed() const
   return prediction;
 }
 
+void InputMethodContextEcoreWl::SetInputPanelLanguage( Dali::InputMethodContext::InputPanelLanguage language )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetInputPanelLanguage\n" );
+  if( mIMFContext )
+  {
+    switch (language)
+    {
+      case Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC:
+      {
+        ecore_imf_context_input_panel_language_set( mIMFContext, ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC );
+        break;
+      }
+      case Dali::InputMethodContext::InputPanelLanguage::ALPHABET:
+      {
+        ecore_imf_context_input_panel_language_set( mIMFContext, ECORE_IMF_INPUT_PANEL_LANG_ALPHABET );
+        break;
+      }
+    }
+  }
+}
+
+Dali::InputMethodContext::InputPanelLanguage InputMethodContextEcoreWl::GetInputPanelLanguage() const
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetInputPanelLanguage\n" );
+  if( mIMFContext )
+  {
+    int value;
+    value =  ecore_imf_context_input_panel_language_get( mIMFContext );
+
+    switch (value)
+    {
+      case ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC:
+      {
+        return Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC;
+        break;
+      }
+      case ECORE_IMF_INPUT_PANEL_LANG_ALPHABET:
+      {
+        return Dali::InputMethodContext::InputPanelLanguage::ALPHABET;
+        break;
+      }
+    }
+  }
+  return Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC;
+}
+
+void InputMethodContextEcoreWl::SetInputPanelPosition( unsigned int x, unsigned int y )
+{
+  DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetInputPanelPosition\n" );
+
+  if( mIMFContext )
+  {
+    ecore_imf_context_input_panel_position_set( mIMFContext, x, y );
+  }
+}
+
 bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent )
 {
   bool eventHandled( false );
   if ( mIMFContext )
   {
+    Integration::KeyEvent integKeyEvent( keyEvent );
+    std::string key = integKeyEvent.logicalKey;
+
     std::string compose = keyEvent.GetCompose();
     std::string deviceName = keyEvent.GetDeviceName();
 
     // We're consuming key down event so we have to pass to InputMethodContext so that it can parse it as well.
     Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
     ecoreKeyDownEvent.keyname = keyEvent.keyPressedName.c_str();
-    ecoreKeyDownEvent.key = keyEvent.keyPressedName.c_str();
+    ecoreKeyDownEvent.key = key.c_str();
     ecoreKeyDownEvent.string = keyEvent.keyPressed.c_str();
     ecoreKeyDownEvent.compose = compose.c_str();
     ecoreKeyDownEvent.timestamp = keyEvent.time;
@@ -961,6 +1102,9 @@ bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent )
     ecoreKeyDownEvent.dev_name = deviceName.c_str();
     ecoreKeyDownEvent.dev_class = static_cast<Ecore_IMF_Device_Class> ( keyEvent.GetDeviceClass() );//ECORE_IMF_DEVICE_CLASS_KEYBOARD;
     ecoreKeyDownEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass> ( keyEvent.GetDeviceSubclass() );//ECORE_IMF_DEVICE_SUBCLASS_NONE;
+#if defined(ECORE_VERSION_MAJOR) && (ECORE_VERSION_MAJOR >= 1) && defined(ECORE_VERSION_MINOR) && (ECORE_VERSION_MINOR >= 22)
+    ecoreKeyDownEvent.keycode = keyEvent.keyCode; // Ecore_IMF_Event structure has added 'keycode' variable since ecore_imf 1.22 version.
+#endif // Since ecore_imf 1.22 version
 
     // If the device is IME and the focused key is the direction keys, then we should send a key event to move a key cursor.
     if ((keyEvent.GetDeviceName() == "ime") && ((!strncmp(keyEvent.keyPressedName.c_str(), "Left", 4)) ||
@@ -974,7 +1118,7 @@ bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent )
     {
       eventHandled = ecore_imf_context_filter_event(mIMFContext,
                                                     ECORE_IMF_EVENT_KEY_DOWN,
-                                                    (Ecore_IMF_Event *) &ecoreKeyDownEvent);
+                                                    reinterpret_cast<Ecore_IMF_Event *>( &ecoreKeyDownEvent ) );
     }
 
     // If the event has not been handled by InputMethodContext then check if we should reset our input method context
@@ -996,13 +1140,16 @@ bool InputMethodContextEcoreWl::ProcessEventKeyUp( const KeyEvent& keyEvent )
   bool eventHandled( false );
   if( mIMFContext )
   {
+    Integration::KeyEvent integKeyEvent( keyEvent );
+    std::string key = integKeyEvent.logicalKey;
+
     std::string compose = keyEvent.GetCompose();
     std::string deviceName = keyEvent.GetDeviceName();
 
     // We're consuming key up event so we have to pass to InputMethodContext so that it can parse it as well.
     Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
     ecoreKeyUpEvent.keyname = keyEvent.keyPressedName.c_str();
-    ecoreKeyUpEvent.key = keyEvent.keyPressedName.c_str();
+    ecoreKeyUpEvent.key = key.c_str();
     ecoreKeyUpEvent.string = keyEvent.keyPressed.c_str();
     ecoreKeyUpEvent.compose = compose.c_str();
     ecoreKeyUpEvent.timestamp = keyEvent.time;
@@ -1011,10 +1158,13 @@ bool InputMethodContextEcoreWl::ProcessEventKeyUp( const KeyEvent& keyEvent )
     ecoreKeyUpEvent.dev_name = deviceName.c_str();
     ecoreKeyUpEvent.dev_class = static_cast<Ecore_IMF_Device_Class> ( keyEvent.GetDeviceClass() );//ECORE_IMF_DEVICE_CLASS_KEYBOARD;
     ecoreKeyUpEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass> ( keyEvent.GetDeviceSubclass() );//ECORE_IMF_DEVICE_SUBCLASS_NONE;
+#if defined(ECORE_VERSION_MAJOR) && (ECORE_VERSION_MAJOR >= 1) && defined(ECORE_VERSION_MINOR) && (ECORE_VERSION_MINOR >= 22)
+    ecoreKeyUpEvent.keycode = keyEvent.keyCode; // Ecore_IMF_Event structure has added 'keycode' variable since ecore_imf 1.22 version.
+#endif // Since ecore_imf 1.22 version
 
     eventHandled = ecore_imf_context_filter_event(mIMFContext,
                                                   ECORE_IMF_EVENT_KEY_UP,
-                                                  (Ecore_IMF_Event *) &ecoreKeyUpEvent);
+                                                  reinterpret_cast<Ecore_IMF_Event *>( &ecoreKeyUpEvent ) );
   }
   return eventHandled;
 }
@@ -1073,10 +1223,22 @@ Ecore_IMF_Keyboard_Locks InputMethodContextEcoreWl::EcoreInputModifierToEcoreIMF
     return static_cast<Ecore_IMF_Keyboard_Locks>( lock );
 }
 
+void InputMethodContextEcoreWl::OnStaged( Dali::Actor actor )
+{
+  int windowId = GetWindowIdFromActor( actor );
+
+  if( mWindowId != windowId )
+  {
+    mWindowId = windowId;
+
+    // Reset
+    Finalize();
+    Initialize();
+  }
+}
+
 } // Adaptor
 
 } // Internal
 
 } // Dali
-
-#pragma GCC diagnostic pop