blob: cf286a91959871f4be4c7475ec29895bbd2c2c8c [file] [log] [blame]
/*
* Copyright (C) 2011 Samsung Electronics
* Copyright (C) 2012 Intel Corporation. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include "config.h"
#include "InputMethodContextEfl.h"
#include "EwkView.h"
#include "WebPageProxy.h"
#include <Ecore_Evas.h>
#include <Ecore_IMF_Evas.h>
#include <WebCore/Editor.h>
using namespace WebCore;
namespace WebKit {
InputMethodContextEfl::InputMethodContextEfl(EwkView* view, EflUniquePtr<Ecore_IMF_Context> context)
: m_view(view)
, m_context(WTFMove(context))
, m_focused(false)
{
ASSERT(m_context);
ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_PREEDIT_CHANGED, onIMFPreeditSequenceChanged, this);
ecore_imf_context_event_callback_add(m_context.get(), ECORE_IMF_CALLBACK_COMMIT, onIMFInputSequenceComplete, this);
}
InputMethodContextEfl::~InputMethodContextEfl()
{
}
void InputMethodContextEfl::onIMFInputSequenceComplete(void* data, Ecore_IMF_Context*, void* eventInfo)
{
InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
if (!eventInfo || !inputMethodContext->m_focused)
return;
inputMethodContext->m_view->page()->confirmComposition(String::fromUTF8(static_cast<char*>(eventInfo)));
}
void InputMethodContextEfl::onIMFPreeditSequenceChanged(void* data, Ecore_IMF_Context* context, void*)
{
InputMethodContextEfl* inputMethodContext = static_cast<InputMethodContextEfl*>(data);
if (!inputMethodContext->m_view->page()->focusedFrame() || !inputMethodContext->m_focused)
return;
char* buffer = 0;
ecore_imf_context_preedit_string_get(context, &buffer, 0);
if (!buffer)
return;
String preeditString = String::fromUTF8(buffer);
free(buffer);
Vector<CompositionUnderline> underlines;
underlines.append(CompositionUnderline(0, preeditString.length(), Color(0, 0, 0), false));
inputMethodContext->m_view->page()->setComposition(preeditString, underlines, 0);
}
EflUniquePtr<Ecore_IMF_Context> InputMethodContextEfl::createIMFContext(Evas* canvas)
{
const char* defaultContextID = ecore_imf_context_default_id_get();
if (!defaultContextID)
return nullptr;
EflUniquePtr<Ecore_IMF_Context> imfContext(ecore_imf_context_add(defaultContextID));
if (!imfContext)
return nullptr;
Ecore_Evas* ecoreEvas = ecore_evas_ecore_evas_get(canvas);
ecore_imf_context_client_window_set(imfContext.get(), reinterpret_cast<void*>(ecore_evas_window_get(ecoreEvas)));
ecore_imf_context_client_canvas_set(imfContext.get(), canvas);
return imfContext;
}
void InputMethodContextEfl::handleMouseUpEvent(const Evas_Event_Mouse_Up*)
{
ecore_imf_context_reset(m_context.get());
}
void InputMethodContextEfl::handleKeyDownEvent(const Evas_Event_Key_Down* downEvent, bool* isFiltered)
{
Ecore_IMF_Event inputMethodEvent;
ecore_imf_evas_event_key_down_wrap(const_cast<Evas_Event_Key_Down*>(downEvent), &inputMethodEvent.key_down);
*isFiltered = ecore_imf_context_filter_event(m_context.get(), ECORE_IMF_EVENT_KEY_DOWN, &inputMethodEvent);
}
void InputMethodContextEfl::updateTextInputState()
{
if (!m_context)
return;
const EditorState& editor = m_view->page()->editorState();
if (editor.isContentEditable) {
if (m_focused)
return;
ecore_imf_context_reset(m_context.get());
ecore_imf_context_focus_in(m_context.get());
m_focused = true;
} else {
if (!m_focused)
return;
if (editor.hasComposition)
m_view->page()->cancelComposition();
m_focused = false;
ecore_imf_context_reset(m_context.get());
ecore_imf_context_focus_out(m_context.get());
}
}
}