Merge "Remove the wearable definition in Makefile.am" into devel/master
[platform/core/uifw/dali-adaptor.git] / adaptors / wayland / input / text / text-input-manager.cpp
1 /*
2  * Copyright (c) 2017 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 #include "text-input-manager.h"
20
21 // EXTERNAL INCLUDES
22 #include <dali/integration-api/debug.h>
23
24 // INTERNAL INCLUDES
25 #include <key-impl.h>
26
27 namespace Dali
28 {
29
30 namespace Internal
31 {
32
33 namespace Adaptor
34 {
35
36 namespace
37 {
38 #if defined(DEBUG_ENABLED)
39 Debug::Filter* gLogFilter = Debug::Filter::New(Debug::NoLogging, false, "LOG_TEXT_INPUT");
40 #endif
41
42 TextInputManager* gTextInputManager = NULL;
43
44
45 struct ReturnKeyInfo
46 {
47   const uint32_t TizenReturnKey;
48   const InputMethod::ActionButton ReturnKey;
49 };
50
51 const ReturnKeyInfo RETURN_KEY_TABLE[] =
52 {
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 }
61 };
62
63 const unsigned int RETURN_KEY_TABLE_COUNT = sizeof( RETURN_KEY_TABLE ) / sizeof( RETURN_KEY_TABLE[ 0 ] );
64
65 int GetTizenReturnKeyType( InputMethod::ActionButton returnKey )
66 {
67   for( unsigned int i = 0; i < RETURN_KEY_TABLE_COUNT; i++ )
68   {
69     const ReturnKeyInfo& info = RETURN_KEY_TABLE[ i ];
70     if( info.ReturnKey == returnKey )
71     {
72       return info.TizenReturnKey;
73     }
74   }
75   DALI_LOG_ERROR("No mapping for InputMethod::ReturnKey %d \n", returnKey );
76
77   return WL_TEXT_INPUT_RETURN_KEY_TYPE_DEFAULT;
78
79 };
80
81 } // unnamed namespace
82
83 TextInputManager::TextInputManager()
84 : mDisplay( NULL ),
85   mLastActiveSeat( NULL ),
86   mWindowEventInterface( NULL )
87 {
88   gTextInputManager = this;
89 }
90
91 void TextInputManager::AssignWindowEventInterface( WindowEventInterface* eventInterface )
92 {
93   mWindowEventInterface = eventInterface;
94 }
95
96 void TextInputManager::AssignDisplay( WlDisplay* display )
97 {
98   mDisplay = display;
99 }
100
101 void TextInputManager::AddSeat( Seat* seat )
102 {
103   SeatInfo info;
104   info.mSeat = seat;
105   mLastActiveSeat = seat;
106
107   mSeats.push_back( info );
108 }
109
110 TextInputManager::~TextInputManager()
111 {
112   gTextInputManager = NULL;
113 }
114
115 TextInputManager& TextInputManager::Get()
116 {
117   return *gTextInputManager;
118 }
119
120 void TextInputManager::Enter( Seat* seat, WlSurface* surface )
121 {
122   // focus received typically in response to an activate request
123   mLastActiveSeat = seat;
124   SeatInfo& info = GetLastActiveSeat();
125   info.mFocused = true;
126 }
127
128 void TextInputManager::Leave( Seat* seat )
129 {
130   mLastActiveSeat = seat;
131   SeatInfo& info = GetLastActiveSeat();
132
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;
136 }
137
138 void TextInputManager::ModifiersMap( Seat* seat, WlArray *map )
139 {
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
144 }
145
146 void TextInputManager::InputPanelState( Seat* seat, uint32_t state )
147 {
148   mLastActiveSeat = seat;
149   SeatInfo& info = GetLastActiveSeat();
150
151   info.mInputPanelVisible = ( state == 1 );
152
153   // is true, then the keyboard has just shown,
154   // state == 1 for show, 0 for hidden
155   mKeyboardStatusSignal.Emit( info.mInputPanelVisible );
156
157   DALI_LOG_INFO( gLogFilter, Debug::Concise, "TextInputManager::InputPanelState changed to %d \n", state );
158 }
159
160 void TextInputManager::PreeditString( Seat* seat, uint32_t serial, const char *text, const char *commit )
161 {
162   mLastActiveSeat = seat;
163   mPreEditStringSignal.Emit( serial, text, commit );
164 }
165
166 void TextInputManager::PreeditStyling( Seat* seat, uint32_t index, uint32_t length, uint32_t style )
167 {
168   mLastActiveSeat = seat;
169   mPreEditStylingSignal.Emit( index, length, style );
170 }
171
172 void TextInputManager::PreeditCursor( Seat* seat, int32_t index )
173 {
174   mLastActiveSeat = seat;
175   mPreEditCursorSignal.Emit( index );
176 }
177
178 void TextInputManager::CommitString( Seat* seat, uint32_t serial, const char *text )
179 {
180   mLastActiveSeat = seat;
181   mCommitStringSignal.Emit( serial, text );
182
183   DALI_LOG_INFO( gLogFilter, Debug::Concise, "TextInputManager::CommitString %s \n", text );
184 }
185
186 void TextInputManager::CursorPosition( Seat* seat, int32_t index, int32_t anchor )
187 {
188   mLastActiveSeat = seat;
189   mCursorPositionSignal.Emit( index, anchor );
190 }
191
192 void TextInputManager::DeleteSurroundingText( Seat* seat, int32_t index, uint32_t length )
193 {
194   mLastActiveSeat = seat;
195   mDeleteSurroundingTextSignal.Emit( index, length );
196 }
197
198
199 void TextInputManager::Keysym( Seat* seat,
200                      uint32_t serial,
201                      uint32_t time,
202                      uint32_t sym,
203                      uint32_t state,
204                      uint32_t modifiers)
205 {
206   mLastActiveSeat = seat;
207
208   Dali::KeyEvent keyEvent = seat->GetDALiKeyEventFromSymbol( serial, time, sym, state, modifiers );
209
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
213
214   int daliKeyCode = KeyLookup::GetDaliKeyCode( keyEvent.keyPressedName.c_str() );
215   if( daliKeyCode != -1 )
216   {
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 ="";
221
222   }
223
224
225   mWindowEventInterface->KeyEvent( keyEvent );
226 }
227
228 void TextInputManager::Language( Seat* seat, uint32_t serial, const char *language )
229 {
230   mLastActiveSeat = seat;
231   SeatInfo& info = GetLastActiveSeat();
232   info.mLanguage = language;
233   mKeyboardLanguageChangedSignal.Emit();
234 }
235
236 void TextInputManager::TextDirection( Seat* seat, uint32_t serial, uint32_t direction )
237 {
238   mLastActiveSeat = seat;
239   SeatInfo& info = GetLastActiveSeat();
240
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 )
244   {
245     info.mTextDirection = Dali::VirtualKeyboard::RightToLeft;
246   }
247   else
248   {
249     info.mTextDirection = Dali::VirtualKeyboard::LeftToRight;
250   }
251 }
252
253 void TextInputManager::SelectionRegion( Seat* seat, uint32_t serial, int32_t start, int32_t end )
254 {
255   mLastActiveSeat = seat;
256   mSelectionRegionSignal.Emit( serial, start, end );
257 }
258
259 void TextInputManager::PrivateCommand( Seat* seat, uint32_t serial, const char *command )
260 {
261   mLastActiveSeat = seat;
262   // not required
263 }
264
265 void TextInputManager::InputPanelGeometry( Seat* seat,
266                                  uint32_t x,
267                                  uint32_t y,
268                                  uint32_t width,
269                                  uint32_t height)
270 {
271   mLastActiveSeat = seat;
272   SeatInfo& info = GetLastActiveSeat();
273   Dali::Rect< int > newDimensions( x, y, width, height );
274
275   if( info.mInputPanelDimensions != newDimensions )
276   {
277     info.mInputPanelDimensions = newDimensions;
278     mKeyboardResizeSignal.Emit();
279   }
280 }
281
282 void TextInputManager::InputPanelData( Seat* seat,
283                               uint32_t serial,
284                               const char* data,
285                               uint32_t dataLength )
286 {
287   mLastActiveSeat = seat;
288   // unsure what this function in the text protocol is used for due to limited documentation
289 }
290
291 TextInputManager::SeatInfo& TextInputManager::GetLastActiveSeat()
292 {
293   SeatInfo* currentSeat = &mSeats[ 0 ];
294
295   for( std::vector< SeatInfo >::iterator iter = mSeats.begin(); iter != mSeats.end(); ++iter )
296   {
297     if( ( *iter ).mSeat == mLastActiveSeat )
298     {
299       currentSeat = &( *iter );
300       break;
301     }
302
303   }
304   return *currentSeat;
305 }
306
307 Seat* TextInputManager::GetSeat( const WlTextInput* textInput)
308 {
309   for( std::vector< SeatInfo >::iterator iter = mSeats.begin(); iter != mSeats.end(); ++iter )
310   {
311     Seat* seat = ( *iter ).mSeat;
312
313     if( seat->GetTextInputInterface() == textInput )
314     {
315       return seat;
316     }
317   }
318   return NULL;
319 }
320
321 void TextInputManager::ShowInputPanel()
322 {
323   SeatInfo& info = GetLastActiveSeat();
324   info.mInputPanelVisible = true;
325   Seat* seat = info.mSeat;
326
327   wl_text_input_show_input_panel( seat->GetTextInputInterface() );
328
329   // imf normally does this...
330   wl_text_input_activate( seat->GetTextInputInterface(), seat->GetSeatInterface(), seat->GetSurface() );
331
332   wl_display_flush( mDisplay );
333 }
334
335 void TextInputManager::HideInputPanel()
336 {
337   SeatInfo& info = GetLastActiveSeat();
338   info.mInputPanelVisible = false;
339   Seat* seat = info.mSeat;
340
341   wl_text_input_deactivate( seat->GetTextInputInterface(), seat->GetSeatInterface() );
342
343   wl_text_input_hide_input_panel( seat->GetTextInputInterface() );
344
345   wl_display_flush( mDisplay );
346 }
347
348 bool TextInputManager::IsInputPanelVisible()
349 {
350    SeatInfo& info = GetLastActiveSeat();
351
352
353    return info.mInputPanelVisible;
354 }
355
356 void TextInputManager::SetReturnKeyType( const InputMethod::ActionButton type )
357 {
358   TextInputManager::SeatInfo& info = TextInputManager::Get().GetLastActiveSeat();
359
360   uint32_t returnKey = GetTizenReturnKeyType( type );
361
362   wl_text_input_set_return_key_type( info.mSeat->GetTextInputInterface(), returnKey );
363
364   wl_display_flush( mDisplay );
365 }
366
367 void TextInputManager::Reset()
368 {
369   TextInputManager::SeatInfo& info = TextInputManager::Get().GetLastActiveSeat();
370
371   wl_text_input_reset( info.mSeat->GetTextInputInterface() );
372
373   wl_display_flush( mDisplay );
374 }
375
376 void TextInputManager::SetSurroundingText( std::string text, unsigned int cursor, unsigned int anchor )
377 {
378   // set surrounding text API is subject to change in wayland.
379   wl_display_flush( mDisplay );
380 }
381
382
383 TextInputManager::PreEditStringSignalType& TextInputManager::PreEditStringSignal()
384 {
385   return mPreEditStringSignal;
386 }
387
388
389 TextInputManager::PreEditStylingSignalType& TextInputManager::PreEditStylingSignal()
390 {
391   return mPreEditStylingSignal;
392 }
393 TextInputManager::PreEditCursorSignalType& TextInputManager::PreEditCursorSignal()
394 {
395   return mPreEditCursorSignal;
396 }
397
398 TextInputManager::CommitStringSignalType& TextInputManager::CommitStringSignal()
399 {
400   return mCommitStringSignal;
401 }
402
403 TextInputManager::CursorPositionSignalType& TextInputManager::CursorPositionSignal()
404 {
405   return mCursorPositionSignal;
406 }
407
408 TextInputManager::DeleteSurroundingTextSignalType& TextInputManager::DeleteSurroundingTextSignal()
409 {
410   return mDeleteSurroundingTextSignal;
411 }
412
413 TextInputManager::SelectionRegionSignalType& TextInputManager::SelectionRegionSignal()
414 {
415   return mSelectionRegionSignal;
416 }
417
418 Dali::VirtualKeyboard::StatusSignalType& TextInputManager::StatusChangedSignal()
419 {
420   return mKeyboardStatusSignal;
421 }
422
423 Dali::VirtualKeyboard::VoidSignalType& TextInputManager::ResizedSignal()
424 {
425   return mKeyboardResizeSignal;
426 }
427
428 Dali::VirtualKeyboard::VoidSignalType& TextInputManager::LanguageChangedSignal()
429 {
430   return mKeyboardLanguageChangedSignal;
431 }
432
433
434 } // namespace Adaptor
435
436 } // namespace Internal
437
438 } // namespace Dali