OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/chromeos/input_method/input_method_engine_ibus.h" | 5 #include "chrome/browser/chromeos/input_method/input_method_engine_ibus.h" |
6 | 6 |
7 #define XK_MISCELLANY | 7 #define XK_MISCELLANY |
8 #include <X11/keysymdef.h> | 8 #include <X11/keysymdef.h> |
9 #include <map> | 9 #include <map> |
10 | 10 |
11 #include "base/bind.h" | |
11 #include "base/logging.h" | 12 #include "base/logging.h" |
12 #include "base/memory/scoped_ptr.h" | 13 #include "base/memory/scoped_ptr.h" |
13 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
14 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
15 #include "base/strings/utf_string_conversions.h" | 16 #include "base/strings/utf_string_conversions.h" |
16 #include "chromeos/dbus/dbus_thread_manager.h" | 17 #include "chromeos/dbus/dbus_thread_manager.h" |
17 #include "chromeos/dbus/ibus/ibus_engine_service.h" | |
18 #include "chromeos/dbus/ibus/ibus_text.h" | 18 #include "chromeos/dbus/ibus/ibus_text.h" |
19 #include "chromeos/ime/candidate_window.h" | 19 #include "chromeos/ime/candidate_window.h" |
20 #include "chromeos/ime/component_extension_ime_manager.h" | 20 #include "chromeos/ime/component_extension_ime_manager.h" |
21 #include "chromeos/ime/extension_ime_util.h" | 21 #include "chromeos/ime/extension_ime_util.h" |
22 #include "chromeos/ime/ibus_keymap.h" | 22 #include "chromeos/ime/ibus_keymap.h" |
23 #include "chromeos/ime/input_method_manager.h" | 23 #include "chromeos/ime/input_method_manager.h" |
24 #include "dbus/object_path.h" | 24 #include "dbus/object_path.h" |
25 | 25 |
26 namespace chromeos { | 26 namespace chromeos { |
27 const char* kErrorNotActive = "IME is not active"; | 27 const char* kErrorNotActive = "IME is not active"; |
28 const char* kErrorWrongContext = "Context is not active"; | 28 const char* kErrorWrongContext = "Context is not active"; |
29 const char* kCandidateNotFound = "Candidate not found"; | 29 const char* kCandidateNotFound = "Candidate not found"; |
30 const char* kEngineBusPrefix = "org.freedesktop.IBus."; | 30 const char* kEngineBusPrefix = "org.freedesktop.IBus."; |
31 | 31 |
32 namespace { | 32 namespace { |
33 const uint32 kIBusAltKeyMask = 1 << 3; | 33 const uint32 kIBusAltKeyMask = 1 << 3; |
34 const uint32 kIBusCtrlKeyMask = 1 << 2; | 34 const uint32 kIBusCtrlKeyMask = 1 << 2; |
35 const uint32 kIBusShiftKeyMask = 1 << 0; | 35 const uint32 kIBusShiftKeyMask = 1 << 0; |
36 const uint32 kIBusCapsLockMask = 1 << 1; | 36 const uint32 kIBusCapsLockMask = 1 << 1; |
37 const uint32 kIBusKeyReleaseMask = 1 << 30; | 37 const uint32 kIBusKeyReleaseMask = 1 << 30; |
38 | |
39 // Notices InputContextHandler that the preedit is changed. | |
satorux1
2013/11/15 02:15:50
Notifies?
Hiro Komatsu
2013/11/15 02:32:53
Done.
| |
40 void UpdatePreedit(const IBusText& ibus_text, | |
41 uint32 cursor_pos, | |
42 bool is_visible) { | |
43 IBusInputContextHandlerInterface* input_context = | |
44 IBusBridge::Get()->GetInputContextHandler(); | |
45 if (input_context) | |
46 input_context->UpdatePreeditText(ibus_text, cursor_pos, is_visible); | |
38 } | 47 } |
39 | 48 |
49 // Notices CandidateWindowHandler that the auxilary text is changed. | |
satorux1
2013/11/15 02:15:50
ditto
Hiro Komatsu
2013/11/15 02:32:53
Done.
| |
50 // Auxilary text is usually footer text. | |
51 void UpdateAuxiliaryText(const IBusText& ibus_text, bool is_visible) { | |
52 IBusPanelCandidateWindowHandlerInterface* candidate_window = | |
53 IBusBridge::Get()->GetCandidateWindowHandler(); | |
54 if (candidate_window) | |
55 candidate_window->UpdateAuxiliaryText(ibus_text.text(), is_visible); | |
56 } | |
57 | |
58 } // namespace | |
59 | |
40 InputMethodEngineIBus::InputMethodEngineIBus() | 60 InputMethodEngineIBus::InputMethodEngineIBus() |
41 : focused_(false), | 61 : focused_(false), |
42 active_(false), | 62 active_(false), |
43 context_id_(0), | 63 context_id_(0), |
44 next_context_id_(1), | 64 next_context_id_(1), |
45 is_create_engine_handler_called_(false), | |
46 aux_text_(new IBusText()), | 65 aux_text_(new IBusText()), |
47 aux_text_visible_(false), | 66 aux_text_visible_(false), |
48 observer_(NULL), | 67 observer_(NULL), |
49 preedit_text_(new IBusText()), | 68 preedit_text_(new IBusText()), |
50 preedit_cursor_(0), | 69 preedit_cursor_(0), |
51 candidate_window_(new input_method::CandidateWindow()), | 70 candidate_window_(new input_method::CandidateWindow()), |
52 window_visible_(false), | 71 window_visible_(false), |
53 weak_ptr_factory_(this) {} | 72 weak_ptr_factory_(this) {} |
54 | 73 |
55 InputMethodEngineIBus::~InputMethodEngineIBus() { | 74 InputMethodEngineIBus::~InputMethodEngineIBus() { |
56 input_method::InputMethodManager::Get()->RemoveInputMethodExtension(ibus_id_); | 75 input_method::InputMethodManager::Get()->RemoveInputMethodExtension(ibus_id_); |
57 | 76 |
58 // Do not unset engine before removing input method extension, above | 77 // Do not unset engine before removing input method extension, above |
59 // function may call reset function of engine object. | 78 // function may call reset function of engine object. |
60 if (is_create_engine_handler_called_) { | 79 if (IBusBridge::Get()->GetEngineHandler() == this) |
61 GetCurrentService()->UnsetEngine(this); | 80 IBusBridge::Get()->SetEngineHandler(NULL); |
62 ibus_engine_service_.reset(); | |
63 } | |
64 } | 81 } |
65 | 82 |
66 void InputMethodEngineIBus::Initialize( | 83 void InputMethodEngineIBus::Initialize( |
67 InputMethodEngine::Observer* observer, | 84 InputMethodEngine::Observer* observer, |
68 const char* engine_name, | 85 const char* engine_name, |
69 const char* extension_id, | 86 const char* extension_id, |
70 const char* engine_id, | 87 const char* engine_id, |
71 const char* description, | 88 const char* description, |
72 const std::vector<std::string>& languages, | 89 const std::vector<std::string>& languages, |
73 const std::vector<std::string>& layouts, | 90 const std::vector<std::string>& layouts, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 default: | 162 default: |
146 continue; | 163 continue; |
147 } | 164 } |
148 | 165 |
149 underline.start_index = segment->start; | 166 underline.start_index = segment->start; |
150 underline.end_index = segment->end; | 167 underline.end_index = segment->end; |
151 preedit_text_->mutable_underline_attributes()->push_back(underline); | 168 preedit_text_->mutable_underline_attributes()->push_back(underline); |
152 } | 169 } |
153 | 170 |
154 // TODO(nona): Makes focus out mode configuable, if necessary. | 171 // TODO(nona): Makes focus out mode configuable, if necessary. |
155 GetCurrentService()->UpdatePreedit( | 172 UpdatePreedit(*preedit_text_, preedit_cursor_, true); |
156 *preedit_text_.get(), | |
157 preedit_cursor_, | |
158 true, | |
159 IBusEngineService::IBUS_ENGINE_PREEEDIT_FOCUS_OUT_MODE_COMMIT); | |
160 return true; | 173 return true; |
161 } | 174 } |
162 | 175 |
163 bool InputMethodEngineIBus::ClearComposition(int context_id, | 176 bool InputMethodEngineIBus::ClearComposition(int context_id, |
164 std::string* error) { | 177 std::string* error) { |
165 if (!active_) { | 178 if (!active_) { |
166 *error = kErrorNotActive; | 179 *error = kErrorNotActive; |
167 return false; | 180 return false; |
168 } | 181 } |
169 if (context_id != context_id_ || context_id_ == -1) { | 182 if (context_id != context_id_ || context_id_ == -1) { |
170 *error = kErrorWrongContext; | 183 *error = kErrorWrongContext; |
171 return false; | 184 return false; |
172 } | 185 } |
173 | 186 |
174 preedit_cursor_ = 0; | 187 preedit_cursor_ = 0; |
175 preedit_text_.reset(new IBusText()); | 188 preedit_text_.reset(new IBusText()); |
176 GetCurrentService()->UpdatePreedit( | 189 UpdatePreedit(*preedit_text_, preedit_cursor_, false); |
177 *preedit_text_.get(), | |
178 0, | |
179 false, | |
180 IBusEngineService::IBUS_ENGINE_PREEEDIT_FOCUS_OUT_MODE_COMMIT); | |
181 return true; | 190 return true; |
182 } | 191 } |
183 | 192 |
184 bool InputMethodEngineIBus::CommitText(int context_id, const char* text, | 193 bool InputMethodEngineIBus::CommitText(int context_id, const char* text, |
185 std::string* error) { | 194 std::string* error) { |
186 if (!active_) { | 195 if (!active_) { |
187 // TODO: Commit the text anyways. | 196 // TODO: Commit the text anyways. |
188 *error = kErrorNotActive; | 197 *error = kErrorNotActive; |
189 return false; | 198 return false; |
190 } | 199 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
237 IBusBridge::Get()->GetCandidateWindowHandler(); | 246 IBusBridge::Get()->GetCandidateWindowHandler(); |
238 if (cw_handler) | 247 if (cw_handler) |
239 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); | 248 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); |
240 return true; | 249 return true; |
241 } | 250 } |
242 | 251 |
243 void InputMethodEngineIBus::SetCandidateWindowAuxText(const char* text) { | 252 void InputMethodEngineIBus::SetCandidateWindowAuxText(const char* text) { |
244 aux_text_->set_text(text); | 253 aux_text_->set_text(text); |
245 if (active_) { | 254 if (active_) { |
246 // Should not show auxiliary text if the whole window visibility is false. | 255 // Should not show auxiliary text if the whole window visibility is false. |
247 GetCurrentService()->UpdateAuxiliaryText( | 256 UpdateAuxiliaryText(*aux_text_, window_visible_ && aux_text_visible_); |
248 *aux_text_.get(), | |
249 window_visible_ && aux_text_visible_); | |
250 } | 257 } |
251 } | 258 } |
252 | 259 |
253 void InputMethodEngineIBus::SetCandidateWindowAuxTextVisible(bool visible) { | 260 void InputMethodEngineIBus::SetCandidateWindowAuxTextVisible(bool visible) { |
254 aux_text_visible_ = visible; | 261 aux_text_visible_ = visible; |
255 if (active_) { | 262 if (active_) { |
256 // Should not show auxiliary text if the whole window visibility is false. | 263 // Should not show auxiliary text if the whole window visibility is false. |
257 GetCurrentService()->UpdateAuxiliaryText( | 264 UpdateAuxiliaryText(*aux_text_, window_visible_ && aux_text_visible_); |
258 *aux_text_.get(), | |
259 window_visible_ && aux_text_visible_); | |
260 } | 265 } |
261 } | 266 } |
262 | 267 |
263 bool InputMethodEngineIBus::SetCandidates( | 268 bool InputMethodEngineIBus::SetCandidates( |
264 int context_id, | 269 int context_id, |
265 const std::vector<Candidate>& candidates, | 270 const std::vector<Candidate>& candidates, |
266 std::string* error) { | 271 std::string* error) { |
267 if (!active_) { | 272 if (!active_) { |
268 *error = kErrorNotActive; | 273 *error = kErrorNotActive; |
269 return false; | 274 return false; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 } | 379 } |
375 if (context_id != context_id_ || context_id_ == -1) { | 380 if (context_id != context_id_ || context_id_ == -1) { |
376 *error = kErrorWrongContext; | 381 *error = kErrorWrongContext; |
377 return false; | 382 return false; |
378 } | 383 } |
379 | 384 |
380 if (offset < 0 && static_cast<size_t>(-1 * offset) != size_t(number_of_chars)) | 385 if (offset < 0 && static_cast<size_t>(-1 * offset) != size_t(number_of_chars)) |
381 return false; // Currently we can only support preceding text. | 386 return false; // Currently we can only support preceding text. |
382 | 387 |
383 // TODO(nona): Return false if there is ongoing composition. | 388 // TODO(nona): Return false if there is ongoing composition. |
384 GetCurrentService()->DeleteSurroundingText(offset, number_of_chars); | 389 |
390 IBusInputContextHandlerInterface* input_context = | |
391 IBusBridge::Get()->GetInputContextHandler(); | |
392 if (input_context) | |
393 input_context->DeleteSurroundingText(offset, number_of_chars); | |
394 | |
385 return true; | 395 return true; |
386 } | 396 } |
387 | 397 |
388 void InputMethodEngineIBus::FocusIn(ibus::TextInputType text_input_type) { | 398 void InputMethodEngineIBus::FocusIn(ibus::TextInputType text_input_type) { |
389 focused_ = true; | 399 focused_ = true; |
390 if (!active_) | 400 if (!active_) |
391 return; | 401 return; |
392 context_id_ = next_context_id_; | 402 context_id_ = next_context_id_; |
393 ++next_context_id_; | 403 ++next_context_id_; |
394 | 404 |
(...skipping 29 matching lines...) Expand all Loading... | |
424 return; | 434 return; |
425 int context_id = context_id_; | 435 int context_id = context_id_; |
426 context_id_ = -1; | 436 context_id_ = -1; |
427 observer_->OnBlur(context_id); | 437 observer_->OnBlur(context_id); |
428 } | 438 } |
429 | 439 |
430 void InputMethodEngineIBus::Enable() { | 440 void InputMethodEngineIBus::Enable() { |
431 active_ = true; | 441 active_ = true; |
432 observer_->OnActivate(engine_id_); | 442 observer_->OnActivate(engine_id_); |
433 FocusIn(ibus::TEXT_INPUT_TYPE_TEXT); | 443 FocusIn(ibus::TEXT_INPUT_TYPE_TEXT); |
434 | |
435 // Calls RequireSurroundingText once here to notify ibus-daemon to send | |
436 // surrounding text to this engine. | |
437 GetCurrentService()->RequireSurroundingText(); | |
438 } | 444 } |
439 | 445 |
440 void InputMethodEngineIBus::Disable() { | 446 void InputMethodEngineIBus::Disable() { |
441 active_ = false; | 447 active_ = false; |
442 observer_->OnDeactivated(engine_id_); | 448 observer_->OnDeactivated(engine_id_); |
443 } | 449 } |
444 | 450 |
445 void InputMethodEngineIBus::PropertyActivate(const std::string& property_name) { | 451 void InputMethodEngineIBus::PropertyActivate(const std::string& property_name) { |
446 observer_->OnMenuItemActivated(engine_id_, property_name); | 452 observer_->OnMenuItemActivated(engine_id_, property_name); |
447 } | 453 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 | 521 |
516 void InputMethodEngineIBus::SetSurroundingText(const std::string& text, | 522 void InputMethodEngineIBus::SetSurroundingText(const std::string& text, |
517 uint32 cursor_pos, | 523 uint32 cursor_pos, |
518 uint32 anchor_pos) { | 524 uint32 anchor_pos) { |
519 observer_->OnSurroundingTextChanged(engine_id_, | 525 observer_->OnSurroundingTextChanged(engine_id_, |
520 text, | 526 text, |
521 static_cast<int>(cursor_pos), | 527 static_cast<int>(cursor_pos), |
522 static_cast<int>(anchor_pos)); | 528 static_cast<int>(anchor_pos)); |
523 } | 529 } |
524 | 530 |
525 IBusEngineService* InputMethodEngineIBus::GetCurrentService() { | |
526 if (!ibus_engine_service_) | |
527 ibus_engine_service_.reset(IBusEngineService::Create()); | |
528 return ibus_engine_service_.get(); | |
529 } | |
530 | |
531 void InputMethodEngineIBus::MenuItemToProperty( | 531 void InputMethodEngineIBus::MenuItemToProperty( |
532 const MenuItem& item, | 532 const MenuItem& item, |
533 input_method::InputMethodProperty* property) { | 533 input_method::InputMethodProperty* property) { |
534 property->key = item.id; | 534 property->key = item.id; |
535 | 535 |
536 if (item.modified & MENU_ITEM_MODIFIED_LABEL) { | 536 if (item.modified & MENU_ITEM_MODIFIED_LABEL) { |
537 property->label = item.label; | 537 property->label = item.label; |
538 } | 538 } |
539 if (item.modified & MENU_ITEM_MODIFIED_VISIBLE) { | 539 if (item.modified & MENU_ITEM_MODIFIED_VISIBLE) { |
540 // TODO(nona): Implement it. | 540 // TODO(nona): Implement it. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
577 } | 577 } |
578 | 578 |
579 void InputMethodEngineIBus::RegisterComponent() { | 579 void InputMethodEngineIBus::RegisterComponent() { |
580 IBusBridge::Get()->SetCreateEngineHandler( | 580 IBusBridge::Get()->SetCreateEngineHandler( |
581 ibus_id_, | 581 ibus_id_, |
582 base::Bind(&InputMethodEngineIBus::CreateEngineHandler, | 582 base::Bind(&InputMethodEngineIBus::CreateEngineHandler, |
583 weak_ptr_factory_.GetWeakPtr())); | 583 weak_ptr_factory_.GetWeakPtr())); |
584 } | 584 } |
585 | 585 |
586 void InputMethodEngineIBus::CreateEngineHandler() { | 586 void InputMethodEngineIBus::CreateEngineHandler() { |
587 GetCurrentService()->UnsetEngine(this); | 587 IBusBridge::Get()->SetEngineHandler(this); |
588 ibus_engine_service_.reset(); | |
589 GetCurrentService()->SetEngine(this); | |
590 is_create_engine_handler_called_ = true; | |
591 } | 588 } |
592 | 589 |
593 } // namespace chromeos | 590 } // namespace chromeos |
OLD | NEW |