Revert "[Tizen] Modify DALI_KEY_H"
[platform/core/uifw/dali-adaptor.git] / dali / internal / input / tizen-wayland / input-method-context-impl-ecore-wl.cpp
1 /*
2  * Copyright (c) 2019 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19
20 #include <dali/internal/input/tizen-wayland/input-method-context-impl-ecore-wl.h>
21
22 // EXTERNAL INCLUDES
23 #include <Ecore_Input.h>
24
25 #ifdef ECORE_WAYLAND2
26 #include <Ecore_Wl2.h>
27 #else
28 #include <Ecore_Wayland.h>
29 #endif
30
31 #include <dali/public-api/events/key-event.h>
32 #include <dali/public-api/adaptor-framework/key.h>
33 #include <dali/public-api/object/type-registry.h>
34 #include <dali/integration-api/debug.h>
35
36 // INTERNAL INCLUDES
37 #include <dali/integration-api/adaptor.h>
38 #include <dali/integration-api/scene-holder.h>
39 #include <dali/internal/system/common/locale-utils.h>
40 #include <dali/internal/system/common/singleton-service-impl.h>
41 #include <dali/public-api/adaptor-framework/input-method.h>
42 #include <dali/internal/input/common/key-impl.h>
43 #include <dali/internal/window-system/common/window-render-surface.h>
44
45 #define TOKEN_STRING(x) #x
46
47 Ecore_IMF_Input_Panel_Layout panelLayoutMap[] =
48 {
49    ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL,
50    ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER,
51    ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL,
52    ECORE_IMF_INPUT_PANEL_LAYOUT_URL,
53    ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER,
54    ECORE_IMF_INPUT_PANEL_LAYOUT_IP,
55    ECORE_IMF_INPUT_PANEL_LAYOUT_MONTH,
56    ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBERONLY,
57    ECORE_IMF_INPUT_PANEL_LAYOUT_HEX,
58    ECORE_IMF_INPUT_PANEL_LAYOUT_TERMINAL,
59    ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD,
60    ECORE_IMF_INPUT_PANEL_LAYOUT_DATETIME,
61    ECORE_IMF_INPUT_PANEL_LAYOUT_EMOTICON,
62    ECORE_IMF_INPUT_PANEL_LAYOUT_VOICE
63 };
64
65 Ecore_IMF_Autocapital_Type autoCapitalMap[] =
66 {
67    ECORE_IMF_AUTOCAPITAL_TYPE_NONE,
68    ECORE_IMF_AUTOCAPITAL_TYPE_WORD,
69    ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE,
70    ECORE_IMF_AUTOCAPITAL_TYPE_ALLCHARACTER,
71 };
72
73 Ecore_IMF_Input_Panel_Return_Key_Type returnKeyTypeMap[] =
74 {
75    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DEFAULT,
76    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_DONE,
77    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_GO,
78    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_JOIN,
79    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_LOGIN,
80    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_NEXT,
81    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEARCH,
82    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SEND,
83    ECORE_IMF_INPUT_PANEL_RETURN_KEY_TYPE_SIGNIN
84 };
85
86 namespace Dali
87 {
88
89 namespace Internal
90 {
91
92 namespace Adaptor
93 {
94
95 namespace
96 {
97 #if defined(DEBUG_ENABLED)
98 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_INPUT_METHOD_CONTEXT");
99 #endif
100
101 const int kUninitializedWindowId = 0;
102
103 // Currently this code is internal to dali/dali/internal/event/text/utf8.h but should be made Public and used from there instead.
104 size_t Utf8SequenceLength(const unsigned char leadByte)
105 {
106   size_t length = 0;
107
108   if ((leadByte & 0x80) == 0 )          //ASCII character (lead bit zero)
109   {
110     length = 1;
111   }
112   else if (( leadByte & 0xe0 ) == 0xc0 ) //110x xxxx
113   {
114     length = 2;
115   }
116   else if (( leadByte & 0xf0 ) == 0xe0 ) //1110 xxxx
117   {
118     length = 3;
119   }
120   else if (( leadByte & 0xf8 ) == 0xf0 ) //1111 0xxx
121   {
122     length = 4;
123   }
124
125   return length;
126 }
127
128 // Static function calls used by ecore 'c' style callback registration
129 void Commit( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
130 {
131   if ( data )
132   {
133     InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
134     inputMethodContext->CommitReceived( data, imfContext, eventInfo );
135   }
136 }
137
138 void PreEdit( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
139 {
140   if ( data )
141   {
142     InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
143     inputMethodContext->PreEditChanged( data, imfContext, eventInfo );
144   }
145 }
146
147 Eina_Bool ImfRetrieveSurrounding(void *data, Ecore_IMF_Context *imfContext, char** text, int* cursorPosition )
148 {
149   if ( data )
150   {
151     InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
152     return inputMethodContext->RetrieveSurrounding( data, imfContext, text, cursorPosition );
153   }
154   else
155   {
156     return false;
157   }
158 }
159
160 void InputPanelStateChangeCallback( void* data, Ecore_IMF_Context* context, int value )
161 {
162   if (!data)
163   {
164     return;
165   }
166   InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
167   switch (value)
168   {
169     case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
170     {
171       inputMethodContext->StatusChangedSignal().Emit( true );
172       break;
173     }
174
175     case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
176     {
177       inputMethodContext->StatusChangedSignal().Emit( false );
178       break;
179     }
180
181     case ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW:
182     default:
183     {
184       // Do nothing
185       break;
186     }
187   }
188 }
189
190 void InputPanelLanguageChangeCallback( void* data, Ecore_IMF_Context* context, int value )
191 {
192   if (!data)
193   {
194     return;
195   }
196   InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
197   // Emit the signal that the language has changed
198   inputMethodContext->LanguageChangedSignal().Emit(value);
199 }
200
201 void InputPanelGeometryChangedCallback ( void *data, Ecore_IMF_Context *context, int value )
202 {
203   if (!data)
204   {
205     return;
206   }
207   InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
208   // Emit signal that the keyboard is resized
209   inputMethodContext->ResizedSignal().Emit(value);
210 }
211
212 void InputPanelKeyboardTypeChangedCallback( void *data, Ecore_IMF_Context *context, int value )
213 {
214   if( !data )
215   {
216     return;
217   }
218
219   InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
220   switch (value)
221   {
222     case ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE:
223     {
224       // Emit Signal that the keyboard type is changed to Software Keyboard
225       inputMethodContext->KeyboardTypeChangedSignal().Emit( Dali::InputMethodContext::KeyboardType::SOFTWARE_KEYBOARD );
226       break;
227     }
228     case ECORE_IMF_INPUT_PANEL_HW_KEYBOARD_MODE:
229     {
230       // Emit Signal that the keyboard type is changed to Hardware Keyboard
231       inputMethodContext->KeyboardTypeChangedSignal().Emit( Dali::InputMethodContext::KeyboardType::HARDWARE_KEYBOARD );
232       break;
233     }
234   }
235 }
236
237 /**
238  * Called when an IMF delete surrounding event is received.
239  * Here we tell the application that it should delete a certain range.
240  */
241 void ImfDeleteSurrounding( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
242 {
243   if ( data )
244   {
245     InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
246     inputMethodContext->DeleteSurrounding( data, imfContext, eventInfo );
247   }
248 }
249
250 /**
251  * Called when the input method sends a private command.
252  */
253 void PrivateCommand( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
254 {
255   if ( data )
256   {
257     InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
258     inputMethodContext->SendPrivateCommand( data, imfContext, eventInfo );
259   }
260 }
261
262 /**
263  * Called when the input method commits content, such as an image.
264  */
265 void CommitContent( void *data, Ecore_IMF_Context *imfContext, void *eventInfo )
266 {
267   if ( data )
268   {
269     InputMethodContextEcoreWl* inputMethodContext = static_cast< InputMethodContextEcoreWl* >( data );
270     inputMethodContext->SendCommitContent( data, imfContext, eventInfo );
271   }
272 }
273
274 int GetWindowIdFromActor( Dali::Actor actor )
275 {
276   int windowId = kUninitializedWindowId;
277
278   if( actor.OnStage() )
279   {
280     Any nativeWindowHandle = Dali::Integration::SceneHolder::Get( actor ).GetNativeHandle();
281
282 #ifdef ECORE_WAYLAND2
283     windowId = ecore_wl2_window_id_get( AnyCast< Ecore_Wl2_Window* >( nativeWindowHandle ) );
284 #else
285     windowId = ecore_wl_window_id_get( AnyCast< Ecore_Wl_Window* >( nativeWindowHandle ) );
286 #endif
287   }
288
289   return windowId;
290 }
291
292 BaseHandle Create()
293 {
294   return Dali::InputMethodContext::New( Dali::Actor() );
295 }
296
297 Dali::TypeRegistration type( typeid(Dali::InputMethodContext), typeid(Dali::BaseHandle), Create );
298
299 } // unnamed namespace
300
301 InputMethodContextPtr InputMethodContextEcoreWl::New( Dali::Actor actor )
302 {
303   InputMethodContextPtr inputMethodContext;
304
305   // Create instance only if the adaptor is available and the valid actor exists
306   if ( actor && Dali::Adaptor::IsAvailable() )
307   {
308     inputMethodContext = new InputMethodContextEcoreWl( actor );
309   }
310   return inputMethodContext;
311 }
312
313 void InputMethodContextEcoreWl::Finalize()
314 {
315   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContext::Finalize\n" );
316
317   DisconnectCallbacks();
318   DeleteContext();
319 }
320
321 InputMethodContextEcoreWl::InputMethodContextEcoreWl( Dali::Actor actor )
322 : mIMFContext(),
323   mIMFCursorPosition( 0 ),
324   mSurroundingText(),
325   mRestoreAfterFocusLost( false ),
326   mIdleCallbackConnected( false ),
327   mWindowId( GetWindowIdFromActor( actor ) )
328 {
329   ecore_imf_init();
330
331   actor.OnStageSignal().Connect( this, &InputMethodContextEcoreWl::OnStaged );
332 }
333
334 InputMethodContextEcoreWl::~InputMethodContextEcoreWl()
335 {
336   Finalize();
337   ecore_imf_shutdown();
338 }
339
340 void InputMethodContextEcoreWl::Initialize()
341 {
342   CreateContext();
343   ConnectCallbacks();
344 }
345
346 void InputMethodContextEcoreWl::CreateContext()
347 {
348   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContext::CreateContext\n" );
349
350   if( mWindowId == kUninitializedWindowId )
351   {
352     return;
353   }
354
355   const char *contextId = ecore_imf_context_default_id_get();
356   if( contextId )
357   {
358     mIMFContext = ecore_imf_context_add( contextId );
359
360     if( mIMFContext )
361     {
362       ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast< void* >( mWindowId ) );
363     }
364     else
365     {
366       DALI_LOG_WARNING( "InputMethodContext Unable to get IMFContext\n" );
367     }
368   }
369   else
370   {
371     DALI_LOG_WARNING( "InputMethodContext Unable to get IMFContext\n" );
372   }
373 }
374
375 void InputMethodContextEcoreWl::DeleteContext()
376 {
377   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::DeleteContext\n" );
378
379   if ( mIMFContext )
380   {
381     ecore_imf_context_del( mIMFContext );
382     mIMFContext = NULL;
383   }
384 }
385
386 // Callbacks for predicitive text support.
387 void InputMethodContextEcoreWl::ConnectCallbacks()
388 {
389   if ( mIMFContext )
390   {
391     DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::ConnectCallbacks\n" );
392
393     ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_PREEDIT_CHANGED,      PreEdit,    this );
394     ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_COMMIT,               Commit,     this );
395     ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_DELETE_SURROUNDING,   ImfDeleteSurrounding, this );
396     ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, PrivateCommand, this );
397     ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_COMMIT_CONTENT,       CommitContent, this );
398
399     ecore_imf_context_input_panel_event_callback_add( mIMFContext, ECORE_IMF_INPUT_PANEL_STATE_EVENT,    InputPanelStateChangeCallback, this );
400     ecore_imf_context_input_panel_event_callback_add( mIMFContext, ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, InputPanelLanguageChangeCallback, this );
401     ecore_imf_context_input_panel_event_callback_add( mIMFContext, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, InputPanelGeometryChangedCallback, this );
402     ecore_imf_context_input_panel_event_callback_add( mIMFContext, ECORE_IMF_INPUT_PANEL_KEYBOARD_MODE_EVENT, InputPanelKeyboardTypeChangedCallback, this );
403
404     ecore_imf_context_retrieve_surrounding_callback_set( mIMFContext, ImfRetrieveSurrounding, this);
405   }
406 }
407
408 void InputMethodContextEcoreWl::DisconnectCallbacks()
409 {
410   if ( mIMFContext )
411   {
412     DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::DisconnectCallbacks\n" );
413
414     ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_PREEDIT_CHANGED,      PreEdit );
415     ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_COMMIT,               Commit );
416     ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_DELETE_SURROUNDING,   ImfDeleteSurrounding );
417     ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_PRIVATE_COMMAND_SEND, PrivateCommand );
418     ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_COMMIT_CONTENT,       CommitContent );
419
420     ecore_imf_context_input_panel_event_callback_del( mIMFContext, ECORE_IMF_INPUT_PANEL_STATE_EVENT,    InputPanelStateChangeCallback     );
421     ecore_imf_context_input_panel_event_callback_del( mIMFContext, ECORE_IMF_INPUT_PANEL_LANGUAGE_EVENT, InputPanelLanguageChangeCallback  );
422     ecore_imf_context_input_panel_event_callback_del( mIMFContext, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, InputPanelGeometryChangedCallback );
423     ecore_imf_context_input_panel_event_callback_del( mIMFContext, ECORE_IMF_INPUT_PANEL_KEYBOARD_MODE_EVENT, InputPanelKeyboardTypeChangedCallback );
424
425     // We do not need to unset the retrieve surrounding callback.
426   }
427 }
428
429 void InputMethodContextEcoreWl::Activate()
430 {
431   // Reset mIdleCallbackConnected
432   mIdleCallbackConnected = false;
433
434   if ( mIMFContext )
435   {
436     DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::Activate\n" );
437
438     ecore_imf_context_focus_in( mIMFContext );
439
440     // emit keyboard activated signal
441     Dali::InputMethodContext handle( this );
442     mActivatedSignal.Emit( handle );
443   }
444 }
445
446 void InputMethodContextEcoreWl::Deactivate()
447 {
448   if( mIMFContext )
449   {
450     DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::Deactivate\n" );
451
452     Reset();
453     ecore_imf_context_focus_out( mIMFContext );
454   }
455
456   // Reset mIdleCallbackConnected
457   mIdleCallbackConnected = false;
458 }
459
460 void InputMethodContextEcoreWl::Reset()
461 {
462   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::Reset\n" );
463
464   if ( mIMFContext )
465   {
466     ecore_imf_context_reset( mIMFContext );
467   }
468 }
469
470 ImfContext* InputMethodContextEcoreWl::GetContext()
471 {
472   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetContext\n" );
473
474   return mIMFContext;
475 }
476
477 bool InputMethodContextEcoreWl::RestoreAfterFocusLost() const
478 {
479   return mRestoreAfterFocusLost;
480 }
481
482 void InputMethodContextEcoreWl::SetRestoreAfterFocusLost( bool toggle )
483 {
484   mRestoreAfterFocusLost = toggle;
485 }
486
487 /**
488  * Called when an InputMethodContext Pre-Edit changed event is received.
489  * We are still predicting what the user is typing.  The latest string is what the InputMethodContext module thinks
490  * the user wants to type.
491  */
492 void InputMethodContextEcoreWl::PreEditChanged( void*, ImfContext* imfContext, void* eventInfo )
493 {
494   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::PreEditChanged\n" );
495   auto context = static_cast<Ecore_IMF_Context*>( imfContext );
496
497   char* preEditString( NULL );
498   int cursorPosition( 0 );
499   Eina_List* attrs = NULL;
500   Eina_List* l = NULL;
501
502   Ecore_IMF_Preedit_Attr* attr;
503
504   // Retrieves attributes as well as the string the cursor position offset from start of pre-edit string.
505   // the attributes (attrs) is used in languages that use the soft arrows keys to insert characters into a current pre-edit string.
506   ecore_imf_context_preedit_string_with_attributes_get( context, &preEditString, &attrs, &cursorPosition );
507
508   if ( attrs )
509   {
510     // iterate through the list of attributes getting the type, start and end position.
511     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) ) ))
512     {
513 #ifdef DALI_PROFILE_UBUNTU
514       if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3 ) // (Ecore_IMF)
515 #else // DALI_PROFILE_UBUNTU
516       if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB4 ) // (Ecore_IMF)
517 #endif // DALI_PROFILE_UBUNTU
518       {
519         // 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.
520
521         size_t visualCharacterIndex = 0;
522         size_t byteIndex = 0;
523
524         // iterate through null terminated string checking each character's position against the given byte position ( attr->end_index ).
525         const char leadByte = preEditString[byteIndex];
526         while( leadByte != '\0' )
527         {
528           // attr->end_index is provided as a byte position not character and we need to know the character position.
529           const size_t currentSequenceLength = Utf8SequenceLength( leadByte ); // returns number of bytes used to represent character.
530           if ( byteIndex == attr->end_index )
531           {
532             cursorPosition = visualCharacterIndex;
533             break;
534             // end loop as found cursor position that matches byte position
535           }
536           else
537           {
538             byteIndex += currentSequenceLength; // jump to next character
539             visualCharacterIndex++;  // increment character count so we know our position for when we get a match
540           }
541
542           DALI_ASSERT_DEBUG( visualCharacterIndex < strlen( preEditString ));
543         }
544       }
545     }
546   }
547
548   if ( Dali::Adaptor::IsAvailable() )
549   {
550     Dali::InputMethodContext handle( this );
551     Dali::InputMethodContext::EventData eventData( Dali::InputMethodContext::PRE_EDIT, preEditString, cursorPosition, 0 );
552     Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, eventData );
553
554     if ( callbackData.update )
555     {
556       SetCursorPosition( callbackData.cursorPosition );
557       SetSurroundingText( callbackData.currentText );
558
559       NotifyCursorPosition();
560     }
561
562     if ( callbackData.preeditResetRequired )
563     {
564       Reset();
565     }
566   }
567   free( preEditString );
568 }
569
570 void InputMethodContextEcoreWl::CommitReceived( void*, ImfContext* imfContext, void* eventInfo )
571 {
572   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::CommitReceived\n" );
573
574   if ( Dali::Adaptor::IsAvailable() )
575   {
576     const std::string keyString( static_cast<char*>( eventInfo ) );
577
578     Dali::InputMethodContext handle( this );
579     Dali::InputMethodContext::EventData eventData( Dali::InputMethodContext::COMMIT, keyString, 0, 0 );
580     Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, eventData );
581
582     if( callbackData.update )
583     {
584       SetCursorPosition( callbackData.cursorPosition );
585       SetSurroundingText( callbackData.currentText );
586
587       NotifyCursorPosition();
588     }
589   }
590 }
591
592 /**
593  * Called when an InputMethodContext retrieve surround event is received.
594  * Here the InputMethodContext module wishes to know the string we are working with and where within the string the cursor is
595  * We need to signal the application to tell us this information.
596  */
597 bool InputMethodContextEcoreWl::RetrieveSurrounding( void* data, ImfContext* imfContext, char** text, int* cursorPosition )
598 {
599   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::RetrieveSurrounding\n" );
600
601   Dali::InputMethodContext::EventData imfData( Dali::InputMethodContext::GET_SURROUNDING, std::string(), 0, 0 );
602   Dali::InputMethodContext handle( this );
603   Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, imfData );
604
605   if( callbackData.update )
606   {
607     if( text )
608     {
609       const char* plainText = callbackData.currentText.c_str();
610       if( plainText )
611       {
612         // If the current input panel is password mode, dali should replace the plain text with '*' (Asterisk) character.
613         if( ecore_imf_context_input_hint_get( mIMFContext ) & ECORE_IMF_INPUT_HINT_SENSITIVE_DATA )
614         {
615           char* iter = NULL;
616           for( iter = const_cast<char*>( plainText ); iter && *iter; ++iter )
617           {
618             *iter = '*';
619           }
620         }
621       }
622       // The memory allocated by strdup() can be freed by ecore_imf_context_surrounding_get() internally.
623       *text = strdup( plainText );
624     }
625
626     if( cursorPosition )
627     {
628       mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
629       *cursorPosition = mIMFCursorPosition;
630     }
631   }
632
633   return EINA_TRUE;
634 }
635
636 /**
637  * Called when an InputMethodContext delete surrounding event is received.
638  * Here we tell the application that it should delete a certain range.
639  */
640 void InputMethodContextEcoreWl::DeleteSurrounding( void* data, ImfContext* imfContext, void* eventInfo )
641 {
642   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::DeleteSurrounding\n" );
643
644   if( Dali::Adaptor::IsAvailable() )
645   {
646     Ecore_IMF_Event_Delete_Surrounding* deleteSurroundingEvent = static_cast<Ecore_IMF_Event_Delete_Surrounding*>( eventInfo );
647
648     Dali::InputMethodContext::EventData imfData( Dali::InputMethodContext::DELETE_SURROUNDING, std::string(), deleteSurroundingEvent->offset, deleteSurroundingEvent->n_chars );
649     Dali::InputMethodContext handle( this );
650     mEventSignal.Emit( handle, imfData );
651   }
652 }
653
654 /**
655  * Called when the input method sends a private command.
656  */
657 void InputMethodContextEcoreWl::SendPrivateCommand( void* data, ImfContext* imfContext, void* eventInfo )
658 {
659   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SendPrivateCommand\n" );
660
661   if( Dali::Adaptor::IsAvailable() )
662   {
663     const char* privateCommandSendEvent = static_cast<const char*>( eventInfo );
664
665     Dali::InputMethodContext::EventData imfData( Dali::InputMethodContext::PRIVATE_COMMAND, privateCommandSendEvent, 0, 0 );
666     Dali::InputMethodContext handle( this );
667     mEventSignal.Emit( handle, imfData );
668   }
669 }
670
671 /**
672  * Called when the input method commits content, such as an image.
673  */
674 void InputMethodContextEcoreWl::SendCommitContent( void* data, ImfContext* imfContext, void* eventInfo )
675 {
676   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SendCommitContent\n" );
677
678   if( Dali::Adaptor::IsAvailable() )
679   {
680     Ecore_IMF_Event_Commit_Content* commitContent = static_cast<Ecore_IMF_Event_Commit_Content *>( eventInfo );
681     if( commitContent )
682     {
683       DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SendCommitContent commit content : %s, description : %s, mime type : %s\n",
684                                                  commitContent->content_uri, commitContent->description, commitContent->mime_types );
685       mContentReceivedSignal.Emit( commitContent->content_uri, commitContent->description, commitContent->mime_types );
686     }
687   }
688 }
689
690 void InputMethodContextEcoreWl::NotifyCursorPosition()
691 {
692   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::NotifyCursorPosition\n" );
693
694   if( mIMFContext )
695   {
696     ecore_imf_context_cursor_position_set( mIMFContext, mIMFCursorPosition );
697   }
698 }
699
700 void InputMethodContextEcoreWl::SetCursorPosition( unsigned int cursorPosition )
701 {
702   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetCursorPosition\n" );
703
704   mIMFCursorPosition = static_cast<int>( cursorPosition );
705 }
706
707 unsigned int InputMethodContextEcoreWl::GetCursorPosition() const
708 {
709   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetCursorPosition\n" );
710
711   return static_cast<unsigned int>( mIMFCursorPosition );
712 }
713
714 void InputMethodContextEcoreWl::SetSurroundingText( const std::string& text )
715 {
716   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetSurroundingText\n" );
717
718   mSurroundingText = text;
719 }
720
721 const std::string& InputMethodContextEcoreWl::GetSurroundingText() const
722 {
723   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetSurroundingText\n" );
724
725   return mSurroundingText;
726 }
727
728 void InputMethodContextEcoreWl::NotifyTextInputMultiLine( bool multiLine )
729 {
730   if( mIMFContext )
731   {
732     Ecore_IMF_Input_Hints currentHint = ecore_imf_context_input_hint_get(mIMFContext);
733     ecore_imf_context_input_hint_set( mIMFContext,
734                                       static_cast< Ecore_IMF_Input_Hints >( multiLine ?
735                                         (currentHint | ECORE_IMF_INPUT_HINT_MULTILINE) :
736                                         (currentHint & ~ECORE_IMF_INPUT_HINT_MULTILINE)));
737   }
738 }
739
740 Dali::InputMethodContext::TextDirection InputMethodContextEcoreWl::GetTextDirection()
741 {
742   Dali::InputMethodContext::TextDirection direction ( Dali::InputMethodContext::LeftToRight );
743
744     if ( mIMFContext )
745     {
746       char* locale( NULL );
747       ecore_imf_context_input_panel_language_locale_get( mIMFContext, &locale );
748
749       if ( locale )
750       {
751         direction = static_cast< Dali::InputMethodContext::TextDirection >( Locale::GetDirection( std::string( locale ) ) );
752         free( locale );
753       }
754     }
755
756   return direction;
757 }
758
759 Rect<int> InputMethodContextEcoreWl::GetInputMethodArea()
760 {
761   int xPos, yPos, width, height;
762
763   width = height = xPos = yPos = 0;
764
765   if( mIMFContext )
766   {
767     ecore_imf_context_input_panel_geometry_get( mIMFContext, &xPos, &yPos, &width, &height );
768   }
769   else
770   {
771     DALI_LOG_WARNING("VKB Unable to get IMFContext so GetSize unavailable\n");
772   // return 0 as real size unknown.
773   }
774
775   return Rect<int>(xPos,yPos,width,height);
776 }
777
778 void InputMethodContextEcoreWl::ApplyOptions( const InputMethodOptions& options )
779 {
780   using namespace Dali::InputMethod::Category;
781
782   int index;
783
784   if( mIMFContext == NULL )
785   {
786     DALI_LOG_WARNING("VKB Unable to excute ApplyOptions with Null ImfContext\n");
787     return;
788   }
789
790   if( mOptions.CompareAndSet(PANEL_LAYOUT, options, index) )
791   {
792     ecore_imf_context_input_panel_layout_set( mIMFContext, panelLayoutMap[index] );
793
794     // Sets the input hint which allows input methods to fine-tune their behavior.
795     if( panelLayoutMap[index] == ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD )
796     {
797       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 ) );
798     }
799     else
800     {
801       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 ) );
802     }
803   }
804   if( mOptions.CompareAndSet(BUTTON_ACTION, options, index) )
805   {
806     ecore_imf_context_input_panel_return_key_type_set( mIMFContext, returnKeyTypeMap[index] );
807   }
808   if( mOptions.CompareAndSet(AUTO_CAPITALIZE, options, index) )
809   {
810     ecore_imf_context_autocapital_type_set( mIMFContext, autoCapitalMap[index] );
811   }
812   if( mOptions.CompareAndSet(VARIATION, options, index) )
813   {
814     ecore_imf_context_input_panel_layout_variation_set( mIMFContext, index );
815   }
816 }
817
818 void InputMethodContextEcoreWl::SetInputPanelData( const std::string& data )
819 {
820   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetInputPanelData\n" );
821
822   if( mIMFContext )
823   {
824     int length = data.length();
825     ecore_imf_context_input_panel_imdata_set( mIMFContext, data.c_str(), length );
826   }
827 }
828
829 void InputMethodContextEcoreWl::GetInputPanelData( std::string& data )
830 {
831   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetInputPanelData\n" );
832
833   if( mIMFContext )
834   {
835     int length = 4096; // The max length is 4096 bytes
836     Dali::Vector< char > buffer;
837     buffer.Resize( length );
838     ecore_imf_context_input_panel_imdata_get( mIMFContext, &buffer[0], &length );
839     data = std::string( buffer.Begin(), buffer.End() );
840   }
841 }
842
843 Dali::InputMethodContext::State InputMethodContextEcoreWl::GetInputPanelState()
844 {
845   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetInputPanelState\n" );
846
847   if( mIMFContext )
848   {
849     int value;
850     value = ecore_imf_context_input_panel_state_get( mIMFContext );
851
852     switch (value)
853     {
854       case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
855       {
856         return Dali::InputMethodContext::SHOW;
857         break;
858       }
859
860       case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
861       {
862         return Dali::InputMethodContext::HIDE;
863         break;
864       }
865
866       case ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW:
867       {
868         return Dali::InputMethodContext::WILL_SHOW;
869         break;
870       }
871
872       default:
873       {
874         return Dali::InputMethodContext::DEFAULT;
875       }
876     }
877   }
878   return Dali::InputMethodContext::DEFAULT;
879 }
880
881 void InputMethodContextEcoreWl::SetReturnKeyState( bool visible )
882 {
883   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetReturnKeyState\n" );
884
885   if( mIMFContext )
886   {
887     ecore_imf_context_input_panel_return_key_disabled_set( mIMFContext, !visible );
888   }
889 }
890
891 void InputMethodContextEcoreWl::AutoEnableInputPanel( bool enabled )
892 {
893   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::AutoEnableInputPanel\n" );
894
895   if( mIMFContext )
896   {
897     ecore_imf_context_input_panel_enabled_set( mIMFContext, enabled );
898   }
899 }
900
901 void InputMethodContextEcoreWl::ShowInputPanel()
902 {
903   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::ShowInputPanel\n" );
904
905   if( mIMFContext )
906   {
907     ecore_imf_context_input_panel_show( mIMFContext );
908   }
909 }
910
911 void InputMethodContextEcoreWl::HideInputPanel()
912 {
913   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::HideInputPanel\n" );
914
915   if( mIMFContext )
916   {
917     ecore_imf_context_input_panel_hide( mIMFContext );
918   }
919 }
920
921 Dali::InputMethodContext::KeyboardType InputMethodContextEcoreWl::GetKeyboardType()
922 {
923   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetKeyboardType\n" );
924
925   if( mIMFContext )
926   {
927     int value;
928     value = ecore_imf_context_keyboard_mode_get( mIMFContext );
929
930     switch (value)
931     {
932       case ECORE_IMF_INPUT_PANEL_SW_KEYBOARD_MODE:
933       {
934         return Dali::InputMethodContext::SOFTWARE_KEYBOARD;
935         break;
936       }
937       case ECORE_IMF_INPUT_PANEL_HW_KEYBOARD_MODE:
938       {
939         return Dali::InputMethodContext::HARDWARE_KEYBOARD;
940         break;
941       }
942     }
943   }
944
945   return Dali::InputMethodContext::KeyboardType::SOFTWARE_KEYBOARD;
946 }
947
948 std::string InputMethodContextEcoreWl::GetInputPanelLocale()
949 {
950   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetInputPanelLocale\n" );
951
952   std::string locale = "";
953
954   if( mIMFContext )
955   {
956     char* value = NULL;
957     ecore_imf_context_input_panel_language_locale_get( mIMFContext, &value );
958
959     if( value )
960     {
961       std::string valueCopy( value );
962       locale = valueCopy;
963
964       // The locale string retrieved must be freed with free().
965       free( value );
966     }
967   }
968   return locale;
969 }
970
971 void InputMethodContextEcoreWl::SetContentMIMETypes( const std::string& mimeTypes )
972 {
973   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetContentMIMETypes\n" );
974
975   if( mIMFContext )
976   {
977     ecore_imf_context_mime_type_accept_set( mIMFContext, mimeTypes.c_str() );
978   }
979 }
980
981 bool InputMethodContextEcoreWl::FilterEventKey( const Dali::KeyEvent& keyEvent )
982 {
983   bool eventHandled( false );
984
985   // If a device key then skip ecore_imf_context_filter_event.
986   if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ))
987   {
988     //check whether it's key down or key up event
989     if ( keyEvent.state == KeyEvent::Down )
990     {
991       eventHandled = ProcessEventKeyDown( keyEvent );
992     }
993     else if ( keyEvent.state == KeyEvent::Up )
994     {
995       eventHandled = ProcessEventKeyUp( keyEvent );
996     }
997   }
998
999   return eventHandled;
1000 }
1001
1002 void InputMethodContextEcoreWl::AllowTextPrediction( bool prediction )
1003 {
1004   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::AllowTextPrediction\n" );
1005
1006   if( mIMFContext )
1007   {
1008     ecore_imf_context_prediction_allow_set( mIMFContext, prediction );
1009   }
1010 }
1011
1012 bool InputMethodContextEcoreWl::IsTextPredictionAllowed() const
1013 {
1014   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::IsTextPredictionAllowed\n" );
1015   bool prediction = false;
1016   if( mIMFContext )
1017   {
1018     prediction = ecore_imf_context_prediction_allow_get( mIMFContext );
1019   }
1020   return prediction;
1021 }
1022
1023 void InputMethodContextEcoreWl::SetInputPanelLanguage( Dali::InputMethodContext::InputPanelLanguage language )
1024 {
1025   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::SetInputPanelLanguage\n" );
1026   if( mIMFContext )
1027   {
1028     switch (language)
1029     {
1030       case Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC:
1031       {
1032         ecore_imf_context_input_panel_language_set( mIMFContext, ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC );
1033         break;
1034       }
1035       case Dali::InputMethodContext::InputPanelLanguage::ALPHABET:
1036       {
1037         ecore_imf_context_input_panel_language_set( mIMFContext, ECORE_IMF_INPUT_PANEL_LANG_ALPHABET );
1038         break;
1039       }
1040     }
1041   }
1042 }
1043
1044 Dali::InputMethodContext::InputPanelLanguage InputMethodContextEcoreWl::GetInputPanelLanguage() const
1045 {
1046   DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextEcoreWl::GetInputPanelLanguage\n" );
1047   if( mIMFContext )
1048   {
1049     int value;
1050     value =  ecore_imf_context_input_panel_language_get( mIMFContext );
1051
1052     switch (value)
1053     {
1054       case ECORE_IMF_INPUT_PANEL_LANG_AUTOMATIC:
1055       {
1056         return Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC;
1057         break;
1058       }
1059       case ECORE_IMF_INPUT_PANEL_LANG_ALPHABET:
1060       {
1061         return Dali::InputMethodContext::InputPanelLanguage::ALPHABET;
1062         break;
1063       }
1064     }
1065   }
1066   return Dali::InputMethodContext::InputPanelLanguage::AUTOMATIC;
1067 }
1068
1069 bool InputMethodContextEcoreWl::ProcessEventKeyDown( const KeyEvent& keyEvent )
1070 {
1071   bool eventHandled( false );
1072   if ( mIMFContext )
1073   {
1074     Integration::KeyEvent integKeyEvent( keyEvent );
1075     std::string key = integKeyEvent.logicalKey;
1076
1077     std::string compose = keyEvent.GetCompose();
1078     std::string deviceName = keyEvent.GetDeviceName();
1079
1080     // We're consuming key down event so we have to pass to InputMethodContext so that it can parse it as well.
1081     Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
1082     ecoreKeyDownEvent.keyname = keyEvent.keyPressedName.c_str();
1083     ecoreKeyDownEvent.key = key.c_str();
1084     ecoreKeyDownEvent.string = keyEvent.keyPressed.c_str();
1085     ecoreKeyDownEvent.compose = compose.c_str();
1086     ecoreKeyDownEvent.timestamp = keyEvent.time;
1087     ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( keyEvent.keyModifier );
1088     ecoreKeyDownEvent.locks = EcoreInputModifierToEcoreIMFLock( keyEvent.keyModifier );
1089     ecoreKeyDownEvent.dev_name = deviceName.c_str();
1090     ecoreKeyDownEvent.dev_class = static_cast<Ecore_IMF_Device_Class> ( keyEvent.GetDeviceClass() );//ECORE_IMF_DEVICE_CLASS_KEYBOARD;
1091     ecoreKeyDownEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass> ( keyEvent.GetDeviceSubclass() );//ECORE_IMF_DEVICE_SUBCLASS_NONE;
1092
1093     // 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.
1094     if ((keyEvent.GetDeviceName() == "ime") && ((!strncmp(keyEvent.keyPressedName.c_str(), "Left", 4)) ||
1095                                    (!strncmp(keyEvent.keyPressedName.c_str(), "Right", 5)) ||
1096                                    (!strncmp(keyEvent.keyPressedName.c_str(), "Up", 2)) ||
1097                                    (!strncmp(keyEvent.keyPressedName.c_str(), "Down", 4))))
1098     {
1099       eventHandled = 0;
1100     }
1101     else
1102     {
1103       eventHandled = ecore_imf_context_filter_event(mIMFContext,
1104                                                     ECORE_IMF_EVENT_KEY_DOWN,
1105                                                     reinterpret_cast<Ecore_IMF_Event *>( &ecoreKeyDownEvent ) );
1106     }
1107
1108     // If the event has not been handled by InputMethodContext then check if we should reset our input method context
1109     if (!eventHandled)
1110     {
1111       if (!strcmp(keyEvent.keyPressedName.c_str(), "Escape") ||
1112           !strcmp(keyEvent.keyPressedName.c_str(), "Return") ||
1113           !strcmp(keyEvent.keyPressedName.c_str(), "KP_Enter"))
1114       {
1115         ecore_imf_context_reset(mIMFContext);
1116       }
1117     }
1118   }
1119   return eventHandled;
1120 }
1121
1122 bool InputMethodContextEcoreWl::ProcessEventKeyUp( const KeyEvent& keyEvent )
1123 {
1124   bool eventHandled( false );
1125   if( mIMFContext )
1126   {
1127     Integration::KeyEvent integKeyEvent( keyEvent );
1128     std::string key = integKeyEvent.logicalKey;
1129
1130     std::string compose = keyEvent.GetCompose();
1131     std::string deviceName = keyEvent.GetDeviceName();
1132
1133     // We're consuming key up event so we have to pass to InputMethodContext so that it can parse it as well.
1134     Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
1135     ecoreKeyUpEvent.keyname = keyEvent.keyPressedName.c_str();
1136     ecoreKeyUpEvent.key = key.c_str();
1137     ecoreKeyUpEvent.string = keyEvent.keyPressed.c_str();
1138     ecoreKeyUpEvent.compose = compose.c_str();
1139     ecoreKeyUpEvent.timestamp = keyEvent.time;
1140     ecoreKeyUpEvent.modifiers =  EcoreInputModifierToEcoreIMFModifier( keyEvent.keyModifier );
1141     ecoreKeyUpEvent.locks = EcoreInputModifierToEcoreIMFLock( keyEvent.keyModifier );
1142     ecoreKeyUpEvent.dev_name = deviceName.c_str();
1143     ecoreKeyUpEvent.dev_class = static_cast<Ecore_IMF_Device_Class> ( keyEvent.GetDeviceClass() );//ECORE_IMF_DEVICE_CLASS_KEYBOARD;
1144     ecoreKeyUpEvent.dev_subclass = static_cast<Ecore_IMF_Device_Subclass> ( keyEvent.GetDeviceSubclass() );//ECORE_IMF_DEVICE_SUBCLASS_NONE;
1145
1146     eventHandled = ecore_imf_context_filter_event(mIMFContext,
1147                                                   ECORE_IMF_EVENT_KEY_UP,
1148                                                   reinterpret_cast<Ecore_IMF_Event *>( &ecoreKeyUpEvent ) );
1149   }
1150   return eventHandled;
1151 }
1152
1153 Ecore_IMF_Keyboard_Modifiers InputMethodContextEcoreWl::EcoreInputModifierToEcoreIMFModifier( unsigned int ecoreModifier )
1154 {
1155   unsigned int modifier( ECORE_IMF_KEYBOARD_MODIFIER_NONE );  // If no other matches returns NONE.
1156
1157   if ( ecoreModifier & ECORE_EVENT_MODIFIER_SHIFT )  // enums from ecore_input/Ecore_Input.h
1158   {
1159     modifier |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT;  // enums from ecore_imf/ecore_imf.h
1160   }
1161
1162   if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALT )
1163   {
1164     modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;
1165   }
1166
1167   if ( ecoreModifier & ECORE_EVENT_MODIFIER_CTRL )
1168   {
1169     modifier |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
1170   }
1171
1172   if ( ecoreModifier & ECORE_EVENT_MODIFIER_WIN )
1173   {
1174     modifier |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
1175   }
1176
1177   if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALTGR )
1178   {
1179     modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;
1180   }
1181
1182   return static_cast<Ecore_IMF_Keyboard_Modifiers>( modifier );
1183 }
1184
1185 Ecore_IMF_Keyboard_Locks InputMethodContextEcoreWl::EcoreInputModifierToEcoreIMFLock( unsigned int modifier )
1186 {
1187     unsigned int lock( ECORE_IMF_KEYBOARD_LOCK_NONE ); // If no other matches, returns NONE.
1188
1189     if( modifier & ECORE_EVENT_LOCK_NUM )
1190     {
1191       lock |= ECORE_IMF_KEYBOARD_LOCK_NUM; // Num lock is active.
1192     }
1193
1194     if( modifier & ECORE_EVENT_LOCK_CAPS )
1195     {
1196       lock |= ECORE_IMF_KEYBOARD_LOCK_CAPS; // Caps lock is active.
1197     }
1198
1199     if( modifier & ECORE_EVENT_LOCK_SCROLL )
1200     {
1201       lock |= ECORE_IMF_KEYBOARD_LOCK_SCROLL; // Scroll lock is active.
1202     }
1203
1204     return static_cast<Ecore_IMF_Keyboard_Locks>( lock );
1205 }
1206
1207 void InputMethodContextEcoreWl::OnStaged( Dali::Actor actor )
1208 {
1209   int windowId = GetWindowIdFromActor( actor );
1210
1211   if( mWindowId != windowId )
1212   {
1213     mWindowId = windowId;
1214
1215     // Reset
1216     Finalize();
1217     Initialize();
1218   }
1219 }
1220
1221 } // Adaptor
1222
1223 } // Internal
1224
1225 } // Dali