Add WTF::move()
[WebKit-https.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 "EwkView.h"
25 #include "WebPageProxy.h"
26 #include <Ecore_Evas.h>
27 #include <Ecore_IMF_Evas.h>
28 #include <WebCore/Editor.h>
29
30 using namespace WebCore;
31
32 namespace WebKit {
33
34 InputMethodContextEfl::InputMethodContextEfl(EwkView* view, EflUniquePtr<Ecore_IMF_Context> context)
35     : m_view(view)
36     , m_context(WTF::move(context))
37     , m_focused(false)
38 {
39     ASSERT(m_context);
40     ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_PREEDIT_CHANGED, onIMFPreeditSequenceChanged, this);
41     ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_COMMIT, onIMFInputSequenceComplete, this);
42 }
43
44 InputMethodContextEfl::~InputMethodContextEfl()
45 {
46 }
47
48 void InputMethodContextEfl::onIMFInputSequenceComplete(void* data, Ecore_IMF_Context*, void* eventInfo)
49 {
50     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
51     if (!eventInfo || !inputMethodContext->m_focused)
52         return;
53
54     inputMethodContext->m_view->page()->confirmComposition(String::fromUTF8(static_cast<char*>(eventInfo)));
55 }
56
57 void InputMethodContextEfl::onIMFPreeditSequenceChanged(void* data, Ecore_IMF_Context* context, void*)
58 {
59     InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
60
61     if (!inputMethodContext->m_view->page()->focusedFrame() || !inputMethodContext->m_focused)
62         return;
63
64     char* buffer = 0;
65     ecore_imf_context_preedit_string_get(context, &buffer, 0);
66     if (!buffer)
67         return;
68
69     String preeditString = String::fromUTF8(buffer);
70     free(buffer);
71     Vector<CompositionUnderline> underlines;
72     underlines.append(CompositionUnderline(0, preeditString.length(), Color(0, 0, 0), false));
73     inputMethodContext->m_view->page()->setComposition(preeditString, underlines, 0);
74 }
75
76 EflUniquePtr<Ecore_IMF_Context> InputMethodContextEfl::createIMFContext(Evas* canvas)
77 {
78     const char* defaultContextID = ecore_imf_context_default_id_get();
79     if (!defaultContextID)
80         return nullptr;
81
82     EflUniquePtr<Ecore_IMF_Context> imfContext(ecore_imf_context_add(defaultContextID));
83     if (!imfContext)
84         return nullptr;
85
86     Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(canvas);
87     ecore_imf_context_client_window_set(imfContext.get(), reinterpret_cast<void*>(ecore_evas_window_get(ecoreEvas)));
88     ecore_imf_context_client_canvas_set(imfContext.get(), canvas);
89
90     return imfContext;
91 }
92
93 void InputMethodContextEfl::handleMouseUpEvent(const Evas_Event_Mouse_Up*)
94 {
95     ecore_imf_context_reset(m_context.get());
96 }
97
98 void InputMethodContextEfl::handleKeyDownEvent(const Evas_Event_Key_Down* downEvent, bool* isFiltered)
99 {
100     Ecore_IMF_Event inputMethodEvent;
101     ecore_imf_evas_event_key_down_wrap(const_cast<Evas_Event_Key_Down*>(downEvent), &inputMethodEvent.key_down);
102
103     *isFiltered = ecore_imf_context_filter_event(m_context.get(), ECORE_IMF_EVENT_KEY_DOWN, &inputMethodEvent);
104 }
105
106 void InputMethodContextEfl::updateTextInputState()
107 {
108     if (!m_context)
109         return;
110
111     const EditorState& editor = m_view->page()->editorState();
112
113     if (editor.isContentEditable) {
114         if (m_focused)
115             return;
116
117         ecore_imf_context_reset(m_context.get());
118         ecore_imf_context_focus_in(m_context.get());
119         m_focused = true;
120     } else {
121         if (!m_focused)
122             return;
123
124         if (editor.hasComposition)
125             m_view->page()->cancelComposition();
126
127         m_focused = false;
128         ecore_imf_context_reset(m_context.get());
129         ecore_imf_context_focus_out(m_context.get());
130     }
131 }
132
133 }