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