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