X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=dali%2Finternal%2Finput%2Ftizen-wayland%2Finput-method-context-impl-ecore-wl.cpp;h=36cb13a58d3cb1c9a4305c5aa6ac5d81cc55a41e;hb=f64504bd77bf30c06870f885ffd48cb447fb4e19;hp=f68c9b80a75731cd0cbd9b05b9a431638d31ca97;hpb=398db97500b00d1a7efdbbbc69eb60956b88b038;p=platform%2Fcore%2Fuifw%2Fdali-adaptor.git diff --git a/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp b/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp index f68c9b8..36cb13a 100755 --- a/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp +++ b/dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019 Samsung Electronics Co., Ltd. + * Copyright (c) 2020 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. @@ -31,6 +31,7 @@ #include #include #include +#include #include // INTERNAL INCLUDES @@ -39,11 +40,8 @@ #include #include #include -#include #include -#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; } @@ -275,7 +281,7 @@ int GetWindowIdFromActor( Dali::Actor actor ) { int windowId = kUninitializedWindowId; - if( actor.OnStage() ) + if( actor.GetProperty< bool >( Dali::Actor::Property::CONNECTED_TO_SCENE ) ) { Any nativeWindowHandle = Dali::Integration::SceneHolder::Get( actor ).GetNativeHandle(); @@ -324,12 +330,11 @@ InputMethodContextEcoreWl::InputMethodContextEcoreWl( Dali::Actor actor ) mSurroundingText(), mRestoreAfterFocusLost( false ), mIdleCallbackConnected( false ), - mPreeditType( Dali::InputMethodContext::PreeditStyle::NONE ), mWindowId( GetWindowIdFromActor( actor ) ) { ecore_imf_init(); - actor.OnStageSignal().Connect( this, &InputMethodContextEcoreWl::OnStaged ); + actor.OnSceneSignal().Connect( this, &InputMethodContextEcoreWl::OnStaged ); } InputMethodContextEcoreWl::~InputMethodContextEcoreWl() @@ -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( eina_list_data_get(l) ) ); l; l = eina_list_next(l), ( attr = static_cast( 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,11 +797,13 @@ 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() { - Dali::InputMethodContext::TextDirection direction ( Dali::InputMethodContext::LeftToRight ); + Dali::InputMethodContext::TextDirection direction ( Dali::InputMethodContext::LEFT_TO_RIGHT ); if ( mIMFContext ) { @@ -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 ) @@ -1015,14 +1055,14 @@ bool InputMethodContextEcoreWl::FilterEventKey( const Dali::KeyEvent& keyEvent ) bool eventHandled( false ); // If a device key then skip ecore_imf_context_filter_event. - if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() )) + if ( ! KeyLookup::IsDeviceButton( keyEvent.GetKeyName().c_str() )) { //check whether it's key down or key up event - if ( keyEvent.state == KeyEvent::Down ) + if ( keyEvent.GetState() == Dali::KeyEvent::DOWN ) { eventHandled = ProcessEventKeyDown( keyEvent ); } - else if ( keyEvent.state == KeyEvent::Up ) + else if ( keyEvent.GetState() == Dali::KeyEvent::UP ) { eventHandled = ProcessEventKeyUp( 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,46 +1150,48 @@ 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 ) +bool InputMethodContextEcoreWl::ProcessEventKeyDown( const Dali::KeyEvent& keyEvent ) { bool eventHandled( false ); if ( mIMFContext ) { - Integration::KeyEvent integKeyEvent( keyEvent ); + Integration::KeyEvent integKeyEvent( keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast< Integration::KeyEvent::State >( keyEvent.GetState() ), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass() ); std::string key = integKeyEvent.logicalKey; - std::string compose = keyEvent.GetCompose(); - std::string deviceName = keyEvent.GetDeviceName(); + std::string compose = integKeyEvent.compose; + std::string deviceName = integKeyEvent.deviceName; // 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.keyname = integKeyEvent.keyName.c_str(); ecoreKeyDownEvent.key = key.c_str(); - ecoreKeyDownEvent.string = keyEvent.keyPressed.c_str(); + ecoreKeyDownEvent.string = integKeyEvent.keyString.c_str(); ecoreKeyDownEvent.compose = compose.c_str(); - ecoreKeyDownEvent.timestamp = keyEvent.time; - ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( keyEvent.keyModifier ); - ecoreKeyDownEvent.locks = EcoreInputModifierToEcoreIMFLock( keyEvent.keyModifier ); + ecoreKeyDownEvent.timestamp = integKeyEvent.time; + ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( integKeyEvent.keyModifier ); + ecoreKeyDownEvent.locks = EcoreInputModifierToEcoreIMFLock( integKeyEvent.keyModifier ); ecoreKeyDownEvent.dev_name = deviceName.c_str(); - ecoreKeyDownEvent.dev_class = static_cast ( keyEvent.GetDeviceClass() );//ECORE_IMF_DEVICE_CLASS_KEYBOARD; - ecoreKeyDownEvent.dev_subclass = static_cast ( keyEvent.GetDeviceSubclass() );//ECORE_IMF_DEVICE_SUBCLASS_NONE; + ecoreKeyDownEvent.dev_class = static_cast ( integKeyEvent.deviceClass );//ECORE_IMF_DEVICE_CLASS_KEYBOARD; + ecoreKeyDownEvent.dev_subclass = static_cast ( integKeyEvent.deviceSubclass );//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. + ecoreKeyDownEvent.keycode = integKeyEvent.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)) || - (!strncmp(keyEvent.keyPressedName.c_str(), "Right", 5)) || - (!strncmp(keyEvent.keyPressedName.c_str(), "Up", 2)) || - (!strncmp(keyEvent.keyPressedName.c_str(), "Down", 4)))) + if ((integKeyEvent.deviceName == "ime") && ((!strncmp(integKeyEvent.keyName.c_str(), "Left", 4)) || + (!strncmp(integKeyEvent.keyName.c_str(), "Right", 5)) || + (!strncmp(integKeyEvent.keyName.c_str(), "Up", 2)) || + (!strncmp(integKeyEvent.keyName.c_str(), "Down", 4)))) { eventHandled = 0; } @@ -1159,9 +1205,9 @@ bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent ) // If the event has not been handled by InputMethodContext then check if we should reset our input method context if (!eventHandled) { - if (!strcmp(keyEvent.keyPressedName.c_str(), "Escape") || - !strcmp(keyEvent.keyPressedName.c_str(), "Return") || - !strcmp(keyEvent.keyPressedName.c_str(), "KP_Enter")) + if (!strcmp(integKeyEvent.keyName.c_str(), "Escape") || + !strcmp(integKeyEvent.keyName.c_str(), "Return") || + !strcmp(integKeyEvent.keyName.c_str(), "KP_Enter")) { ecore_imf_context_reset(mIMFContext); } @@ -1170,31 +1216,31 @@ bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent ) return eventHandled; } -bool InputMethodContextEcoreWl::ProcessEventKeyUp( const KeyEvent& keyEvent ) +bool InputMethodContextEcoreWl::ProcessEventKeyUp( const Dali::KeyEvent& keyEvent ) { bool eventHandled( false ); if( mIMFContext ) { - Integration::KeyEvent integKeyEvent( keyEvent ); + Integration::KeyEvent integKeyEvent( keyEvent.GetKeyName(), keyEvent.GetLogicalKey(), keyEvent.GetKeyString(), keyEvent.GetKeyCode(), keyEvent.GetKeyModifier(), keyEvent.GetTime(), static_cast< Integration::KeyEvent::State >( keyEvent.GetState() ), keyEvent.GetCompose(), keyEvent.GetDeviceName(), keyEvent.GetDeviceClass(), keyEvent.GetDeviceSubclass() ); std::string key = integKeyEvent.logicalKey; - std::string compose = keyEvent.GetCompose(); - std::string deviceName = keyEvent.GetDeviceName(); + std::string compose = integKeyEvent.compose; + std::string deviceName = integKeyEvent.deviceName; // 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.keyname = integKeyEvent.keyName.c_str(); ecoreKeyUpEvent.key = key.c_str(); - ecoreKeyUpEvent.string = keyEvent.keyPressed.c_str(); + ecoreKeyUpEvent.string = integKeyEvent.keyString.c_str(); ecoreKeyUpEvent.compose = compose.c_str(); - ecoreKeyUpEvent.timestamp = keyEvent.time; - ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( keyEvent.keyModifier ); - ecoreKeyUpEvent.locks = EcoreInputModifierToEcoreIMFLock( keyEvent.keyModifier ); + ecoreKeyUpEvent.timestamp = integKeyEvent.time; + ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( integKeyEvent.keyModifier ); + ecoreKeyUpEvent.locks = EcoreInputModifierToEcoreIMFLock( integKeyEvent.keyModifier ); ecoreKeyUpEvent.dev_name = deviceName.c_str(); - ecoreKeyUpEvent.dev_class = static_cast ( keyEvent.GetDeviceClass() );//ECORE_IMF_DEVICE_CLASS_KEYBOARD; - ecoreKeyUpEvent.dev_subclass = static_cast ( keyEvent.GetDeviceSubclass() );//ECORE_IMF_DEVICE_SUBCLASS_NONE; + ecoreKeyUpEvent.dev_class = static_cast ( integKeyEvent.deviceClass );//ECORE_IMF_DEVICE_CLASS_KEYBOARD; + ecoreKeyUpEvent.dev_subclass = static_cast ( integKeyEvent.deviceSubclass );//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. + ecoreKeyUpEvent.keycode = integKeyEvent.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,