/*
- * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2017 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.
#include <adaptor.h>
#include <window-render-surface.h>
#include <adaptor-impl.h>
+#include <locale-utils.h>
#include <singleton-service-impl.h>
#include <virtual-keyboard-impl.h>
+// Ecore is littered with C style cast
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+#include "ecore-virtual-keyboard.h"
namespace Dali
{
namespace
{
-
#if defined(DEBUG_ENABLED)
Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_IMF_MANAGER");
#endif
}
}
-BaseHandle Create()
-{
- return ImfManager::Get();
-}
-
-TypeRegistration IMF_MANAGER_TYPE( typeid(Dali::ImfManager), typeid(Dali::BaseHandle), Create );
-
} // unnamed namespace
bool ImfManager::IsAvailable()
// Create instance and register singleton only if the adaptor is available
Adaptor& adaptorImpl( Adaptor::GetImplementation( Adaptor::Get() ) );
+ Any nativeWindow = adaptorImpl.GetNativeWindowHandle();
// 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( 0 );
- Dali::RenderSurface& surface( adaptorImpl.GetSurface() );
- if( surface.GetType() == Dali::RenderSurface::WINDOW )
+ Ecore_X_Window ecoreXwin( AnyCast<Ecore_X_Window>(nativeWindow) );
+ if (ecoreXwin)
{
- ecoreXwin = AnyCast< Ecore_X_Window >( adaptorImpl.GetSurface().GetSurface() );
- }
-
- // 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().
+ // 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 ) );
- service.Register( typeid( manager ), manager );
+ manager = Dali::ImfManager( new ImfManager( ecoreXwin ) );
+ service.Register( typeid( manager ), manager );
+ }
+ else
+ {
+ DALI_LOG_ERROR("Failed to get native window handle\n");
+ }
}
}
ImfManager::ImfManager( Ecore_X_Window ecoreXwin )
: mIMFContext(),
mIMFCursorPosition( 0 ),
- mSurroundingText(""),
+ mSurroundingText(),
mRestoreAfterFocusLost( false ),
- mIdleCallbackConnected( false ),
- mKeyEvents()
+ mIdleCallbackConnected( false )
{
ecore_imf_init();
CreateContext( ecoreXwin );
}
else
{
- DALI_LOG_WARNING("IMF Unable to get IMF Context\n");
+ DALI_LOG_INFO( gLogFilter, Debug::General, "IMF Unable to get IMF Context\n");
}
}
else
{
- DALI_LOG_WARNING("IMF Unable to get IMF Context\n");
+ DALI_LOG_INFO( gLogFilter, Debug::General, "IMF Unable to get IMF Context\n");
}
}
if ( mIMFContext )
{
+ ecore_imf_context_del( mIMFContext );
mIMFContext = NULL;
}
}
* We are still predicting what the user is typing. The latest string is what the IMF module thinks
* the user wants to type.
*/
-void ImfManager::PreEditChanged( void *, Ecore_IMF_Context *imfContext, void *event_info )
+void ImfManager::PreEditChanged( void*, Ecore_IMF_Context* imfContext, void* event_info )
{
DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::PreEditChanged\n" );
- char *preEditString( NULL );
+ char* preEditString( NULL );
int cursorPosition( 0 );
- Eina_List *attrs = NULL;
- Eina_List *l = NULL;
+ Eina_List* attrs = NULL;
+ Eina_List* l = NULL;
- Ecore_IMF_Preedit_Attr *attr;
+ Ecore_IMF_Preedit_Attr* attr;
// 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.
if ( attrs )
{
// iterate through the list of attributes getting the type, start and end position.
- for ( l = attrs, (attr = (Ecore_IMF_Preedit_Attr*)eina_list_data_get(l) ); l; l = eina_list_next(l), ( attr = (Ecore_IMF_Preedit_Attr*)eina_list_data_get(l) ))
+ 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) ) ))
{
#ifdef DALI_PROFILE_UBUNTU
if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3 ) // (Ecore_IMF)
size_t byteIndex = 0;
// iterate through null terminated string checking each character's position against the given byte position ( attr->end_index ).
- while ( preEditString[byteIndex] != '\0' )
+ const char leadByte = preEditString[byteIndex];
+ while( leadByte != '\0' )
{
// attr->end_index is provided as a byte position not character and we need to know the character position.
- size_t currentSequenceLength = Utf8SequenceLength(preEditString[byteIndex]); // returns number of bytes used to represent character.
+ const size_t currentSequenceLength = Utf8SequenceLength( leadByte ); // returns number of bytes used to represent character.
if ( byteIndex == attr->end_index )
{
cursorPosition = visualCharacterIndex;
if ( Dali::Adaptor::IsAvailable() )
{
- std::string keyString ( preEditString );
- int numberOfChars( 0 );
-
Dali::ImfManager handle( this );
- Dali::ImfManager::ImfEventData imfEventData ( Dali::ImfManager::PREEDIT, keyString, cursorPosition, numberOfChars );
+ Dali::ImfManager::ImfEventData imfEventData( Dali::ImfManager::PREEDIT, preEditString, cursorPosition, 0 );
Dali::ImfManager::ImfCallbackData callbackData = mEventSignal.Emit( handle, imfEventData );
- if ( callbackData.update )
+ if( callbackData.update )
{
- SetCursorPosition( callbackData.cursorPosition );
- SetSurroundingText( callbackData.currentText );
+ mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
NotifyCursorPosition();
}
- if ( callbackData.preeditResetRequired )
+ if( callbackData.preeditResetRequired )
{
Reset();
}
free( preEditString );
}
-void ImfManager::CommitReceived( void *, Ecore_IMF_Context *imfContext, void *event_info )
+void ImfManager::CommitReceived( void*, Ecore_IMF_Context* imfContext, void* event_info )
{
DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::CommitReceived\n" );
if ( Dali::Adaptor::IsAvailable() )
{
- const std::string keyString( (char *)event_info );
- const int cursorOffset( 0 );
- const int numberOfChars( 0 );
+ const std::string keyString( static_cast<char*>( event_info ) );
Dali::ImfManager handle( this );
- Dali::ImfManager::ImfEventData imfEventData ( Dali::ImfManager::COMMIT, keyString, cursorOffset, numberOfChars );
+ Dali::ImfManager::ImfEventData imfEventData( Dali::ImfManager::COMMIT, keyString, 0, 0 );
Dali::ImfManager::ImfCallbackData callbackData = mEventSignal.Emit( handle, imfEventData );
- if ( callbackData.update )
+ if( callbackData.update )
{
- SetCursorPosition( callbackData.cursorPosition );
- SetSurroundingText( callbackData.currentText );
+ mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
NotifyCursorPosition();
}
* Here the IMF module wishes to know the string we are working with and where within the string the cursor is
* We need to signal the application to tell us this information.
*/
-Eina_Bool ImfManager::RetrieveSurrounding( void *data, Ecore_IMF_Context *imfContext, char** text, int* cursorPosition )
+Eina_Bool ImfManager::RetrieveSurrounding( void* data, Ecore_IMF_Context* imfContext, char** text, int* cursorPosition )
{
DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::RetrieveSurrounding\n" );
- std::string keyString ( "" );
- int cursorOffset( 0 );
- int numberOfChars( 0 );
-
- Dali::ImfManager::ImfEventData imfData ( Dali::ImfManager::GETSURROUNDING , keyString, cursorOffset, numberOfChars );
+ Dali::ImfManager::ImfEventData imfData( Dali::ImfManager::GETSURROUNDING, std::string(), 0, 0 );
Dali::ImfManager handle( this );
- mEventSignal.Emit( handle, imfData );
+ Dali::ImfManager::ImfCallbackData callbackData = mEventSignal.Emit( handle, imfData );
- if ( text )
+ if( callbackData.update )
{
- std::string surroundingText( GetSurroundingText() );
-
- if ( !surroundingText.empty() )
+ if( text )
{
- *text = strdup( surroundingText.c_str() );
+ *text = strdup( callbackData.currentText.c_str() );
}
- else
+
+ if( cursorPosition )
{
- *text = strdup( "" );
+ mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
+ *cursorPosition = mIMFCursorPosition;
}
}
- if ( cursorPosition )
- {
- *cursorPosition = GetCursorPosition();
- }
-
-
return EINA_TRUE;
}
* Called when an IMF delete surrounding event is received.
* Here we tell the application that it should delete a certain range.
*/
-void ImfManager::DeleteSurrounding( void *data, Ecore_IMF_Context *imfContext, void *event_info )
+void ImfManager::DeleteSurrounding( void* data, Ecore_IMF_Context* imfContext, void* event_info )
{
DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::DeleteSurrounding\n" );
- if ( Dali::Adaptor::IsAvailable() )
+ if( Dali::Adaptor::IsAvailable() )
{
- Ecore_IMF_Event_Delete_Surrounding* deleteSurroundingEvent = (Ecore_IMF_Event_Delete_Surrounding*) event_info;
-
- const std::string keyString( "" );
- const int cursorOffset( deleteSurroundingEvent->offset );
- const int numberOfChars( deleteSurroundingEvent->n_chars );
+ Ecore_IMF_Event_Delete_Surrounding* deleteSurroundingEvent = static_cast<Ecore_IMF_Event_Delete_Surrounding*>( event_info );
- Dali::ImfManager::ImfEventData imfData ( Dali::ImfManager::DELETESURROUNDING , keyString, cursorOffset, numberOfChars );
+ Dali::ImfManager::ImfEventData imfData( Dali::ImfManager::DELETESURROUNDING, std::string(), deleteSurroundingEvent->offset, deleteSurroundingEvent->n_chars );
Dali::ImfManager handle( this );
- mEventSignal.Emit( handle, imfData );
+ Dali::ImfManager::ImfCallbackData callbackData = mEventSignal.Emit( handle, imfData );
+
+ if( callbackData.update )
+ {
+ mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
+
+ NotifyCursorPosition();
+ }
}
}
{
DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::NotifyCursorPosition\n" );
- if ( mIMFContext )
+ if( mIMFContext )
{
ecore_imf_context_cursor_position_set( mIMFContext, mIMFCursorPosition );
}
}
-int ImfManager::GetCursorPosition()
+void ImfManager::SetCursorPosition( unsigned int cursorPosition )
{
- DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetCursorPosition\n" );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetCursorPosition\n" );
- return mIMFCursorPosition;
+ mIMFCursorPosition = static_cast<int>( cursorPosition );
}
-void ImfManager::SetCursorPosition( unsigned int cursorPosition )
+unsigned int ImfManager::GetCursorPosition() const
{
- DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetCursorPosition\n" );
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetCursorPosition\n" );
- mIMFCursorPosition = ( int )cursorPosition;
+ return static_cast<unsigned int>( mIMFCursorPosition );
}
-void ImfManager::SetSurroundingText( std::string text )
+void ImfManager::SetSurroundingText( const std::string& text )
{
DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetSurroundingText\n" );
mSurroundingText = text;
}
-std::string ImfManager::GetSurroundingText()
+const std::string& ImfManager::GetSurroundingText() const
{
DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetSurroundingText\n" );
return mSurroundingText;
}
+void ImfManager::NotifyTextInputMultiLine( bool multiLine )
+{
+}
+
+Dali::ImfManager::TextDirection ImfManager::GetTextDirection()
+{
+ Dali::ImfManager::TextDirection direction ( Dali::ImfManager::LeftToRight );
+
+ if ( ImfManager::IsAvailable() /* We do not want to create an instance of ImfManager */ )
+ {
+ if ( mIMFContext )
+ {
+ char* locale( NULL );
+ ecore_imf_context_input_panel_language_locale_get( mIMFContext, &locale );
+
+ if ( locale )
+ {
+ direction = Locale::GetTextDirection( std::string( locale ) );
+ free( locale );
+ }
+ }
+ }
+ return direction;
+}
+
+Rect<int> ImfManager::GetInputMethodArea()
+{
+ int xPos, yPos, width, height;
+
+ width = height = xPos = yPos = 0;
+
+ if( mIMFContext )
+ {
+ ecore_imf_context_input_panel_geometry_get( mIMFContext, &xPos, &yPos, &width, &height );
+ }
+ else
+ {
+ DALI_LOG_WARNING("VKB Unable to get IMF Context so GetSize unavailable\n");
+ }
+
+ return Rect<int>(xPos,yPos,width,height);
+}
+
+void ImfManager::ApplyOptions( const InputMethodOptions& options )
+{
+ using namespace Dali::InputMethod::Category;
+
+ int index;
+
+ 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(AUTO_CAPITALISE, options, index) )
+ {
+ }
+ if ( mOptions.CompareAndSet(ACTION_BUTTON_TITLE, options, index) )
+ {
+ }
+ if ( mOptions.CompareAndSet(VARIATION, options, index) )
+ {
+ }
+}
+
+void ImfManager::SetInputPanelUserData( const std::string& data )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetInputPanelUserData\n" );
+
+ if( mIMFContext )
+ {
+ int length = data.length();
+ ecore_imf_context_input_panel_imdata_set( mIMFContext, &data, length );
+ }
+}
+
+void ImfManager::GetInputPanelUserData( std::string& data )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetInputPanelUserData\n" );
+
+ if( mIMFContext )
+ {
+ int* length = NULL;
+ ecore_imf_context_input_panel_imdata_get( mIMFContext, &data, length );
+ }
+}
+
+Dali::ImfManager::State ImfManager::GetInputPanelState()
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::GetInputPanelState\n" );
+
+ if( mIMFContext )
+ {
+ int value;
+ value = ecore_imf_context_input_panel_state_get( mIMFContext );
+
+ switch (value)
+ {
+ case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
+ {
+ return Dali::ImfManager::SHOW;
+ break;
+ }
+
+ case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
+ {
+ return Dali::ImfManager::HIDE;
+ break;
+ }
+
+ case ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW:
+ {
+ return Dali::ImfManager::WILL_SHOW;
+ break;
+ }
+
+ default:
+ {
+ return Dali::ImfManager::DEFAULT;
+ }
+ }
+ }
+ return Dali::ImfManager::DEFAULT;
+}
+
+void ImfManager::SetReturnKeyState( bool visible )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::SetReturnKeyState\n" );
+
+ if( mIMFContext )
+ {
+ ecore_imf_context_input_panel_return_key_disabled_set( mIMFContext, !visible );
+ }
+}
+
+void ImfManager::AutoEnableInputPanel( bool enabled )
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::AutoEnableInputPanel\n" );
+
+ if( mIMFContext )
+ {
+ ecore_imf_context_input_panel_enabled_set( mIMFContext, enabled );
+ }
+}
+
+void ImfManager::ShowInputPanel()
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::ShowInputPanel\n" );
+
+ if( mIMFContext )
+ {
+ ecore_imf_context_input_panel_show( mIMFContext );
+ }
+}
+
+void ImfManager::HideInputPanel()
+{
+ DALI_LOG_INFO( gLogFilter, Debug::General, "ImfManager::HideInputPanel\n" );
+
+ if( mIMFContext )
+ {
+ ecore_imf_context_input_panel_hide( mIMFContext );
+ }
+}
+
} // Adaptor
} // Internal
} // Dali
+
+#pragma GCC diagnostic pop