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 void UpdatePreedit(const IBusText& ibus_text, | |
satorux1
2013/11/13 14:22:07
function comment is missing.
Hiro Komatsu
2013/11/14 01:55:24
Done.
| |
40 uint32 cursor_pos, | |
41 bool is_visible) { | |
42 IBusInputContextHandlerInterface* input_context = | |
43 IBusBridge::Get()->GetInputContextHandler(); | |
44 if (input_context) | |
45 input_context->UpdatePreeditText(ibus_text, cursor_pos, is_visible); | |
38 } | 46 } |
39 | 47 |
48 void UpdateAuxiliaryText(const IBusText& ibus_text, bool is_visible) { | |
satorux1
2013/11/13 14:22:07
ditto.
Hiro Komatsu
2013/11/14 01:55:24
Done.
| |
49 IBusPanelCandidateWindowHandlerInterface* candidate_window = | |
50 IBusBridge::Get()->GetCandidateWindowHandler(); | |
51 if (candidate_window) | |
52 candidate_window->UpdateAuxiliaryText(ibus_text.text(), is_visible); | |
53 } | |
54 | |
55 } // namespace | |
56 | |
40 InputMethodEngineIBus::InputMethodEngineIBus() | 57 InputMethodEngineIBus::InputMethodEngineIBus() |
41 : focused_(false), | 58 : focused_(false), |
42 active_(false), | 59 active_(false), |
43 context_id_(0), | 60 context_id_(0), |
44 next_context_id_(1), | 61 next_context_id_(1), |
45 is_create_engine_handler_called_(false), | |
46 aux_text_(new IBusText()), | 62 aux_text_(new IBusText()), |
47 aux_text_visible_(false), | 63 aux_text_visible_(false), |
48 observer_(NULL), | 64 observer_(NULL), |
49 preedit_text_(new IBusText()), | 65 preedit_text_(new IBusText()), |
50 preedit_cursor_(0), | 66 preedit_cursor_(0), |
51 candidate_window_(new input_method::CandidateWindow()), | 67 candidate_window_(new input_method::CandidateWindow()), |
52 window_visible_(false), | 68 window_visible_(false), |
53 weak_ptr_factory_(this) {} | 69 weak_ptr_factory_(this) {} |
54 | 70 |
55 InputMethodEngineIBus::~InputMethodEngineIBus() { | 71 InputMethodEngineIBus::~InputMethodEngineIBus() { |
56 input_method::InputMethodManager::Get()->RemoveInputMethodExtension(ibus_id_); | 72 input_method::InputMethodManager::Get()->RemoveInputMethodExtension(ibus_id_); |
57 | 73 |
58 // Do not unset engine before removing input method extension, above | 74 // Do not unset engine before removing input method extension, above |
59 // function may call reset function of engine object. | 75 // function may call reset function of engine object. |
60 if (is_create_engine_handler_called_) { | 76 if (IBusBridge::Get()->GetEngineHandler() == this) |
61 GetCurrentService()->UnsetEngine(this); | 77 IBusBridge::Get()->SetEngineHandler(NULL); |
62 ibus_engine_service_.reset(); | |
63 } | |
64 } | 78 } |
65 | 79 |
66 void InputMethodEngineIBus::Initialize( | 80 void InputMethodEngineIBus::Initialize( |
67 InputMethodEngine::Observer* observer, | 81 InputMethodEngine::Observer* observer, |
68 const char* engine_name, | 82 const char* engine_name, |
69 const char* extension_id, | 83 const char* extension_id, |
70 const char* engine_id, | 84 const char* engine_id, |
71 const char* description, | 85 const char* description, |
72 const std::vector<std::string>& languages, | 86 const std::vector<std::string>& languages, |
73 const std::vector<std::string>& layouts, | 87 const std::vector<std::string>& layouts, |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
145 default: | 159 default: |
146 continue; | 160 continue; |
147 } | 161 } |
148 | 162 |
149 underline.start_index = segment->start; | 163 underline.start_index = segment->start; |
150 underline.end_index = segment->end; | 164 underline.end_index = segment->end; |
151 preedit_text_->mutable_underline_attributes()->push_back(underline); | 165 preedit_text_->mutable_underline_attributes()->push_back(underline); |
152 } | 166 } |
153 | 167 |
154 // TODO(nona): Makes focus out mode configuable, if necessary. | 168 // TODO(nona): Makes focus out mode configuable, if necessary. |
155 GetCurrentService()->UpdatePreedit( | 169 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; | 170 return true; |
161 } | 171 } |
162 | 172 |
163 bool InputMethodEngineIBus::ClearComposition(int context_id, | 173 bool InputMethodEngineIBus::ClearComposition(int context_id, |
164 std::string* error) { | 174 std::string* error) { |
165 if (!active_) { | 175 if (!active_) { |
166 *error = kErrorNotActive; | 176 *error = kErrorNotActive; |
167 return false; | 177 return false; |
168 } | 178 } |
169 if (context_id != context_id_ || context_id_ == -1) { | 179 if (context_id != context_id_ || context_id_ == -1) { |
170 *error = kErrorWrongContext; | 180 *error = kErrorWrongContext; |
171 return false; | 181 return false; |
172 } | 182 } |
173 | 183 |
174 preedit_cursor_ = 0; | 184 preedit_cursor_ = 0; |
175 preedit_text_.reset(new IBusText()); | 185 preedit_text_.reset(new IBusText()); |
176 GetCurrentService()->UpdatePreedit( | 186 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; | 187 return true; |
182 } | 188 } |
183 | 189 |
184 bool InputMethodEngineIBus::CommitText(int context_id, const char* text, | 190 bool InputMethodEngineIBus::CommitText(int context_id, const char* text, |
185 std::string* error) { | 191 std::string* error) { |
186 if (!active_) { | 192 if (!active_) { |
187 // TODO: Commit the text anyways. | 193 // TODO: Commit the text anyways. |
188 *error = kErrorNotActive; | 194 *error = kErrorNotActive; |
189 return false; | 195 return false; |
190 } | 196 } |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
237 IBusBridge::Get()->GetCandidateWindowHandler(); | 243 IBusBridge::Get()->GetCandidateWindowHandler(); |
238 if (cw_handler) | 244 if (cw_handler) |
239 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); | 245 cw_handler->UpdateLookupTable(*candidate_window_, window_visible_); |
240 return true; | 246 return true; |
241 } | 247 } |
242 | 248 |
243 void InputMethodEngineIBus::SetCandidateWindowAuxText(const char* text) { | 249 void InputMethodEngineIBus::SetCandidateWindowAuxText(const char* text) { |
244 aux_text_->set_text(text); | 250 aux_text_->set_text(text); |
245 if (active_) { | 251 if (active_) { |
246 // Should not show auxiliary text if the whole window visibility is false. | 252 // Should not show auxiliary text if the whole window visibility is false. |
247 GetCurrentService()->UpdateAuxiliaryText( | 253 UpdateAuxiliaryText(*aux_text_, window_visible_ && aux_text_visible_); |
248 *aux_text_.get(), | |
249 window_visible_ && aux_text_visible_); | |
250 } | 254 } |
251 } | 255 } |
252 | 256 |
253 void InputMethodEngineIBus::SetCandidateWindowAuxTextVisible(bool visible) { | 257 void InputMethodEngineIBus::SetCandidateWindowAuxTextVisible(bool visible) { |
254 aux_text_visible_ = visible; | 258 aux_text_visible_ = visible; |
255 if (active_) { | 259 if (active_) { |
256 // Should not show auxiliary text if the whole window visibility is false. | 260 // Should not show auxiliary text if the whole window visibility is false. |
257 GetCurrentService()->UpdateAuxiliaryText( | 261 UpdateAuxiliaryText(*aux_text_, window_visible_ && aux_text_visible_); |
258 *aux_text_.get(), | |
259 window_visible_ && aux_text_visible_); | |
260 } | 262 } |
261 } | 263 } |
262 | 264 |
263 bool InputMethodEngineIBus::SetCandidates( | 265 bool InputMethodEngineIBus::SetCandidates( |
264 int context_id, | 266 int context_id, |
265 const std::vector<Candidate>& candidates, | 267 const std::vector<Candidate>& candidates, |
266 std::string* error) { | 268 std::string* error) { |
267 if (!active_) { | 269 if (!active_) { |
268 *error = kErrorNotActive; | 270 *error = kErrorNotActive; |
269 return false; | 271 return false; |
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
374 } | 376 } |
375 if (context_id != context_id_ || context_id_ == -1) { | 377 if (context_id != context_id_ || context_id_ == -1) { |
376 *error = kErrorWrongContext; | 378 *error = kErrorWrongContext; |
377 return false; | 379 return false; |
378 } | 380 } |
379 | 381 |
380 if (offset < 0 && static_cast<size_t>(-1 * offset) != size_t(number_of_chars)) | 382 if (offset < 0 && static_cast<size_t>(-1 * offset) != size_t(number_of_chars)) |
381 return false; // Currently we can only support preceding text. | 383 return false; // Currently we can only support preceding text. |
382 | 384 |
383 // TODO(nona): Return false if there is ongoing composition. | 385 // TODO(nona): Return false if there is ongoing composition. |
384 GetCurrentService()->DeleteSurroundingText(offset, number_of_chars); | 386 |
387 IBusInputContextHandlerInterface* input_context = | |
388 IBusBridge::Get()->GetInputContextHandler(); | |
389 if (input_context) | |
390 input_context->DeleteSurroundingText(offset, number_of_chars); | |
391 | |
385 return true; | 392 return true; |
386 } | 393 } |
387 | 394 |
388 void InputMethodEngineIBus::FocusIn(ibus::TextInputType text_input_type) { | 395 void InputMethodEngineIBus::FocusIn(ibus::TextInputType text_input_type) { |
389 focused_ = true; | 396 focused_ = true; |
390 if (!active_) | 397 if (!active_) |
391 return; | 398 return; |
392 context_id_ = next_context_id_; | 399 context_id_ = next_context_id_; |
393 ++next_context_id_; | 400 ++next_context_id_; |
394 | 401 |
(...skipping 29 matching lines...) Expand all Loading... | |
424 return; | 431 return; |
425 int context_id = context_id_; | 432 int context_id = context_id_; |
426 context_id_ = -1; | 433 context_id_ = -1; |
427 observer_->OnBlur(context_id); | 434 observer_->OnBlur(context_id); |
428 } | 435 } |
429 | 436 |
430 void InputMethodEngineIBus::Enable() { | 437 void InputMethodEngineIBus::Enable() { |
431 active_ = true; | 438 active_ = true; |
432 observer_->OnActivate(engine_id_); | 439 observer_->OnActivate(engine_id_); |
433 FocusIn(ibus::TEXT_INPUT_TYPE_TEXT); | 440 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 } | 441 } |
439 | 442 |
440 void InputMethodEngineIBus::Disable() { | 443 void InputMethodEngineIBus::Disable() { |
441 active_ = false; | 444 active_ = false; |
442 observer_->OnDeactivated(engine_id_); | 445 observer_->OnDeactivated(engine_id_); |
443 } | 446 } |
444 | 447 |
445 void InputMethodEngineIBus::PropertyActivate(const std::string& property_name) { | 448 void InputMethodEngineIBus::PropertyActivate(const std::string& property_name) { |
446 observer_->OnMenuItemActivated(engine_id_, property_name); | 449 observer_->OnMenuItemActivated(engine_id_, property_name); |
447 } | 450 } |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
515 | 518 |
516 void InputMethodEngineIBus::SetSurroundingText(const std::string& text, | 519 void InputMethodEngineIBus::SetSurroundingText(const std::string& text, |
517 uint32 cursor_pos, | 520 uint32 cursor_pos, |
518 uint32 anchor_pos) { | 521 uint32 anchor_pos) { |
519 observer_->OnSurroundingTextChanged(engine_id_, | 522 observer_->OnSurroundingTextChanged(engine_id_, |
520 text, | 523 text, |
521 static_cast<int>(cursor_pos), | 524 static_cast<int>(cursor_pos), |
522 static_cast<int>(anchor_pos)); | 525 static_cast<int>(anchor_pos)); |
523 } | 526 } |
524 | 527 |
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( | 528 void InputMethodEngineIBus::MenuItemToProperty( |
532 const MenuItem& item, | 529 const MenuItem& item, |
533 input_method::InputMethodProperty* property) { | 530 input_method::InputMethodProperty* property) { |
534 property->key = item.id; | 531 property->key = item.id; |
535 | 532 |
536 if (item.modified & MENU_ITEM_MODIFIED_LABEL) { | 533 if (item.modified & MENU_ITEM_MODIFIED_LABEL) { |
537 property->label = item.label; | 534 property->label = item.label; |
538 } | 535 } |
539 if (item.modified & MENU_ITEM_MODIFIED_VISIBLE) { | 536 if (item.modified & MENU_ITEM_MODIFIED_VISIBLE) { |
540 // TODO(nona): Implement it. | 537 // TODO(nona): Implement it. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
577 } | 574 } |
578 | 575 |
579 void InputMethodEngineIBus::RegisterComponent() { | 576 void InputMethodEngineIBus::RegisterComponent() { |
580 IBusBridge::Get()->SetCreateEngineHandler( | 577 IBusBridge::Get()->SetCreateEngineHandler( |
581 ibus_id_, | 578 ibus_id_, |
582 base::Bind(&InputMethodEngineIBus::CreateEngineHandler, | 579 base::Bind(&InputMethodEngineIBus::CreateEngineHandler, |
583 weak_ptr_factory_.GetWeakPtr())); | 580 weak_ptr_factory_.GetWeakPtr())); |
584 } | 581 } |
585 | 582 |
586 void InputMethodEngineIBus::CreateEngineHandler() { | 583 void InputMethodEngineIBus::CreateEngineHandler() { |
587 GetCurrentService()->UnsetEngine(this); | 584 IBusBridge::Get()->SetEngineHandler(this); |
588 ibus_engine_service_.reset(); | |
589 GetCurrentService()->SetEngine(this); | |
590 is_create_engine_handler_called_ = true; | |
591 } | 585 } |
592 | 586 |
593 } // namespace chromeos | 587 } // namespace chromeos |
OLD | NEW |