[dali_1.9.1] Merge branch 'devel/master'
[platform/core/uifw/dali-adaptor.git] / dali / internal / input / tizen-wayland / input-method-context-impl-ecore-wl.cpp
index f68c9b8..bdbd873 100755 (executable)
@@ -31,6 +31,7 @@
 #include <dali/public-api/events/key-event.h>
 #include <dali/public-api/adaptor-framework/key.h>
 #include <dali/public-api/object/type-registry.h>
+#include <dali/devel-api/common/singleton-service.h>
 #include <dali/integration-api/debug.h>
 
 // INTERNAL INCLUDES
 #include <dali/integration-api/adaptor-framework/scene-holder.h>
 #include <dali/internal/input/common/key-impl.h>
 #include <dali/internal/system/common/locale-utils.h>
-#include <dali/internal/system/common/singleton-service-impl.h>
 #include <dali/internal/window-system/common/window-render-surface.h>
 
-#define TOKEN_STRING(x) #x
-
 Ecore_IMF_Input_Panel_Layout panelLayoutMap[] =
 {
    ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL,
@@ -105,22 +103,30 @@ size_t Utf8SequenceLength(const unsigned char leadByte)
 {
   size_t length = 0;
 
-  if ((leadByte & 0x80) == 0 )          //ASCII character (lead bit zero)
+  if( ( leadByte & 0x80 ) == 0 )         //ASCII character (lead bit zero)
   {
     length = 1;
   }
-  else if (( leadByte & 0xe0 ) == 0xc0 ) //110x xxxx
+  else if( leadByte & 0xe0 ) == 0xc0 ) //110x xxxx
   {
     length = 2;
   }
-  else if (( leadByte & 0xf0 ) == 0xe0 ) //1110 xxxx
+  else if( leadByte & 0xf0 ) == 0xe0 ) //1110 xxxx
   {
     length = 3;
   }
-  else if (( leadByte & 0xf8 ) == 0xf0 ) //1111 0xxx
+  else if( leadByte & 0xf8 ) == 0xf0 ) //1111 0xxx
   {
     length = 4;
   }
+  else if( ( leadByte & 0xfc ) == 0xf8 ) //1111 10xx
+  {
+    length = 5;
+  }
+  else if( ( leadByte & 0xfe ) == 0xfc ) //1111 110x
+  {
+    length = 6;
+  }
 
   return length;
 }
@@ -324,7 +330,6 @@ InputMethodContextEcoreWl::InputMethodContextEcoreWl( Dali::Actor actor )
   mSurroundingText(),
   mRestoreAfterFocusLost( false ),
   mIdleCallbackConnected( false ),
-  mPreeditType( Dali::InputMethodContext::PreeditStyle::NONE ),
   mWindowId( GetWindowIdFromActor( actor ) )
 {
   ecore_imf_init();
@@ -342,6 +347,7 @@ void InputMethodContextEcoreWl::Initialize()
 {
   CreateContext();
   ConnectCallbacks();
+  ApplyBackupOperations();
 }
 
 void InputMethodContextEcoreWl::CreateContext()
@@ -502,6 +508,8 @@ void InputMethodContextEcoreWl::PreEditChanged( void*, ImfContext* imfContext, v
 
   Ecore_IMF_Preedit_Attr* attr;
 
+  mPreeditAttrs.Clear();
+
   // Retrieves attributes as well as the string the cursor position offset from start of pre-edit string.
   // the attributes (attrs) is used in languages that use the soft arrows keys to insert characters into a current pre-edit string.
   ecore_imf_context_preedit_string_with_attributes_get( context, &preEditString, &attrs, &cursorPosition );
@@ -511,66 +519,88 @@ void InputMethodContextEcoreWl::PreEditChanged( void*, ImfContext* imfContext, v
     // iterate through the list of attributes getting the type, start and end position.
     for ( l = attrs, (attr =  static_cast<Ecore_IMF_Preedit_Attr*>( eina_list_data_get(l) ) ); l; l = eina_list_next(l), ( attr = static_cast<Ecore_IMF_Preedit_Attr*>( eina_list_data_get(l) ) ))
     {
+      Dali::InputMethodContext::PreeditAttributeData data;
+      data.startIndex = 0;
+      data.endIndex = 0;
+
+      size_t visualCharacterIndex = 0;
+      size_t byteIndex = 0;
+
+      // iterate through null terminated string checking each character's position against the given byte position ( attr->end_index ).
+      char leadByte = preEditString[byteIndex];
+
+      while( leadByte != '\0' )
+      {
+        leadByte = preEditString[byteIndex]; // Update the character to get the number of its byte
+
+        // attr->end_index is provided as a byte position not character and we need to know the character position.
+        const size_t currentSequenceLength = Utf8SequenceLength( leadByte ); // returns number of bytes used to represent character.
+        if( byteIndex <= attr->start_index )
+        {
+           data.startIndex = visualCharacterIndex;
+        }
+        if( byteIndex >= attr->end_index )
+        {
+          data.endIndex = visualCharacterIndex;
+          break;
+          // end loop as found cursor position that matches byte position
+        }
+        else
+        {
+          byteIndex += currentSequenceLength; // jump to next character
+          visualCharacterIndex++;  // increment character count so we know our position for when we get a match
+        }
+      }
+
       switch( attr->preedit_type )
       {
         case ECORE_IMF_PREEDIT_TYPE_NONE:
         {
-          mPreeditType = Dali::InputMethodContext::PreeditStyle::NONE;
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::NONE;
           break;
         }
         case ECORE_IMF_PREEDIT_TYPE_SUB1:
         {
-          mPreeditType = Dali::InputMethodContext::PreeditStyle::UNDERLINE;
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::UNDERLINE;
           break;
         }
         case ECORE_IMF_PREEDIT_TYPE_SUB2:
         {
-          mPreeditType = Dali::InputMethodContext::PreeditStyle::REVERSE;
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::REVERSE;
           break;
         }
         case ECORE_IMF_PREEDIT_TYPE_SUB3:
         {
-          mPreeditType = Dali::InputMethodContext::PreeditStyle::HIGHLIGHT;
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::HIGHLIGHT;
           break;
         }
-        default:
+        case ECORE_IMF_PREEDIT_TYPE_SUB4:
         {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_1;
           break;
         }
-      }
-
-#ifdef DALI_PROFILE_UBUNTU
-      if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3 ) // (Ecore_IMF)
-#else // DALI_PROFILE_UBUNTU
-      if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB4 ) // (Ecore_IMF)
-#endif // DALI_PROFILE_UBUNTU
-      {
-        // check first byte so know how many bytes a character is represented by as keyboard returns cursor position in bytes. Which is different for some languages.
-
-        size_t visualCharacterIndex = 0;
-        size_t byteIndex = 0;
-
-        // iterate through null terminated string checking each character's position against the given byte position ( attr->end_index ).
-        const char leadByte = preEditString[byteIndex];
-        while( leadByte != '\0' )
+        case ECORE_IMF_PREEDIT_TYPE_SUB5:
         {
-          // attr->end_index is provided as a byte position not character and we need to know the character position.
-          const size_t currentSequenceLength = Utf8SequenceLength( leadByte ); // returns number of bytes used to represent character.
-          if ( byteIndex == attr->end_index )
-          {
-            cursorPosition = visualCharacterIndex;
-            break;
-            // end loop as found cursor position that matches byte position
-          }
-          else
-          {
-            byteIndex += currentSequenceLength; // jump to next character
-            visualCharacterIndex++;  // increment character count so we know our position for when we get a match
-          }
-
-          DALI_ASSERT_DEBUG( visualCharacterIndex < strlen( preEditString ));
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_2;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB6:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_3;
+          break;
+        }
+        case ECORE_IMF_PREEDIT_TYPE_SUB7:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::CUSTOM_PLATFORM_STYLE_4;
+          break;
+        }
+        default:
+        {
+          data.preeditType = Dali::InputMethodContext::PreeditStyle::NONE;
+          break;
         }
       }
+      mPreeditAttrs.PushBack( data );
     }
   }
 
@@ -649,7 +679,7 @@ bool InputMethodContextEcoreWl::RetrieveSurrounding( void* data, ImfContext* imf
         *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 )
+        if( ( ecore_imf_context_input_hint_get( mIMFContext ) & ECORE_IMF_INPUT_HINT_SENSITIVE_DATA ) && *text )
         {
           for( char* iter = *text; *iter; ++iter )
           {
@@ -767,6 +797,8 @@ void InputMethodContextEcoreWl::NotifyTextInputMultiLine( bool multiLine )
                                         (currentHint | ECORE_IMF_INPUT_HINT_MULTILINE) :
                                         (currentHint & ~ECORE_IMF_INPUT_HINT_MULTILINE)));
   }
+
+  mBackupOperations[Operation::NOTIFY_TEXT_INPUT_MULTILINE] = std::bind( &InputMethodContextEcoreWl::NotifyTextInputMultiLine, this, multiLine );
 }
 
 Dali::InputMethodContext::TextDirection InputMethodContextEcoreWl::GetTextDirection()
@@ -856,6 +888,8 @@ void InputMethodContextEcoreWl::SetInputPanelData( const std::string& data )
     int length = data.length();
     ecore_imf_context_input_panel_imdata_set( mIMFContext, data.c_str(), length );
   }
+
+  mBackupOperations[Operation::SET_INPUT_PANEL_DATA] = std::bind( &InputMethodContextEcoreWl::SetInputPanelData, this, data );
 }
 
 void InputMethodContextEcoreWl::GetInputPanelData( std::string& data )
@@ -918,6 +952,8 @@ void InputMethodContextEcoreWl::SetReturnKeyState( bool visible )
   {
     ecore_imf_context_input_panel_return_key_disabled_set( mIMFContext, !visible );
   }
+
+  mBackupOperations[Operation::SET_RETURN_KEY_STATE] = std::bind( &InputMethodContextEcoreWl::SetReturnKeyState, this, visible );
 }
 
 void InputMethodContextEcoreWl::AutoEnableInputPanel( bool enabled )
@@ -928,6 +964,8 @@ void InputMethodContextEcoreWl::AutoEnableInputPanel( bool enabled )
   {
     ecore_imf_context_input_panel_enabled_set( mIMFContext, enabled );
   }
+
+  mBackupOperations[Operation::AUTO_ENABLE_INPUT_PANEL] = std::bind( &InputMethodContextEcoreWl::AutoEnableInputPanel, this, enabled );
 }
 
 void InputMethodContextEcoreWl::ShowInputPanel()
@@ -1008,6 +1046,8 @@ void InputMethodContextEcoreWl::SetContentMIMETypes( const std::string& mimeType
   {
     ecore_imf_context_mime_type_accept_set( mIMFContext, mimeTypes.c_str() );
   }
+
+  mBackupOperations[Operation::SET_CONTENT_MIME_TYPES] = std::bind( &InputMethodContextEcoreWl::SetContentMIMETypes, this, mimeTypes );
 }
 
 bool InputMethodContextEcoreWl::FilterEventKey( const Dali::KeyEvent& keyEvent )
@@ -1039,6 +1079,8 @@ void InputMethodContextEcoreWl::AllowTextPrediction( bool prediction )
   {
     ecore_imf_context_prediction_allow_set( mIMFContext, prediction );
   }
+
+  mBackupOperations[Operation::ALLOW_TEXT_PREDICTION] = std::bind( &InputMethodContextEcoreWl::AllowTextPrediction, this, prediction );
 }
 
 bool InputMethodContextEcoreWl::IsTextPredictionAllowed() const
@@ -1071,6 +1113,8 @@ void InputMethodContextEcoreWl::SetInputPanelLanguage( Dali::InputMethodContext:
       }
     }
   }
+
+  mBackupOperations[Operation::SET_INPUT_PANEL_LANGUAGE] = std::bind( &InputMethodContextEcoreWl::SetInputPanelLanguage, this, language );
 }
 
 Dali::InputMethodContext::InputPanelLanguage InputMethodContextEcoreWl::GetInputPanelLanguage() const
@@ -1106,12 +1150,14 @@ void InputMethodContextEcoreWl::SetInputPanelPosition( unsigned int x, unsigned
   {
     ecore_imf_context_input_panel_position_set( mIMFContext, x, y );
   }
+
+  mBackupOperations[Operation::SET_INPUT_PANEL_POSITION] = std::bind( &InputMethodContextEcoreWl::SetInputPanelPosition, this, x, y );
 }
 
-Dali::InputMethodContext::PreeditStyle InputMethodContextEcoreWl::GetPreeditStyle() const
+void InputMethodContextEcoreWl::GetPreeditStyle( Dali::InputMethodContext::PreEditAttributeDataContainer& attrs ) const
 {
   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetPreeditStyle\n" );
-  return mPreeditType;
+  attrs = mPreeditAttrs;
 }
 
 bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent )