2 * Copyright (c) 2018 Samsung Electronics Co., Ltd.
\r
4 * Licensed under the Apache License, Version 2.0 (the "License");
\r
5 * you may not use this file except in compliance with the License.
\r
6 * You may obtain a copy of the License at
\r
8 * http://www.apache.org/licenses/LICENSE-2.0
\r
10 * Unless required by applicable law or agreed to in writing, software
\r
11 * distributed under the License is distributed on an "AS IS" BASIS,
\r
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
13 * See the License for the specific language governing permissions and
\r
14 * limitations under the License.
\r
19 #include <dali/internal/input/windows/input-method-context-impl-win.h>
\r
21 // EXTERNAL INCLUDES
\r
22 //#include <Ecore_IMF.h>
\r
23 //#include <Ecore_Input.h>
\r
24 #include <dali/public-api/events/key-event.h>
\r
25 #include <dali/public-api/adaptor-framework/key.h>
\r
26 #include <dali/public-api/object/type-registry.h>
\r
27 #include <dali/integration-api/debug.h>
\r
29 // INTERNAL INCLUDES
\r
30 #include <dali/integration-api/adaptor.h>
\r
31 #include <dali/internal/adaptor/common/adaptor-impl.h>
\r
32 #include <dali/internal/system/common/locale-utils.h>
\r
33 #include <dali/internal/system/common/singleton-service-impl.h>
\r
34 #include <dali/internal/input/common/virtual-keyboard-impl.h>
\r
35 #include <dali/internal/input/common/key-impl.h>
\r
36 // Ecore is littered with C style cast
\r
37 #pragma GCC diagnostic push
\r
38 #pragma GCC diagnostic ignored "-Wold-style-cast"
\r
39 //#include <dali/internal/input/tizen-wayland/ecore-virtual-keyboard.h>
\r
52 #if defined(DEBUG_ENABLED)
\r
53 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_INPUT_METHOD_CONTEXT");
\r
56 // Currently this code is internal to dali/dali/internal/event/text/utf8.h but should be made Public and used from there instead.
\r
57 size_t Utf8SequenceLength(const unsigned char leadByte)
\r
61 if ((leadByte & 0x80) == 0 ) //ASCII character (lead bit zero)
\r
65 else if (( leadByte & 0xe0 ) == 0xc0 ) //110x xxxx
\r
69 else if (( leadByte & 0xf0 ) == 0xe0 ) //1110 xxxx
\r
73 else if (( leadByte & 0xf8 ) == 0xf0 ) //1111 0xxx
\r
81 //// Static function calls used by ecore 'c' style callback registration
\r
82 //void Commit( void *data, Ecore_IMF_Context *imfContext, void *event_info )
\r
86 // InputMethodContextWin* inputMethodContext = reinterpret_cast< InputMethodContextWin* > ( data );
\r
87 // inputMethodContext->CommitReceived( data, imfContext, event_info );
\r
91 //void PreEdit( void *data, Ecore_IMF_Context *imfContext, void *event_info )
\r
95 // InputMethodContextWin* inputMethodContext = reinterpret_cast< InputMethodContextWin* > ( data );
\r
96 // inputMethodContext->PreEditChanged( data, imfContext, event_info );
\r
100 //Eina_Bool ImfRetrieveSurrounding(void *data, Ecore_IMF_Context *imfContext, char** text, int* cursorPosition )
\r
104 // InputMethodContextWin* inputMethodContext = reinterpret_cast< InputMethodContextWin* > ( data );
\r
105 // return inputMethodContext->RetrieveSurrounding( data, imfContext, text, cursorPosition );
\r
114 // * Called when an InputMethodContext delete surrounding event is received.
\r
115 // * Here we tell the application that it should delete a certain range.
\r
117 //void ImfDeleteSurrounding( void *data, Ecore_IMF_Context *imfContext, void *event_info )
\r
121 // InputMethodContextWin* inputMethodContext = reinterpret_cast< InputMethodContextWin* > ( data );
\r
122 // inputMethodContext->DeleteSurrounding( data, imfContext, event_info );
\r
126 } // unnamed namespace
\r
128 InputMethodContextPtr InputMethodContextWin::New()
\r
130 InputMethodContextPtr manager;
\r
132 if ( Adaptor::IsAvailable() )
\r
134 // Create instance and register singleton only if the adaptor is available
\r
135 Adaptor& adaptorImpl( Adaptor::GetImplementation( Adaptor::Get() ) );
\r
136 Any nativeWindow = adaptorImpl.GetNativeWindowHandle();
\r
138 // The Win_Window_Handle needs to use the InputMethodContext.
\r
139 // Only when the render surface is window, we can get the Win_Window_Handle.
\r
140 Win_Window_Handle winWindow( AnyCast<Win_Window_Handle>(nativeWindow) );
\r
143 // If we fail to get Win_Window_Handle, we can't use the InputMethodContext correctly.
\r
144 // Thus you have to call "ecore_imf_context_client_window_set" somewhere.
\r
145 // In EvasPlugIn, this function is called in EvasPlugin::ConnectEcoreEvent().
\r
147 manager = new InputMethodContextWin( winWindow );
\r
151 DALI_LOG_ERROR("Failed to get native window handle\n");
\r
158 void InputMethodContextWin::Finalize()
\r
160 //DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::Finalize\n" );
\r
161 //VirtualKeyboard::DisconnectCallbacks( mIMFContext );
\r
162 //DisconnectCallbacks();
\r
166 InputMethodContextWin::InputMethodContextWin( Win_Window_Handle winWindow )
\r
167 : mWin32Window( winWindow ),
\r
168 mIMFCursorPosition( 0 ),
\r
169 mSurroundingText(),
\r
170 mRestoreAfterFocusLost( false ),
\r
171 mIdleCallbackConnected( false )
\r
173 //ecore_imf_init();
\r
176 InputMethodContextWin::~InputMethodContextWin()
\r
179 //ecore_imf_shutdown();
\r
182 void InputMethodContextWin::Initialize()
\r
184 CreateContext( mWin32Window );
\r
185 ConnectCallbacks();
\r
186 //VirtualKeyboard::ConnectCallbacks( mIMFContext );
\r
189 void InputMethodContextWin::CreateContext( Win_Window_Handle ecoreXwin )
\r
191 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::CreateContext\n" );
\r
193 //const char *contextId = ecore_imf_context_default_id_get();
\r
196 // mIMFContext = ecore_imf_context_add( contextId );
\r
198 // if( mIMFContext )
\r
202 // ecore_imf_context_client_window_set( mIMFContext, reinterpret_cast<void*>( ecoreXwin ) );
\r
207 // DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContext Unable to get IMFContext\n");
\r
212 // DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContext Unable to get IMFContext\n");
\r
216 void InputMethodContextWin::DeleteContext()
\r
218 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::DeleteContext\n" );
\r
220 //if ( mIMFContext )
\r
222 // ecore_imf_context_del( mIMFContext );
\r
223 // mIMFContext = NULL;
\r
227 // Callbacks for predicitive text support.
\r
228 void InputMethodContextWin::ConnectCallbacks()
\r
230 //if ( mIMFContext )
\r
232 // DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::ConnectCallbacks\n" );
\r
234 // ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, PreEdit, this );
\r
235 // ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_COMMIT, Commit, this );
\r
236 // ecore_imf_context_event_callback_add( mIMFContext, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, ImfDeleteSurrounding, this );
\r
238 // ecore_imf_context_retrieve_surrounding_callback_set( mIMFContext, ImfRetrieveSurrounding, this);
\r
242 void InputMethodContextWin::DisconnectCallbacks()
\r
244 //if ( mIMFContext )
\r
246 // DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::DisconnectCallbacks\n" );
\r
248 // ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, PreEdit );
\r
249 // ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_COMMIT, Commit );
\r
250 // ecore_imf_context_event_callback_del( mIMFContext, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, ImfDeleteSurrounding );
\r
252 // // We do not need to unset the retrieve surrounding callback.
\r
256 void InputMethodContextWin::Activate()
\r
258 // Reset mIdleCallbackConnected
\r
259 mIdleCallbackConnected = false;
\r
261 //if ( mIMFContext )
\r
263 // DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::Activate\n" );
\r
265 // ecore_imf_context_focus_in( mIMFContext );
\r
267 // // emit keyboard activated signal
\r
268 // Dali::InputMethodContext handle( this );
\r
269 // mActivatedSignal.Emit( handle );
\r
273 void InputMethodContextWin::Deactivate()
\r
275 //if( mIMFContext )
\r
277 // DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::Deactivate\n" );
\r
280 // ecore_imf_context_focus_out( mIMFContext );
\r
283 // Reset mIdleCallbackConnected
\r
284 mIdleCallbackConnected = false;
\r
287 void InputMethodContextWin::Reset()
\r
289 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::Reset\n" );
\r
291 //if ( mIMFContext )
\r
293 // ecore_imf_context_reset( mIMFContext );
\r
297 ImfContext* InputMethodContextWin::GetContext()
\r
299 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetContext\n" );
\r
301 //return mIMFContext;
\r
305 bool InputMethodContextWin::RestoreAfterFocusLost() const
\r
307 return mRestoreAfterFocusLost;
\r
310 void InputMethodContextWin::SetRestoreAfterFocusLost( bool toggle )
\r
312 mRestoreAfterFocusLost = toggle;
\r
316 * Called when an InputMethodContext Pre-Edit changed event is received.
\r
317 * We are still predicting what the user is typing. The latest string is what the InputMethodContext module thinks
\r
318 * the user wants to type.
\r
320 void InputMethodContextWin::PreEditChanged( void*, ImfContext* imfContext, void* event_info )
\r
322 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::PreEditChanged\n" );
\r
323 // auto context = reinterpret_cast<Ecore_IMF_Context*>(imfContext);
\r
325 // char* preEditString( NULL );
\r
326 // int cursorPosition( 0 );
\r
327 // Eina_List* attrs = NULL;
\r
328 // Eina_List* l = NULL;
\r
330 // Ecore_IMF_Preedit_Attr* attr;
\r
332 // // Retrieves attributes as well as the string the cursor position offset from start of pre-edit string.
\r
333 // // the attributes (attrs) is used in languages that use the soft arrows keys to insert characters into a current pre-edit string.
\r
334 // ecore_imf_context_preedit_string_with_attributes_get( context, &preEditString, &attrs, &cursorPosition );
\r
338 // // iterate through the list of attributes getting the type, start and end position.
\r
339 // 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) ) ))
\r
341 //#ifdef DALI_PROFILE_UBUNTU
\r
342 // if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB3 ) // (Ecore_IMF)
\r
343 //#else // DALI_PROFILE_UBUNTU
\r
344 // if ( attr->preedit_type == ECORE_IMF_PREEDIT_TYPE_SUB4 ) // (Ecore_IMF)
\r
345 //#endif // DALI_PROFILE_UBUNTU
\r
347 // // 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.
\r
349 // size_t visualCharacterIndex = 0;
\r
350 // size_t byteIndex = 0;
\r
352 // // iterate through null terminated string checking each character's position against the given byte position ( attr->end_index ).
\r
353 // const char leadByte = preEditString[byteIndex];
\r
354 // while( leadByte != '\0' )
\r
356 // // attr->end_index is provided as a byte position not character and we need to know the character position.
\r
357 // const size_t currentSequenceLength = Utf8SequenceLength( leadByte ); // returns number of bytes used to represent character.
\r
358 // if ( byteIndex == attr->end_index )
\r
360 // cursorPosition = visualCharacterIndex;
\r
362 // // end loop as found cursor position that matches byte position
\r
366 // byteIndex += currentSequenceLength; // jump to next character
\r
367 // visualCharacterIndex++; // increment character count so we know our position for when we get a match
\r
370 // DALI_ASSERT_DEBUG( visualCharacterIndex < strlen( preEditString ));
\r
376 //if ( Dali::Adaptor::IsAvailable() )
\r
378 // Dali::InputMethodContext handle( this );
\r
379 // Dali::InputMethodContext::EventData eventData( Dali::InputMethodContext::PRE_EDIT, preEditString, cursorPosition, 0 );
\r
380 // Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, eventData );
\r
382 // if( callbackData.update )
\r
384 // mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
\r
386 // NotifyCursorPosition();
\r
389 // if( callbackData.preeditResetRequired )
\r
394 //free( preEditString );
\r
397 void InputMethodContextWin::CommitReceived( void*, ImfContext* imfContext, void* event_info )
\r
399 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::CommitReceived\n" );
\r
401 if ( Dali::Adaptor::IsAvailable() )
\r
403 const std::string keyString( static_cast<char*>( event_info ) );
\r
405 Dali::InputMethodContext handle( this );
\r
406 Dali::InputMethodContext::EventData eventData( Dali::InputMethodContext::COMMIT, keyString, 0, 0 );
\r
407 Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, eventData );
\r
409 if( callbackData.update )
\r
411 mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
\r
413 NotifyCursorPosition();
\r
419 * Called when an InputMethodContext retrieve surround event is received.
\r
420 * Here the InputMethodContext module wishes to know the string we are working with and where within the string the cursor is
\r
421 * We need to signal the application to tell us this information.
\r
423 bool InputMethodContextWin::RetrieveSurrounding( void* data, ImfContext* imfContext, char** text, int* cursorPosition )
\r
425 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::RetrieveSurrounding\n" );
\r
427 Dali::InputMethodContext::EventData imfData( Dali::InputMethodContext::GET_SURROUNDING, std::string(), 0, 0 );
\r
428 Dali::InputMethodContext handle( this );
\r
429 Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, imfData );
\r
431 if( callbackData.update )
\r
435 *text = strdup( callbackData.currentText.c_str() );
\r
438 if( cursorPosition )
\r
440 mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
\r
441 *cursorPosition = mIMFCursorPosition;
\r
445 //return EINA_TRUE;
\r
450 * Called when an InputMethodContext delete surrounding event is received.
\r
451 * Here we tell the application that it should delete a certain range.
\r
453 void InputMethodContextWin::DeleteSurrounding( void* data, ImfContext* imfContext, void* event_info )
\r
455 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::DeleteSurrounding\n" );
\r
457 //if( Dali::Adaptor::IsAvailable() )
\r
459 // Ecore_IMF_Event_Delete_Surrounding* deleteSurroundingEvent = static_cast<Ecore_IMF_Event_Delete_Surrounding*>( event_info );
\r
461 // Dali::InputMethodContext::EventData imfData( Dali::InputMethodContext::DELETE_SURROUNDING, std::string(), deleteSurroundingEvent->offset, deleteSurroundingEvent->n_chars );
\r
462 // Dali::InputMethodContext handle( this );
\r
463 // Dali::InputMethodContext::CallbackData callbackData = mEventSignal.Emit( handle, imfData );
\r
465 // if( callbackData.update )
\r
467 // mIMFCursorPosition = static_cast<int>( callbackData.cursorPosition );
\r
469 // NotifyCursorPosition();
\r
474 void InputMethodContextWin::NotifyCursorPosition()
\r
476 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::NotifyCursorPosition\n" );
\r
478 //if( mIMFContext )
\r
480 // ecore_imf_context_cursor_position_set( mIMFContext, mIMFCursorPosition );
\r
484 void InputMethodContextWin::SetCursorPosition( unsigned int cursorPosition )
\r
486 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetCursorPosition\n" );
\r
488 mIMFCursorPosition = static_cast<int>( cursorPosition );
\r
491 unsigned int InputMethodContextWin::GetCursorPosition() const
\r
493 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetCursorPosition\n" );
\r
495 return static_cast<unsigned int>( mIMFCursorPosition );
\r
498 void InputMethodContextWin::SetSurroundingText( const std::string& text )
\r
500 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetSurroundingText\n" );
\r
502 mSurroundingText = text;
\r
505 const std::string& InputMethodContextWin::GetSurroundingText() const
\r
507 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetSurroundingText\n" );
\r
509 return mSurroundingText;
\r
512 void InputMethodContextWin::NotifyTextInputMultiLine( bool multiLine )
\r
516 Dali::InputMethodContext::TextDirection InputMethodContextWin::GetTextDirection()
\r
518 Dali::InputMethodContext::TextDirection direction ( Dali::InputMethodContext::LeftToRight );
\r
520 //if ( mIMFContext )
\r
522 // char* locale( NULL );
\r
523 // ecore_imf_context_input_panel_language_locale_get( mIMFContext, &locale );
\r
527 // direction = static_cast< Dali::InputMethodContext::TextDirection >( Locale::GetDirection( std::string( locale ) ) );
\r
535 Rect<int> InputMethodContextWin::GetInputMethodArea()
\r
537 int xPos, yPos, width, height;
\r
539 width = height = xPos = yPos = 0;
\r
541 //if( mIMFContext )
\r
543 // ecore_imf_context_input_panel_geometry_get( mIMFContext, &xPos, &yPos, &width, &height );
\r
547 // DALI_LOG_WARNING("VKB Unable to get InputMethodContext Context so GetSize unavailable\n");
\r
550 return Rect<int>(xPos,yPos,width,height);
\r
553 void InputMethodContextWin::ApplyOptions( const InputMethodOptions& options )
\r
555 using namespace Dali::InputMethod::Category;
\r
559 //if (mIMFContext == NULL)
\r
561 // DALI_LOG_WARNING("VKB Unable to excute ApplyOptions with Null ImfContext\n");
\r
565 if ( mOptions.CompareAndSet(PANEL_LAYOUT, options, index) )
\r
568 if ( mOptions.CompareAndSet(BUTTON_ACTION, options, index) )
\r
571 if ( mOptions.CompareAndSet(AUTO_CAPITALIZE, options, index) )
\r
574 if ( mOptions.CompareAndSet(VARIATION, options, index) )
\r
579 void InputMethodContextWin::SetInputPanelData( const std::string& data )
\r
581 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetInputPanelData\n" );
\r
583 //if( mIMFContext )
\r
585 // int length = data.length();
\r
586 // ecore_imf_context_input_panel_imdata_set( mIMFContext, data.c_str(), length );
\r
590 void InputMethodContextWin::GetInputPanelData( std::string& data )
\r
592 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetInputPanelData\n" );
\r
594 //if( mIMFContext )
\r
596 // int length = 4096; // The max length is 4096 bytes
\r
597 // Dali::Vector< char > buffer;
\r
598 // buffer.Resize( length );
\r
599 // ecore_imf_context_input_panel_imdata_get( mIMFContext, &buffer[0], &length );
\r
600 // data = std::string( buffer.Begin(), buffer.End() );
\r
604 Dali::InputMethodContext::State InputMethodContextWin::GetInputPanelState()
\r
606 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetInputPanelState\n" );
\r
608 //if( mIMFContext )
\r
611 // value = ecore_imf_context_input_panel_state_get( mIMFContext );
\r
615 // case ECORE_IMF_INPUT_PANEL_STATE_SHOW:
\r
617 // return Dali::InputMethodContext::SHOW;
\r
621 // case ECORE_IMF_INPUT_PANEL_STATE_HIDE:
\r
623 // return Dali::InputMethodContext::HIDE;
\r
627 // case ECORE_IMF_INPUT_PANEL_STATE_WILL_SHOW:
\r
629 // return Dali::InputMethodContext::WILL_SHOW;
\r
635 // return Dali::InputMethodContext::DEFAULT;
\r
639 return Dali::InputMethodContext::DEFAULT;
\r
642 void InputMethodContextWin::SetReturnKeyState( bool visible )
\r
644 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::SetReturnKeyState\n" );
\r
646 //if( mIMFContext )
\r
648 // ecore_imf_context_input_panel_return_key_disabled_set( mIMFContext, !visible );
\r
652 void InputMethodContextWin::AutoEnableInputPanel( bool enabled )
\r
654 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::AutoEnableInputPanel\n" );
\r
656 //if( mIMFContext )
\r
658 // ecore_imf_context_input_panel_enabled_set( mIMFContext, enabled );
\r
662 void InputMethodContextWin::ShowInputPanel()
\r
664 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::ShowInputPanel\n" );
\r
666 //if( mIMFContext )
\r
668 // ecore_imf_context_input_panel_show( mIMFContext );
\r
672 void InputMethodContextWin::HideInputPanel()
\r
674 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::HideInputPanel\n" );
\r
676 //if( mIMFContext )
\r
678 // ecore_imf_context_input_panel_hide( mIMFContext );
\r
682 Dali::InputMethodContext::KeyboardType InputMethodContextWin::GetKeyboardType()
\r
684 return Dali::InputMethodContext::KeyboardType::SOFTWARE_KEYBOARD;
\r
687 std::string InputMethodContextWin::GetInputPanelLocale()
\r
689 DALI_LOG_INFO( gLogFilter, Debug::General, "InputMethodContextWin::GetInputPanelLocale\n" );
\r
691 std::string locale = "";
\r
693 //if( mIMFContext )
\r
695 // char* value = NULL;
\r
696 // ecore_imf_context_input_panel_language_locale_get( mIMFContext, &value );
\r
700 // std::string valueCopy( value );
\r
701 // locale = valueCopy;
\r
703 // // The locale string retrieved must be freed with free().
\r
710 bool InputMethodContextWin::FilterEventKey( const Dali::KeyEvent& keyEvent )
\r
712 bool eventHandled( false );
\r
714 // If a device key then skip ecore_imf_context_filter_event.
\r
715 if ( ! KeyLookup::IsDeviceButton( keyEvent.keyPressedName.c_str() ))
\r
717 //check whether it's key down or key up event
\r
718 if ( keyEvent.state == KeyEvent::Down )
\r
720 eventHandled = ProcessEventKeyDown( keyEvent );
\r
722 else if ( keyEvent.state == KeyEvent::Up )
\r
724 eventHandled = ProcessEventKeyUp( keyEvent );
\r
728 return eventHandled;
\r
731 bool InputMethodContextWin::ProcessEventKeyDown( const KeyEvent& keyEvent )
\r
733 bool eventHandled( false );
\r
734 // if ( mIMFContext )
\r
736 // // We're consuming key down event so we have to pass to InputMethodContext so that it can parse it as well.
\r
737 // Ecore_IMF_Event_Key_Down ecoreKeyDownEvent;
\r
738 // ecoreKeyDownEvent.keyname = keyEvent.keyPressedName.c_str();
\r
739 // ecoreKeyDownEvent.key = keyEvent.keyPressedName.c_str();
\r
740 // ecoreKeyDownEvent.string = keyEvent.keyPressed.c_str();
\r
741 // ecoreKeyDownEvent.compose = keyEvent.GetCompose().c_str();
\r
742 // ecoreKeyDownEvent.timestamp = keyEvent.time;
\r
743 // ecoreKeyDownEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( keyEvent.keyModifier );
\r
744 // ecoreKeyDownEvent.locks = EcoreInputModifierToEcoreIMFLock( keyEvent.keyModifier );
\r
745 //#ifdef ECORE_IMF_1_13
\r
746 // ecoreKeyDownEvent.dev_name = "";
\r
747 // ecoreKeyDownEvent.dev_class = ECORE_IMF_DEVICE_CLASS_KEYBOARD;
\r
748 // ecoreKeyDownEvent.dev_subclass = ECORE_IMF_DEVICE_SUBCLASS_NONE;
\r
749 //#endif // ECORE_IMF_1_13
\r
751 // // 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.
\r
752 // if ((keyEvent.GetDeviceName() == "ime") && ((!strncmp(keyEvent.keyPressedName.c_str(), "Left", 4)) ||
\r
753 // (!strncmp(keyEvent.keyPressedName.c_str(), "Right", 5)) ||
\r
754 // (!strncmp(keyEvent.keyPressedName.c_str(), "Up", 2)) ||
\r
755 // (!strncmp(keyEvent.keyPressedName.c_str(), "Down", 4))))
\r
757 // eventHandled = 0;
\r
761 // eventHandled = ecore_imf_context_filter_event(mIMFContext,
\r
762 // ECORE_IMF_EVENT_KEY_DOWN,
\r
763 // (Ecore_IMF_Event *) &ecoreKeyDownEvent);
\r
766 // // If the event has not been handled by InputMethodContext then check if we should reset our IMFcontext
\r
767 // if (!eventHandled)
\r
769 // if (!strcmp(keyEvent.keyPressedName.c_str(), "Escape") ||
\r
770 // !strcmp(keyEvent.keyPressedName.c_str(), "Return") ||
\r
771 // !strcmp(keyEvent.keyPressedName.c_str(), "KP_Enter"))
\r
773 // ecore_imf_context_reset(mIMFContext);
\r
777 return eventHandled;
\r
780 bool InputMethodContextWin::ProcessEventKeyUp( const KeyEvent& keyEvent )
\r
782 bool eventHandled( false );
\r
783 // if( mIMFContext )
\r
785 // // We're consuming key up event so we have to pass to InputMethodContext so that it can parse it as well.
\r
786 // Ecore_IMF_Event_Key_Up ecoreKeyUpEvent;
\r
787 // ecoreKeyUpEvent.keyname = keyEvent.keyPressedName.c_str();
\r
788 // ecoreKeyUpEvent.key = keyEvent.keyPressedName.c_str();
\r
789 // ecoreKeyUpEvent.string = keyEvent.keyPressed.c_str();
\r
790 // ecoreKeyUpEvent.compose = keyEvent.GetCompose().c_str();
\r
791 // ecoreKeyUpEvent.timestamp = keyEvent.time;
\r
792 // ecoreKeyUpEvent.modifiers = EcoreInputModifierToEcoreIMFModifier( keyEvent.keyModifier );
\r
793 // ecoreKeyUpEvent.locks = EcoreInputModifierToEcoreIMFLock( keyEvent.keyModifier );
\r
794 //#ifdef ECORE_IMF_1_13
\r
795 // ecoreKeyUpEvent.dev_name = "";
\r
796 //#endif // ECORE_IMF_1_13
\r
798 // eventHandled = ecore_imf_context_filter_event(mIMFContext,
\r
799 // ECORE_IMF_EVENT_KEY_UP,
\r
800 // (Ecore_IMF_Event *) &ecoreKeyUpEvent);
\r
802 return eventHandled;
\r
805 //Ecore_IMF_Keyboard_Modifiers InputMethodContextWin::EcoreInputModifierToEcoreIMFModifier( unsigned int ecoreModifier )
\r
807 // unsigned int modifier( ECORE_IMF_KEYBOARD_MODIFIER_NONE ); // If no other matches returns NONE.
\r
809 // if ( ecoreModifier & ECORE_EVENT_MODIFIER_SHIFT ) // enums from ecore_input/Ecore_Input.h
\r
811 // modifier |= ECORE_IMF_KEYBOARD_MODIFIER_SHIFT; // enums from ecore_imf/ecore_imf.h
\r
814 // if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALT )
\r
816 // modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALT;
\r
819 // if ( ecoreModifier & ECORE_EVENT_MODIFIER_CTRL )
\r
821 // modifier |= ECORE_IMF_KEYBOARD_MODIFIER_CTRL;
\r
824 // if ( ecoreModifier & ECORE_EVENT_MODIFIER_WIN )
\r
826 // modifier |= ECORE_IMF_KEYBOARD_MODIFIER_WIN;
\r
829 // if ( ecoreModifier & ECORE_EVENT_MODIFIER_ALTGR )
\r
831 // modifier |= ECORE_IMF_KEYBOARD_MODIFIER_ALTGR;
\r
834 // return static_cast<Ecore_IMF_Keyboard_Modifiers>( modifier );
\r
837 //Ecore_IMF_Keyboard_Locks InputMethodContextWin::EcoreInputModifierToEcoreIMFLock( unsigned int modifier )
\r
839 // unsigned int lock( ECORE_IMF_KEYBOARD_LOCK_NONE ); // If no other matches, returns NONE.
\r
841 // if( modifier & ECORE_EVENT_LOCK_NUM )
\r
843 // lock |= ECORE_IMF_KEYBOARD_LOCK_NUM; // Num lock is active.
\r
846 // if( modifier & ECORE_EVENT_LOCK_CAPS )
\r
848 // lock |= ECORE_IMF_KEYBOARD_LOCK_CAPS; // Caps lock is active.
\r
851 // if( modifier & ECORE_EVENT_LOCK_SCROLL )
\r
853 // lock |= ECORE_IMF_KEYBOARD_LOCK_SCROLL; // Scroll lock is active.
\r
856 // return static_cast<Ecore_IMF_Keyboard_Locks>( lock );
\r
865 #pragma GCC diagnostic pop
\r