Fix the issue that input picker is shown twice
[framework/web/webkit-efl.git] / Source / WebKit2 / UIProcess / efl / InputMethodContextEfl.cpp
1 /*
2    Copyright (C) 2011 Samsung Electronics
3    Copyright (C) 2012 Intel Corporation. All rights reserved.
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22 #include "InputMethodContextEfl.h"
23
24 #include "EwkViewImpl.h"
25 #include "WebPageProxy.h"
26 #include <Ecore_Evas.h>
27 #include <Ecore_IMF_Evas.h>
28
29 using namespace WebCore;
30
31 namespace WebKit {
32
33 InputMethodContextEfl::InputMethodContextEfl(EwkViewImpl* viewImpl, PassOwnPtr<Ecore_IMF_Context> context)
34     : m_viewImpl(viewImpl)
35     , m_context(context)
36     , m_focused(false)
37 {
38     ASSERT(context);
39 #if ENABLE(TIZEN_ISF_PORT)
40     initializeIMFContext(m_context.get(), ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL);
41 #else
42     ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_PREEDIT_CHANGED, onIMFPreeditSequenceChanged, this);
43     ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_COMMIT, onIMFInputSequenceComplete, this);
44 #endif
45 }
46
47 InputMethodContextEfl::~InputMethodContextEfl()
48 {
49 }
50
51 #if ENABLE(TIZEN_ISF_PORT)
52 void InputMethodContextEfl::onIMFInputPanelStateChanged(void* data, Ecore_IMF_Context*, int state)
53 {
54     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
55
56     if (state == ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
57 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
58         if (inputMethodContext->m_viewImpl->pageClient->isClipboardWindowOpened())
59             inputMethodContext->m_viewImpl->pageClient->closeClipboardWindow();
60 #endif
61         evas_object_smart_callback_call(inputMethodContext->m_viewImpl->view(), "editorclient,ime,closed", 0);
62         if (inputMethodContext->m_context)
63             evas_object_focus_set(inputMethodContext->m_viewImpl->view(), false);
64     } else if (state == ECORE_IMF_INPUT_PANEL_STATE_SHOW)
65         evas_object_smart_callback_call(inputMethodContext->m_viewImpl->view(), "editorclient,ime,opened", 0);
66 }
67
68 void InputMethodContextEfl::onIMFInputPanelGeometryChanged(void* data, Ecore_IMF_Context*, int value)
69 {
70     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
71
72     Eina_Rectangle rect;
73     ecore_imf_context_input_panel_geometry_get(inputMethodContext->m_context.get(), &rect.x, &rect.y, &rect.w, &rect.h);
74     evas_object_smart_callback_call(inputMethodContext->m_viewImpl->view(), "inputmethod,changed", &rect);
75 }
76
77 void InputMethodContextEfl::onIMFCandidatePanelStateChanged(void* data, Ecore_IMF_Context*, int state)
78 {
79     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
80
81     if (state == ECORE_IMF_CANDIDATE_PANEL_SHOW)
82         evas_object_smart_callback_call(inputMethodContext->m_viewImpl->view(), "editorclient,candidate,opened", 0);
83     else
84         evas_object_smart_callback_call(inputMethodContext->m_viewImpl->view(), "editorclient,candidate,closed", 0);
85 }
86
87 void InputMethodContextEfl::onIMFCandidatePanelGeometryChanged(void* data, Ecore_IMF_Context*, int)
88 {
89     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
90
91     Eina_Rectangle rect;
92     ecore_imf_context_candidate_panel_geometry_get(inputMethodContext->m_context.get(), &rect.x, &rect.y, &rect.w, &rect.h);
93     evas_object_smart_callback_call(inputMethodContext->m_viewImpl->view(), "editorclient,candidate,changed", &rect);
94 }
95
96 Eina_Bool InputMethodContextEfl::onIMFRetrieveSurrounding(void* data, Ecore_IMF_Context*, char** text, int* offset)
97 {
98     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
99     if (!inputMethodContext->m_viewImpl->page()->focusedFrame() || !inputMethodContext->m_focused || (!text && !offset))
100         return false;
101
102     String surroundingText;
103     int cursorOffset;
104     inputMethodContext->m_viewImpl->page()->getSurroundingTextAndCursorOffset(surroundingText, cursorOffset);
105
106     if (text) {
107         CString utf8Text(surroundingText.utf8());
108         size_t length = utf8Text.length();
109
110         *text = static_cast<char*>(malloc((length + 1) * sizeof(char)));
111         if (!(*text))
112             return false;
113
114         if (length)
115             strncpy(*text, utf8Text.data(), length);
116         (*text)[length] = 0;
117     }
118
119     if (offset)
120         *offset = cursorOffset;
121
122     return true;
123 }
124
125 void InputMethodContextEfl::onIMFDeleteSurrounding(void* data, Ecore_IMF_Context*, void* eventInfo)
126 {
127     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
128     if (!eventInfo || !inputMethodContext->m_viewImpl->page()->focusedFrame() || !inputMethodContext->m_focused)
129         return;
130
131     Ecore_IMF_Event_Delete_Surrounding* event = static_cast<Ecore_IMF_Event_Delete_Surrounding*>(eventInfo);
132     inputMethodContext->m_viewImpl->page()->deleteSurroundingText(event->offset, event->n_chars);
133 }
134
135 void InputMethodContextEfl::onIMFInputSequenceComplete(void* data, Ecore_IMF_Context*, void* eventInfo)
136 {
137     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
138     if (!eventInfo || !inputMethodContext->m_focused)
139         return;
140
141     inputMethodContext->m_viewImpl->page()->confirmComposition(String::fromUTF8(static_cast<char*>(eventInfo)));
142 }
143
144 #if ENABLE(TIZEN_WEBKIT2_SUPPORT_JAPANESE_IME)
145 unsigned getUTF8CharacterIndex(const char* string, unsigned byteIndex)
146 {
147     unsigned index = 0;
148     const char* end = string + byteIndex;
149
150     while (*string && string < end) {
151         unsigned offset;
152
153         if ((*string & 0x80) == 0x00)
154             offset = 1;
155         else if ((*string & 0xe0) == 0xc0)
156             offset = 2;
157         else if ((*string & 0xf0) == 0xe0)
158             offset = 3;
159         else if ((*string & 0xf8) == 0xf0)
160             offset = 4;
161         else if ((*string & 0xfc) == 0xf8)
162             offset = 5;
163         else if ((*string & 0xfe) == 0xfc)
164             offset = 6;
165         else
166             offset = 1;
167
168         ++index;
169         while (*string && offset--)
170             ++string;
171     }
172
173     return index;
174 }
175 #endif
176
177 void InputMethodContextEfl::onIMFPreeditSequenceChanged(void* data, Ecore_IMF_Context* context, void*)
178 {
179     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
180
181     if (!inputMethodContext->m_viewImpl->page()->focusedFrame() || !inputMethodContext->m_focused)
182         return;
183
184     WebPageProxy* page = inputMethodContext->m_viewImpl->page();
185     if (!page->focusedFrame())
186         return;
187
188     PageClientImpl* pageClient = inputMethodContext->m_viewImpl->pageClient.get();
189     IntRect caretRect;
190     page->getCaretPosition(caretRect);
191     caretRect.scale(pageClient->scaleFactor());
192
193     int viewX, viewY;
194     evas_object_geometry_get(inputMethodContext->m_viewImpl->view(), &viewX, &viewY, 0, 0);
195
196     int x = caretRect.x() - pageClient->scrollPosition().x() + viewX;
197     int y = caretRect.y() - pageClient->scrollPosition().y() + viewY;
198     int w = caretRect.width();
199     int h = caretRect.height();
200     ecore_imf_context_cursor_location_set(context, x, y, w, h);
201
202     char* buffer = 0;
203     Eina_List* preeditAttrs = 0;
204     int cursorPosition = 0;
205
206     ecore_imf_context_preedit_string_with_attributes_get(context, &buffer, &preeditAttrs, &cursorPosition);
207
208     String preeditString = String::fromUTF8(buffer);
209     Vector<CompositionUnderline> underlines;
210
211     if (preeditAttrs) {
212         void* item = 0;
213 #if ENABLE(TIZEN_WEBKIT2_SUPPORT_JAPANESE_IME)
214         Eina_List* listIterator = 0;
215         EINA_LIST_FOREACH(preeditAttrs, listIterator, item) {
216             Ecore_IMF_Preedit_Attr* preeditAttr = static_cast<Ecore_IMF_Preedit_Attr*>(item);
217
218             unsigned startIndex = getUTF8CharacterIndex(buffer, preeditAttr->start_index);
219             unsigned endIndex = getUTF8CharacterIndex(buffer, preeditAttr->end_index);
220             switch (preeditAttr->preedit_type) {
221             case ECORE_IMF_PREEDIT_TYPE_SUB1:
222                 underlines.append(CompositionUnderline(startIndex, endIndex, Color(0, 0, 0), false));
223                 break;
224             case ECORE_IMF_PREEDIT_TYPE_SUB2:
225             case ECORE_IMF_PREEDIT_TYPE_SUB3:
226                 underlines.append(CompositionUnderline(startIndex, endIndex, Color(0, 0, 0), Color(255, 255, 255), false));
227                 break;
228             case ECORE_IMF_PREEDIT_TYPE_SUB4:
229                 underlines.append(CompositionUnderline(startIndex, endIndex, Color(0, 0, 0), Color(46, 168, 255), false));
230                 break;
231             case ECORE_IMF_PREEDIT_TYPE_SUB5:
232                 underlines.append(CompositionUnderline(startIndex, endIndex, Color(0, 0, 0), Color(153, 98, 195), false));
233                 break;
234             case ECORE_IMF_PREEDIT_TYPE_SUB6:
235                 underlines.append(CompositionUnderline(startIndex, endIndex, Color(0, 0, 0), Color(118, 222, 55), false));
236                 break;
237             case ECORE_IMF_PREEDIT_TYPE_SUB7:
238                 underlines.append(CompositionUnderline(startIndex, endIndex, Color(0, 0, 0), Color(153, 153, 153), false));
239                 break;
240             default:
241                 break;
242             }
243         }
244 #endif
245         EINA_LIST_FREE(preeditAttrs, item)
246             free(item);
247     }
248
249     if (underlines.isEmpty())
250         underlines.append(CompositionUnderline(0, preeditString.length(), Color(0, 0, 0), false));
251
252     page->setComposition(preeditString, underlines, cursorPosition);
253
254     if (buffer)
255         free(buffer);
256 }
257 #else
258 void InputMethodContextEfl::onIMFInputSequenceComplete(void* data, Ecore_IMF_Context*, void* eventInfo)
259 {
260     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
261     if (!eventInfo || !inputMethodContext->m_focused)
262         return;
263
264     inputMethodContext->m_viewImpl->page()->confirmComposition(String::fromUTF8(static_cast<char*>(eventInfo)));
265 }
266
267 void InputMethodContextEfl::onIMFPreeditSequenceChanged(void* data, Ecore_IMF_Context* context, void*)
268 {
269     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
270
271     if (!inputMethodContext->m_viewImpl->page()->focusedFrame() || !inputMethodContext->m_focused)
272         return;
273
274     char* buffer = 0;
275     ecore_imf_context_preedit_string_get(context, &buffer, 0);
276     if (!buffer)
277         return;
278
279     String preeditString = String::fromUTF8(buffer);
280     free(buffer);
281     Vector<CompositionUnderline> underlines;
282     underlines.append(CompositionUnderline(0, preeditString.length(), Color(0, 0, 0), false));
283     inputMethodContext->m_viewImpl->page()->setComposition(preeditString, underlines, 0);
284 }
285 #endif
286
287 PassOwnPtr<Ecore_IMF_Context> InputMethodContextEfl::createIMFContext(Evas* canvas)
288 {
289     const char* defaultContextID = ecore_imf_context_default_id_get();
290     if (!defaultContextID)
291         return nullptr;
292
293     OwnPtr<Ecore_IMF_Context> imfContext = adoptPtr(ecore_imf_context_add(defaultContextID));
294     if (!imfContext)
295         return nullptr;
296
297     Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(canvas);
298     ecore_imf_context_client_window_set(imfContext.get(), reinterpret_cast<void*>(ecore_evas_window_get(ecoreEvas)));
299     ecore_imf_context_client_canvas_set(imfContext.get(), canvas);
300
301     return imfContext.release();
302 }
303
304 void InputMethodContextEfl::handleMouseUpEvent(const Evas_Event_Mouse_Up*)
305 {
306     ecore_imf_context_reset(m_context.get());
307 }
308
309 void InputMethodContextEfl::handleKeyDownEvent(const Evas_Event_Key_Down* downEvent, bool* isFiltered)
310 {
311     Ecore_IMF_Event inputMethodEvent;
312     ecore_imf_evas_event_key_down_wrap(const_cast<Evas_Event_Key_Down*>(downEvent), &inputMethodEvent.key_down);
313
314     *isFiltered = ecore_imf_context_filter_event(m_context.get(), ECORE_IMF_EVENT_KEY_DOWN, &inputMethodEvent);
315 }
316
317 void InputMethodContextEfl::updateTextInputState()
318 {
319 #if !ENABLE(TIZEN_ISF_PORT)
320     if (!m_context)
321         return;
322 #endif
323
324     const EditorState& editor = m_viewImpl->page()->editorState();
325
326 #if ENABLE(TIZEN_ISF_PORT)
327     bool isActive = !editor.selectionIsNone && (editor.isContentEditable || m_tryToShow);
328 #else
329     bool isActive = editor.isContentEditable;
330 #endif
331
332     if (isActive) {
333 #if ENABLE(TIZEN_ISF_PORT)
334         if (m_context)
335             ecore_imf_context_cursor_position_set(m_context.get(), editor.cursorPosition);
336 #endif
337
338         if (m_focused)
339             return;
340
341 #if ENABLE(TIZEN_ISF_PORT)
342         Ewk_Settings* settings = ewk_view_settings_get(m_viewImpl->view());
343         bool defaultKeypadEnabled = ewk_settings_default_keypad_enabled_get(settings);
344
345 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
346         if (editor.inputMethodHints == "date") {
347             showInputPicker(EWK_INPUT_TYPE_DATE, editor);
348             return;
349         } else if (editor.inputMethodHints == "datetime") {
350             showInputPicker(EWK_INPUT_TYPE_DATETIME, editor);
351             return;
352         } else if (editor.inputMethodHints == "datetime-local") {
353             showInputPicker(EWK_INPUT_TYPE_DATETIMELOCAL, editor);
354             return;
355         } else if (editor.inputMethodHints == "month") {
356             showInputPicker(EWK_INPUT_TYPE_MONTH, editor);
357             return;
358         } else if (editor.inputMethodHints == "time") {
359             showInputPicker(EWK_INPUT_TYPE_TIME, editor);
360             return;
361         } else if (editor.inputMethodHints == "week") {
362             showInputPicker(EWK_INPUT_TYPE_WEEK, editor);
363             return;
364         }
365
366 #if ENABLE(TIZEN_DATALIST_ELEMENT)
367         Vector<String> optionList = m_viewImpl->page()->getFocusedInputElementDataList();
368         if (optionList.size() > 0) {
369             if (editor.selectionIsRange || !evas_object_focus_get(m_viewImpl->view()))
370                 return;
371
372             if (editor.inputMethodHints == "tel")
373                 ewkViewDataListShowRequest(m_viewImpl->view(), EWK_INPUT_TYPE_TELEPHONE, optionList);
374             else if (editor.inputMethodHints == "number")
375                 ewkViewDataListShowRequest(m_viewImpl->view(), EWK_INPUT_TYPE_NUMBER, optionList);
376             else if (editor.inputMethodHints == "email")
377                 ewkViewDataListShowRequest(m_viewImpl->view(), EWK_INPUT_TYPE_EMAIL, optionList);
378             else if (editor.inputMethodHints == "url")
379                 ewkViewDataListShowRequest(m_viewImpl->view(), EWK_INPUT_TYPE_URL, optionList);
380             else
381                 ewkViewDataListShowRequest(m_viewImpl->view(), EWK_INPUT_TYPE_TEXT, optionList);
382
383             return;
384         }
385 #endif
386 #endif // ENABLE(TIZEN_INPUT_TAG_EXTENSION)
387
388 #if ENABLE(TIZEN_WEBKIT2_CONTEXT_MENU_CLIPBOARD)
389         if (m_viewImpl->pageClient->isClipboardWindowOpened()) {
390             LOG(ISF, "[FAIL] Clipboard\n");
391             return;
392         }
393 #endif
394
395         bool hasFocus = evas_object_focus_get(m_viewImpl->view());
396
397         if (!defaultKeypadEnabled) {
398             if (hasFocus) {
399                 Eina_Rectangle dummyRectForCustomKeypadCallback;
400                 memset(&dummyRectForCustomKeypadCallback, 0, sizeof(Eina_Rectangle));
401                 evas_object_smart_callback_call(m_viewImpl->view(), "inputmethod,changed", &dummyRectForCustomKeypadCallback);
402             }
403             return;
404         }
405
406         setType(editor.inputMethodHints);
407
408         if (!hasFocus) {
409             m_focused = true;
410             return;
411         }
412 #endif
413
414         ecore_imf_context_reset(m_context.get());
415         ecore_imf_context_focus_in(m_context.get());
416 #if ENABLE(TIZEN_ISF_PORT)
417         ecore_imf_context_input_panel_show(m_context.get());
418
419         // input field zoom for external keyboard
420         ewk_view_focused_node_adjust(m_viewImpl->view(), EINA_TRUE);
421 #endif
422         m_focused = true;
423     } else {
424         if (!m_focused)
425             return;
426
427         if (editor.hasComposition)
428             m_viewImpl->page()->cancelComposition();
429
430         m_focused = false;
431         ecore_imf_context_reset(m_context.get());
432         ecore_imf_context_focus_out(m_context.get());
433 #if ENABLE(TIZEN_ISF_PORT)
434         ecore_imf_context_input_panel_hide(m_context.get());
435         revertIMFContext();
436 #endif
437     }
438 }
439
440 #if ENABLE(TIZEN_ISF_PORT)
441 void InputMethodContextEfl::initializeIMFContext(Ecore_IMF_Context* context, Ecore_IMF_Input_Panel_Layout layout)
442 {
443     ecore_imf_context_input_panel_enabled_set(context, false);
444     ecore_imf_context_input_panel_event_callback_add(context, ECORE_IMF_INPUT_PANEL_STATE_EVENT, onIMFInputPanelStateChanged, this);
445     ecore_imf_context_input_panel_event_callback_add(context, ECORE_IMF_INPUT_PANEL_GEOMETRY_EVENT, onIMFInputPanelGeometryChanged, this);
446     ecore_imf_context_input_panel_event_callback_add(context, ECORE_IMF_CANDIDATE_PANEL_STATE_EVENT, onIMFCandidatePanelStateChanged, this);
447     ecore_imf_context_input_panel_event_callback_add(context, ECORE_IMF_CANDIDATE_PANEL_GEOMETRY_EVENT, onIMFCandidatePanelGeometryChanged, this);
448     ecore_imf_context_retrieve_surrounding_callback_set(context, onIMFRetrieveSurrounding, this);
449     ecore_imf_context_event_callback_add(context, ECORE_IMF_CALLBACK_DELETE_SURROUNDING, onIMFDeleteSurrounding, this);
450     ecore_imf_context_event_callback_add(context, ECORE_IMF_CALLBACK_PREEDIT_CHANGED, onIMFPreeditSequenceChanged, this);
451     ecore_imf_context_event_callback_add(context, ECORE_IMF_CALLBACK_COMMIT, onIMFInputSequenceComplete, this);
452     ecore_imf_context_input_panel_layout_set(m_context.get(), layout);
453 }
454
455 void InputMethodContextEfl::setType(const String& type)
456 {
457     Ecore_IMF_Input_Panel_Layout layout;
458     if (type == "number")
459         layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NUMBER;
460     else if (type == "email")
461         layout = ECORE_IMF_INPUT_PANEL_LAYOUT_EMAIL;
462     else if (type == "url")
463         layout = ECORE_IMF_INPUT_PANEL_LAYOUT_URL;
464     else if (type == "tel")
465         layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PHONENUMBER;
466     else if (type == "password")
467         layout = ECORE_IMF_INPUT_PANEL_LAYOUT_PASSWORD;
468     else
469         layout = ECORE_IMF_INPUT_PANEL_LAYOUT_NORMAL;
470
471     if (m_contextList.contains(layout)) {
472         revertIMFContext();
473         m_context = m_contextList.take(layout);
474     } else if (!m_context || ecore_imf_context_input_panel_layout_get(m_context.get()) != layout) {
475         OwnPtr<Ecore_IMF_Context> context = createIMFContext(evas_object_evas_get(m_viewImpl->view()));
476         if (m_context)
477             revertIMFContext();
478         m_context = context.release();
479         initializeIMFContext(m_context.get(), layout);
480     }
481
482     if (type == "password" || type == "plugin")
483         ecore_imf_context_prediction_allow_set(m_context.get(), false);
484     else
485         ecore_imf_context_prediction_allow_set(m_context.get(), true);
486
487     if (type.isEmpty() || type == "textarea")
488         ecore_imf_context_autocapital_type_set(m_context.get(), ECORE_IMF_AUTOCAPITAL_TYPE_SENTENCE);
489     else
490         ecore_imf_context_autocapital_type_set(m_context.get(), ECORE_IMF_AUTOCAPITAL_TYPE_NONE);
491 }
492
493 bool InputMethodContextEfl::isShow()
494 {
495     return (m_context && m_focused && ecore_imf_context_input_panel_state_get(m_context.get()) != ECORE_IMF_INPUT_PANEL_STATE_HIDE);
496 }
497
498 Ecore_IMF_Autocapital_Type InputMethodContextEfl::autoCapitalType()
499 {
500     return (m_context ? ecore_imf_context_autocapital_type_get(m_context.get()) : ECORE_IMF_AUTOCAPITAL_TYPE_NONE);
501 }
502
503 void InputMethodContextEfl::onFocusIn()
504 {
505     if (!m_context || !m_focused)
506         return;
507
508     ecore_imf_context_focus_in(m_context.get());
509     ecore_imf_context_input_panel_show(m_context.get());
510 }
511
512 void InputMethodContextEfl::onFocusOut()
513 {
514     if (!m_context || !m_focused)
515         return;
516
517     ecore_imf_context_input_panel_hide(m_context.get());
518     ecore_imf_context_focus_out(m_context.get());
519 }
520
521 void InputMethodContextEfl::revertIMFContext()
522 {
523     if (!m_context)
524         return;
525
526     PassOwnPtr<Ecore_IMF_Context> imfContext = m_context.release();
527     int layout = ecore_imf_context_input_panel_layout_get(imfContext.get());
528     m_contextList.add(layout, imfContext);
529 }
530
531 void InputMethodContextEfl::resetIMFContext()
532 {
533     if (!m_context)
534         return;
535
536     ecore_imf_context_reset(m_context.get());
537 }
538
539 void InputMethodContextEfl::hideIMFContext()
540 {
541     if (!m_context)
542         return;
543
544     if (ecore_imf_context_input_panel_state_get(m_context.get()) != ECORE_IMF_INPUT_PANEL_STATE_HIDE) {
545         ecore_imf_context_reset(m_context.get());
546         ecore_imf_context_input_panel_hide(m_context.get());
547         ecore_imf_context_focus_out(m_context.get());
548     }
549
550     revertIMFContext();
551 }
552
553 void InputMethodContextEfl::destroyIMFContextList()
554 {
555     m_contextList.clear();
556 }
557
558 #if ENABLE(TIZEN_INPUT_TAG_EXTENSION)
559 void InputMethodContextEfl::showInputPicker(Ewk_Input_Type type, const EditorState& editorState)
560 {
561     if (editorState.selectionIsRange || !evas_object_focus_get(m_viewImpl->view()))
562         return;
563
564     ewkViewInputPickerRequest(m_viewImpl->view(), type, editorState.surroundingText);
565 }
566 #endif
567
568 #endif
569
570 }