2 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include "text-input-manager.h"
22 #include <dali/integration-api/debug.h>
38 #if defined(DEBUG_ENABLED)
39 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TEXT_INPUT");
42 TextInputManager* gTextInputManager = NULL;
47 const uint32_t TizenReturnKey;
48 const InputMethod::ActionButton ReturnKey;
51 const ReturnKeyInfo RETURN_KEY_TABLE[] =
53 { WL_TEXT_INPUT_RETURN_KEY_TYPE_DEFAULT, InputMethod::ACTION_DEFAULT },
54 { WL_TEXT_INPUT_RETURN_KEY_TYPE_DONE, InputMethod::ACTION_DONE },
55 { WL_TEXT_INPUT_RETURN_KEY_TYPE_GO, InputMethod::ACTION_GO },
56 { WL_TEXT_INPUT_RETURN_KEY_TYPE_JOIN, InputMethod::ACTION_JOIN },
57 { WL_TEXT_INPUT_RETURN_KEY_TYPE_LOGIN, InputMethod::ACTION_LOGIN },
58 { WL_TEXT_INPUT_RETURN_KEY_TYPE_NEXT, InputMethod::ACTION_NEXT },
59 { WL_TEXT_INPUT_RETURN_KEY_TYPE_SEARCH, InputMethod::ACTION_SEARCH },
60 { WL_TEXT_INPUT_RETURN_KEY_TYPE_SEND, InputMethod::ACTION_SEND }
63 const unsigned int RETURN_KEY_TABLE_COUNT = sizeof( RETURN_KEY_TABLE ) / sizeof( RETURN_KEY_TABLE[ 0 ] );
65 int GetTizenReturnKeyType( InputMethod::ActionButton returnKey )
67 for( unsigned int i = 0; i < RETURN_KEY_TABLE_COUNT; i++ )
69 const ReturnKeyInfo& info = RETURN_KEY_TABLE[ i ];
70 if( info.ReturnKey == returnKey )
72 return info.TizenReturnKey;
75 DALI_LOG_ERROR("No mapping for InputMethod::ReturnKey %d \n", returnKey );
77 return WL_TEXT_INPUT_RETURN_KEY_TYPE_DEFAULT;
81 } // unnamed namespace
83 TextInputManager::TextInputManager()
85 mLastActiveSeat( NULL ),
86 mWindowEventInterface( NULL )
88 gTextInputManager = this;
91 void TextInputManager::AssignWindowEventInterface( WindowEventInterface* eventInterface )
93 mWindowEventInterface = eventInterface;
96 void TextInputManager::AssignDisplay( WlDisplay* display )
101 void TextInputManager::AddSeat( Seat* seat )
105 mLastActiveSeat = seat;
107 mSeats.push_back( info );
110 TextInputManager::~TextInputManager()
112 gTextInputManager = NULL;
115 TextInputManager& TextInputManager::Get()
117 return *gTextInputManager;
120 void TextInputManager::Enter( Seat* seat, WlSurface* surface )
122 // focus received typically in response to an activate request
123 mLastActiveSeat = seat;
124 SeatInfo& info = GetLastActiveSeat();
125 info.mFocused = true;
128 void TextInputManager::Leave( Seat* seat )
130 mLastActiveSeat = seat;
131 SeatInfo& info = GetLastActiveSeat();
133 // Focus has been lost either in response
134 // to a deactivate request or when the assigned surface lost focus or was destroyed.
135 info.mFocused = false;
138 void TextInputManager::ModifiersMap( Seat* seat, WlArray *map )
140 // Map contains an array of 0-terminated modifiers names. The
141 // position in the array is the index of the modifier as used in
142 // the modifiers bitmask in the keysym event
143 // workout if we need to use this
146 void TextInputManager::InputPanelState( Seat* seat, uint32_t state )
148 mLastActiveSeat = seat;
149 SeatInfo& info = GetLastActiveSeat();
151 info.mInputPanelVisible = ( state == 1 );
153 // is true, then the keyboard has just shown,
154 // state == 1 for show, 0 for hidden
155 mKeyboardStatusSignal.Emit( info.mInputPanelVisible );
157 DALI_LOG_INFO( gLogFilter, Debug::Concise, "TextInputManager::InputPanelState changed to %d \n", state );
160 void TextInputManager::PreeditString( Seat* seat, uint32_t serial, const char *text, const char *commit )
162 mLastActiveSeat = seat;
163 mPreEditStringSignal.Emit( serial, text, commit );
166 void TextInputManager::PreeditStyling( Seat* seat, uint32_t index, uint32_t length, uint32_t style )
168 mLastActiveSeat = seat;
169 mPreEditStylingSignal.Emit( index, length, style );
172 void TextInputManager::PreeditCursor( Seat* seat, int32_t index )
174 mLastActiveSeat = seat;
175 mPreEditCursorSignal.Emit( index );
178 void TextInputManager::CommitString( Seat* seat, uint32_t serial, const char *text )
180 mLastActiveSeat = seat;
181 mCommitStringSignal.Emit( serial, text );
183 DALI_LOG_INFO( gLogFilter, Debug::Concise, "TextInputManager::CommitString %s \n", text );
186 void TextInputManager::CursorPosition( Seat* seat, int32_t index, int32_t anchor )
188 mLastActiveSeat = seat;
189 mCursorPositionSignal.Emit( index, anchor );
192 void TextInputManager::DeleteSurroundingText( Seat* seat, int32_t index, uint32_t length )
194 mLastActiveSeat = seat;
195 mDeleteSurroundingTextSignal.Emit( index, length );
199 void TextInputManager::Keysym( Seat* seat,
206 mLastActiveSeat = seat;
208 Dali::KeyEvent keyEvent = seat->GetDALiKeyEventFromSymbol( serial, time, sym, state, modifiers );
210 // key.h which is shared between all platforms uses X keycodes
211 // We convert from a Wayland keycode to a DALi key ( if it exists).
212 // For examples Backspace in Wayland is the code 65288, we convert this to 22 = DALI_KEY_BACKSPACE
214 int daliKeyCode = KeyLookup::GetDaliKeyCode( keyEvent.keyPressedName.c_str() );
215 if( daliKeyCode != -1 )
217 // we have a match, the key will be backspace, shift etc.
218 // we have to clear out the keyPressed string, otherwise the toolkit can end up displaying it.
219 keyEvent.keyCode = daliKeyCode;
220 keyEvent.keyPressed ="";
224 Integration::KeyEvent convertedEvent( keyEvent );
225 mWindowEventInterface->KeyEvent( convertedEvent );
228 void TextInputManager::Language( Seat* seat, uint32_t serial, const char *language )
230 mLastActiveSeat = seat;
231 SeatInfo& info = GetLastActiveSeat();
232 info.mLanguage = language;
233 mKeyboardLanguageChangedSignal.Emit();
236 void TextInputManager::TextDirection( Seat* seat, uint32_t serial, uint32_t direction )
238 mLastActiveSeat = seat;
239 SeatInfo& info = GetLastActiveSeat();
241 // text-input direction can be auto, left to right, or right to left
242 // DALi only supports ltr or rtl
243 if( direction == WL_TEXT_INPUT_TEXT_DIRECTION_RTL )
245 info.mTextDirection = Dali::VirtualKeyboard::RightToLeft;
249 info.mTextDirection = Dali::VirtualKeyboard::LeftToRight;
253 void TextInputManager::SelectionRegion( Seat* seat, uint32_t serial, int32_t start, int32_t end )
255 mLastActiveSeat = seat;
256 mSelectionRegionSignal.Emit( serial, start, end );
259 void TextInputManager::PrivateCommand( Seat* seat, uint32_t serial, const char *command )
261 mLastActiveSeat = seat;
265 void TextInputManager::InputPanelGeometry( Seat* seat,
271 mLastActiveSeat = seat;
272 SeatInfo& info = GetLastActiveSeat();
273 Dali::Rect< int > newDimensions( x, y, width, height );
275 if( info.mInputPanelDimensions != newDimensions )
277 info.mInputPanelDimensions = newDimensions;
278 mKeyboardResizeSignal.Emit();
282 void TextInputManager::InputPanelData( Seat* seat,
285 uint32_t dataLength )
287 mLastActiveSeat = seat;
288 // unsure what this function in the text protocol is used for due to limited documentation
291 TextInputManager::SeatInfo& TextInputManager::GetLastActiveSeat()
293 SeatInfo* currentSeat = &mSeats[ 0 ];
295 for( std::vector< SeatInfo >::iterator iter = mSeats.begin(); iter != mSeats.end(); ++iter )
297 if( ( *iter ).mSeat == mLastActiveSeat )
299 currentSeat = &( *iter );
307 Seat* TextInputManager::GetSeat( const WlTextInput* textInput)
309 for( std::vector< SeatInfo >::iterator iter = mSeats.begin(); iter != mSeats.end(); ++iter )
311 Seat* seat = ( *iter ).mSeat;
313 if( seat->GetTextInputInterface() == textInput )
321 void TextInputManager::ShowInputPanel()
323 SeatInfo& info = GetLastActiveSeat();
324 info.mInputPanelVisible = true;
325 Seat* seat = info.mSeat;
327 wl_text_input_show_input_panel( seat->GetTextInputInterface() );
329 // imf normally does this...
330 wl_text_input_activate( seat->GetTextInputInterface(), seat->GetSeatInterface(), seat->GetSurface() );
332 wl_display_flush( mDisplay );
335 void TextInputManager::HideInputPanel()
337 SeatInfo& info = GetLastActiveSeat();
338 info.mInputPanelVisible = false;
339 Seat* seat = info.mSeat;
341 wl_text_input_deactivate( seat->GetTextInputInterface(), seat->GetSeatInterface() );
343 wl_text_input_hide_input_panel( seat->GetTextInputInterface() );
345 wl_display_flush( mDisplay );
348 bool TextInputManager::IsInputPanelVisible()
350 SeatInfo& info = GetLastActiveSeat();
353 return info.mInputPanelVisible;
356 void TextInputManager::SetReturnKeyType( const InputMethod::ActionButton type )
358 TextInputManager::SeatInfo& info = TextInputManager::Get().GetLastActiveSeat();
360 uint32_t returnKey = GetTizenReturnKeyType( type );
362 wl_text_input_set_return_key_type( info.mSeat->GetTextInputInterface(), returnKey );
364 wl_display_flush( mDisplay );
367 void TextInputManager::Reset()
369 TextInputManager::SeatInfo& info = TextInputManager::Get().GetLastActiveSeat();
371 wl_text_input_reset( info.mSeat->GetTextInputInterface() );
373 wl_display_flush( mDisplay );
376 void TextInputManager::SetSurroundingText( std::string text, unsigned int cursor, unsigned int anchor )
378 // set surrounding text API is subject to change in wayland.
379 wl_display_flush( mDisplay );
383 TextInputManager::PreEditStringSignalType& TextInputManager::PreEditStringSignal()
385 return mPreEditStringSignal;
389 TextInputManager::PreEditStylingSignalType& TextInputManager::PreEditStylingSignal()
391 return mPreEditStylingSignal;
393 TextInputManager::PreEditCursorSignalType& TextInputManager::PreEditCursorSignal()
395 return mPreEditCursorSignal;
398 TextInputManager::CommitStringSignalType& TextInputManager::CommitStringSignal()
400 return mCommitStringSignal;
403 TextInputManager::CursorPositionSignalType& TextInputManager::CursorPositionSignal()
405 return mCursorPositionSignal;
408 TextInputManager::DeleteSurroundingTextSignalType& TextInputManager::DeleteSurroundingTextSignal()
410 return mDeleteSurroundingTextSignal;
413 TextInputManager::SelectionRegionSignalType& TextInputManager::SelectionRegionSignal()
415 return mSelectionRegionSignal;
418 Dali::VirtualKeyboard::StatusSignalType& TextInputManager::StatusChangedSignal()
420 return mKeyboardStatusSignal;
423 Dali::VirtualKeyboard::VoidSignalType& TextInputManager::ResizedSignal()
425 return mKeyboardResizeSignal;
428 Dali::VirtualKeyboard::VoidSignalType& TextInputManager::LanguageChangedSignal()
430 return mKeyboardLanguageChangedSignal;
434 } // namespace Adaptor
436 } // namespace Internal