- add sources.
[platform/framework/web/crosswalk.git] / src / ui / base / ime / input_method_linux_x11.cc
1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "ui/base/ime/input_method_linux_x11.h"
6
7 #include "ui/base/ime/linux/linux_input_method_context_factory.h"
8 #include "ui/base/ime/text_input_client.h"
9 #include "ui/events/event.h"
10 #include "ui/events/event_utils.h"
11 #include "ui/events/keycodes/keyboard_code_conversion.h"
12 #include "ui/events/keycodes/keyboard_code_conversion_x.h"
13
14 namespace ui {
15
16 InputMethodLinuxX11::InputMethodLinuxX11(
17     internal::InputMethodDelegate* delegate) {
18   SetDelegate(delegate);
19 }
20
21 InputMethodLinuxX11::~InputMethodLinuxX11() {}
22
23 // Overriden from InputMethod.
24
25 void InputMethodLinuxX11::Init(bool focused) {
26   CHECK(LinuxInputMethodContextFactory::instance());
27   input_method_context_ =
28       LinuxInputMethodContextFactory::instance()->CreateInputMethodContext(
29           this);
30   CHECK(input_method_context_.get());
31
32   InputMethodBase::Init(focused);
33
34   if (focused) {
35     input_method_context_->OnTextInputTypeChanged(
36         GetTextInputClient() ?
37         GetTextInputClient()->GetTextInputType() :
38         TEXT_INPUT_TYPE_TEXT);
39   }
40 }
41
42 bool InputMethodLinuxX11::OnUntranslatedIMEMessage(
43     const base::NativeEvent& event,
44     NativeEventResult* result) {
45   return false;
46 }
47
48 bool InputMethodLinuxX11::DispatchKeyEvent(
49     const base::NativeEvent& native_key_event) {
50   EventType event_type = EventTypeFromNative(native_key_event);
51   DCHECK(event_type == ET_KEY_PRESSED || event_type == ET_KEY_RELEASED);
52   DCHECK(system_toplevel_window_focused());
53
54   // If no text input client, do nothing.
55   if (!GetTextInputClient())
56     return DispatchKeyEventPostIME(native_key_event);
57
58   // Let an IME handle the key event first.
59   if (input_method_context_->DispatchKeyEvent(native_key_event)) {
60     if (event_type == ET_KEY_PRESSED)
61       DispatchFabricatedKeyEventPostIME(ET_KEY_PRESSED, VKEY_PROCESSKEY,
62                                         EventFlagsFromNative(native_key_event));
63     return true;
64   }
65
66   // Otherwise, insert the character.
67   const bool handled = DispatchKeyEventPostIME(native_key_event);
68   if (event_type == ET_KEY_PRESSED && GetTextInputClient()) {
69     uint16 ch = 0;
70     const int flags = EventFlagsFromNative(native_key_event);
71     if (!(flags & EF_CONTROL_DOWN))
72       ch = GetCharacterFromXEvent(native_key_event);
73     if (!ch)
74       ch = GetCharacterFromKeyCode(KeyboardCodeFromNative(native_key_event),
75                                    flags);
76     if (ch) {
77       GetTextInputClient()->InsertChar(ch, flags);
78       return true;
79     }
80   }
81   return handled;
82 }
83
84 bool InputMethodLinuxX11::DispatchFabricatedKeyEvent(
85     const ui::KeyEvent& event) {
86   // Let a post IME handler handle the key event.
87   if (DispatchFabricatedKeyEventPostIME(event.type(), event.key_code(),
88                                         event.flags()))
89     return true;
90
91   // Otherwise, insert the character.
92   if (event.type() == ET_KEY_PRESSED && GetTextInputClient()) {
93     const uint16 ch = event.GetCharacter();
94     if (ch) {
95       GetTextInputClient()->InsertChar(ch, event.flags());
96       return true;
97     }
98   }
99
100   return false;
101 }
102
103 void InputMethodLinuxX11::OnTextInputTypeChanged(
104     const TextInputClient* client) {
105   if (IsTextInputClientFocused(client)) {
106     input_method_context_->Reset();
107     // TODO(yoichio): Support inputmode HTML attribute.
108     input_method_context_->OnTextInputTypeChanged(client->GetTextInputType());
109   }
110   InputMethodBase::OnTextInputTypeChanged(client);
111 }
112
113 void InputMethodLinuxX11::OnCaretBoundsChanged(const TextInputClient* client) {
114   if (IsTextInputClientFocused(client)) {
115     input_method_context_->OnCaretBoundsChanged(
116         GetTextInputClient()->GetCaretBounds());
117   }
118   InputMethodBase::OnCaretBoundsChanged(client);
119 }
120
121 void InputMethodLinuxX11::CancelComposition(const TextInputClient* client) {
122   if (!IsTextInputClientFocused(client))
123     return;
124
125   input_method_context_->Reset();
126   input_method_context_->OnTextInputTypeChanged(client->GetTextInputType());
127 }
128
129 void InputMethodLinuxX11::OnInputLocaleChanged() {
130   InputMethodBase::OnInputLocaleChanged();
131 }
132
133 std::string InputMethodLinuxX11::GetInputLocale() {
134   return "";
135 }
136
137 base::i18n::TextDirection InputMethodLinuxX11::GetInputTextDirection() {
138   return input_method_context_->GetInputTextDirection();
139 }
140
141 bool InputMethodLinuxX11::IsActive() {
142   // InputMethodLinuxX11 is always ready and up.
143   return true;
144 }
145
146 bool InputMethodLinuxX11::IsCandidatePopupOpen() const {
147   // There seems no way to detect candidate windows or any popups.
148   return false;
149 }
150
151 // Overriden from ui::LinuxInputMethodContextDelegate
152
153 void InputMethodLinuxX11::OnCommit(const base::string16& text) {
154   TextInputClient* text_input_client = GetTextInputClient();
155   if (text_input_client)
156     text_input_client->InsertText(text);
157 }
158
159 void InputMethodLinuxX11::OnPreeditChanged(
160     const CompositionText& composition_text) {
161   TextInputClient* text_input_client = GetTextInputClient();
162   if (text_input_client)
163     text_input_client->SetCompositionText(composition_text);
164 }
165
166 void InputMethodLinuxX11::OnPreeditEnd() {
167   TextInputClient* text_input_client = GetTextInputClient();
168   if (text_input_client && text_input_client->HasCompositionText())
169     text_input_client->ClearCompositionText();
170 }
171
172 void InputMethodLinuxX11::OnPreeditStart() {}
173
174 // Overridden from InputMethodBase.
175
176 void InputMethodLinuxX11::OnDidChangeFocusedClient(
177     TextInputClient* focused_before,
178     TextInputClient* focused) {
179   input_method_context_->Reset();
180   input_method_context_->OnTextInputTypeChanged(
181       focused ? focused->GetTextInputType() : TEXT_INPUT_TYPE_NONE);
182
183   InputMethodBase::OnDidChangeFocusedClient(focused_before, focused);
184 }
185
186 }  // namespace ui